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.
Files changed (37) hide show
  1. package/DOCS.md +546 -0
  2. package/README.md +484 -45
  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-C0vjijlP.mjs → apply-BfAGTHMh.mjs} +1044 -593
  7. package/dist/bin.mjs +6 -3
  8. package/dist/cli-B3NVm6zL.mjs +3904 -0
  9. package/dist/cli.mjs +6 -3
  10. package/dist/{coreTypes-T7dAuewt.d.mts → coreTypes-BXhhz9Iq.d.mts} +2795 -685
  11. package/dist/coreTypes-Dful87E0.mjs +537 -0
  12. package/dist/index.d.mts +196 -18
  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 +52 -12
  26. package/examples/simple/simple-skipped-filled.form.md +170 -0
  27. package/examples/simple/simple-with-skips.session.yaml +189 -0
  28. package/examples/simple/simple.form.md +34 -12
  29. package/examples/simple/simple.session.yaml +80 -37
  30. package/examples/startup-deep-research/startup-deep-research.form.md +456 -0
  31. package/examples/startup-research/startup-research-mock-filled.form.md +307 -0
  32. package/examples/startup-research/startup-research.form.md +211 -0
  33. package/package.json +11 -5
  34. package/dist/cli-9fvFySww.mjs +0 -2564
  35. package/dist/src-DBD3Dt4f.mjs +0 -1785
  36. package/examples/political-research/political-research.form.md +0 -233
  37. 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
- Agent-friendly, human-readable, editable 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 forms using structured patches, while keeping the
6
- form source in human-readable Markdown.
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
- ## Documentation
9
-
10
- - [Development Guide](docs/development.md) - Getting started, workflows, and AI SDK
11
- integration
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
- - [Publishing](docs/publishing.md) - Release workflow and npm publishing
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
- - [Architecture Design](docs/project/architecture/current/arch-markform-initial-design.md)
16
- \- Technical specification
22
+ ## Installation
17
23
 
18
- ## Project Structure
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
- packages/markform/ # Main package
22
- src/engine/ # Core: parsing, validation, serialization
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
- # Install dependencies
33
- pnpm install
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
- # Build
36
- pnpm build
83
+ {% string-field id="full_title" label="Full Title" role="agent" required=true %}{% /string-field %}
37
84
 
38
- # Run tests
39
- pnpm test
85
+ {% number-field id="year" label="Release Year" role="agent" min=1888 max=2030 %}{% /number-field %}
40
86
 
41
- # CLI usage (use pnpm markform in development)
42
- pnpm markform inspect packages/markform/examples/simple/simple.form.md
43
- pnpm markform export packages/markform/examples/simple/simple.form.md --format=json
44
- pnpm markform serve packages/markform/examples/simple/simple.form.md
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
- # Fill a form with live agent (requires API key for chosen provider)
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
- # Fill a form with mock agent (for testing)
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
- # See available providers and models
56
- pnpm markform fill --help
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.2, gpt-5-mini, gpt-5.2-pro |
64
- | google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.0-flash |
65
- | anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-5, claude-haiku-4-5 |
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
- ## Example Form
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
- See
72
- [`packages/markform/examples/simple/simple.form.md`](packages/markform/examples/simple/simple.form.md)
73
- for a working example.
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