@eigenpal/cli 0.13.0 → 0.13.2

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.
@@ -17,7 +17,10 @@ appear in user examples, but do not prefer them.
17
17
  ## Choose A Command
18
18
 
19
19
  - `eigenpal workflow` manages YAML workflow definitions, datasets, evaluators,
20
- experiments, versions, and step schemas.
20
+ experiments, versions, workspace templates, and step schemas.
21
+ - `eigenpal models list` inventories text, vision, and OCR models configured
22
+ for the current tenant environment (`--json` for scripting). Health is
23
+ `configured` or `unconfigured` from local credentials — not a live provider probe.
21
24
  - `eigenpal agents` manages Git-backed agent source packages, shared resources,
22
25
  releases, sync, secrets, datasets, and live file inspection.
23
26
  - `eigenpal run` starts a single workflow or agent run from a target. This is the
@@ -30,6 +33,8 @@ appear in user examples, but do not prefer them.
30
33
  Use stable ids in scripts:
31
34
 
32
35
  - Workflow id: `wf_...`
36
+ - Template id: `tmpl_...`
37
+ - Template revision id: `tmpr_...`
33
38
  - Workflow execution id: `evx_...`
34
39
  - Agent execution id: `aex_...`
35
40
  - Experiment batch id: `evb_...`
@@ -49,10 +54,13 @@ eigenpal workflow step-type get ai.extract --json | jq '.configSchema.properties
49
54
 
50
55
  # Validate and push.
51
56
  eigenpal workflow validate ./workflow.yaml
52
- # If the workflow has action.invoke-workflow steps, local validation cannot
53
- # resolve their targets (sibling workflows live in the server DB). Add --online
54
- # to check invoke targets, input types, and cycles before pushing.
57
+ # --online also checks action.invoke-workflow targets, transform.template
58
+ # tmpl_… ids, and explicitly selected OCR/vision/text models against live tenant
59
+ # catalog metadata. Local `template: ./file.xlsx` paths
60
+ # are inspected on disk with or without --online and must stay inside the
61
+ # workflow project unless you pass --allow-external-templates.
55
62
  eigenpal workflow validate ./workflow.yaml --online
63
+ eigenpal models list --json
56
64
  eigenpal workflow push --file workflow.yaml
57
65
 
58
66
  # Run with ad-hoc input and read the output (use this for API-triggered workflows).
@@ -161,6 +169,75 @@ eigenpal run agents.<slug> \
161
169
  `agents file list/get/diff` are read/compare commands only. Change agent files
162
170
  through Git source, then use `agents save`, `agents release`, and `agents sync`.
163
171
 
172
+ ## Agent templates (Git source)
173
+
174
+ DOCX/XLSX templates for **runtime agents** live in Git source, not in the
175
+ workspace Templates table. YAML workflows use workspace templates via
176
+ `transform.template` and `tmpl_...` instead — see `reference/step-types.md`.
177
+
178
+ Workspace DOCX/XLSX templates for YAML workflows:
179
+
180
+ ```bash
181
+ eigenpal workflow templates upload ./templates/roster.xlsx --json
182
+ eigenpal workflow templates smoke ./templates/roster.xlsx --data ./fixture.json --out ./filled.xlsx
183
+ # YAML may keep a source path; push uploads and sends tmpl_ + tmpr_ ids.
184
+ # template: ./templates/roster.xlsx
185
+ eigenpal workflow validate ./workflow.yaml --online
186
+ eigenpal workflow push --file workflow.yaml
187
+ ```
188
+
189
+ **Local template** (one agent):
190
+
191
+ ```text
192
+ agents/<slug>/templates/<template-slug>/
193
+ template.docx # or template.xlsx
194
+ TEMPLATE.md # frontmatter: name, description, type: docx|xlsx
195
+ ```
196
+
197
+ **Shared template package** (reused across agents):
198
+
199
+ ```text
200
+ resources/templates/<template-slug>/
201
+ eigenpal.yaml # required package manifest
202
+ template.docx # or template.xlsx
203
+ TEMPLATE.md # optional metadata
204
+ ```
205
+
206
+ At runtime the agent fills templates with the baked-in **fill-template**
207
+ platform skill (`vars`, then `fill`) — not `transform.template`. Local
208
+ templates resolve by slug under `agent/templates/<slug>/`. Shared dependencies
209
+ install under `agent/eigenpal_modules/resources/templates/<slug>/`; pass that
210
+ file path to fill-template when the template is not copied locally.
211
+
212
+ ```bash
213
+ # Add or update a local template, then validate and save.
214
+ cp ./invoice.docx agents/<slug>/templates/invoice/template.docx
215
+ $EDITOR agents/<slug>/templates/invoice/TEMPLATE.md
216
+ eigenpal agents validate agents/<slug>
217
+ eigenpal agents save -m "Add invoice template"
218
+ eigenpal agents release patch agents/<slug>
219
+ eigenpal agents sync agents.<slug>
220
+
221
+ # Shared template: validate, save, and release the package.
222
+ cp ./report.xlsx resources/templates/monthly-report/template.xlsx
223
+ $EDITOR resources/templates/monthly-report/eigenpal.yaml
224
+ eigenpal agents validate resources/templates/monthly-report
225
+ eigenpal agents save -m "Add monthly report template"
226
+ eigenpal agents release patch resources/templates/monthly-report
227
+
228
+ # Consuming agent: pin an exact dependency version, then release and sync.
229
+ $EDITOR agents/<slug>/eigenpal.yaml # workspace:resources.templates.monthly-report: "1.0.0"
230
+ eigenpal agents validate agents/<slug>
231
+ eigenpal agents save -m "Use monthly report template"
232
+ eigenpal agents release patch agents/<slug>
233
+ eigenpal agents sync agents.<slug>
234
+ ```
235
+
236
+ Updating a shared template does not auto-sync dependent agents. Release the
237
+ template package, bump each consumer's exact-version dependency, then release
238
+ and sync those agents. Workspace `tmpl_...` templates are a different system —
239
+ use `eigenpal workflow templates`, not `agents save`.
240
+
164
241
  ## Shared Resource Updates
