markform 0.1.1 → 0.1.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 (36) hide show
  1. package/DOCS.md +546 -0
  2. package/README.md +338 -71
  3. package/SPEC.md +2779 -0
  4. package/dist/ai-sdk.d.mts +2 -2
  5. package/dist/ai-sdk.mjs +5 -3
  6. package/dist/{apply-BQdd-fdx.mjs → apply-BfAGTHMh.mjs} +837 -730
  7. package/dist/bin.mjs +6 -3
  8. package/dist/{cli-pjOiHgCW.mjs → cli-B3NVm6zL.mjs} +1349 -422
  9. package/dist/cli.mjs +6 -3
  10. package/dist/{coreTypes--6etkcwb.d.mts → coreTypes-BXhhz9Iq.d.mts} +1946 -794
  11. package/dist/coreTypes-Dful87E0.mjs +537 -0
  12. package/dist/index.d.mts +116 -19
  13. package/dist/index.mjs +5 -3
  14. package/dist/session-Bqnwi9wp.mjs +110 -0
  15. package/dist/session-DdAtY2Ni.mjs +4 -0
  16. package/dist/shared-D7gf27Tr.mjs +3 -0
  17. package/dist/shared-N_s1M-_K.mjs +176 -0
  18. package/dist/src-BXRkGFpG.mjs +7587 -0
  19. package/examples/celebrity-deep-research/celebrity-deep-research.form.md +912 -0
  20. package/examples/earnings-analysis/earnings-analysis.form.md +6 -1
  21. package/examples/earnings-analysis/earnings-analysis.valid.ts +119 -59
  22. package/examples/movie-research/movie-research-basic.form.md +164 -0
  23. package/examples/movie-research/movie-research-deep.form.md +486 -0
  24. package/examples/movie-research/movie-research-minimal.form.md +73 -0
  25. package/examples/simple/simple-mock-filled.form.md +17 -13
  26. package/examples/simple/simple-skipped-filled.form.md +32 -9
  27. package/examples/simple/simple-with-skips.session.yaml +102 -143
  28. package/examples/simple/simple.form.md +13 -13
  29. package/examples/simple/simple.session.yaml +80 -69
  30. package/examples/startup-deep-research/startup-deep-research.form.md +60 -8
  31. package/examples/startup-research/startup-research-mock-filled.form.md +1 -1
  32. package/examples/startup-research/startup-research.form.md +1 -1
  33. package/package.json +9 -5
  34. package/dist/src-Cs4_9lWP.mjs +0 -2151
  35. package/examples/political-research/political-research.form.md +0 -233
  36. package/examples/political-research/political-research.mock.lincoln.form.md +0 -355
package/README.md CHANGED
@@ -1,40 +1,180 @@
1
1
  # Markform
2
2
 
3
- Agent-friendly, human-readable forms stored as `.form.md` files.
3
+ ***Structured Markdown documents for humans, agents, and APIs***
4
4
 
