@eigenpal/cli 0.0.1 → 0.4.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +441 -0
  2. package/LICENSE +201 -0
  3. package/README.md +60 -2
  4. package/dist/cli.js +162295 -0
  5. package/dist/skill/SKILL.md +366 -0
  6. package/dist/skill/examples/hello-world/dataset/examples/sample/expected/output.json +4 -0
  7. package/dist/skill/examples/hello-world/dataset/examples/sample/input/arguments.json +3 -0
  8. package/dist/skill/examples/hello-world/evaluators.yaml +5 -0
  9. package/dist/skill/examples/hello-world/workflow.yaml +28 -0
  10. package/dist/skill/reference/cli/agent.md +7 -0
  11. package/dist/skill/reference/cli/auth.md +75 -0
  12. package/dist/skill/reference/cli/completion.md +13 -0
  13. package/dist/skill/reference/cli/init.md +63 -0
  14. package/dist/skill/reference/cli/skill.md +79 -0
  15. package/dist/skill/reference/cli/status.md +14 -0
  16. package/dist/skill/reference/cli/workflow.md +788 -0
  17. package/dist/skill/reference/dataset-format.md +251 -0
  18. package/dist/skill/reference/debugging.md +280 -0
  19. package/dist/skill/reference/evaluators.md +210 -0
  20. package/dist/skill/reference/step-exec.md +164 -0
  21. package/dist/skill/reference/step-types.md +519 -0
  22. package/dist/skill/reference/workflow-yaml.md +304 -0
  23. package/dist/templates/blank/README.md +22 -0
  24. package/dist/templates/blank/dataset/examples/sample/expected/output.json +4 -0
  25. package/dist/templates/blank/dataset/examples/sample/input/arguments.json +3 -0
  26. package/dist/templates/blank/evaluators.yaml +9 -0
  27. package/dist/templates/blank/workflow.yaml +39 -0
  28. package/dist/templates/pdf-extraction/README.md +20 -0
  29. package/dist/templates/pdf-extraction/dataset/examples/sample-invoice/README.md +5 -0
  30. package/dist/templates/pdf-extraction/dataset/examples/sample-invoice/expected/output.json +6 -0
  31. package/dist/templates/pdf-extraction/dataset/examples/sample-invoice/input/arguments.json +1 -0
  32. package/dist/templates/pdf-extraction/evaluators.yaml +5 -0
  33. package/dist/templates/pdf-extraction/workflow.yaml +38 -0
  34. package/dist/templates/text-classification/README.md +8 -0
  35. package/dist/templates/text-classification/dataset/examples/negative/expected/output.json +3 -0
  36. package/dist/templates/text-classification/dataset/examples/negative/input/arguments.json +3 -0
  37. package/dist/templates/text-classification/dataset/examples/positive/expected/output.json +3 -0
  38. package/dist/templates/text-classification/dataset/examples/positive/input/arguments.json +3 -0
  39. package/dist/templates/text-classification/evaluators.yaml +6 -0
  40. package/dist/templates/text-classification/workflow.yaml +35 -0
  41. package/package.json +60 -15
  42. package/index.js +0 -4