165
242
 
166
243
  Do not move every dependent agent automatically. Find dependents, ask which ones
@@ -0,0 +1,40 @@
1
+ # eigenpal models
2
+
3
+ Inspect models and providers configured for the current tenant environment (text, vision, OCR).
4
+
5
+ ## Contents
6
+
7
+ - [Surface](#surface)
8
+ - [Commands](#commands)
9
+ - [Core](#core)
10
+ - [Details](#details)
11
+ - [`eigenpal models list|ls [options]`](#eigenpal-models-listls-options)
12
+
13
+ ## Surface
14
+
15
+ ```
16
+ models
17
+ └── list|ls
18
+ ```
19
+
20
+ ## Commands
21
+
22
+ ### Core
23
+
24
+ | Command | Description |
25
+ | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | `eigenpal models list\|ls [options]` | List configured text, vision, and OCR models. This is a catalog inventory from the server, not a live provider health probe. `health` is `configured` or `unconfigured` from local credentials. Pair with `--json` for scripting. |
27
+
28
+ ## Details
29
+
30
+ ### `eigenpal models list|ls [options]`
31
+
32
+ List configured text, vision, and OCR models. This is a catalog inventory from the server, not a live provider health probe. `health` is `configured` or `unconfigured` from local credentials. Pair with `--json` for scripting.
33
+
34
+ ### Options
35
+
36
+ | Flag | Required | Default | Description |
37
+ | --------------------- | -------- | ------- | -------------------------------------------------------------------------- |
38
+ | `--capability <kind>` | no | | Filter to `text`, `vision`, or `ocr` (matches the API `capability` query). |
39
+ | `--base-url <url>` | no | | Server base URL |
40
+ | `--json` | no | | Output the raw server response as JSON |
@@ -21,6 +21,7 @@ Inspect, watch, and manage workflow, agent, and eval runs.
21
21
  - [`eigenpal runs cancel [options] <run-id>`](#eigenpal-runs-cancel-options-run-id)
22
22
  - [`eigenpal runs artifacts|artifact list|ls [options] <run-id>`](#eigenpal-runs-artifactsartifact-listls-options-run-id)
23
23
  - [`eigenpal runs artifacts|artifact fetch [options] <run-id>`](#eigenpal-runs-artifactsartifact-fetch-options-run-id)
24
+ - [`eigenpal runs artifacts|artifact inspect [options] [run-id] [artifact-path]`](#eigenpal-runs-artifactsartifact-inspect-options-run-id-artifact-path)
24
25
  - [`eigenpal runs reviews|rv update [options] <run-id>`](#eigenpal-runs-reviewsrv-update-options-run-id)
25
26
  - [`eigenpal runs reviews|rv close [options] <run-id>`](#eigenpal-runs-reviewsrv-close-options-run-id)
26
27
  - [`eigenpal runs reviews|rv clear [options] <run-id>`](#eigenpal-runs-reviewsrv-clear-options-run-id)
@@ -42,7 +43,8 @@ runs
42
43
  ├── promote <run-id>
43
44
  ├── artifacts|artifact
44
45
  │ ├── list|ls <run-id>
45
- │ └── fetch <run-id>
46
+ │ ├── fetch <run-id>
47
+ │ └── inspect [run-id] [artifact-path]
46
48
  ├── trace <run-id>
47
49
  ├── reviews|rv
48
50
  │ ├── update <run-id>
@@ -63,23 +65,24 @@ runs
63
65
 
64
66
  ### Core
65
67
 
66
- | Command | Description |
67
- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
68
- | `eigenpal runs list\|ls [options] [source]` | List runs across workflows and agents, optionally scoped to one source. |
69
- | `eigenpal runs get [options] <run-id>` | Get one run. |
70
- | `eigenpal runs compare\|diff [options] <reference-run-id> <run-id>` | Compare one run against another run. PDF/DOCX text comparison uses pdftotext/python3 and reports byte fallbacks. |
71
- | `eigenpal runs rerun [options] <run-id>` | Create a new run from a previous run's stored input snapshot. |
72
- | `eigenpal runs promote [options] <run-id>` | Promote a run into a dataset example on the run's automation. |
73
- | `eigenpal runs trace [options] <run-id>` | Print raw trace.jsonl for a run, or write it with --out. |
74
- | `eigenpal runs watch [options] <run-id>` | Watch a run until it reaches a terminal status. |
75
- | `eigenpal runs cancel [options] <run-id>` | Cancel a run. |
68
+ | Command | Description |
69
+ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
70
+ | `eigenpal runs list\|ls [options] [source]` | List runs across workflows and agents, optionally scoped to one source. |
71
+ | `eigenpal runs get [options] <run-id>` | Get one run. |
72
+ | `eigenpal runs compare\|diff [options] <reference-run-id> <run-id>` | Compare one run against another run. PDF/DOCX use pdftotext/python3; XLSX compares structured workbook content (not ZIP bytes). |
73
+ | `eigenpal runs rerun [options] <run-id>` | Create a new run from a previous run's stored input snapshot. |
74
+ | `eigenpal runs promote [options] <run-id>` | Promote a run into a dataset example on the run's automation. |
75
+ | `eigenpal runs trace [options] <run-id>` | Print raw trace.jsonl for a run, or write it with --out. |
76
+ | `eigenpal runs watch [options] <run-id>` | Watch a run until it reaches a terminal status. |
77
+ | `eigenpal runs cancel [options] <run-id>` | Cancel a run. |
76
78
 
77
79
  ### Artifacts
78
80
 
79
- | Command | Description |
80
- | --------------------------------------------------------------- | ------------------------------------------------------ |
81
- | `eigenpal runs artifacts\|artifact list\|ls [options] <run-id>` | List available run artifacts without downloading them. |
82
- | `eigenpal runs artifacts\|artifact fetch [options] <run-id>` | Download run artifacts by canonical artifact path. |
81
+ | Command | Description |
82
+ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
83
+ | `eigenpal runs artifacts\|artifact list\|ls [options] <run-id>` | List available run artifacts without downloading them. |
84
+ | `eigenpal runs artifacts\|artifact fetch [options] <run-id>` | Download run artifacts by canonical artifact path. |
85
+ | `eigenpal runs artifacts\|artifact inspect [options] [run-id] [artifact-path]` | Inspect a run XLSX artifact as structured JSON (sheet names, headers, typed rows). Use --file for a local workbook. |
83
86
 
84
87
  ### Reviews
85
88
 
@@ -158,7 +161,7 @@ Get one run.
158
161
 
159
162
  ### `eigenpal runs compare|diff [options] <reference-run-id> <run-id>`
160
163
 
161
- Compare one run against another run. PDF/DOCX text comparison uses pdftotext/python3 and reports byte fallbacks.
164
+ Compare one run against another run. PDF/DOCX use pdftotext/python3; XLSX compares structured workbook content (not ZIP bytes).
162
165
 
163
166
  ### Arguments
164
167
 
@@ -310,6 +313,30 @@ Download run artifacts by canonical artifact path.
310
313
  | `--path <path>` | no | `[]` | Fetch one exact artifact path from `artifacts list`; repeatable |
311
314
  | `--json` | no | | Output a JSON summary of written artifacts |
312
315
 
316
+ ### `eigenpal runs artifacts|artifact inspect [options] [run-id] [artifact-path]`
317
+
318
+ Inspect a run XLSX artifact as structured JSON (sheet names, headers, typed rows). Use --file for a local workbook.
319
+
320
+ ### Arguments
321
+
322
+ | Name | Required | Variadic | Description |
323
+ | --------------- | -------- | -------- | ----------- |
324
+ | `run-id` | no | no | |
325
+ | `artifact-path` | no | no | |
326
+
327
+ ### Options
328
+
329
+ | Flag | Required | Default | Description |
330
+ | ------------------ | -------- | ------- | ---------------------------------------------------------------------------------- |
331
+ | `--base-url <url>` | no | | Server base URL |
332
+ | `--json` | no | | Output the raw server response as JSON |
333
+ | `--file <path>` | no | | Inspect a local .xlsx/.xls file instead of downloading a run artifact |
334
+ | `--path <path>` | no | | Canonical artifact path from `artifacts list` (alias for positional artifact-path) |
335
+ | `--sheet <names>` | no | | Comma-separated sheet names or zero-based indices to include |
336
+ | `--max-sheets <n>` | no | | Maximum sheets to include (default 20) |
337
+ | `--max-rows <n>` | no | | Maximum data rows per sheet (default 500) |
338
+ | `--max-cols <n>` | no | | Maximum columns per sheet (default 50) |
339
+
313
340
  ### `eigenpal runs reviews|rv update [options] <run-id>`
314
341
 
315
342
  Edit review verdict, status, note, or corrected JSON for a run.
@@ -32,6 +32,14 @@ eigenpal
32
32
  │ │ │ ├── delete <workflow-id> <exampleId>
33
33
  │ │ │ └── get <workflow-id> <exampleId>
34
34
  │ │ └── validate [path]
35
+ │ ├── templates
36
+ │ │ ├── upload <file>
37
+ │ │ ├── list|ls
38
+ │ │ ├── get|inspect <template-id>
39
+ │ │ ├── download <template-id>
40
+ │ │ ├── replace <template-id> <file>
41
+ │ │ ├── delete <template-id>
42
+ │ │ └── smoke <template>
35
43
  │ ├── experiment|exp
36
44
  │ │ ├── list|ls <workflow-id>
37
45
  │ │ ├── run <workflow-id>
@@ -104,6 +112,8 @@ eigenpal
104
112
  │ │ └── stop <session-id>
105
113
  │ └── env
106
114
  │ └── pull [target]
115
+ ├── models
116
+ │ └── list|ls
107
117
  ├── run <target>
108
118
  ├── rerun <run-id>
109
119
  ├── runs
@@ -114,7 +124,8 @@ eigenpal
114
124
  │ ├── promote <run-id>
115
125
  │ ├── artifacts|artifact
116
126
  │ │ ├── list|ls <run-id>
117
- │ │ └── fetch <run-id>
127
+ │ │ ├── fetch <run-id>
128
+ │ │ └── inspect [run-id] [artifact-path]
118
129
  │ ├── trace <run-id>
119
130
  │ ├── reviews|rv
120
131
  │ │ ├── update <run-id>
@@ -9,6 +9,7 @@ Manage workflows: push, pull, and evaluate.
9
9
  - [Core](#core)
10
10
  - [Evaluators](#evaluators)
11
11
  - [Dataset](#dataset)
12
+ - [Templates](#templates)
12
13
  - [Experiment](#experiment)
13
14
  - [Versions](#versions)
14
15
  - [Step-type](#step-type)
@@ -33,6 +34,13 @@ Manage workflows: push, pull, and evaluate.
33
34
  - [`eigenpal workflow dataset example delete [options] <workflow-id> <exampleId>`](#eigenpal-workflow-dataset-example-delete-options-workflow-id-exampleid)
34
35
  - [`eigenpal workflow dataset example get [options] <workflow-id> <exampleId>`](#eigenpal-workflow-dataset-example-get-options-workflow-id-exampleid)
35
36
  - [`eigenpal workflow dataset validate [options] [path]`](#eigenpal-workflow-dataset-validate-options-path)
37
+ - [`eigenpal workflow templates upload [options] <file>`](#eigenpal-workflow-templates-upload-options-file)
38
+ - [`eigenpal workflow templates list|ls [options]`](#eigenpal-workflow-templates-listls-options)
39
+ - [`eigenpal workflow templates get|inspect [options] <template-id>`](#eigenpal-workflow-templates-getinspect-options-template-id)
40
+ - [`eigenpal workflow templates download [options] <template-id>`](#eigenpal-workflow-templates-download-options-template-id)
41
+ - [`eigenpal workflow templates replace [options] <template-id> <file>`](#eigenpal-workflow-templates-replace-options-template-id-file)
42
+ - [`eigenpal workflow templates delete [options] <template-id>`](#eigenpal-workflow-templates-delete-options-template-id)
43
+ - [`eigenpal workflow templates smoke [options] <template>`](#eigenpal-workflow-templates-smoke-options-template)
36
44
  - [`eigenpal workflow experiment|exp list|ls [options] <workflow-id>`](#eigenpal-workflow-experimentexp-listls-options-workflow-id)
37
45
  - [`eigenpal workflow experiment|exp run [options] <workflow-id>`](#eigenpal-workflow-experimentexp-run-options-workflow-id)
38
46
  - [`eigenpal workflow experiment|exp status [options] <workflow-id> <batchId>`](#eigenpal-workflow-experimentexp-status-options-workflow-id-batchid)
@@ -73,6 +81,14 @@ workflow
73
81
  │ │ ├── delete <workflow-id> <exampleId>
74
82
  │ │ └── get <workflow-id> <exampleId>
75
83
  │ └── validate [path]
84
+ ├── templates
85
+ │ ├── upload <file>
86
+ │ ├── list|ls
87
+ │ ├── get|inspect <template-id>
88
+ │ ├── download <template-id>
89
+ │ ├── replace <template-id> <file>
90
+ │ ├── delete <template-id>
91
+ │ └── smoke <template>
76
92
  ├── experiment|exp
77
93
  │ ├── list|ls <workflow-id>
78
94
  │ ├── run <workflow-id>
@@ -133,6 +149,18 @@ workflow
133
149
  | `eigenpal workflow dataset example get [options] <workflow-id> <exampleId>` | Fetch one eval example with full triggerInput, expectedOutput, and metadata. |
134
150
  | `eigenpal workflow dataset validate [options] [path]` | Validate a dataset folder against the examples/<name>/{input,expected,meta} convention. Defaults to ./dataset/. |
135
151
 
152
+ ### Templates
153
+
154
+ | Command | Description |
155
+ | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
156
+ | `eigenpal workflow templates upload [options] <file>` | Upload a DOCX or XLSX file as a new tmpl*… resource with an immutable tmpr*… revision. |
157
+ | `eigenpal workflow templates list\|ls [options]` | List workspace templates. |
158
+ | `eigenpal workflow templates get\|inspect [options] <template-id>` | Inspect a tmpl*… resource: current tmpr*…, format, checksum, tokens, grammar. |
159
+ | `eigenpal workflow templates download [options] <template-id>` | Download current (or pinned) template bytes. |
160
+ | `eigenpal workflow templates replace [options] <template-id> <file>` | Append an immutable revision and advance the tmpl\_… pointer. |
161
+ | `eigenpal workflow templates delete [options] <template-id>` | Delete the mutable tmpl*… pointer. Pinned tmpr*… revisions remain so workflows that set templateRevisionId still run. |
162
+ | `eigenpal workflow templates smoke [options] <template>` | Fill a local Office file or a tmpl\_… resource with a JSON fixture and write the result. Local files never contact the server. |
163
+
136
164
  ### Experiment
137
165
 
138
166
  | Command | Description |
@@ -231,14 +259,15 @@ Create or update a workflow from a YAML file.
231
259
 
232
260
  ### Options
233
261
 
234
- | Flag | Required | Default | Description |
235
- | ------------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
236
- | `--file <yaml>` | no | | Path to YAML file |
237
- | `--workflow-id <id>` | no | | Update existing workflow (default: create new) |
238
- | `--bump <level>` | no | | Auto-bump from the server's current version: patch \| minor \| major. Mutually exclusive with `--version` and with a top-level `version:` in the YAML. |
239
- | `--set-version <semver>` | no | | Push at this exact semver (e.g. 1.4.0). Mutually exclusive with `--bump` and with a top-level `version:` in the YAML. (Named `--set-version` to avoid the global `-v, --version` flag.) |
240
- | `--base-url <url>` | no | | Server base URL |
241
- | `--json` | no | | Output the raw server response as JSON |
262
+ | Flag | Required | Default | Description |
263
+ | ---------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
264
+ | `--file <yaml>` | no | | Path to YAML file |
265
+ | `--workflow-id <id>` | no | | Update existing workflow (default: create new) |
266
+ | `--bump <level>` | no | | Auto-bump from the server's current version: patch \| minor \| major. Mutually exclusive with `--version` and with a top-level `version:` in the YAML. |
267
+ | `--set-version <semver>` | no | | Push at this exact semver (e.g. 1.4.0). Mutually exclusive with `--bump` and with a top-level `version:` in the YAML. (Named `--set-version` to avoid the global `-v, --version` flag.) |
268
+ | `--allow-external-templates` | no | | Allow local template: paths whose real path is outside the workflow project directory (the folder that contains the YAML file). Off by default; ../ and symlink escapes are rejected. |
269
+ | `--base-url <url>` | no | | Server base URL |
270
+ | `--json` | no | | Output the raw server response as JSON |
242
271
 
243
272
  ### `eigenpal workflow move [options] <workflow-id>`
244
273
 
@@ -270,11 +299,12 @@ Local-only validation. Without [path]: runs the templated three-way check (./wor
270
299
 
271
300
  ### Options
272
301
 
273
- | Flag | Required | Default | Description |
274
- | ------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
275
- | `--dir <path>` | no | | Project root (defaults to cwd; resolves the three default paths from here) |
276
- | `--online` | no | | Also validate cross-workflow action.invoke-workflow references against the server (needs auth). Catches target-not-found, input type mismatches, missing/unknown input keys, undeclared output, and invoke cycles that local validation cannot see. |
277
- | `--base-url <url>` | no | | Server base URL |
302
+ | Flag | Required | Default | Description |
303
+ | ---------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
304
+ | `--dir <path>` | no | | Project root (defaults to cwd; resolves the three default paths from here) |
305
+ | `--online` | no | | Authenticate and also validate action.invoke-workflow targets, transform.template tmpl\_… references, and explicitly selected OCR/vision/text models against this tenant environment (existence, format, revision pairing, tokens vs data, XLSX {{ }} mistakes, configured catalog). Local template: paths are inspected on disk with or without this flag. Model checks use the configured catalog only — they do not probe live provider health. |
306
+ | `--allow-external-templates` | no | | Allow local template: paths whose real path is outside the workflow project directory (the folder that contains the YAML file). Off by default; ../ and symlink escapes are rejected. |
307
+ | `--base-url <url>` | no | | Server base URL |
278
308
 
279
309
  ### `eigenpal workflow clear-local [options] [examples...]`
280
310
 
@@ -490,6 +520,129 @@ Validate a dataset folder against the examples/<name>/{input,expected,meta} conv
490
520
  | ------ | -------- | -------- | ----------- |
491
521
  | `path` | no | no | |
492
522
 
523
+ ### `eigenpal workflow templates upload [options] <file>`
524
+
525
+ Upload a DOCX or XLSX file as a new tmpl*… resource with an immutable tmpr*… revision.
526
+
527
+ ### Arguments
528
+
529
+ | Name | Required | Variadic | Description |
530
+ | ------ | -------- | -------- | ----------- |
531
+ | `file` | yes | no | |
532
+
533
+ ### Options
534
+
535
+ | Flag | Required | Default | Description |
536
+ | ---------------------- | -------- | ------- | --------------------------------------------------------- |
537
+ | `--name <name>` | no | | Display name (defaults to the filename without extension) |
538
+ | `--description <text>` | no | | Optional description |
539
+ | `--base-url <url>` | no | | Server base URL |
540
+ | `--json` | no | | Output the raw server response as JSON |
541
+
542
+ ### `eigenpal workflow templates list|ls [options]`
543
+
544
+ List workspace templates.
545
+
546
+ ### Options
547
+
548
+ | Flag | Required | Default | Description |
549
+ | ------------------ | -------- | ------- | -------------------------------------- |
550
+ | `--limit <n>` | no | `50` | Page size |
551
+ | `--offset <n>` | no | `0` | Page offset |
552
+ | `--base-url <url>` | no | | Server base URL |
553
+ | `--json` | no | | Output the raw server response as JSON |
554
+
555
+ ### `eigenpal workflow templates get|inspect [options] <template-id>`
556
+
557
+ Inspect a tmpl*… resource: current tmpr*…, format, checksum, tokens, grammar.
558
+
559
+ ### Arguments
560
+
561
+ | Name | Required | Variadic | Description |
562
+ | ------------- | -------- | -------- | ----------- |
563
+ | `template-id` | yes | no | |
564
+
565
+ ### Options
566
+
567
+ | Flag | Required | Default | Description |
568
+ | ------------------ | -------- | ------- | -------------------------------------- |
569
+ | `--base-url <url>` | no | | Server base URL |
570
+ | `--json` | no | | Output the raw server response as JSON |
571
+
572
+ ### `eigenpal workflow templates download [options] <template-id>`
573
+
574
+ Download current (or pinned) template bytes.
575
+
576
+ ### Arguments
577
+
578
+ | Name | Required | Variadic | Description |
579
+ | ------------- | -------- | -------- | ----------- |
580
+ | `template-id` | yes | no | |
581
+
582
+ ### Options
583
+
584
+ | Flag | Required | Default | Description |
585
+ | ---------------------- | -------- | ------- | --------------------------------- |
586
+ | `--out <path>` | no | | Write to this file (required) |
587
+ | `--revision-id <tmpr>` | no | | Pin an immutable tmpr\_… revision |
588
+ | `--base-url <url>` | no | | Server base URL |
589
+
590
+ ### `eigenpal workflow templates replace [options] <template-id> <file>`
591
+
592
+ Append an immutable revision and advance the tmpl\_… pointer.
593
+
594
+ ### Arguments
595
+
596
+ | Name | Required | Variadic | Description |
597
+ | ------------- | -------- | -------- | ----------- |
598
+ | `template-id` | yes | no | |
599
+ | `file` | yes | no | |
600
+
601
+ ### Options
602
+
603
+ | Flag | Required | Default | Description |
604
+ | ------------------ | -------- | ------- | -------------------------------------- |
605
+ | `--base-url <url>` | no | | Server base URL |
606
+ | `--json` | no | | Output the raw server response as JSON |
607
+
608
+ ### `eigenpal workflow templates delete [options] <template-id>`
609
+
610
+ Delete the mutable tmpl*… pointer. Pinned tmpr*… revisions remain so workflows that set templateRevisionId still run.
611
+
612
+ ### Arguments
613
+
614
+ | Name | Required | Variadic | Description |
615
+ | ------------- | -------- | -------- | ----------- |
616
+ | `template-id` | yes | no | |
617
+
618
+ ### Options
619
+
620
+ | Flag | Required | Default | Description |
621
+ | ------------------ | -------- | ------- | -------------------------------------- |
622
+ | `--yes` | no | `false` | Required for non-TTY shells |
623
+ | `--base-url <url>` | no | | Server base URL |
624
+ | `--json` | no | | Output the raw server response as JSON |
625
+
626
+ ### `eigenpal workflow templates smoke [options] <template>`
627
+
628
+ Fill a local Office file or a tmpl\_… resource with a JSON fixture and write the result. Local files never contact the server.
629
+
630
+ ### Arguments
631
+
632
+ | Name | Required | Variadic | Description |
633
+ | ---------- | -------- | -------- | ----------- |
634
+ | `template` | yes | no | |
635
+
636
+ ### Options
637
+
638
+ | Flag | Required | Default | Description |
639
+ | ---------------------- | -------- | ------- | ------------------------------------------------------------ |
640
+ | `--data <file>` | yes | | Path to a JSON fixture file (object with template data keys) |
641
+ | `--out <path>` | yes | | Filled DOCX/XLSX output path |
642
+ | `--revision-id <tmpr>` | no | | When <template> is a tmpl\_… id, pin this revision |
643
+ | `--base-url <url>` | no | | Server base URL |
644
+ | `--json` | no | | Output the raw server response as JSON |
645
+
493
646
  ### `eigenpal workflow experiment|exp list|ls [options] <workflow-id>`
494
647
 
495
648
  List executions for the workflow, newest first.
@@ -664,14 +817,15 @@ Create a tagged workflow version from YAML or by copying an existing snapshot.
664
817
 
665
818
  ### Options
666
819
 
667
- | Flag | Required | Default | Description |
668
- | ------------------------ | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
669
- | `--file <yaml>` | no | | Path to workflow YAML. Mutually exclusive with --from. |
670
- | `--from <version-id>` | no | | Existing version id to copy into a new tagged snapshot. Leaves the source tag unchanged. Mutually exclusive with --file. |
671
- | `--set-version <semver>` | no | | Bare semver tag such as 1.4.0. Required when copying with --from. For --file, omit this flag if the YAML already has a top-level version: field. (Named --set-version to avoid the global -v, --version flag.) |
672
- | `--no-activate` | no | | Keep the tagged version off live traffic until you promote it. Default is to make it current. Requires an existing current version. |
673
- | `--base-url <url>` | no | | Server base URL |
674
- | `--json` | no | | Output the raw server response as JSON |
820
+ | Flag | Required | Default | Description |
821
+ | ---------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
822
+ | `--file <yaml>` | no | | Path to workflow YAML. Mutually exclusive with --from. |
823
+ | `--allow-external-templates` | no | | Allow local template paths outside the workflow project. Use only for trusted YAML. |
824
+ | `--from <version-id>` | no | | Existing version id to copy into a new tagged snapshot. Leaves the source tag unchanged. Mutually exclusive with --file. |
825
+ | `--set-version <semver>` | no | | Bare semver tag such as 1.4.0. Required when copying with --from. For --file, omit this flag if the YAML already has a top-level version: field. (Named --set-version to avoid the global -v, --version flag.) |
826
+ | `--no-activate` | no | | Keep the tagged version off live traffic until you promote it. Default is to make it current. Requires an existing current version. |
827
+ | `--base-url <url>` | no | | Server base URL |
828
+ | `--json` | no | | Output the raw server response as JSON |
675
829
 
676
830
  ### `eigenpal workflow versions promote [options] <workflow-id> <versionId>`
677
831
 
@@ -29,6 +29,21 @@ eigenpal runs list <workflow-id> --type workflow --status failed --limit 5
29
29
  eigenpal runs get exec_…
30
30
  ```
31
31
 
32
+ If a `transform.template` fill looks wrong (leftover `{braces}`, empty
33
+ rows, or the wrong spreadsheet), smoke the Office file locally before
34
+ re-pushing. Local files never contact the server:
35
+
36
+ ```bash
37
+ eigenpal workflow templates smoke ./templates/roster.xlsx \
38
+ --data ./fixture.json --out ./filled.xlsx --json
39
+ ```
40
+
41
+ XLSX prototype rows use `{table:subjects.first_name}` in the spreadsheet.
42
+ YAML `data` mapping still uses `{{ steps.extract.output.subjects }}` —
43
+ do not put `{{ }}` in the Office file. `tmpl_…` smoke downloads current
44
+ bytes through `GET /v1/templates/:id/content` and fills on this machine;
45
+ there is no private remote-render route.
46
+
32
47
  ## 2. Pull the full execution
33
48
 
34
49
  ```bash
@@ -161,6 +176,27 @@ eigenpal runs compare <exec-a> <exec-b>
161
176
  Output: per-step status / Δ duration / output diff. Useful for spotting
162
177
  regressions between revisions of a workflow.
163
178
 
179
+ For agent runs with spreadsheet outputs, `runs compare` compares XLSX
180
+ workbooks by structured sheet content (headers, typed rows, sheet order) —
181
+ not raw ZIP bytes — so metadata-only rewrites still match when cell data
182
+ matches. Comparison scans the full workbook (within CLI safety limits); the
183
+ `--max-*` caps below apply only to `artifacts inspect`, not to `compare`.
184
+ When a workbook exceeds compare safety limits, the file diff is reported as
185
+ `inconclusive` and `--fail-on-diff` does not treat it as a match.
186
+
187
+ Inspect a downloaded or remote XLSX artifact as machine-readable JSON:
188
+
189
+ ```bash
190
+ eigenpal runs artifacts list <run-id>
191
+ eigenpal runs artifacts inspect <run-id> output/report.xlsx --json
192
+ eigenpal runs artifacts inspect <run-id> output/report.xlsx --sheet Summary,1 --max-rows 100 --json
193
+ eigenpal runs artifacts inspect --file ./report.xlsx --json
194
+ ```
195
+
196
+ The JSON payload includes `sheetNames`, per-sheet `dimensions`, ordered
197
+ `headers`, typed `rows`, and `truncated` flags when `--max-*` caps apply
198
+ (defaults: 20 sheets, 500 rows/sheet, 50 cols/sheet).
199
+
164
200
  For a freer-form diff, dump both and compare with `jq`:
165
201
 
166
202
  ```bash