5
- Markform enables AI agents to fill out structured forms using patches, while keeping the
6
- form source in human-readable Markdown with [Markdoc](https://markdoc.dev/) tags.
5
+ **Markform** is a **file format**, **data model**, and **editing API** for
6
+ **token-friendly, human-readable text forms**. Markform syntax is a superset of Markdown
7
+ based on [Markdoc](https://github.com/markdoc/markdoc), stored as `.form.md` files.
8
+
9
+ Markform is like if Markdown docs had a customizable API. The idea is to combine the
10
+ simple utility of a Markdown document with structured tags that define typed fields and
11
+ validation rules.
12
+ Fields, validation rules, and instructions are encoded as Markdoc tags.
13
+
14
+ Markform lets you build powerful agent workflows by structuring and validating *what*
15
+ you want (the form structure and validations) instead of *how* to get it (coding up
16
+ agent workflows). For deep research and other tasks where you want a high level of
17
+ control on intermediate states and final output from an AI pipeline, this approach is a
18
+ compelling alternative to programmatic or UI-based agent workflows.
19
+ Because it’s just Markdown with tags, agents are also very good at writing Markform,
20
+ which makes creating new workflows much easier.
7
21
 
8
22
  ## Installation
9
23
 
10
24
  ```bash
25
+ # As a global CLI
26
+ npm install -g markform
27
+
28
+ # Or as a project dependency
11
29
  npm install markform
12
- # or
13
- pnpm add markform
14
30
  ```
15
31
 
16
- Requires Node.js 24+.
32
+ Requires Node.js 20+ (v24 recommended).
17
33
 
18
34
  ## Quick Start
19
35
 
20
- The fastest way to try Markform is the interactive `examples` command:
21
-
22
36
  ```bash
23
- # Try it without installing (uses npx)
37
+ # Try it without installing
24
38
  npx markform examples
39
+ ```
25
40
 
26
- # Or after installing globally
27
- npm install -g markform
28
- markform examples
41
+ This walks you through an example form interactively, with optional AI agent filling.
42
+ You’ll need at least one [API key](#supported-providers) to have LLMs fill in forms.
43
+
44
+ ### A Simple Form
45
+
46
+ A `.form.md` file is simply a Markdoc file.
47
+ It combines YAML frontmatter with Markdoc-tagged content:
48
+
49
+ ```markdown
50
+ ---
51
+ markform:
52
+ spec: MF/0.1
53
+ title: Movie Research (Simple)
54
+ roles: # Who can fill fields
55
+ - user
56
+ - agent
57
+ role_instructions: # Instructions shown to each role
58
+ user: "Enter the movie title."
59
+ agent: "Research the movie and fill in the details from IMDB."
60
+ ---
61
+
62
+ {% form id="movie_research" title="Movie Research" %}
63
+
64
+ {% field-group id="input" title="Input" %}
65
+
66
+ <!-- User fills this field -->
67
+
68
+ {% string-field id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 %}{% /string-field %}
69
+
70
+ {% instructions ref="movie" %}
71
+
72
+ <!-- Guidance for filling the field -->
73
+
74
+ Enter the movie title (add any details to help identify, like "Barbie 2023" or "the Batman movie with Robert Pattinson").
75
+ {% /instructions %}
76
+
77
+ {% /field-group %}
78
+
79
+ {% field-group id="details" title="Movie Details" %}
80
+
81
+ <!-- Agent researches and fills these fields -->
82
+
83
+ {% string-field id="full_title" label="Full Title" role="agent" required=true %}{% /string-field %}
84
+
85
+ {% number-field id="year" label="Release Year" role="agent" min=1888 max=2030 %}{% /number-field %}
86
+
87
+ {% single-select id="mpaa_rating" label="MPAA Rating" role="agent" %}
88
+ - [ ] G {% #g %}
89
+ - [ ] PG {% #pg %}
90
+ - [ ] PG-13 {% #pg_13 %}
91
+ - [ ] R {% #r %}
92
+ - [ ] NC-17 {% #nc_17 %}
93
+ - [ ] NR/Unrated {% #nr %}
94
+ {% /single-select %}
95
+
96
+ {% url-field id="imdb_url" label="IMDB URL" role="agent" %}{% /url-field %}
97
+
98
+ {% number-field id="imdb_rating" label="IMDB Rating" role="agent" min=1.0 max=10.0 %}{% /number-field %}
99
+
100
+ {% string-field id="logline" label="Summary" role="agent" maxLength=200 %}{% /string-field %}
101
+
102
+ {% /field-group %}
103
+
104
+ {% /form %}
29
105
  ```
30
106
 
31
- This walks you through:
107
+ This is a simplified version of the [full movie research
108
+ form](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research.form.md),
109
+ which includes multiple rating sources (IMDB, Rotten Tomatoes, Metacritic), detailed
110
+ instructions, and harness configuration.
111
+
112
+ **Key concepts:**
113
+
114
+ - **Roles**: Define who fills what (`user` for humans, `agent` for AI)
115
+
116
+ - **Field types**: `string-field`, `number-field`, `url-field`, `string-list`,
117
+ `single-select`, `multi-select`, `checkboxes`
118
+
119
+ - **Validation**: `required`, `min/max`, `minLength/maxLength`, `pattern`
120
+
121
+ - **Structure**: Fields organized in `field-group` containers
122
+
123
+ - **Instructions**: Per-field guidance for users or agents
124
+
125
+ ### More Example Forms
126
+
127
+ The package includes example forms in
128
+ [`examples/`](https://github.com/jlevy/markform/tree/main/packages/markform/examples):
129
+
130
+ - [`movie-research/movie-research-minimal.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-minimal.form.md)
131
+ \- Quick movie lookup (title, year, rating)
132
+
133
+ - [`movie-research/movie-research-basic.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-basic.form.md)
134
+ \- Standard research with IMDB, Rotten Tomatoes, Metacritic
135
+
136
+ - [`movie-research/movie-research-deep.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-deep.form.md)
137
+ \- Comprehensive analysis with streaming, box office
138
+
139
+ - [`simple/simple.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/simple/simple.form.md)
140
+ \- Basic form demonstrating all field types
141
+
142
+ - [`earnings-analysis/earnings-analysis.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/earnings-analysis/earnings-analysis.form.md)
143
+ \- Financial analysis form
144
+
145
+ View them with `markform examples --list` or try them interactively.
146
+
147
+ ## Supported Providers
148
+
149
+ Standard LLMs can be used to fill in forms or create research reports from form
150
+ templates. The package currently has support for these models built in, and enables web
151
+ search tools for them if possible.
152
+
153
+ | Provider | Env Variable | Example Models |
154
+ | --- | --- | --- |
155
+ | openai | `OPENAI_API_KEY` | gpt-5-mini, gpt-5.1, gpt-5.2 |
156
+ | anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-5, claude-opus-4-5 |
157
+ | google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.5-flash |
158
+ | xai | `XAI_API_KEY` | grok-4, grok-4-fast |
159
+ | deepseek | `DEEPSEEK_API_KEY` | deepseek-chat, deepseek-reasoner |
160
+
161
+ Set the appropriate environment variable for your provider before running `markform
162
+ fill`. See
163
+ [`src/settings.ts`](https://github.com/jlevy/markform/blob/main/packages/markform/src/settings.ts)
164
+ for the full list of models.
165
+
166
+ ## Why?
32
167
 
33
- 1. Selecting an example form (simple, political research, earnings analysis)
168
+ Many agent workflow frameworks emphasize the *flow* of information (the *how*) over its
169
+ *structure* (the *what*). But the *how* is constantly changing.
34
170
 
35
- 2. Filling in user fields interactively
171
+ What we often really want is to express *desired structure and validation rules* for
172
+ content directly in a way that provides clear context to agents and humans at all times.
36
173
 
37
- 3. Optionally running an AI agent to complete remaining fields
174
+ Humans have for centuries used paper forms to systematize and manage processes.
175
+ The key insight of Markform is that the most natural way to express the state and
176
+ context for a workflow is often *forms*. Just as Markdown is a transparent format for
177
+ documents, Markform is a transparent text format for structured information.
38
178
 
39
179
  ## CLI Commands
40
180
 
@@ -104,35 +244,86 @@ markform apply my-form.form.md --patch '[{"op":"set","fieldId":"name","value":"A
104
244
  markform serve my-form.form.md
105
245
  ```
106
246
 
107
- ### List Models
247
+ ### Documentation Commands
108
248
 
109
249
  ```bash
250
+ # Quick reference for writing forms (agent-friendly)
251
+ markform docs
252
+
253
+ # Full specification (SPEC.md)
254
+ markform spec
255
+
256
+ # This README
257
+ markform readme
258
+
110
259
  # See supported AI providers and example models
111
260
  markform models
261
+
262
+ # See all commands
263
+ markform --help
112
264
  ```
113
265
 
114
- ### View Documentation
266
+ ## Architecture
115
267
 
116
- ```bash
117
- # Display this README with terminal formatting
118
- markform instructions
268
+ ```mermaid
269
+ flowchart LR
270
+ subgraph SPEC["<b>MARKFORM SPEC</b>"]
271
+ direction TB
119
272
 
120
- # Output raw markdown (for piping)
121
- markform instructions --raw
122
- ```
273
+ subgraph L1["<b>LAYER 1: SYNTAX</b><br/>Markdoc tag syntax and frontmatter (form, field-group, string-field, checkboxes, etc.)"]
274
+ end
123
275
 
124
- ## Supported AI Providers
276
+ subgraph L2["<b>LAYER 2: FORM DATA MODEL</b><br/>Schema definitions for forms, fields, values (in Zod but mappable to JSON Schema or Pydantic)"]
277
+ end
125
278
 
126
- | Provider | Env Variable | Example Models |
127
- | --- | --- | --- |
128
- | openai | `OPENAI_API_KEY` | gpt-5-mini, gpt-5.1, gpt-5.2 |
129
- | anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-5, claude-opus-4-5 |
130
- | google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.5-flash |
131
- | xai | `XAI_API_KEY` | grok-4, grok-4-fast |
132
- | deepseek | `DEEPSEEK_API_KEY` | deepseek-chat, deepseek-reasoner |
279
+ subgraph L3["<b>LAYER 3: VALIDATION & FORM FILLING</b><br/>Rules for filling forms via patches, field ids, required field semantics, validation hooks"]
280
+ end
281
+
282
+ subgraph L4["<b>LAYER 4: TOOL API & INTERFACES</b><br/>Abstract API for agents and humans (TypeScript and AI SDK integration)"]
283
+ end
284
+
285
+ L4 --> L3 --> L2 --> L1
286
+ end
287
+
288
+ subgraph IMPL["<b>THIS IMPLEMENTATION</b>"]
289
+ direction TB
290
+
291
+ subgraph ENGINE["<b>ENGINE IMPLEMENTATION</b><br/>Markdoc parser, serializer, patch application, validation (uses jiti for TypeScript rules)"]
292
+ end
293
+
294
+ subgraph UI["<b>USER INTERFACES</b><br/>CLI commands, web UI (serve), render to HTML"]
295
+ end
133
296
 
134
- Set the appropriate environment variable for your provider before running `markform fill`.
135
- See [`src/settings.ts`](src/settings.ts) for the full list of models.
297
+ subgraph AGENT["<b>AGENT INTERFACES</b><br/>Tool API library, MCP server, AI SDK tools"]
298
+ end
299
+
300
+ subgraph HARNESS["<b>EXECUTION HARNESS</b><br/>Step-by-step form-filling agentic loop"]
301
+ end
302
+
303
+ subgraph TEST["<b>TESTING FRAMEWORK</b><br/>Golden session testing with .session.yaml transcripts"]
304
+ end
305
+
306
+ UI --> ENGINE
307
+ AGENT --> HARNESS
308
+ AGENT --> ENGINE
309
+ HARNESS --> ENGINE
310
+ ENGINE --> TEST
311
+ end
312
+
313
+ SPEC ~~~ IMPL
314
+
315
+ style SPEC fill:#e8f4f8,stroke:#0077b6
316
+ style L1 fill:#caf0f8,stroke:#0077b6
317
+ style L2 fill:#caf0f8,stroke:#0077b6
318
+ style L3 fill:#caf0f8,stroke:#0077b6
319
+ style L4 fill:#caf0f8,stroke:#0077b6
320
+ style IMPL fill:#fff3e6,stroke:#fb8500
321
+ style ENGINE fill:#ffe8cc,stroke:#fb8500
322
+ style UI fill:#ffe8cc,stroke:#fb8500
323
+ style AGENT fill:#ffe8cc,stroke:#fb8500
324
+ style HARNESS fill:#ffe8cc,stroke:#fb8500
325
+ style TEST fill:#ffe8cc,stroke:#fb8500
326
+ ```
136
327
 
137
328
  ## Programmatic Usage
138
329
 
@@ -186,64 +377,140 @@ const result = await generateText({
186
377
  | `markform_export` | Export schema and values as JSON |
187
378
  | `markform_get_markdown` | Get canonical Markdown representation |
188
379
 
189
- ## Form Structure
380
+ ## FAQ
190
381
 
191
- A `.form.md` file combines YAML frontmatter with Markdoc-tagged content:
382
+ ### Is this mature?
192
383
 
193
- ```markdown
194
- ---
195
- markform:
196
- markform_version: "0.1.0"
197
- roles:
198
- - user
199
- - agent
200
- role_instructions:
201
- user: "Fill in your details."
202
- agent: "Complete the analysis fields."
203
- ---
384
+ No! I just wrote it.
385
+ The spec is a draft.
386
+ But it’s been useful for me already.
204
387
 
205
- {% form id="my_form" title="My Form" %}
388
+ ### Was it Vibe Coded?
206
389
 
207
- {% field-group id="basics" title="Basic Info" %}
390
+ It’s all written by LLMs but using a strongly spec-driven process, using rules from
391
+ [Speculate](https://github.com/jlevy/speculate).
392
+ See [the spec](SPEC.md) and the architecture docs and specs in [docs/](docs/).
208
393
 
209
- {% string-field id="name" label="Name" role="user" required=true %}{% /string-field %}
394
+ ### What are the goals of Markform?
210
395
 
211
- {% number-field id="score" label="Score" role="agent" min=0 max=100 %}{% /number-field %}
396
+ - **Markform should express complex structure and validation rules for outputs:** Fields
397
+ can be arbitrary types like checkboxes, strings, dates, numbers, URLs, and lists.
398
+ Validation rules can be simple (min and max value, regexes), arbitrary code, or LLM
399
+ calls.
212
400
 
213
- {% /field-group %}
401
+ - **Markform is programmatically editable:** Field state should be updated via APIs, by
402
+ apps, or by agent tools.
214
403
 
215
- {% /form %}
216
- ```
404
+ - **Markform is readable by humans and agents:** Both templates and field values of a
405
+ form should have a clear text format (not a binary or obscure XML format only readable
406
+ by certain applications).
217
407
 
218
- **Key concepts:**
408
+ ### How do agents fill in forms?
219
409
 
220
- - **Roles**: Define who fills what (`user` for humans, `agent` for AI)
410
+ The data model and editing API let agents fill in forms.
411
+ This enables powerful AI workflows that assemble information in a defined structure:
221
412
 
222
- - **Field types**: `string-field`, `number-field`, `string-list`, `single-select`,
223
- `multi-select`, `checkboxes`
413
+ - **Form content, structure, and field values are in a single text file** for better
414
+ context engineering.
415
+ This is a major advantage for LLM agents and for humans reviewing their work.
224
416
 
225
- - **Validation**: `required`, `min/max`, `minLength/maxLength`, `pattern`
417
+ - **Incremental filling** means an agent or a human can take many iterations, filling
418
+ and correcting a form until it is complete and satisfies the validation rules.
226
419
 
227
- - **Structure**: Fields organized in `field-group` containers
420
+ - **Multiple interfaces for humans or agents** can work with the same forms.
421
+ You can interact with a form via a CLI, a programmatic API, from Vercel AI SDK or in
422
+ an MCP server used by an agent, or in web form UIs for humans.
423
+
424
+ - **Flexible validation** at multiple scopes (field/group/form), including declarative
425
+ constraints and external hooks to arbitrary code (currently TypeScript) or LLM-based
426
+ validation instructions.
427
+
428
+ - An **agent execution harness** for step-by-step form filling, enabling deep research
429
+ agents that assemble validated output in a structured format.
430
+
431
+ ### Does anything like this already exist?
432
+
433
+ Not really. The closest alternatives are:
228
434
 
229
- ## Example Forms
435
+ - Plain Markdown docs can be used as templates and filled in by agents.
436
+ These are more expressive, but it is hard to edit them programmatically or use LLMs to
437
+ update them reliably.
230
438
 
231
- The package includes example forms in the `examples/` directory:
439
+ - Agent to-do lists are part of many chat or coding interfaces and are programmatically
440
+ edited by agents. But these are limited to simple checklists, not forms with other
441
+ fields.
232
442
 
233
- - `simple/simple.form.md` - Basic form demonstrating all field types
443
+ - Numerous tools like Typeform, Google Forms, PDF forms, and Docusign offer
444
+ human-friendly UI. But these do not have a human-friendly text format for use by
445
+ agents as well as humans.
234
446
 
235
- - `political-research/political-research.form.md` - Biographical research form
447
+ | Approach | Human-readable | Agent-editable | Custom validations |
448
+ | --- | :---: | :---: | :---: |
449
+ | Plain Markdown | ✅ | ⚠️ fragile | ❌ |
450
+ | JSON Schema | ❌ | ✅ | ✅ |
451
+ | PDF Forms, SaaS tools | ⚠️ | ❌ | ⚠️ |
452
+ | **Markform** | ✅ | ✅ | ✅ |
236
453
 
237
- - `earnings-analysis/earnings-analysis.form.md` - Financial analysis form
454
+ ### What are example use cases?
238
455
 
239
- View them with `markform examples --list` or try them interactively with `markform
240
- examples`.
456
+ - Deep research tools where agents need to follow codified processes to assemble
457
+ information
241
458
 
242
- ## Contributing
459
+ - Practical task execution plans with checklists and assembled answers and notes
243
460
 
244
- For development and contributing, see the
245
- [GitHub repository](https://github.com/jlevy/markform).
461
+ - Analysis processes, like assembling insights from unstructured sources in structured
462
+ form
463
+
464
+ - Multi-agent and agent-human workflows, where humans and/or agents fill in different
465
+ parts of a form, or where humans or agents review each other’s work in structured ways
466
+
467
+ - A clean and readable text format for web UIs that involve filling in forms, supporting
468
+ strings, lists, numbers, checkboxes, URLs, and other fields
469
+
470
+ ### Why use Markdoc as a base format?
471
+
472
+ Markdoc extends Markdown with structured tags, allowing AST parsing and programmatic
473
+ manipulation while preserving human and LLM readability.
474
+ See Stripe’s [Markdoc overview][markdoc-overview] and [blog post][stripe-markdoc] for
475
+ more on the philosophy behind “docs-as-data” that Markform extends to “forms-as-data.”
476
+ We could use XML tags, but Markdoc has some niceties like tagging Markdown AST nodes
477
+ (`{% #some-id %}`) so I decided to go with this.
478
+
479
+ ### Is there a VSCode plugin for Markform or Markdoc?
480
+
481
+ For quick syntax highlighting of `{% tag %}` syntax, install
482
+ [Better Jinja](https://marketplace.visualstudio.com/items?itemName=samuelcolvin.jinjahtml)
483
+ and associate `.form.md` files with the `jinja-md` language mode in your VS Code
484
+ settings:
485
+
486
+ ```json
487
+ "files.associations": {
488
+ "*.form.md": "jinja-md"
489
+ }
490
+ ```
491
+
492
+ Or see [markdoc/language-server](https://github.com/markdoc/language-server).
493
+
494
+ ## Documentation
495
+
496
+ - **[Quick
497
+ Reference](https://github.com/jlevy/markform/blob/main/packages/markform/DOCS.md)**
498
+ (or run `markform docs`) - Concise syntax reference (agent-friendly)
499
+
500
+ - **[Markform Spec](https://github.com/jlevy/markform/blob/main/SPEC.md)** (or run
501
+ `markform spec`) - Complete syntax and semantics
502
+
503
+ - **[Design
504
+ Doc](https://github.com/jlevy/markform/blob/main/docs/project/architecture/current/arch-markform-design.md)**
505
+ \- Technical design and roadmap
506
+
507
+ - **[Development](https://github.com/jlevy/markform/blob/main/docs/development.md)** -
508
+ Build, test, and contribute
246
509
 
247
510
  ## License
248
511
 
249
- AGPL-3.0-or-later
512
+ AGPL-3.0-or-later. [Contact me](https://github.com/jlevy) for additional licensing
513
+ options.
514
+
515
+ [markdoc-overview]: https://markdoc.dev/docs/overview
516
+ [stripe-markdoc]: https://stripe.com/blog/markdoc