markform 0.1.0 → 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.
- package/DOCS.md +546 -0
- package/README.md +484 -45
- package/SPEC.md +2779 -0
- package/dist/ai-sdk.d.mts +2 -2
- package/dist/ai-sdk.mjs +5 -3
- package/dist/{apply-C0vjijlP.mjs → apply-BfAGTHMh.mjs} +1044 -593
- package/dist/bin.mjs +6 -3
- package/dist/cli-B3NVm6zL.mjs +3904 -0
- package/dist/cli.mjs +6 -3
- package/dist/{coreTypes-T7dAuewt.d.mts → coreTypes-BXhhz9Iq.d.mts} +2795 -685
- package/dist/coreTypes-Dful87E0.mjs +537 -0
- package/dist/index.d.mts +196 -18
- package/dist/index.mjs +5 -3
- package/dist/session-Bqnwi9wp.mjs +110 -0
- package/dist/session-DdAtY2Ni.mjs +4 -0
- package/dist/shared-D7gf27Tr.mjs +3 -0
- package/dist/shared-N_s1M-_K.mjs +176 -0
- package/dist/src-BXRkGFpG.mjs +7587 -0
- package/examples/celebrity-deep-research/celebrity-deep-research.form.md +912 -0
- package/examples/earnings-analysis/earnings-analysis.form.md +6 -1
- package/examples/earnings-analysis/earnings-analysis.valid.ts +119 -59
- package/examples/movie-research/movie-research-basic.form.md +164 -0
- package/examples/movie-research/movie-research-deep.form.md +486 -0
- package/examples/movie-research/movie-research-minimal.form.md +73 -0
- package/examples/simple/simple-mock-filled.form.md +52 -12
- package/examples/simple/simple-skipped-filled.form.md +170 -0
- package/examples/simple/simple-with-skips.session.yaml +189 -0
- package/examples/simple/simple.form.md +34 -12
- package/examples/simple/simple.session.yaml +80 -37
- package/examples/startup-deep-research/startup-deep-research.form.md +456 -0
- package/examples/startup-research/startup-research-mock-filled.form.md +307 -0
- package/examples/startup-research/startup-research.form.md +211 -0
- package/package.json +11 -5
- package/dist/cli-9fvFySww.mjs +0 -2564
- package/dist/src-DBD3Dt4f.mjs +0 -1785
- package/examples/political-research/political-research.form.md +0 -233
- package/examples/political-research/political-research.mock.lincoln.form.md +0 -355
package/README.md
CHANGED
|
@@ -1,77 +1,516 @@
|
|
|
1
1
|
# Markform
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
***Structured Markdown documents for humans, agents, and APIs***
|
|
4
4
|
|
|
5
|
-
Markform
|
|
6
|
-
|
|
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.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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.
|
|
12
13
|
|
|
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.
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
\- Technical specification
|
|
22
|
+
## Installation
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
```bash
|
|
25
|
+
# As a global CLI
|
|
26
|
+
npm install -g markform
|
|
19
27
|
|
|
28
|
+
# Or as a project dependency
|
|
29
|
+
npm install markform
|
|
20
30
|
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
src/cli/ # CLI commands (inspect, export, serve, fill)
|
|
24
|
-
src/harness/ # Execution harness for agents
|
|
25
|
-
src/integrations/ # AI SDK tools
|
|
26
|
-
examples/ # Example forms
|
|
27
|
-
```
|
|
31
|
+
|
|
32
|
+
Requires Node.js 20+ (v24 recommended).
|
|
28
33
|
|
|
29
34
|
## Quick Start
|
|
30
35
|
|
|
31
36
|
```bash
|
|
32
|
-
#
|
|
33
|
-
|
|
37
|
+
# Try it without installing
|
|
38
|
+
npx markform examples
|
|
39
|
+
```
|
|
40
|
+
|
|
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 -->
|
|
34
82
|
|
|
35
|
-
|
|
36
|
-
pnpm build
|
|
83
|
+
{% string-field id="full_title" label="Full Title" role="agent" required=true %}{% /string-field %}
|
|
37
84
|
|
|
38
|
-
|
|
39
|
-
pnpm test
|
|
85
|
+
{% number-field id="year" label="Release Year" role="agent" min=1888 max=2030 %}{% /number-field %}
|
|
40
86
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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 %}
|
|
45
95
|
|
|
46
|
-
|
|
47
|
-
pnpm markform fill packages/markform/examples/simple/simple.form.md \
|
|
48
|
-
--agent=live --model=openai/gpt-5.2
|
|
96
|
+
{% url-field id="imdb_url" label="IMDB URL" role="agent" %}{% /url-field %}
|
|
49
97
|
|
|
50
|
-
|
|
51
|
-
pnpm markform fill packages/markform/examples/simple/simple.form.md \
|
|
52
|
-
--agent=mock \
|
|
53
|
-
--mock-source packages/markform/examples/simple/simple-mock-filled.form.md
|
|
98
|
+
{% number-field id="imdb_rating" label="IMDB Rating" role="agent" min=1.0 max=10.0 %}{% /number-field %}
|
|
54
99
|
|
|
55
|
-
|
|
56
|
-
|
|
100
|
+
{% string-field id="logline" label="Summary" role="agent" maxLength=200 %}{% /string-field %}
|
|
101
|
+
|
|
102
|
+
{% /field-group %}
|
|
103
|
+
|
|
104
|
+
{% /form %}
|
|
57
105
|
```
|
|
58
106
|
|
|
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
|
+
|
|
59
147
|
## Supported Providers
|
|
60
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
|
+
|
|
61
153
|
| Provider | Env Variable | Example Models |
|
|
62
154
|
| --- | --- | --- |
|
|
63
|
-
| openai | `OPENAI_API_KEY` | gpt-5
|
|
64
|
-
|
|
|
65
|
-
|
|
|
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 |
|
|
66
158
|
| xai | `XAI_API_KEY` | grok-4, grok-4-fast |
|
|
67
159
|
| deepseek | `DEEPSEEK_API_KEY` | deepseek-chat, deepseek-reasoner |
|
|
68
160
|
|
|
69
|
-
|
|
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?
|
|
167
|
+
|
|
168
|
+
Many agent workflow frameworks emphasize the *flow* of information (the *how*) over its
|
|
169
|
+
*structure* (the *what*). But the *how* is constantly changing.
|
|
170
|
+
|
|
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.
|
|
173
|
+
|
|
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.
|
|
178
|
+
|
|
179
|
+
## CLI Commands
|
|
180
|
+
|
|
181
|
+
### Explore Examples
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Interactive: select an example, fill it, optionally run agent
|
|
185
|
+
markform examples
|
|
186
|
+
|
|
187
|
+
# List available examples
|
|
188
|
+
markform examples --list
|
|
189
|
+
|
|
190
|
+
# Start with a specific example
|
|
191
|
+
markform examples --name political-research
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Inspect Forms
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# View form structure, progress, and validation issues
|
|
198
|
+
markform inspect my-form.form.md
|
|
199
|
+
|
|
200
|
+
# Output as JSON
|
|
201
|
+
markform inspect my-form.form.md --format=json
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Fill Forms
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Interactive mode: fill user-role fields via prompts
|
|
208
|
+
markform fill my-form.form.md --interactive
|
|
209
|
+
|
|
210
|
+
# Agent mode: use an LLM to fill agent-role fields
|
|
211
|
+
markform fill my-form.form.md --model=anthropic/claude-sonnet-4-5
|
|
212
|
+
|
|
213
|
+
# Mock agent for testing (uses pre-filled form as source)
|
|
214
|
+
markform fill my-form.form.md --mock --mock-source filled.form.md
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Export and Transform
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Export as readable markdown (strips Markdoc tags)
|
|
221
|
+
markform export my-form.form.md --format=markdown
|
|
222
|
+
|
|
223
|
+
# Export values as JSON
|
|
224
|
+
markform export my-form.form.md --format=json
|
|
225
|
+
|
|
226
|
+
# Export values as YAML
|
|
227
|
+
markform export my-form.form.md --format=yaml
|
|
228
|
+
|
|
229
|
+
# Dump just the current values
|
|
230
|
+
markform dump my-form.form.md
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Apply Patches
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Apply a JSON patch to update field values
|
|
237
|
+
markform apply my-form.form.md --patch '[{"op":"set","fieldId":"name","value":"Alice"}]'
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Web Interface
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Serve a form as a web page for browsing
|
|
244
|
+
markform serve my-form.form.md
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Documentation Commands
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Quick reference for writing forms (agent-friendly)
|
|
251
|
+
markform docs
|
|
252
|
+
|
|
253
|
+
# Full specification (SPEC.md)
|
|
254
|
+
markform spec
|
|
70
255
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
256
|
+
# This README
|
|
257
|
+
markform readme
|
|
258
|
+
|
|
259
|
+
# See supported AI providers and example models
|
|
260
|
+
markform models
|
|
261
|
+
|
|
262
|
+
# See all commands
|
|
263
|
+
markform --help
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Architecture
|
|
267
|
+
|
|
268
|
+
```mermaid
|
|
269
|
+
flowchart LR
|
|
270
|
+
subgraph SPEC["<b>MARKFORM SPEC</b>"]
|
|
271
|
+
direction TB
|
|
272
|
+
|
|
273
|
+
subgraph L1["<b>LAYER 1: SYNTAX</b><br/>Markdoc tag syntax and frontmatter (form, field-group, string-field, checkboxes, etc.)"]
|
|
274
|
+
end
|
|
275
|
+
|
|
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
|
|
278
|
+
|
|
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
|
|
296
|
+
|
|
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
|
+
```
|
|
327
|
+
|
|
328
|
+
## Programmatic Usage
|
|
329
|
+
|
|
330
|
+
Markform exports a parsing engine and AI SDK integration for use in your own
|
|
331
|
+
applications.
|
|
332
|
+
|
|
333
|
+
### Basic Parsing
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
import { parseForm, serializeForm } from "markform";
|
|
337
|
+
|
|
338
|
+
// Parse a .form.md file
|
|
339
|
+
const form = parseForm(markdownContent);
|
|
340
|
+
|
|
341
|
+
// Access schema and values
|
|
342
|
+
console.log(form.schema.title);
|
|
343
|
+
console.log(form.values);
|
|
344
|
+
|
|
345
|
+
// Serialize back to markdown
|
|
346
|
+
const output = serializeForm(form);
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### AI SDK Integration
|
|
350
|
+
|
|
351
|
+
Markform provides tools compatible with the [Vercel AI SDK](https://sdk.vercel.ai/):
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { parseForm } from "markform";
|
|
355
|
+
import { createMarkformTools, MarkformSessionStore } from "markform/ai-sdk";
|
|
356
|
+
import { generateText } from "ai";
|
|
357
|
+
import { anthropic } from "@ai-sdk/anthropic";
|
|
358
|
+
|
|
359
|
+
const form = parseForm(markdownContent);
|
|
360
|
+
const store = new MarkformSessionStore(form);
|
|
361
|
+
const tools = createMarkformTools({ sessionStore: store });
|
|
362
|
+
|
|
363
|
+
const result = await generateText({
|
|
364
|
+
model: anthropic("claude-sonnet-4-5-20250929"),
|
|
365
|
+
prompt: "Fill out this form with appropriate values...",
|
|
366
|
+
tools,
|
|
367
|
+
maxSteps: 10,
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Available tools:**
|
|
372
|
+
|
|
373
|
+
| Tool | Description |
|
|
374
|
+
| --- | --- |
|
|
375
|
+
| `markform_inspect` | Get current form state, issues, progress |
|
|
376
|
+
| `markform_apply` | Apply patches to update field values |
|
|
377
|
+
| `markform_export` | Export schema and values as JSON |
|
|
378
|
+
| `markform_get_markdown` | Get canonical Markdown representation |
|
|
379
|
+
|
|
380
|
+
## FAQ
|
|
381
|
+
|
|
382
|
+
### Is this mature?
|
|
383
|
+
|
|
384
|
+
No! I just wrote it.
|
|
385
|
+
The spec is a draft.
|
|
386
|
+
But it’s been useful for me already.
|
|
387
|
+
|
|
388
|
+
### Was it Vibe Coded?
|
|
389
|
+
|
|
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/).
|
|
393
|
+
|
|
394
|
+
### What are the goals of Markform?
|
|
395
|
+
|
|
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.
|
|
400
|
+
|
|
401
|
+
- **Markform is programmatically editable:** Field state should be updated via APIs, by
|
|
402
|
+
apps, or by agent tools.
|
|
403
|
+
|
|
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).
|
|
407
|
+
|
|
408
|
+
### How do agents fill in forms?
|
|
409
|
+
|
|
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:
|
|
412
|
+
|
|
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.
|
|
416
|
+
|
|
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.
|
|
419
|
+
|
|
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:
|
|
434
|
+
|
|
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.
|
|
438
|
+
|
|
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.
|
|
442
|
+
|
|
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.
|
|
446
|
+
|
|
447
|
+
| Approach | Human-readable | Agent-editable | Custom validations |
|
|
448
|
+
| --- | :---: | :---: | :---: |
|
|
449
|
+
| Plain Markdown | ✅ | ⚠️ fragile | ❌ |
|
|
450
|
+
| JSON Schema | ❌ | ✅ | ✅ |
|
|
451
|
+
| PDF Forms, SaaS tools | ⚠️ | ❌ | ⚠️ |
|
|
452
|
+
| **Markform** | ✅ | ✅ | ✅ |
|
|
453
|
+
|
|
454
|
+
### What are example use cases?
|
|
455
|
+
|
|
456
|
+
- Deep research tools where agents need to follow codified processes to assemble
|
|
457
|
+
information
|
|
458
|
+
|
|
459
|
+
- Practical task execution plans with checklists and assembled answers and notes
|
|
460
|
+
|
|
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
|
|
74
509
|
|
|
75
510
|
## License
|
|
76
511
|
|
|
77
|
-
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
|