@meistrari/tela-cli 0.7.58 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCliCredentialAdapter = createCliCredentialAdapter;
4
+ const tela_local_config_1 = require("@meistrari/tela-local-config");
5
+ function createCliCredentialAdapter(env = process.env) {
6
+ return (0, tela_local_config_1.createLocalCredentialAdapter)(env);
7
+ }
@@ -0,0 +1,434 @@
1
+ ## API Reference
2
+
3
+ Workflow Code lets you describe a Tela Workflow V3 workflow as typed, inert TypeScript. Authoring APIs create declarations only. The compiler later validates references, evaluates supported `code()` handlers from source, and produces deterministic Workflow V3 payloads.
4
+
5
+ Use this page as the complete authoring guide while writing workflow source.
6
+
7
+ ### Authoring model
8
+
9
+ Import the authoring helpers from `@meistrari/workflow-code`.
10
+
11
+ ```ts
12
+ import {
13
+ agent,
14
+ build,
15
+ code,
16
+ input,
17
+ llm,
18
+ workflow,
19
+ } from '@meistrari/workflow-code'
20
+ import type { WorkflowCodeConfig } from '@meistrari/workflow-code'
21
+ ```
22
+
23
+ | API | Use it for |
24
+ | --- | --- |
25
+ | [`workflow()`](#workflowworkflowkey) | Naming the workflow with a stable source key. |
26
+ | [`build()`](#buildworkflowhandle-options) | Creating the default-exported declaration consumed by `compile`. |
27
+ | [`input.text()`](#inputtextoptions) | Text input supplied by a user, API caller, or run payload. |
28
+ | [`input.file()`](#inputfileoptions) | File input supplied by upload or Vault reference. |
29
+ | [`llm()`](#llmoptions) | Single model-call transformation with optional structured output. |
30
+ | [`agent()`](#agentoptions) | Multi-round reasoning, tool use, Tela tools, or external skills. |
31
+ | [`code()`](#codeoptions) | Sandboxed runtime JavaScript/TypeScript execution. |
32
+ | [`ref()` / `paths()` / `formats()`](#references-ref-paths-and-formats) | References to workflow inputs or prior node output in prompt callbacks and code handlers. |
33
+
34
+ A workflow file normally creates inputs, creates nodes, then default-exports `build(workflow(...), { inputs, nodes })`.
35
+
36
+ ```ts
37
+ import { agent, build, input, llm, workflow } from '@meistrari/workflow-code'
38
+
39
+ const topic = input.text({ name: 'topic', required: true })
40
+
41
+ const outline = llm({
42
+ name: 'Draft outline',
43
+ input: {
44
+ temperature: 0.2,
45
+ prompt: ({ ref }) => `Create an outline about ${ref(topic).formats().format}.`,
46
+ },
47
+ schema: {
48
+ bullets: { type: 'array', items: { type: 'string' } },
49
+ },
50
+ })
51
+
52
+ const review = agent({
53
+ name: 'Review outline',
54
+ input: {
55
+ maxRounds: 8,
56
+ prompt: ({ ref, paths }) => [
57
+ 'Review this outline for a new Tela user.',
58
+ `Bullets: ${ref(outline, paths(outline).bullets).formats().format}`,
59
+ ].join('\n'),
60
+ },
61
+ })
62
+
63
+ export default build(workflow('first-workflow'), {
64
+ inputs: [topic],
65
+ nodes: [outline, review],
66
+ })
67
+ ```
68
+
69
+ Rules to keep in mind:
70
+
71
+ - Declarations are inert. They do not create remote workflows, publish versions, or run handlers.
72
+ - `nodes` order is execution order. Adjacent nodes compile to default Workflow V3 edges.
73
+ - `key` is optional on inputs and nodes. Use it when display `name` may change but identity should stay stable.
74
+ - References in node inputs may target workflow inputs or earlier nodes. Forward references are compile diagnostics.
75
+
76
+
77
+ ### References: `ref()`, `paths()`, and `formats()`
78
+
79
+ Workflow references connect node inputs to workflow inputs or earlier node outputs. Under the hood, Tela represents those links as URI references such as `input://customer_question` or `step://extract_invoice?path=total&format=...`. Workflow Code hides the URI string and exposes typed helpers instead.
80
+
81
+ The important rule is that reference compatibility is decided by the destination node input. A node input declares which value shapes it accepts and which reference formats make sense for those shapes. For example, a prompt input can accept text-oriented references, file-oriented references, object fields, numbers, or booleans, but each source may expose different formats. The helper types should guide you toward the formats that are valid for the specific input you are authoring.
82
+
83
+ | Helper | What it does |
84
+ | --- | --- |
85
+ | `ref(input)` | References a workflow input. In prompt-like inputs it renders a reference token; in `code()` handlers it reads the runtime value. |
86
+ | `ref(node)` | References an earlier node output. Forward references to later nodes are compile diagnostics. |
87
+ | `paths(node).field` | Selects a typed field from a node output schema. Pass the selected path as the second argument to `ref()`. |
88
+ | `formats().format` | Chooses the destination-compatible representation for a prompt/reference token. Available formats depend on the destination input and referenced value shape. |
89
+
90
+ ```ts
91
+ const extractInvoice = llm({
92
+ name: 'Extract invoice data',
93
+ input: {
94
+ prompt: ({ ref }) => [
95
+ 'Extract invoice data from this document.',
96
+ ref(invoicePdf).formats().format,
97
+ ].join('\n'),
98
+ },
99
+ schema: {
100
+ vendor: { type: 'string' },
101
+ total: { type: 'number' },
102
+ },
103
+ })
104
+
105
+ const reviewInvoice = agent({
106
+ name: 'Review invoice extraction',
107
+ input: {
108
+ prompt: ({ ref, paths }) => [
109
+ `Vendor: ${ref(extractInvoice, paths(extractInvoice).vendor).formats().format}`,
110
+ `Total: ${ref(extractInvoice, paths(extractInvoice).total).formats().format}`,
111
+ ].join('\n'),
112
+ },
113
+ })
114
+
115
+ const normalizeInvoice = code({
116
+ name: 'Normalize invoice',
117
+ handler: ({ ref, paths }) => {
118
+ const vendor = ref(extractInvoice, paths(extractInvoice).vendor)
119
+ const total = Number(ref(extractInvoice, paths(extractInvoice).total))
120
+ return { vendor: String(vendor).trim(), totalCents: Math.round(total * 100) }
121
+ },
122
+ })
123
+ ```
124
+
125
+ Reference rules:
126
+
127
+ - References in node inputs may target workflow inputs or earlier nodes.
128
+ - `paths()` only accepts node declarations, not inputs.
129
+ - Path tokens are branded; do not replace them with strings or arrays.
130
+ - A path token must come from the same node used in `ref()`, or authoring throws `ref path source must match ref target`.
131
+ - In prompt/reference inputs, call `formats()` on `ref(...)` when the input needs a specific representation.
132
+ - In code handlers, `ref(...)` returns runtime data directly, so `formats()` is not available.
133
+
134
+ ### `workflow(workflowKey)`
135
+
136
+ ```ts
137
+ function workflow(workflowKey: string): WorkflowHandle
138
+ ```
139
+
140
+ Creates the workflow handle passed to `build()`. The key is the stable source identity for review, config matching, and deterministic compiler output.
141
+
142
+ | Parameter | Type | Required | Description |
143
+ | --- | --- | --- | --- |
144
+ | `workflowKey` | `string` | Yes | Non-empty author-facing key such as `invoice-processing`. If `workflow-code.config.ts` sets `workflowKey`, compile reports a mismatch when values differ. |
145
+
146
+ | Returns | Description |
147
+ | --- | --- |
148
+ | `WorkflowHandle` | Frozen object with `kind: 'workflow'` and `workflowKey`. |
149
+
150
+ ```ts
151
+ const invoiceWorkflow = workflow('invoice-processing')
152
+ ```
153
+
154
+ Use lowercase, stable, reviewable keys. Do not put project ids, prompt ids, secrets, or environment names in `workflowKey`.
155
+
156
+ ### `build(workflowHandle, options)`
157
+
158
+ ```ts
159
+ type BuildOptions = {
160
+ input?: readonly InputDeclaration[]
161
+ inputs?: readonly InputDeclaration[]
162
+ nodes: readonly NodeDeclaration[]
163
+ }
164
+
165
+ function build(workflow: WorkflowHandle, options: BuildOptions): WorkflowDeclaration
166
+ ```
167
+
168
+ Finalizes the workflow declaration. The compiled graph is derived from `inputs` and ordered `nodes`; authors should not hand-author raw Workflow V3 edge objects.
169
+
170
+ | Parameter | Type | Required | Description |
171
+ | --- | --- | --- | --- |
172
+ | `workflow` | `WorkflowHandle` | Yes | Handle returned by `workflow()`. |
173
+ | `options.input` | `readonly InputDeclaration[]` | No | Scaffold-friendly alias for `options.inputs`. |
174
+ | `options.inputs` | `readonly InputDeclaration[]` | No | Inputs available to prompts, code handlers, and runtime callers. Defaults to an empty array. |
175
+ | `options.nodes` | `readonly NodeDeclaration[]` | Yes | Ordered node sequence. MVP compile lowers adjacent nodes into default edges. |
176
+
177
+ | Returns | Description |
178
+ | --- | --- |
179
+ | `WorkflowDeclaration` | Frozen declaration expected as the workflow module default export. |
180
+
181
+ ```ts
182
+ export default build(workflow('support-triage'), {
183
+ inputs: [message, attachment],
184
+ nodes: [classify, draftReply, normalizeResult],
185
+ })
186
+ ```
187
+
188
+ Author one `build()` default export per workflow entrypoint.
189
+
190
+ ### `input.text(options)`
191
+
192
+ ```ts
193
+ declare function text(options: BaseInputOptions): TextInputDeclaration
194
+ ```
195
+
196
+ Declares a text input. Text inputs are best for prompts, questions, small JSON snippets, URLs, or freeform user instructions.
197
+
198
+
199
+
200
+ | Option | Type | Required | Default | Description |
201
+ | --- | --- | --- | --- | --- |
202
+ | `name` | `string` | Yes | — | Human-readable input name. Also used as fallback identity when `key` is omitted. |
203
+ | `required` | `boolean` | No | `false` | Whether callers must supply the value. |
204
+ | `description` | `string` | No | — | Help text for UI and metadata. |
205
+ | `key` | `string` | No | `name` | Stable identity independent from display `name`. |
206
+
207
+ ```ts
208
+ const customerQuestion = input.text({
209
+ name: 'customer question',
210
+ key: 'customer_question',
211
+ required: true,
212
+ description: 'Question or support request to answer.',
213
+ })
214
+ ```
215
+
216
+ ### `input.file(options)`
217
+
218
+ ```ts
219
+ declare function file(options: BaseInputOptions): FileInputDeclaration
220
+ ```
221
+
222
+ Declares a file input. Use it for uploaded documents, images, or PDFs passed to the workflow.
223
+
224
+ | Option | Type | Required | Default | Description |
225
+ | --- | --- | --- | --- | --- |
226
+ | `name` | `string` | Yes | — | Human-readable file input name. |
227
+ | `required` | `boolean` | No | `false` | Whether callers must supply the file. |
228
+ | `description` | `string` | No | — | UI/help text explaining supported file expectations. |
229
+ | `key` | `string` | No | `name` | Stable identity independent from display `name`. |
230
+
231
+ ```ts
232
+ const invoicePdf = input.file({
233
+ name: 'invoice PDF',
234
+ key: 'invoice_pdf',
235
+ required: true,
236
+ description: 'PDF invoice to extract and review.',
237
+ })
238
+ ```
239
+
240
+ ### `llm(options)`
241
+
242
+ ```ts
243
+ type LlmOptions = {
244
+ name: string
245
+ key?: string
246
+ input: {
247
+ prompt: string | ((context: PromptFactoryContext) => string)
248
+ model?: string
249
+ temperature?: number
250
+ }
251
+ schema?: WorkflowCodeOutputSchema | null
252
+ }
253
+
254
+ function llm(options: LlmOptions): LlmNodeDeclaration
255
+ ```
256
+
257
+ Declares a single LLM completion node. Use `llm()` for bounded transformations where one model call should produce the desired output.
258
+
259
+ | Option | Type | Required | Description |
260
+ | --- | --- | --- | --- |
261
+ | `name` | `string` | Yes | Display name and fallback node identity. Must be non-empty. |
262
+ | `key` | `string` | No | Stable identity when `name` may change. |
263
+ | `input.prompt` | `string \| (context) => string` | Yes | Prompt text. Callback form enables `ref()` and `paths()`. Must render to non-empty string. |
264
+ | `input.model` | `string` | No | Model id passed through to Workflow V3 completion input. |
265
+ | `input.temperature` | `number` | No | Model temperature passed through to Workflow V3 completion input. |
266
+ | `schema` | `WorkflowCodeOutputSchema \| null` | No | Structured output fields for the model response. Use field names mapped to JSON-schema-like field definitions; omit for default behavior or set `null` when intentionally no schema should be emitted. |
267
+
268
+ `schema` helps constrain the completion output and creates named fields that later nodes can reference with `paths()`. Keep fields small and explicit: use `type`, `description`, `enum`, `properties`, `items`, and `required` when useful.
269
+
270
+ ```ts
271
+ const extractInvoice = llm({
272
+ name: 'Extract invoice data',
273
+ key: 'extract_invoice',
274
+ input: {
275
+ model: 'gpt-4.1-mini',
276
+ temperature: 0,
277
+ prompt: ({ ref }) => [
278
+ 'Extract invoice data from this document.',
279
+ ref(invoicePdf).formats().format,
280
+ ].join('\n'),
281
+ },
282
+ schema: {
283
+ vendor: { type: 'string', description: 'Supplier name.' },
284
+ total: { type: 'number', description: 'Invoice total.' },
285
+ lineItems: {
286
+ type: 'array',
287
+ items: {
288
+ type: 'object',
289
+ properties: {
290
+ description: { type: 'string' },
291
+ amount: { type: 'number' },
292
+ },
293
+ },
294
+ },
295
+ },
296
+ })
297
+ ```
298
+
299
+ ### `agent(options)`
300
+
301
+ ```ts
302
+ type AgentOptions = {
303
+ name: string
304
+ key?: string
305
+ input: {
306
+ prompt: string | ((context: PromptFactoryContext) => string)
307
+ model?: string
308
+ maxRounds?: number
309
+ tools?: AgentToolOptions
310
+ }
311
+ schema?: WorkflowCodeOutputSchema | null
312
+ }
313
+
314
+ function agent(options: AgentOptions): AgentNodeDeclaration
315
+ ```
316
+
317
+ Declares an agent node. Use `agent()` when the step may need iteration, tool calls, Tela tools, or broader reasoning than a single completion.
318
+
319
+ | Option | Type | Required | Description |
320
+ | --- | --- | --- | --- |
321
+ | `name` | `string` | Yes | Display name and fallback node identity. Must be non-empty. |
322
+ | `key` | `string` | No | Stable identity when `name` may change. |
323
+ | `input.prompt` | `string \| (context) => string` | Yes | Agent instruction. Callback form enables `ref()` and `paths()`. Must render to non-empty string. |
324
+ | `input.model` | `string` | No | Agent model id passed through to Workflow V3. |
325
+ | `input.maxRounds` | `number` | No | Maximum reasoning/tool-use rounds. |
326
+ | `input.tools` | `AgentToolOptions` | No | Built-in or platform tool options accepted by Workflow V3. |
327
+ | `schema` | `WorkflowCodeOutputSchema \| null` | No | Structured output fields for the agent result. Use field names mapped to JSON-schema-like field definitions; omit for default behavior or set `null` when intentionally no schema should be emitted. |
328
+
329
+ `schema` gives the agent an explicit result contract after reasoning/tool use and creates fields that downstream nodes can reference with `paths()`. Keep fields small and explicit: use `type`, `description`, `enum`, `properties`, `items`, and `required` when useful.
330
+
331
+ ```ts
332
+ const reviewInvoice = agent({
333
+ name: 'Review invoice extraction',
334
+ key: 'review_invoice',
335
+ input: {
336
+ maxRounds: 6,
337
+ prompt: ({ ref, paths }) => [
338
+ 'Review extracted invoice data for missing or suspicious fields.',
339
+ `Vendor: ${ref(extractInvoice, paths(extractInvoice).vendor).formats().format}`,
340
+ `Total: ${ref(extractInvoice, paths(extractInvoice).total).formats().format}`,
341
+ ].join('\n'),
342
+ },
343
+ schema: {
344
+ approved: { type: 'boolean' },
345
+ notes: { type: 'array', items: { type: 'string' } },
346
+ },
347
+ })
348
+ ```
349
+
350
+ Choose `agent()` over `llm()` when the workflow step needs investigation, retries, tools, or judgment across multiple pieces of context.
351
+
352
+ ### `code(options)`
353
+
354
+ ```ts
355
+ type CodeOptions<Handler extends CodeHandler = CodeHandler> = {
356
+ name: string
357
+ key?: string
358
+ handler: Handler
359
+ libraries?: readonly string[]
360
+ }
361
+
362
+ type CodeHandler<Output = unknown> = (
363
+ context: CodeHandlerContext,
364
+ ) => Output | Promise<Output>
365
+
366
+ function code<Handler extends CodeHandler>(
367
+ options: CodeOptions<Handler>,
368
+ ): CodeNodeHandle<Awaited<ReturnType<Handler>>>
369
+ ```
370
+
371
+ Declares a typed code-execution node. `compile` evaluates trusted declaration modules but does not call the handler. Instead, the compiler extracts supported handler source, rewrites Workflow Code `ref()` reads to runtime input access, computes library metadata, and emits sandbox code for Workflow V3 execution. The handler return type becomes the `CodeNodeHandle` output type, so downstream `paths(codeNode).field` references can autocomplete against that shape.
372
+
373
+ | Option | Type | Required | Description |
374
+ | --- | --- | --- | --- |
375
+ | `name` | `string` | Yes | Display name and fallback node identity. Must be non-empty. |
376
+ | `key` | `string` | No | Stable identity when `name` may change. |
377
+ | `handler` | `CodeHandler` | Yes | Runtime function. Receives `ref()` and `paths()` helpers for workflow inputs and prior nodes. |
378
+ | `libraries` | `readonly string[]` | No | Explicit sandbox package specs such as `zod@4.3.6`. User specs win over inferred package versions. |
379
+
380
+ ```ts
381
+ const normalizeInvoice = code({
382
+ name: 'Normalize invoice',
383
+ key: 'normalize_invoice',
384
+ libraries: ['zod@4.3.6'],
385
+ handler: ({ ref, paths }) => {
386
+ const vendor = ref(extractInvoice, paths(extractInvoice).vendor)
387
+ const total = Number(ref(extractInvoice, paths(extractInvoice).total))
388
+
389
+ return {
390
+ vendor: String(vendor).trim(),
391
+ totalCents: Math.round(total * 100),
392
+ needsHumanReview: total > 10_000,
393
+ }
394
+ },
395
+ })
396
+ ```
397
+
398
+ Supported extraction patterns:
399
+
400
+ - Inline handlers or named top-level handler functions.
401
+ - Source-visible same-file helpers, constants, types, and classes.
402
+ - Supported local TypeScript imports that can be copied into the source bundle.
403
+ - Package imports preserved in generated source with versions resolved from lockfile/package metadata or `libraries`.
404
+
405
+ Avoid these patterns:
406
+
407
+ - Dynamic import specifiers.
408
+ - Runtime-created closure values that cannot be statically traced.
409
+ - Unsupported local imports or unresolved exports.
410
+ - Forward references to later nodes.
411
+ - Declaring generated-reserved names such as `execute` or `TelaInput` in extracted handler/helper/type code.
412
+
413
+ ### Config and shared types
414
+
415
+ These types are exported for config files and integrations. See [Config](/docs/config) for full examples.
416
+
417
+ | Type | Shape | Purpose |
418
+ | --- | --- | --- |
419
+ | `WorkflowCodeConfig` | `{ version: 1; tsconfig?: string; outDir?: string; workflows: Record<string, WorkflowTarget> }` | Top-level `workflow-code.config.ts` default export shape. |
420
+ | `WorkflowTarget` | `{ entry: string; contexts?: Record<string, WorkflowContextBinding>; projectId?: string; export?: 'default'; promptId?: string; workflowKey?: string; title?: string }` | Per-target entrypoint and remote binding metadata. |
421
+ | `WorkflowContextBinding` | `{ projectId?: string; promptId?: string }` | Context-specific project/prompt ids selected by Tela Dock/CLI context. Required only by remote lifecycle commands such as `sync`. |
422
+ | `Diagnostic` | `{ code: string; severity: 'error' \| 'warning' \| 'info'; message: string; hint?: string; location?: { file: string; line?: number; column?: number; offset?: number; endOffset?: number }; stack?: string }` | Compiler and loader diagnostic payload. |
423
+
424
+ ### Diagnostics checklist
425
+
426
+ When authoring fails, check these first:
427
+
428
+ - Empty `workflowKey`, input `name`, node `name`, or prompt output.
429
+ - Missing default export from the workflow entrypoint.
430
+ - `workflowKey` mismatch between source and config.
431
+ - `ref()` to a node that appears later in `nodes`.
432
+ - `paths()` token from one node passed to `ref()` for another node.
433
+ - `code()` handler uses unsupported closures, dynamic imports, unresolved local imports, or generated-reserved names.
434
+ - Package import version cannot be resolved from lockfile, installed package, package.json, or `libraries` override.
@@ -0,0 +1,187 @@
1
+ ## CLI
2
+
3
+ The workflow command group documents implemented `init`, `compile`, `docs`, `sync`, and `publish` workflows. Current MVP behavior is local-first until you run explicit remote lifecycle commands such as `sync` or `publish`.
4
+
5
+ ### Command surface
6
+
7
+ | Command | Status | Remote mutation | Purpose |
8
+ | --- | --- | --- | --- |
9
+ | `init [--directory <path>] [--config <path>] [--workflow <key>...] [--yes] [--init-git\|--no-init-git] [--install-deps\|--no-install-deps] [--package-manager bun\|pnpm\|npm\|yarn] [--json]` | Implemented | No | Create local Workflow Code scaffold. |
10
+ | `compile [target] [--config <path>] [--env <path>] [--json]` | Implemented | No | Compile selected source into Workflow V3 output. |
11
+ | `docs [page] [--json]` | Implemented | No | Read the version-matched Workflow Code documentation bundled with the installed CLI. |
12
+ | `sync [target] [--config <path>] [--env <path>] [--yes] [--json]` | Implemented | Yes | Synchronize local compiled workflow(s) with configured Tela prompt(s). |
13
+ | `publish [target] [--environment <name>] [--create-environment-if-missing] [--config <path>] [--env <path>] [--yes] [--json]` | Implemented | Yes | Publish local-matching workflow version(s) to the selected workflow environment. |
14
+
15
+ ### Target selection
16
+
17
+ The positional target is the key inside `workflow-code.config.ts` `workflows`. If `compile` sees exactly one configured workflow, the target may be omitted. If multiple workflows exist, `compile` requires a target. `sync` and `publish` use the same target key; when the target is omitted, they run every configured workflow. For publish, `--environment <name>` selects the workflow publication environment and is independent from the active Tela Local context. `--env <path>` remains a dotenv loader.
18
+
19
+ ```bash
20
+ tela workflow compile
21
+ tela workflow compile invoice-processing
22
+ tela workflow compile invoice-processing --env .env.staging --json
23
+ tela workflow docs cli
24
+ tela workflow sync
25
+ tela workflow sync invoice-processing --env .env.staging --json
26
+ tela workflow publish
27
+ tela workflow publish invoice-processing --environment staging --json
28
+ ```
29
+
30
+ ### init
31
+
32
+ **Description.** `tela workflow init` scaffolds a local Workflow Code project. It is local-only: it does not contact Tela APIs, create remote resources, write lockfiles, emit generated artifacts, or print environment values.
33
+
34
+ Init creates the target directory when needed, then writes a safe starter project:
35
+
36
+ - `workflow-code.config.ts` with `tsconfig: './tsconfig.json'`, `outDir: '.tela/workflows'`, and a `workflows` map.
37
+ - `src/workflows/<key>.workflow.ts` for each workflow key passed with `--workflow <key>` or entered interactively.
38
+ - `.env.example` with placeholder project and prompt variables for generated workflow targets.
39
+ - `tsconfig.json` when missing.
40
+ - `package.json` updates for `@meistrari/workflow-code` and missing `workflow:*` scripts.
41
+ - `.gitignore` entry for `.tela/workflows/*/contexts/dev/lock.json`.
42
+
43
+ Existing files and package scripts are preserved by default. Conflicts become diagnostics and `--json` reports written paths, skipped paths, skipped scripts, and setup actions.
44
+
45
+ Interactive init prompts in this order: target directory, workflow keys, git initialization, dependency installation, then package manager when installation is enabled. Defaults are safe: current directory, no workflow keys, no git init, no dependency install, and Bun when a package manager is needed. `--yes` answers non-interactive prompts with those safe defaults while still honoring explicit flags such as `--workflow`, `--directory`, or `--install-deps`.
46
+
47
+ | Prop | Type | Required | Description |
48
+ |---|---|---:|---|
49
+ | `--directory <path>` | Flag | No | Target directory to initialize. Defaults to `.` and is created when missing. |
50
+ | `--config <path>` | Flag | No | Config file path to create inside the target directory. Defaults to `workflow-code.config.ts`. |
51
+ | `--workflow <key>` | Flag | No | Add a workflow target and source file. Repeat for multiple workflows. Keys must be safe file names. |
52
+ | `--yes` | Flag | No | Disable prompts and use safe defaults for unspecified choices. |
53
+ | `--init-git` / `--no-init-git` | Flag | No | Create or skip a git repository when the target directory is not already inside one. |
54
+ | `--install-deps` / `--no-install-deps` | Flag | No | Install Workflow Code dependencies. If `package.json` is missing, init runs the selected package manager's non-interactive init first. |
55
+ | `--package-manager bun|pnpm|npm|yarn` | Flag | No | Package manager for dependency installation. Defaults to Bun. |
56
+ | `--json` | Flag | No | Emit the result envelope, diagnostics, scaffold paths, skipped scripts, and setup actions as JSON. |
57
+
58
+ **Examples.**
59
+
60
+ ```bash
61
+ tela workflow init
62
+ tela workflow init --directory ./workflow-app --workflow invoice-processing --workflow review
63
+ tela workflow init --install-deps --package-manager pnpm --yes
64
+ tela workflow init --workflow invoice-processing --yes --json
65
+ ```
66
+
67
+
68
+
69
+ ### compile
70
+
71
+ **Description.** `tela workflow compile` loads config, loads dotenv files, evaluates the TypeScript entrypoint, validates declarations, and returns deterministic Workflow V3 graph, payload, hashes, and diagnostics. It does not require or validate remote `projectId`/`promptId`, write lockfiles, sync remote content, or publish.
72
+
73
+ | Prop | Type | Required | Description |
74
+ |---|---|---:|---|
75
+ | `target` | Positional | No | Config `workflows` key to compile. Required when more than one workflow is configured. |
76
+ | `--config <path>` | Flag | No | Load a custom config file instead of `workflow-code.config.ts`. |
77
+ | `--env <path>` | Flag | No | Load a custom dotenv file before evaluating config. |
78
+ | `--json` | Flag | No | Emit compiled graph, payload, hashes, and diagnostics as JSON. |
79
+
80
+ **Examples.**
81
+
82
+ ```bash
83
+ tela workflow compile
84
+ tela workflow compile invoice-processing
85
+ tela workflow compile invoice-processing --env .env.staging --json
86
+ tela workflow compile --config ./workflow-code.config.ts
87
+ ```
88
+
89
+ ### docs
90
+
91
+ **Description.** `tela workflow docs` reads the official Workflow Code documentation bundled with the installed CLI. It is local-only, performs no network requests, and reports the Workflow Code package version represented by the bundle.
92
+
93
+ Omit the page to list the available documentation. Pass a page slug to print its Markdown content. JSON output includes the package version, source package, and either the page catalog or selected page content.
94
+
95
+ | Prop | Type | Required | Description |
96
+ |---|---|---:|---|
97
+ | `page` | Positional | No | Bundled documentation page such as `cli`, `config`, or `api-reference`. |
98
+ | `--json` | Flag | No | Emit bundle provenance, package version, and page metadata or content as JSON. |
99
+
100
+ **Examples.**
101
+
102
+ ```bash
103
+ tela workflow docs
104
+ tela workflow docs cli
105
+ tela workflow docs api-reference --json
106
+ ```
107
+
108
+ ### sync
109
+
110
+ **Description.** `tela workflow sync` compiles local source, resolves the active Tela Local context, selects the matching `projectId` and `promptId`, verifies remote content, and writes per-context lockfile state under `.tela/workflows/<workflowKey>/contexts/<context>/lock.json`.
111
+
112
+ Sync uses a consolidated version strategy. The compiled workflow becomes the complete source of truth for the next remote version: source files, hashes, lifecycle payload, package metadata, and binding metadata are consolidated into one prompt version snapshot. When compiled content changed, sync creates a new non-draft version. The only exception is a verified no-op: if local hashes already match the active-context lockfile and fresh remote content confirms the same version, sync returns without creating a version.
113
+
114
+ Consolidated versions make sync safe to repeat. A sync never edits an existing version in place, never mutates a draft, and never changes the previous consolidated version. If the workflow is currently pointing at a draft version, sync leaves that draft untouched and creates a new consolidated non-draft version for the compiled workflow instead.
115
+
116
+ | Prop | Type | Required | Description |
117
+ |---|---|---:|---|
118
+ | `target` | Positional | No | Config `workflows` key to sync. Omit to sync every configured workflow. |
119
+ | `--config <path>` | Flag | No | Load a custom config file instead of `workflow-code.config.ts`. |
120
+ | `--env <path>` | Flag | No | Load a custom dotenv file before evaluating config. |
121
+ | `--yes` | Flag | No | Continue non-interactively when remote content changed since the last successful sync. |
122
+ | `--json` | Flag | No | Emit selected workflows, sync status, remote version ids, lockfile paths, compiled payloads, and diagnostics as JSON. |
123
+
124
+ **Examples.**
125
+
126
+ ```bash
127
+ tela workflow sync
128
+ tela workflow sync invoice-processing
129
+ tela workflow sync invoice-processing --env .env.staging --yes --json
130
+ ```
131
+
132
+ **Example: local source changes after review.** You update `src/invoice.workflow.ts`, run `compile`, review the payload, then run `tela workflow sync invoice-processing`. Sync creates a new non-draft consolidated version that contains the compiled workflow and updates the active-context lockfile to that version.
133
+
134
+ **Example: active remote workflow is a draft.** A teammate is experimenting in Tela and the current workflow points at a draft version. Running `tela workflow sync invoice-processing` does not overwrite or publish that draft. Sync creates a new consolidated non-draft version from local source and records that new version in the lockfile; the former draft version remains available as it was.
135
+
136
+ **Example: no local changes.** CI runs `tela workflow sync --yes --json` after a previous successful sync. If local hashes match the lockfile and the remote snapshot still matches, sync returns a no-op and does not create another version.
137
+
138
+
139
+
140
+ ### publish
141
+
142
+ **Description.** `tela workflow publish` releases only remote versions proven to match local compiled source. It uses shared Tela CLI authentication and the active Tela Local context to resolve each workflow's configured `projectId` and `promptId`. If the current remote version cannot be proven to match the local hashes and synced lineage, publish runs sync internally for that workflow before continuing. A matching draft is consolidated before publication; publish does not create an unrelated workflow version.
143
+
144
+ `--environment <name>` selects the workflow publication environment for every selected workflow and defaults to `production`. Before changing any workflow version, publish resolves that environment and its current remote version for every selected workflow. If a custom environment is missing in an interactive terminal, publish shows its exact name and affected workflows, then asks once whether to create it; the default answer is no. In `--json` or another non-interactive execution, pass `--create-environment-if-missing` to authorize creation explicitly. `--yes` remains limited to remote-divergence handling during the sync lifecycle. These flags do not change the Tela Local context, API endpoint, workspace, or credentials. `--env <path>` only loads dotenv values used by config and workflow source.
145
+
146
+ Publish does not store publication state in the Workflow Code lockfile; Tela's environment state remains authoritative. The lockfile changes only when publish needs to run sync internally first.
147
+
148
+ | Prop | Type | Required | Description |
149
+ |---|---|---:|---|
150
+ | `target` | Positional | No | Config `workflows` key to publish. Omit to publish every configured workflow. |
151
+ | `--environment <name>` | Flag | No | Workflow publication environment. Defaults to `production`. |
152
+ | `--create-environment-if-missing` | Flag | No | Create the selected custom environment when absent. Required for non-interactive creation. |
153
+ | `--config <path>` | Flag | No | Load a custom config file instead of `workflow-code.config.ts`. |
154
+ | `--env <path>` | Flag | No | Load a custom dotenv file before evaluating config. |
155
+ | `--yes` | Flag | No | Continue non-interactively if the sync performed by publish detects remote divergence. |
156
+ | `--json` | Flag | No | Emit selected workflow, context, and environment identities, version ids, hashes, diagnostics, and written paths as JSON. |
157
+
158
+ **Examples.**
159
+
160
+ ```bash
161
+ tela workflow publish
162
+ tela workflow publish invoice-processing
163
+ tela workflow publish invoice-processing --environment staging
164
+ tela workflow publish invoice-processing --environment dev --create-environment-if-missing --json
165
+ tela workflow publish --environment production --yes --json
166
+ ```
167
+
168
+
169
+
170
+ ### JSON diagnostics
171
+
172
+ ```ts
173
+ type Diagnostic = Readonly<{
174
+ code: string
175
+ severity: 'error' | 'warning' | 'info'
176
+ message: string
177
+ hint?: string
178
+ location?: {
179
+ file: string
180
+ line?: number
181
+ column?: number
182
+ offset?: number
183
+ endOffset?: number
184
+ }
185
+ stack?: string
186
+ }>
187
+ ```