@@ -0,0 +1,304 @@
1
+ # workflow.yaml — required schema
2
+
3
+ A workflow is a DAG of named steps with named inputs, named outputs, and
4
+ trigger metadata. The full Zod schema lives in
5
+ `@eigenpal/types/src/workflow/` and ships with the CLI — query the
6
+ authoritative shape per step type with:
7
+
8
+ ```bash
9
+ eigenpal workflow step-type list # all step types
10
+ eigenpal workflow step-type get <type> # JSON Schema for one type's config + output
11
+ ```
12
+
13
+ ## Top-level required fields
14
+
15
+ ```yaml
16
+ name: extract-invoices # string, lowercase kebab/snake-case, unique within tenant
17
+ version: 1.0.0 # bare semver `MAJOR.MINOR.PATCH`, no leading `v`
18
+ description: Parse a PDF and extract invoice fields. # string, optional
19
+ triggerMethods: [api] # array, ≥1 entry from: api | cron | email
20
+ inputs: [...] # array of input definitions (see below)
21
+ steps: [...] # array of steps, executed in topological order
22
+ output: {...} # object — the workflow's return shape
23
+ ```
24
+
25
+ `name` + `version` together identify the version row. Pushing a new
26
+ version with the same `name` and a different `version` appends to history;
27
+ re-using the same `version` is rejected.
28
+
29
+ ### `triggerMethods`
30
+
31
+ Required. Each entry adds an invocation surface:
32
+
33
+ - `api` — the workflow can be called via REST or the CLI's `workflow execution run`
34
+ - `cron` — scheduled. Add a sibling `cron: { schedule: "0 9 * * *", timezone: "UTC" }`
35
+ - `email` — inbound email. Add a sibling `email: { subject?: ..., aliases?: [...] }`
36
+
37
+ If `api` is missing, `eigenpal workflow execution run` and `workflow run` reject with a
38
+ 403 / "Workflow does not have API trigger enabled."
39
+
40
+ ### `inputs`
41
+
42
+ ```yaml
43
+ inputs:
44
+ - name: document # required — becomes a key on triggerInput
45
+ type: file # one of: string | number | boolean | object | file
46
+ file: true # required when type=file (legacy duplicate of `type: file`)
47
+ description: PDF or image to extract from
48
+ required: true # default true; pass false for optional inputs
49
+
50
+ - name: language
51
+ type: string
52
+ description: Language hint
53
+ default: auto
54
+ ```
55
+
56
+ Per input:
57
+
58
+ - `name` — `[a-z0-9][a-z0-9-_]*`
59
+ - `type` — `string` | `number` | `boolean` | `object` | `array` | `file`
60
+ - `file: true` for binary inputs (PDF, DOCX, image). The CLI uploads,
61
+ then references via `{{ input.<name> }}` which resolves to a
62
+ `FilePathDescriptor` the worker reads.
63
+ - `default` — used when the input is omitted at runtime
64
+ - `description` — surfaced in the dashboard + agent tools
65
+
66
+ #### File input shape — single vs array
67
+
68
+ The materialized shape on `triggerInput` is driven by the YAML, not by
69
+ how many files the dataset uploaded. Get this wrong and the worker
70
+ sees the opposite shape:
71
+
72
+ | YAML | `triggerInput.<name>` | Template |
73
+ | ------------------------------------------ | --------------------- | --------------------------------------- |
74
+ | `type: file` | `{ fileId }` | `{{ input.<name> }}` |
75
+ | `type: array`, `items: { type: file }` | `[{ fileId }, ...]` | `{{ input.<name>[0] }}` (or `forEach:`) |
76
+
77
+ If you see `Invalid input ... expected object, received array` from a
78
+ step that takes a single file, the workflow input is `type: file` but
79
+ the dataset folder probably has multiple files in it (or the workflow
80
+ was on a stale version that materialized arrays unconditionally).
81
+ Trim the folder to one file, or switch the input to the array form.
82
+
83
+ ### `steps`
84
+
85
+ ```yaml
86
+ steps:
87
+ - name: parse # required, unique within the workflow
88
+ type: ai.document-parser # see `reference/step-types.md`; introspect with `step-type get`
89
+ if: '{{ input.skipParse != true }}' # optional — Liquid expression; falsy skips the step
90
+ forEach: '{{ input.documents }}' # optional — runs the step over each item; output is array
91
+ with: # step-specific config — schema depends on `type`
92
+ file: '{{ input.document }}'
93
+ parser: auto
94
+
95
+ - name: extract
96
+ type: ai.extract
97
+ with:
98
+ input: '{{ steps.parse.output.text }}'
99
+ schema:
100
+ type: object
101
+ properties:
102
+ invoiceNumber: { type: string }
103
+ totalAmount: { type: number }
104
+ required: [invoiceNumber]
105
+ ```
106
+
107
+ Step references resolve via Liquid template expressions:
108
+
109
+ - `{{ input.<name> }}` — workflow input
110
+ - `{{ steps.<step-name>.output.<field> }}` — prior step output
111
+ - `{{ item.<field> }}` — current item inside `forEach`
112
+
113
+ `steps[].name` is the only handle into the step from later steps. Use
114
+ short, descriptive names (`parse`, `extract`, `score`).
115
+
116
+ ### `output`
117
+
118
+ ```yaml
119
+ output:
120
+ invoiceNumber: '{{ steps.extract.output.invoiceNumber }}'
121
+ totalAmount: '{{ steps.extract.output.totalAmount }}'
122
+ confidence: '{{ steps.score.output.confidence | default: 0 }}'
123
+ ```
124
+
125
+ Whatever shape you write here is the workflow's return value. Reference
126
+ any step's output. Static keys are fine — only the values are templated.
127
+
128
+ ## Step types — pick the right one
129
+
130
+ See `reference/step-types.md` for the full catalog. Categories:
131
+
132
+ - `action.*` — side-effectful operations (HTTP, email, connectors)
133
+ - `ai.*` — model-backed processing (parse, extract, classify, judge)
134
+ - `transform.*` — deterministic data transforms (script, template, merge)
135
+ - `control.*` — flow control (if, for-each, parallel-map)
136
+
137
+ When in doubt, use `eigenpal workflow step-type get <type>` — it returns
138
+ the exact JSON Schema for the step's `config` + `output` so you know
139
+ which fields are required and what values they accept.
140
+
141
+ ## Liquid vs `transform.script`
142
+
143
+ Use Liquid `{{ ... }}` for one-liners:
144
+
145
+ | Use case | Use |
146
+ | ------------- | -------------------------------- |
147
+ | Field access | `{{ steps.x.output.field }}` |
148
+ | Default value | `{{ value \| default: 0 }}` |
149
+ | Simple math | `{{ price \| times: quantity }}` |
150
+
151
+ Anything more complex (array reduce/filter, multi-step calc, date
152
+ arithmetic, regex) goes in `transform.script`:
153
+
154
+ ```yaml
155
+ - name: total
156
+ type: transform.script
157
+ with:
158
+ inputs: # explicit data deps — visible to the validator
159
+ lineItems: '{{ steps.extract.output.lineItems }}'
160
+ taxRate: '{{ input.taxRate }}'
161
+ code: |
162
+ const subtotal = lineItems.reduce((s, i) => s + i.price * i.qty, 0);
163
+ const tax = subtotal * taxRate;
164
+ return { subtotal, tax, total: subtotal + tax };
165
+ outputSchema: # optional but recommended — runtime-validated
166
+ type: object
167
+ properties:
168
+ subtotal: { type: number }
169
+ tax: { type: number }
170
+ total: { type: number }
171
+ ```
172
+
173
+ The script runs in a WASM sandbox: 5s wall clock, 10 MB heap, no network,
174
+ no filesystem. Trips show up as `script_timeout` / `script_memory_limit`
175
+ on the step execution.
176
+
177
+ ## Common patterns
178
+
179
+ ### Conditional branches
180
+
181
+ ```yaml
182
+ - name: classify
183
+ type: ai.extract
184
+ with:
185
+ input: '{{ input.text }}'
186
+ schema:
187
+ type: object
188
+ properties:
189
+ kind: { type: string, enum: [invoice, contract, other] }
190
+
191
+ - name: extract-invoice
192
+ type: ai.extract
193
+ if: '{{ steps.classify.output.kind == "invoice" }}'
194
+ with: { ... }
195
+
196
+ - name: extract-contract
197
+ type: ai.extract
198
+ if: '{{ steps.classify.output.kind == "contract" }}'
199
+ with: { ... }
200
+ ```
201
+
202
+ ### Map over an array input
203
+
204
+ ```yaml
205
+ - name: extract-each
206
+ type: ai.extract
207
+ forEach: '{{ input.documents }}'
208
+ with:
209
+ input: '{{ item.text }}'
210
+ schema: { ... }
211
+ # steps.extract-each.output is an array of {invoiceNumber, totalAmount, ...}
212
+ ```
213
+
214
+ ### Parallel fan-out
215
+
216
+ ```yaml
217
+ - name: extract-fields
218
+ type: control.parallel-map
219
+ forEach: '{{ input.fieldNames }}'
220
+ with:
221
+ steps:
222
+ - name: extract-one
223
+ type: ai.extract
224
+ with:
225
+ input: '{{ input.document }}'
226
+ schema: { type: object, properties: { value: { type: string } } }
227
+ ```
228
+
229
+ ## Validate before pushing
230
+
231
+ ```bash
232
+ eigenpal workflow validate ./workflow.yaml
233
+ ```
234
+
235
+ Reports field-level issues:
236
+
237
+ ```
238
+ ✗ workflow (./workflow.yaml) — 2 issues
239
+ steps.2.config.passThreshold Required
240
+ steps.2.type Invalid step type: 'eval.llm-judg'
241
+ ```
242
+
243
+ Push:
244
+
245
+ ```bash
246
+ # Create a new workflow (version comes from the YAML's top-level `version:` field)
247
+ eigenpal workflow push --file workflow.yaml
248
+
249
+ # Update an existing one — three ways to set the new version:
250
+ eigenpal workflow push --file workflow.yaml --workflow-id wf_… # bump in YAML's `version:`
251
+ eigenpal workflow push --file workflow.yaml --workflow-id wf_… --set-version 2.0.0 # explicit semver
252
+ eigenpal workflow push --file workflow.yaml --workflow-id wf_… --bump patch # auto-bump (patch | minor | major)
253
+ ```
254
+
255
+ `--bump` requires `--workflow-id` (it bumps from the current server
256
+ version). `--set-version` works with or without `--workflow-id`. The
257
+ YAML's top-level `version:` field is the fallback when neither flag is
258
+ passed — server rejects pushes whose version doesn't strictly increase.
259
+
260
+ ## Discover step + evaluator types
261
+
262
+ Don't memorize fields — introspect:
263
+
264
+ ```bash
265
+ eigenpal workflow step-type list # full step catalog
266
+ eigenpal workflow step-type get <type> # config + output schema for one step type
267
+ eigenpal workflow evaluator-type list # full evaluator catalog
268
+ eigenpal workflow evaluator-type get <type> # config schema for one evaluator type
269
+ ```
270
+
271
+ Both catalogs are generated from the canonical Zod schemas in
272
+ `@eigenpal/types`, so they're always in sync with what the deployment
273
+ supports.
274
+
275
+ <!-- GENERATED:WORKFLOW_REFERENCE START -->
276
+ ## Top-level fields — full reference
277
+
278
+ _Generated from `WorkflowDefinitionSchema` in `@eigenpal/types/src/workflow/workflow.ts`. Do not hand-edit between the GENERATED fences — run `bun run --cwd packages/cli generate:skill`._
279
+
280
+ | Field | Type | Required | Default | Description |
281
+ | --- | --- | --- | --- | --- |
282
+ | `name` | string | yes | | |
283
+ | `kind` | `"workflow"` \| `"block"` | no | `"workflow"` | |
284
+ | `version` | string | no | `"1.0.0"` | |
285
+ | `description` | string | no | | |
286
+ | `enabled` | boolean | no | `true` | |
287
+ | `triggerMethods` | array<object> | no | `[{"type":"manual"}]` | |
288
+ | `inputs` | array<object> | no | | |
289
+ | `steps` | array<unknown> | yes | | |
290
+ | `output` | record<string, string> | no | | |
291
+ | `settings` | object | no | | |
292
+
293
+
294
+ ## Per-input fields
295
+
296
+ | Field | Type | Required | Default | Description |
297
+ | --- | --- | --- | --- | --- |
298
+ | `name` | string | yes | | |
299
+ | `type` | string | yes | | |
300
+ | `description` | string | no | | |
301
+ | `required` | boolean | no | `true` | |
302
+ | `default` | unknown | no | | |
303
+ | `items` | object | no | | |
304
+ <!-- GENERATED:WORKFLOW_REFERENCE END -->
@@ -0,0 +1,22 @@
1
+ # __NAME__
2
+
3
+ Generated by `eigenpal init workflow`. Edit `workflow.yaml` to define your pipeline,
4
+ then run:
5
+
6
+ ```bash
7
+ # Validate locally (no server contact)
8
+ eigenpal workflow validate
9
+
10
+ # Run an example end-to-end against the configured base URL
11
+ eigenpal workflow execution run __NAME__ sample
12
+ ```
13
+
14
+ Add more examples under `dataset/examples/<name>/`. Each example needs an
15
+ `input/arguments.json`; `expected/output.json` and `meta.json` are optional.
16
+ File arguments live in `input/<arg-name>/<filename>`.
17
+
18
+ When you're ready to push this workflow to the server:
19
+
20
+ ```bash
21
+ eigenpal workflow push --file workflow.yaml
22
+ ```
@@ -0,0 +1,4 @@
1
+ {
2
+ "length": 16,
3
+ "original": "Hello, eigenpal."
4
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "text": "Hello, eigenpal."
3
+ }
@@ -0,0 +1,9 @@
1
+ # Evaluators run after every workflow execution that's part of an eval batch.
2
+ # Comment them in once you have an `expected/output.json` to compare against.
3
+ #
4
+ # evaluators:
5
+ # - name: exact-match
6
+ # type: exact-diff
7
+ # config:
8
+ # passThreshold: 1.0
9
+ evaluators: []
@@ -0,0 +1,39 @@
1
+ name: __NAME__
2
+ version: 1.0.0
3
+ description: Replace this with what your workflow does.
4
+
5
+ # `triggerMethods` controls how this workflow can be invoked:
6
+ # - api: workflow can be called via the REST API and CLI
7
+ # - cron: workflow can be scheduled (set `cron` field below)
8
+ triggerMethods:
9
+ - api
10
+
11
+ # `inputs` declares the schema of arguments the workflow accepts. Each entry
12
+ # becomes a top-level key on the call's `triggerInput` object. Use `file: true`
13
+ # to mark an input as a file-arg (its value is a `[{ fileId }]` array at
14
+ # runtime; in the dataset folder layout it lives under `input/<name>/`).
15
+ inputs:
16
+ - name: text
17
+ type: string
18
+ description: Free-form text to process
19
+
20
+ # A pipeline of one or more steps. The first step receives `input.*`; later
21
+ # steps reference earlier outputs via `{{ steps.<name>.output.<field> }}`.
22
+ steps:
23
+ - name: passthrough
24
+ type: transform.script
25
+ with:
26
+ inputs:
27
+ text: '{{ input.text }}'
28
+ code: |
29
+ return { length: text.length, original: text };
30
+ outputSchema:
31
+ type: object
32
+ properties:
33
+ length: { type: number }
34
+ original: { type: string }
35
+
36
+ # `output` shapes the final return value. References any step's output.
37
+ output:
38
+ length: '{{ steps.passthrough.output.length }}'
39
+ original: '{{ steps.passthrough.output.original }}'
@@ -0,0 +1,20 @@
1
+ # __NAME__
2
+
3
+ A PDF/document extraction workflow scaffolded by `eigenpal init workflow`. The
4
+ pipeline parses an uploaded document with the auto-detected parser
5
+ (plaintext / office / OCR / LLM-vision), then runs `ai.extract` against a
6
+ fixed JSON schema.
7
+
8
+ ## Wire it up
9
+
10
+ 1. Drop a sample PDF at `dataset/examples/sample-invoice/input/document/<filename>`.
11
+ 2. Adjust the `extract.with.schema` to the fields your documents actually carry.
12
+ 3. Run an example: `eigenpal workflow execution run __NAME__ sample-invoice`.
13
+ 4. When the output looks right, push: `eigenpal workflow push --file workflow.yaml`.
14
+
15
+ ## Extending
16
+
17
+ - Multiple file inputs: declare more inputs in `workflow.yaml` and add
18
+ `dataset/examples/<name>/input/<arg>/` folders with their files.
19
+ - Per-example overrides: drop a `meta.json` next to the example with
20
+ `{ "overrides": { "steps": { "<step>": { ... } } } }` to skip steps in eval.
@@ -0,0 +1,5 @@
1
+ # sample-invoice
2
+
3
+ Drop your PDF/image at `input/document/<filename>` to give this example
4
+ something to extract from. The argument folder name (`document`) matches
5
+ the input declared in `workflow.yaml`.
@@ -0,0 +1,6 @@
1
+ {
2
+ "invoiceNumber": "INV-001",
3
+ "totalAmount": 1500,
4
+ "vendorName": "Acme Corp",
5
+ "dueDate": "2026-05-15"
6
+ }
@@ -0,0 +1,5 @@
1
+ evaluators:
2
+ - name: exact-match
3
+ type: exact-diff
4
+ config:
5
+ passThreshold: 1.0
@@ -0,0 +1,38 @@
1
+ name: __NAME__
2
+ version: 1.0.0
3
+ description: Parse a PDF and extract structured fields with an LLM.
4
+
5
+ triggerMethods:
6
+ - api
7
+
8
+ inputs:
9
+ - name: document
10
+ type: file
11
+ file: true
12
+ description: PDF or image to extract from
13
+
14
+ steps:
15
+ - name: parse
16
+ type: ai.document-parser
17
+ with:
18
+ file: '{{ input.document }}'
19
+ parser: auto
20
+
21
+ - name: extract
22
+ type: ai.extract
23
+ with:
24
+ input: '{{ steps.parse.output.text }}'
25
+ schema:
26
+ type: object
27
+ properties:
28
+ invoiceNumber: { type: string }
29
+ totalAmount: { type: number }
30
+ vendorName: { type: string }
31
+ dueDate: { type: string, format: date }
32
+ required: [invoiceNumber, totalAmount, vendorName]
33
+
34
+ output:
35
+ invoiceNumber: '{{ steps.extract.output.invoiceNumber }}'
36
+ totalAmount: '{{ steps.extract.output.totalAmount }}'
37
+ vendorName: '{{ steps.extract.output.vendorName }}'
38
+ dueDate: '{{ steps.extract.output.dueDate | default: null }}'
@@ -0,0 +1,8 @@
1
+ # __NAME__
2
+
3
+ A text classification workflow scaffolded by `eigenpal init workflow`. Two examples
4
+ are pre-seeded so you can immediately run `eigenpal workflow execution run __NAME__` and see
5
+ end-to-end behavior.
6
+
7
+ The eval config asserts on the `label` path only — confidence/rationale are
8
+ free to vary between runs without failing the eval.
@@ -0,0 +1,3 @@
1
+ {
2
+ "text": "Worst experience ever, do not buy."
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "text": "Best product I have used in years!"
3
+ }
@@ -0,0 +1,6 @@
1
+ evaluators:
2
+ - name: label-match
3
+ type: exact-diff
4
+ config:
5
+ passThreshold: 1.0
6
+ paths: [label]
@@ -0,0 +1,35 @@
1
+ name: __NAME__
2
+ version: 1.0.0
3
+ description: Classify free-form text into one of a fixed set of labels.
4
+
5
+ triggerMethods:
6
+ - api
7
+
8
+ inputs:
9
+ - name: text
10
+ type: string
11
+ description: Text to classify
12
+
13
+ steps:
14
+ - name: classify
15
+ type: ai.extract
16
+ with:
17
+ input: '{{ input.text }}'
18
+ schema:
19
+ type: object
20
+ properties:
21
+ label:
22
+ type: string
23
+ enum: [positive, neutral, negative]
24
+ confidence:
25
+ type: number
26
+ minimum: 0
27
+ maximum: 1
28
+ rationale:
29
+ type: string
30
+ required: [label, confidence]
31
+
32
+ output:
33
+ label: '{{ steps.classify.output.label }}'
34
+ confidence: '{{ steps.classify.output.confidence }}'
35
+ rationale: '{{ steps.classify.output.rationale | default: null }}'
package/package.json CHANGED
@@ -1,12 +1,35 @@
1
1
  {
2
2
  "name": "@eigenpal/cli",
3
- "version": "0.0.1",
4
- "description": "Eigenpal CLI — placeholder release. The real CLI will replace this shortly.",
3
+ "version": "0.4.2",
4
+ "description": "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
5
+ "keywords": [
6
+ "eigenpal",
7
+ "cli",
8
+ "ai",
9
+ "agent",
10
+ "workflow",
11
+ "llm",
12
+ "evals",
13
+ "experiments",
14
+ "document",
15
+ "extraction",
16
+ "ocr"
17
+ ],
18
+ "homepage": "https://github.com/eigenpal/cli#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/eigenpal/cli/issues"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/eigenpal/cli.git"
25
+ },
5
26
  "license": "Apache-2.0",
27
+ "author": "Eigenpal <hello@eigenpal.com> (https://eigenpal.com)",
6
28
  "type": "module",
7
- "main": "./index.js",
29
+ "main": "./src/index.ts",
30
+ "types": "./src/index.ts",
8
31
  "bin": {
9
- "eigenpal": "./index.js"
32
+ "eigenpal": "dist/cli.js"
10
33
  },
11
34
  "engines": {
12
35
  "node": ">=20"
@@ -14,16 +37,38 @@
14
37
  "publishConfig": {
15
38
  "access": "public"
16
39
  },
17
- "files": [
18
- "index.js",
19
- "README.md"
20
- ],
21
- "repository": {
22
- "type": "git",
23
- "url": "https://github.com/eigenpal/cli"
40
+ "scripts": {
41
+ "dev": "bun src/cli.ts",
42
+ "build": "bun run generate:skill && bun build src/cli.ts --outdir dist --target node --format esm && rm -rf dist/templates dist/skill && cp -R src/templates dist/templates && cp -R src/skill dist/skill",
43
+ "generate:skill": "bun scripts/generate-skill-reference.ts",
44
+ "generate:skill:check": "bun scripts/generate-skill-reference.ts --check",
45
+ "generate:cli-docs": "bun scripts/generate-cli-docs.ts",
46
+ "generate:cli-docs:check": "bun scripts/generate-cli-docs.ts --check",
47
+ "generate:logo": "bun scripts/render-logo-ascii.ts --cells 20",
48
+ "lint": "eslint src/",
49
+ "typecheck": "tsc --noEmit"
24
50
  },
25
- "homepage": "https://github.com/eigenpal/cli#readme",
26
- "bugs": {
27
- "url": "https://github.com/eigenpal/cli/issues"
28
- }
51
+ "dependencies": {
52
+ "@clack/prompts": "^0.10.1",
53
+ "ajv": "^8.17.1",
54
+ "commander": "^13.1.0",
55
+ "fflate": "0.8.2",
56
+ "openai": "^6.27.0",
57
+ "picocolors": "^1.1.1",
58
+ "quickjs-emscripten": "^0.31.0",
59
+ "yaml": "^2.7.0",
60
+ "zod": "^4.0.0"
61
+ },
62
+ "devDependencies": {
63
+ "@eigenpal/types": "workspace:*",
64
+ "@eigenpal/workflow-yaml": "workspace:*",
65
+ "@t3-oss/env-core": "^0.13.11",
66
+ "typescript": "^5.3.0"
67
+ },
68
+ "files": [
69
+ "dist",
70
+ "LICENSE",
71
+ "README.md",
72
+ "CHANGELOG.md"
73
+ ]
29
74
  }
package/index.js DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
- console.log('@eigenpal/cli placeholder — the real CLI ships in the next release.');
3
- console.log('See https://github.com/eigenpal/cli for source.');
4
- process.exit(0);