markform 0.1.24 → 0.1.26
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/README.md +55 -31
- package/dist/ai-sdk.d.mts +1 -1
- package/dist/ai-sdk.mjs +2 -2
- package/dist/bin.mjs +1 -1
- package/dist/{cli-B1DhFYBS.mjs → cli-BMQ9k9z7.mjs} +85 -40
- package/dist/cli-BMQ9k9z7.mjs.map +1 -0
- package/dist/cli.mjs +1 -1
- package/dist/{coreTypes-GxzWNXap.d.mts → coreTypes-CxpqKpBA.d.mts} +45 -2
- package/dist/{coreTypes-CctFK6uE.mjs → coreTypes-DIv9Aabl.mjs} +19 -5
- package/dist/coreTypes-DIv9Aabl.mjs.map +1 -0
- package/dist/{fillRecord-DeqI2pQ5.d.mts → fillRecord-V3vlyobd.d.mts} +5 -1
- package/dist/{fillRecordRenderer-VBQ2vwPV.mjs → fillRecordRenderer-BqRPHPmE.mjs} +47 -15
- package/dist/fillRecordRenderer-BqRPHPmE.mjs.map +1 -0
- package/dist/index.d.mts +32 -4
- package/dist/index.mjs +4 -4
- package/dist/{prompts-BCnYaH4_.mjs → prompts-4jZmkGKW.mjs} +114 -11
- package/dist/prompts-4jZmkGKW.mjs.map +1 -0
- package/dist/render.d.mts +2 -2
- package/dist/render.mjs +1 -1
- package/dist/{session-BLjN3BkJ.mjs → session-BW9jtYNV.mjs} +2 -2
- package/dist/{session-BLjN3BkJ.mjs.map → session-BW9jtYNV.mjs.map} +1 -1
- package/dist/{session-D7C7IlEv.mjs → session-DHyTMP67.mjs} +1 -1
- package/dist/{shared-DtorFV21.mjs → shared-BLh342F5.mjs} +1 -1
- package/dist/{shared-CuSRYcIB.mjs → shared-BszoSkAO.mjs} +8 -8
- package/dist/{shared-CuSRYcIB.mjs.map → shared-BszoSkAO.mjs.map} +1 -1
- package/dist/{src-C5OWf1dL.mjs → src-Dy3cDjDS.mjs} +165 -35
- package/dist/src-Dy3cDjDS.mjs.map +1 -0
- package/docs/markform-apis.md +19 -7
- package/docs/markform-reference.md +247 -178
- package/docs/markform-spec.md +81 -33
- package/docs/skill/SKILL.md +62 -20
- package/examples/markform-demo-playbook.md +342 -0
- package/examples/parallel/parallel-research.form.md +2 -6
- package/examples/simple/simple-mock-filled.report.md +2 -2
- package/examples/simple/simple-skipped-filled.report.md +2 -2
- package/examples/twitter-thread/twitter-thread.form.md +5 -5
- package/package.json +1 -1
- package/dist/cli-B1DhFYBS.mjs.map +0 -1
- package/dist/coreTypes-CctFK6uE.mjs.map +0 -1
- package/dist/fillRecordRenderer-VBQ2vwPV.mjs.map +0 -1
- package/dist/prompts-BCnYaH4_.mjs.map +0 -1
- package/dist/src-C5OWf1dL.mjs.map +0 -1
- package/examples/startup-research/startup-research-mock-filled.form.md +0 -297
- package/examples/startup-research/startup-research.form.md +0 -181
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
SPDX-License-Identifier: CC-BY-4.0
|
|
1
|
+
<!-- SPDX-License-Identifier: CC-BY-4.0
|
|
3
2
|
|
|
4
3
|
Markform Quick Reference - Licensed under Creative Commons Attribution 4.0 International
|
|
5
4
|
https://creativecommons.org/licenses/by/4.0/
|
|
6
5
|
|
|
7
6
|
You may freely implement this specification in your own software under any license.
|
|
8
|
-
The reference implementation at https://github.com/jlevy/markform is separately
|
|
9
|
-
|
|
7
|
+
The reference implementation at https://github.com/jlevy/markform is separately licensed
|
|
8
|
+
under AGPL-3.0-or-later.
|
|
9
|
+
Contact the author with licensing questions or for other licensing options.
|
|
10
10
|
-->
|
|
11
11
|
|
|
12
12
|
# Markform Quick Reference
|
|
@@ -64,14 +64,15 @@ markform:
|
|
|
64
64
|
### File Extensions
|
|
65
65
|
|
|
66
66
|
| File Type | Extension | Description |
|
|
67
|
-
|
|
67
|
+
| --- | --- | --- |
|
|
68
68
|
| Form | `.form.md` | Markform source and filled forms |
|
|
69
69
|
| Fill Record | `.fill.json` | Execution metadata (sidecar file) |
|
|
70
70
|
| Report | `.report.md` | Filtered human-readable output |
|
|
71
71
|
| Schema | `.schema.json` | JSON Schema for form structure |
|
|
72
72
|
| Values | `.yml` or `.json` | Exported field values |
|
|
73
73
|
|
|
74
|
-
**Recommended:** Use `.form.md` for all Markform files.
|
|
74
|
+
**Recommended:** Use `.form.md` for all Markform files.
|
|
75
|
+
This enables:
|
|
75
76
|
- Auto-discovery of fill records by `markform serve`
|
|
76
77
|
- Consistent tooling behavior across CLI commands
|
|
77
78
|
- Clear distinction from regular markdown files
|
|
@@ -80,10 +81,12 @@ Markform uses HTML comment syntax for structure tags, which render invisibly on
|
|
|
80
81
|
|
|
81
82
|
### Syntax
|
|
82
83
|
|
|
83
|
-
**
|
|
84
|
+
**Default:** Always use HTML comment syntax for new forms.
|
|
85
|
+
This renders invisibly in Markdown renderers (including GitHub) and is the recommended
|
|
86
|
+
style for all Markform files.
|
|
84
87
|
|
|
85
88
|
| Element | Syntax | Notes |
|
|
86
|
-
|
|
89
|
+
| --- | --- | --- |
|
|
87
90
|
| Opening tag | `<!-- form id="x" -->` | Tag name directly after `<!--` |
|
|
88
91
|
| Closing tag | `<!-- /form -->` | Closing tags |
|
|
89
92
|
| Self-closing | `<!-- field ... /-->` | Self-closing tags |
|
|
@@ -97,8 +100,10 @@ Markform uses HTML comment syntax for structure tags, which render invisibly on
|
|
|
97
100
|
<!-- group id="basics" -->
|
|
98
101
|
<!-- field kind="string" id="name" label="Name" --><!-- /field -->
|
|
99
102
|
<!-- field kind="single_select" id="rating" label="Rating" -->
|
|
103
|
+
|
|
100
104
|
- [ ] Good <!-- #good -->
|
|
101
105
|
- [ ] Bad <!-- #bad -->
|
|
106
|
+
|
|
102
107
|
<!-- /field -->
|
|
103
108
|
<!-- /group -->
|
|
104
109
|
<!-- /form -->
|
|
@@ -107,16 +112,18 @@ Markform uses HTML comment syntax for structure tags, which render invisibly on
|
|
|
107
112
|
### Alternative Syntax (Markdoc Tags)
|
|
108
113
|
|
|
109
114
|
Markform also supports **Markdoc tag syntax** (`{% tag %}`), which is the underlying
|
|
110
|
-
format used internally
|
|
115
|
+
format used internally.
|
|
116
|
+
Use HTML comments unless you have a specific reason to prefer Markdoc tags.
|
|
111
117
|
|
|
112
118
|
| HTML Comment | Markdoc Tag |
|
|
113
|
-
|
|
119
|
+
| --- | --- |
|
|
114
120
|
| `<!-- form id="x" -->` | `{% form id="x" %}` |
|
|
115
121
|
| `<!-- /form -->` | `{% /form %}` |
|
|
116
122
|
| `<!-- #id -->` | `{% #id %}` |
|
|
117
123
|
| `<!-- .class -->` | `{% .class %}` |
|
|
118
124
|
|
|
119
|
-
Both syntaxes are always supported.
|
|
125
|
+
Both syntaxes are always supported.
|
|
126
|
+
Files preserve their original syntax on round-trip.
|
|
120
127
|
|
|
121
128
|
## Field Kinds
|
|
122
129
|
|
|
@@ -129,14 +136,14 @@ representation. See the Type System section in SPEC.md for full details.
|
|
|
129
136
|
Single-line or multi-line text.
|
|
130
137
|
|
|
131
138
|
````markdown
|
|
132
|
-
|
|
139
|
+
<!-- field kind="string" id="name" label="Name" required=true minLength=2 maxLength=100 --><!-- /field -->
|
|
133
140
|
|
|
134
|
-
|
|
141
|
+
<!-- field kind="string" id="bio" label="Biography" pattern="^[A-Z].*" -->
|
|
135
142
|
```value
|
|
136
143
|
Existing value here
|
|
137
144
|
````
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
<!-- /field -->
|
|
146
|
+
`````
|
|
140
147
|
|
|
141
148
|
| Attribute | Type | Description |
|
|
142
149
|
|-----------|------|-------------|
|
|
@@ -148,15 +155,15 @@ Existing value here
|
|
|
148
155
|
|
|
149
156
|
Numeric values with optional constraints.
|
|
150
157
|
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
````markdown
|
|
159
|
+
<!-- field kind="number" id="age" label="Age" required=true min=0 max=150 integer=true --><!-- /field -->
|
|
153
160
|
|
|
154
|
-
|
|
161
|
+
<!-- field kind="number" id="price" label="Price" min=0.01 max=999999.99 -->
|
|
155
162
|
```value
|
|
156
163
|
49.99
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
164
|
+
`````
|
|
165
|
+
<!-- /field -->
|
|
166
|
+
`````
|
|
160
167
|
|
|
161
168
|
| Attribute | Type | Description |
|
|
162
169
|
|-----------|------|-------------|
|
|
@@ -168,16 +175,16 @@ Numeric values with optional constraints.
|
|
|
168
175
|
|
|
169
176
|
Array of strings, one per line.
|
|
170
177
|
|
|
171
|
-
|
|
172
|
-
|
|
178
|
+
````markdown
|
|
179
|
+
<!-- field kind="string_list" id="tags" label="Tags" required=true minItems=1 maxItems=10 uniqueItems=true --><!-- /field -->
|
|
173
180
|
|
|
174
|
-
|
|
181
|
+
<!-- field kind="string_list" id="features" label="Key Features" minItems=3 itemMinLength=10 -->
|
|
175
182
|
```value
|
|
176
183
|
Feature one description
|
|
177
184
|
Feature two description
|
|
178
185
|
Feature three description
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
`````
|
|
187
|
+
<!-- /field -->
|
|
181
188
|
````
|
|
182
189
|
|
|
183
190
|
| Attribute | Type | Description |
|
|
@@ -193,27 +200,31 @@ Feature three description
|
|
|
193
200
|
Choose exactly one option.
|
|
194
201
|
|
|
195
202
|
```markdown
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
- [ ]
|
|
199
|
-
- [
|
|
200
|
-
|
|
203
|
+
<!-- field kind="single_select" id="rating" label="Rating" required=true -->
|
|
204
|
+
|
|
205
|
+
- [ ] Low <!-- #low -->
|
|
206
|
+
- [ ] Medium <!-- #medium -->
|
|
207
|
+
- [x] High <!-- #high -->
|
|
208
|
+
|
|
209
|
+
<!-- /field -->
|
|
201
210
|
````
|
|
202
211
|
|
|
203
212
|
Options use `[ ]` (unselected) or `[x]` (selected).
|
|
204
|
-
Each option needs
|
|
213
|
+
Each option needs `<!-- #id -->`.
|
|
205
214
|
|
|
206
215
|
### Multi Select
|
|
207
216
|
|
|
208
217
|
Choose multiple options.
|
|
209
218
|
|
|
210
219
|
```markdown
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
- [x]
|
|
214
|
-
- [
|
|
215
|
-
- [ ]
|
|
216
|
-
|
|
220
|
+
<!-- field kind="multi_select" id="categories" label="Categories" required=true minSelections=1 maxSelections=3 -->
|
|
221
|
+
|
|
222
|
+
- [x] Frontend <!-- #frontend -->
|
|
223
|
+
- [x] Backend <!-- #backend -->
|
|
224
|
+
- [ ] Database <!-- #database -->
|
|
225
|
+
- [ ] DevOps <!-- #devops -->
|
|
226
|
+
|
|
227
|
+
<!-- /field -->
|
|
217
228
|
```
|
|
218
229
|
|
|
219
230
|
| Attribute | Type | Description |
|
|
@@ -228,13 +239,15 @@ Stateful checklists with three modes.
|
|
|
228
239
|
**Multi Mode** (default) - 5 states for workflow tracking:
|
|
229
240
|
|
|
230
241
|
```markdown
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
- [
|
|
234
|
-
- [
|
|
235
|
-
- [
|
|
236
|
-
- [
|
|
237
|
-
|
|
242
|
+
<!-- field kind="checkboxes" id="tasks" label="Tasks" required=true checkboxMode="multi" -->
|
|
243
|
+
|
|
244
|
+
- [ ] Research <!-- #research -->
|
|
245
|
+
- [x] Design <!-- #design -->
|
|
246
|
+
- [/] Implementation <!-- #impl -->
|
|
247
|
+
- [*] Testing <!-- #test -->
|
|
248
|
+
- [-] N/A item <!-- #na -->
|
|
249
|
+
|
|
250
|
+
<!-- /field -->
|
|
238
251
|
```
|
|
239
252
|
|
|
240
253
|
| Token | State | Meaning |
|
|
@@ -248,20 +261,24 @@ Stateful checklists with three modes.
|
|
|
248
261
|
**Simple Mode** - 2 states (GFM compatible):
|
|
249
262
|
|
|
250
263
|
```markdown
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
- [
|
|
254
|
-
|
|
264
|
+
<!-- field kind="checkboxes" id="agreements" label="Agreements" checkboxMode="simple" required=true -->
|
|
265
|
+
|
|
266
|
+
- [x] I agree to terms <!-- #terms -->
|
|
267
|
+
- [ ] Subscribe to newsletter <!-- #news -->
|
|
268
|
+
|
|
269
|
+
<!-- /field -->
|
|
255
270
|
```
|
|
256
271
|
|
|
257
272
|
**Explicit Mode** - Requires yes/no for each:
|
|
258
273
|
|
|
259
274
|
```markdown
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
- [
|
|
263
|
-
- [
|
|
264
|
-
|
|
275
|
+
<!-- field kind="checkboxes" id="confirmations" label="Confirmations" checkboxMode="explicit" required=true -->
|
|
276
|
+
|
|
277
|
+
- [y] Backup completed <!-- #backup -->
|
|
278
|
+
- [n] Stakeholders notified <!-- #notify -->
|
|
279
|
+
- [ ] Deployment ready <!-- #deploy -->
|
|
280
|
+
|
|
281
|
+
<!-- /field -->
|
|
265
282
|
```
|
|
266
283
|
|
|
267
284
|
| Token | Value | Meaning |
|
|
@@ -272,30 +289,30 @@ Stateful checklists with three modes.
|
|
|
272
289
|
|
|
273
290
|
### Implicit Checkboxes (Plan Documents)
|
|
274
291
|
|
|
275
|
-
Forms designed as task lists can omit explicit field wrappers.
|
|
276
|
-
|
|
277
|
-
an implicit checkboxes field.
|
|
292
|
+
Forms designed as task lists can omit explicit field wrappers.
|
|
293
|
+
When a form has a `<!-- form -->` tag but no `<!-- field -->` tags, checkboxes are
|
|
294
|
+
automatically wrapped in an implicit checkboxes field.
|
|
278
295
|
|
|
279
296
|
```markdown
|
|
280
297
|
---
|
|
281
298
|
markform:
|
|
282
299
|
spec: MF/0.1
|
|
283
300
|
---
|
|
284
|
-
|
|
301
|
+
<!-- form id="plan" title="Project Plan" -->
|
|
285
302
|
|
|
286
303
|
## Phase 1: Research
|
|
287
|
-
- [ ] Literature review
|
|
288
|
-
- [ ] Competitive analysis
|
|
304
|
+
- [ ] Literature review <!-- #lit_review -->
|
|
305
|
+
- [ ] Competitive analysis <!-- #comp -->
|
|
289
306
|
|
|
290
307
|
## Phase 2: Design
|
|
291
|
-
- [x] Architecture doc
|
|
292
|
-
- [/] API design
|
|
308
|
+
- [x] Architecture doc <!-- #arch -->
|
|
309
|
+
- [/] API design <!-- #api -->
|
|
293
310
|
|
|
294
|
-
|
|
311
|
+
<!-- /form -->
|
|
295
312
|
```
|
|
296
313
|
|
|
297
314
|
**Requirements:**
|
|
298
|
-
- Each checkbox MUST have an ID annotation (
|
|
315
|
+
- Each checkbox MUST have an ID annotation (`<!-- #id -->`)
|
|
299
316
|
- IDs must be unique (same rules as explicit checkboxes fields)
|
|
300
317
|
- The implicit field uses ID `checkboxes` (reserved)
|
|
301
318
|
- Always uses `checkboxMode="multi"` (5-state)
|
|
@@ -306,26 +323,26 @@ markform:
|
|
|
306
323
|
Single URL with format validation.
|
|
307
324
|
|
|
308
325
|
````markdown
|
|
309
|
-
|
|
326
|
+
<!-- field kind="url" id="website" label="Website" required=true --><!-- /field -->
|
|
310
327
|
|
|
311
|
-
|
|
328
|
+
<!-- field kind="url" id="repo" label="Repository" -->
|
|
312
329
|
```value
|
|
313
330
|
https://github.com/example/repo
|
|
314
331
|
````
|
|
315
|
-
|
|
316
|
-
|
|
332
|
+
<!-- /field -->
|
|
333
|
+
`````
|
|
317
334
|
|
|
318
335
|
### URL List
|
|
319
336
|
|
|
320
337
|
Array of URLs.
|
|
321
338
|
|
|
322
|
-
|
|
323
|
-
|
|
339
|
+
````markdown
|
|
340
|
+
<!-- field kind="url_list" id="sources" label="Sources" required=true minItems=1 maxItems=10 uniqueItems=true -->
|
|
324
341
|
```value
|
|
325
342
|
https://example.com/source1
|
|
326
343
|
https://example.com/source2
|
|
327
|
-
|
|
328
|
-
|
|
344
|
+
`````
|
|
345
|
+
<!-- /field -->
|
|
329
346
|
`````
|
|
330
347
|
|
|
331
348
|
### Date Field
|
|
@@ -333,13 +350,13 @@ https://example.com/source2
|
|
|
333
350
|
Date value in ISO 8601 format (YYYY-MM-DD).
|
|
334
351
|
|
|
335
352
|
````markdown
|
|
336
|
-
|
|
353
|
+
<!-- field kind="date" id="deadline" label="Deadline" required=true --><!-- /field -->
|
|
337
354
|
|
|
338
|
-
|
|
355
|
+
<!-- field kind="date" id="start_date" label="Start Date" min="2020-01-01" max="2030-12-31" -->
|
|
339
356
|
```value
|
|
340
357
|
2024-06-15
|
|
341
358
|
`````
|
|
342
|
-
|
|
359
|
+
<!-- /field -->
|
|
343
360
|
`````
|
|
344
361
|
|
|
345
362
|
| Attribute | Type | Description |
|
|
@@ -352,13 +369,13 @@ Date value in ISO 8601 format (YYYY-MM-DD).
|
|
|
352
369
|
Integer year with optional constraints.
|
|
353
370
|
|
|
354
371
|
````markdown
|
|
355
|
-
|
|
372
|
+
<!-- field kind="year" id="release_year" label="Release Year" required=true min=1888 max=2030 --><!-- /field -->
|
|
356
373
|
|
|
357
|
-
|
|
374
|
+
<!-- field kind="year" id="founded" label="Year Founded" -->
|
|
358
375
|
```value
|
|
359
376
|
2015
|
|
360
377
|
`````
|
|
361
|
-
|
|
378
|
+
<!-- /field -->
|
|
362
379
|
`````
|
|
363
380
|
|
|
364
381
|
| Attribute | Type | Description |
|
|
@@ -371,33 +388,35 @@ Integer year with optional constraints.
|
|
|
371
388
|
Structured tabular data with typed columns. Uses standard markdown table syntax.
|
|
372
389
|
|
|
373
390
|
````markdown
|
|
374
|
-
|
|
391
|
+
<!-- field kind="table" id="team" label="Team Members" required=true
|
|
375
392
|
columnIds=["name", "title", "start_date"]
|
|
376
393
|
columnLabels=["Name", "Job Title", "Start Date"]
|
|
377
394
|
columnTypes=["string", "string", "date"]
|
|
378
|
-
minRows=1 maxRows=20
|
|
395
|
+
minRows=1 maxRows=20 -->
|
|
379
396
|
| Name | Job Title | Start Date |
|
|
380
397
|
|------|-----------|------------|
|
|
381
398
|
| Alice Smith | Engineer | 2023-01-15 |
|
|
382
399
|
| Bob Jones | Designer | 2022-06-01 |
|
|
383
|
-
|
|
400
|
+
|
|
401
|
+
<!-- /field -->
|
|
384
402
|
`````
|
|
385
403
|
|
|
386
404
|
**Basic table (columnLabels backfilled from header row):**
|
|
387
405
|
|
|
388
406
|
```markdown
|
|
389
|
-
|
|
390
|
-
columnIds=["name", "quantity", "price"]
|
|
407
|
+
<!-- field kind="table" id="items" label="Items"
|
|
408
|
+
columnIds=["name", "quantity", "price"] -->
|
|
391
409
|
| Name | Quantity | Price |
|
|
392
410
|
|------|----------|-------|
|
|
393
|
-
|
|
411
|
+
|
|
412
|
+
<!-- /field -->
|
|
394
413
|
```
|
|
395
414
|
|
|
396
415
|
| Attribute | Type | Required | Description |
|
|
397
416
|
| --- | --- | --- | --- |
|
|
398
417
|
| `columnIds` | string[] | Yes | Array of snake_case column identifiers |
|
|
399
418
|
| `columnLabels` | string[] | No | Display labels (defaults to header row) |
|
|
400
|
-
| `columnTypes` | string[] | No | Column types (defaults to all `string`) |
|
|
419
|
+
| `columnTypes` | (string \| object)[] | No | Column types with optional constraints (defaults to all `string`) |
|
|
401
420
|
| `minRows` | number | No | Minimum row count (default: 0) |
|
|
402
421
|
| `maxRows` | number | No | Maximum row count (default: unlimited) |
|
|
403
422
|
|
|
@@ -405,12 +424,29 @@ Structured tabular data with typed columns. Uses standard markdown table syntax.
|
|
|
405
424
|
|
|
406
425
|
| Type | Description | Validation |
|
|
407
426
|
| --- | --- | --- |
|
|
408
|
-
| `string` | Any text value | None |
|
|
427
|
+
| `string` | Any text value | None (unless constraints specified) |
|
|
409
428
|
| `number` | Numeric value | Integer or float |
|
|
410
429
|
| `url` | URL value | Valid URL format |
|
|
411
430
|
| `date` | Date value | ISO 8601 (YYYY-MM-DD) |
|
|
412
431
|
| `year` | Year value | Integer (1000-9999) |
|
|
413
432
|
|
|
433
|
+
**Per-column constraints:** Each column type can be an object with constraints:
|
|
434
|
+
|
|
435
|
+
```markdown
|
|
436
|
+
<!-- field kind="table" id="items" label="Items"
|
|
437
|
+
columnIds=["name", "rank", "status"]
|
|
438
|
+
columnTypes=[{"type": "string", "minLength": 2}, {"type": "number", "min": 1, "max": 100, "integer": true}, {"type": "string", "enum": ["active", "inactive"]}] -->
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
| Constraint | Types | Description |
|
|
442
|
+
| --- | --- | --- |
|
|
443
|
+
| `required` | all | Cell must have a value |
|
|
444
|
+
| `minLength` / `maxLength` | `string` | String length bounds |
|
|
445
|
+
| `pattern` | `string` | Regex pattern match |
|
|
446
|
+
| `enum` | `string` | Allowed values (controlled vocabulary) |
|
|
447
|
+
| `min` / `max` | `number`, `year`, `date` | Value bounds |
|
|
448
|
+
| `integer` | `number` | Must be integer |
|
|
449
|
+
|
|
414
450
|
**Sentinel values in cells:** Use `%SKIP%` or `%ABORT%` with optional reasons:
|
|
415
451
|
|
|
416
452
|
```markdown
|
|
@@ -418,6 +454,7 @@ Structured tabular data with typed columns. Uses standard markdown table syntax.
|
|
|
418
454
|
```
|
|
419
455
|
|
|
420
456
|
**Cell escaping:** Use `\|` for literal pipe characters in cell values.
|
|
457
|
+
Multi-line content in cells is encoded as `<br>` in markdown table format.
|
|
421
458
|
|
|
422
459
|
## Common Attributes
|
|
423
460
|
|
|
@@ -441,8 +478,8 @@ All fields support these attributes:
|
|
|
441
478
|
| `examples` | string[] | Example values (helps LLMs understand expected format) |
|
|
442
479
|
|
|
443
480
|
```markdown
|
|
444
|
-
|
|
445
|
-
|
|
481
|
+
<!-- field kind="string" id="name" label="Name" placeholder="Enter your name" examples=["John Doe", "Jane Smith"] --><!-- /field -->
|
|
482
|
+
<!-- field kind="number" id="revenue" label="Revenue" placeholder="1000000" examples=["500000", "1000000"] --><!-- /field -->
|
|
446
483
|
```
|
|
447
484
|
|
|
448
485
|
Note: `placeholder` and `examples` are NOT valid on chooser fields (single-select,
|
|
@@ -450,8 +487,8 @@ multi-select, checkboxes).
|
|
|
450
487
|
|
|
451
488
|
## Harness Configuration
|
|
452
489
|
|
|
453
|
-
Optional harness hints can be set in YAML frontmatter under `markform.harness`.
|
|
454
|
-
|
|
490
|
+
Optional harness hints can be set in YAML frontmatter under `markform.harness`. All keys
|
|
491
|
+
must be `snake_case` and all values must be numbers.
|
|
455
492
|
These are suggestions — a harness may ignore or override them via API options.
|
|
456
493
|
|
|
457
494
|
| Key | Type | Description |
|
|
@@ -478,21 +515,21 @@ Unrecognized keys or non-numeric values cause parse errors.
|
|
|
478
515
|
Add context to fields, groups, or the form.
|
|
479
516
|
|
|
480
517
|
```markdown
|
|
481
|
-
|
|
518
|
+
<!-- description ref="form_id" -->
|
|
482
519
|
Overall form description and purpose.
|
|
483
|
-
|
|
520
|
+
<!-- /description -->
|
|
484
521
|
|
|
485
|
-
|
|
522
|
+
<!-- instructions ref="field_id" -->
|
|
486
523
|
Step-by-step guidance for filling this field.
|
|
487
|
-
|
|
524
|
+
<!-- /instructions -->
|
|
488
525
|
|
|
489
|
-
|
|
526
|
+
<!-- notes ref="field_id" -->
|
|
490
527
|
Additional context or caveats.
|
|
491
|
-
|
|
528
|
+
<!-- /notes -->
|
|
492
529
|
|
|
493
|
-
|
|
530
|
+
<!-- examples ref="field_id" -->
|
|
494
531
|
Example values: "AAPL", "GOOGL", "MSFT"
|
|
495
|
-
|
|
532
|
+
<!-- /examples -->
|
|
496
533
|
```
|
|
497
534
|
|
|
498
535
|
Place doc blocks after the element they reference.
|
|
@@ -501,7 +538,7 @@ Place doc blocks after the element they reference.
|
|
|
501
538
|
|
|
502
539
|
- **Form/Group/Field IDs**: Globally unique, `snake_case`
|
|
503
540
|
|
|
504
|
-
- **Option IDs**: Unique within field, `snake_case`, use
|
|
541
|
+
- **Option IDs**: Unique within field, `snake_case`, use `<!-- #id -->` syntax
|
|
505
542
|
|
|
506
543
|
- **Qualified refs**: `field_id.option_id` for external references
|
|
507
544
|
|
|
@@ -516,8 +553,8 @@ roles:
|
|
|
516
553
|
```
|
|
517
554
|
|
|
518
555
|
```markdown
|
|
519
|
-
|
|
520
|
-
|
|
556
|
+
<!-- field kind="string" id="query" label="Search Query" role="user" --><!-- /field -->
|
|
557
|
+
<!-- field kind="string" id="summary" label="AI Summary" role="agent" --><!-- /field -->
|
|
521
558
|
```
|
|
522
559
|
|
|
523
560
|
## Value Encoding
|
|
@@ -525,17 +562,17 @@ roles:
|
|
|
525
562
|
Values use fenced code blocks with language `value`:
|
|
526
563
|
|
|
527
564
|
````markdown
|
|
528
|
-
|
|
565
|
+
<!-- field kind="string" id="name" label="Name" -->
|
|
529
566
|
```value
|
|
530
567
|
John Smith
|
|
531
568
|
````
|
|
532
|
-
|
|
569
|
+
<!-- /field -->
|
|
533
570
|
````
|
|
534
571
|
|
|
535
572
|
Empty fields omit the value block entirely:
|
|
536
573
|
|
|
537
574
|
```markdown
|
|
538
|
-
|
|
575
|
+
<!-- field kind="string" id="name" label="Name" --><!-- /field -->
|
|
539
576
|
````
|
|
540
577
|
|
|
541
578
|
## Complete Example
|
|
@@ -569,141 +606,143 @@ markform:
|
|
|
569
606
|
max_patches_per_turn: 8
|
|
570
607
|
---
|
|
571
608
|
|
|
572
|
-
|
|
609
|
+
<!-- form id="movie_research" title="Movie Research" -->
|
|
573
610
|
|
|
574
|
-
|
|
611
|
+
<!-- description ref="movie_research" -->
|
|
575
612
|
A focused research form for gathering ratings and key statistics for any film.
|
|
576
613
|
Pulls from IMDB, Rotten Tomatoes, and Metacritic.
|
|
577
|
-
|
|
614
|
+
<!-- /description -->
|
|
578
615
|
|
|
579
|
-
|
|
616
|
+
<!-- group id="movie_input" title="Movie Identification" -->
|
|
580
617
|
|
|
581
|
-
|
|
618
|
+
<!-- field kind="string" id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 --><!-- /field -->
|
|
582
619
|
|
|
583
|
-
|
|
620
|
+
<!-- instructions ref="movie" -->
|
|
584
621
|
Enter the movie title (add any details to help identify, like "Barbie 2023" or "the Batman movie with Robert Pattinson")
|
|
585
|
-
|
|
622
|
+
<!-- /instructions -->
|
|
586
623
|
|
|
587
|
-
|
|
624
|
+
<!-- /group -->
|
|
588
625
|
|
|
589
|
-
|
|
626
|
+
<!-- group id="title_identification" title="Title Identification" -->
|
|
590
627
|
|
|
591
|
-
|
|
628
|
+
<!-- field kind="string" id="full_title" label="Full Title" role="agent" required=true --><!-- /field -->
|
|
592
629
|
|
|
593
|
-
|
|
630
|
+
<!-- instructions ref="full_title" -->
|
|
594
631
|
Look up what film the user had in mind and fill in the official title including subtitle if any (e.g., "The Lord of the Rings: The Fellowship of the Ring").
|
|
595
|
-
|
|
632
|
+
<!-- /instructions -->
|
|
596
633
|
|
|
597
|
-
|
|
634
|
+
<!-- /group -->
|
|
598
635
|
|
|
599
|
-
|
|
636
|
+
<!-- group id="sources" title="Sources" -->
|
|
600
637
|
|
|
601
|
-
|
|
638
|
+
<!-- field kind="url" id="imdb_url" label="IMDB URL" role="agent" required=true --><!-- /field -->
|
|
602
639
|
|
|
603
|
-
|
|
640
|
+
<!-- instructions ref="imdb_url" -->
|
|
604
641
|
Direct link to the movie's IMDB page (e.g., https://www.imdb.com/title/tt0111161/).
|
|
605
|
-
|
|
642
|
+
<!-- /instructions -->
|
|
606
643
|
|
|
607
|
-
|
|
644
|
+
<!-- field kind="url" id="rt_url" label="Rotten Tomatoes URL" role="agent" --><!-- /field -->
|
|
608
645
|
|
|
609
|
-
|
|
646
|
+
<!-- instructions ref="rt_url" -->
|
|
610
647
|
Direct link to the movie's Rotten Tomatoes page.
|
|
611
|
-
|
|
648
|
+
<!-- /instructions -->
|
|
612
649
|
|
|
613
|
-
|
|
650
|
+
<!-- field kind="url" id="metacritic_url" label="Metacritic URL" role="agent" --><!-- /field -->
|
|
614
651
|
|
|
615
|
-
|
|
652
|
+
<!-- instructions ref="metacritic_url" -->
|
|
616
653
|
Direct link to the movie's Metacritic page.
|
|
617
|
-
|
|
654
|
+
<!-- /instructions -->
|
|
618
655
|
|
|
619
|
-
|
|
656
|
+
<!-- /group -->
|
|
620
657
|
|
|
621
|
-
|
|
658
|
+
<!-- group id="basic_details" title="Basic Details" -->
|
|
622
659
|
|
|
623
|
-
|
|
660
|
+
<!-- field kind="number" id="year" label="Release Year" role="agent" required=true min=1888 max=2030 --><!-- /field -->
|
|
624
661
|
|
|
625
|
-
|
|
662
|
+
<!-- field kind="string_list" id="directors" label="Director(s)" role="agent" required=true --><!-- /field -->
|
|
626
663
|
|
|
627
|
-
|
|
664
|
+
<!-- instructions ref="directors" -->
|
|
628
665
|
One director per line. Most films have one; some have two or more co-directors.
|
|
629
|
-
|
|
666
|
+
<!-- /instructions -->
|
|
630
667
|
|
|
631
|
-
|
|
668
|
+
<!-- field kind="number" id="runtime_minutes" label="Runtime (minutes)" role="agent" min=1 max=1000 --><!-- /field -->
|
|
632
669
|
|
|
633
|
-
|
|
634
|
-
- [ ] G {% #g %}
|
|
635
|
-
- [ ] PG {% #pg %}
|
|
636
|
-
- [ ] PG-13 {% #pg_13 %}
|
|
637
|
-
- [ ] R {% #r %}
|
|
638
|
-
- [ ] NC-17 {% #nc_17 %}
|
|
639
|
-
- [ ] NR/Unrated {% #nr %}
|
|
640
|
-
{% /field %}
|
|
670
|
+
<!-- field kind="single_select" id="mpaa_rating" label="MPAA Rating" role="agent" -->
|
|
641
671
|
|
|
642
|
-
|
|
672
|
+
- [ ] G <!-- #g -->
|
|
673
|
+
- [ ] PG <!-- #pg -->
|
|
674
|
+
- [ ] PG-13 <!-- #pg_13 -->
|
|
675
|
+
- [ ] R <!-- #r -->
|
|
676
|
+
- [ ] NC-17 <!-- #nc_17 -->
|
|
677
|
+
- [ ] NR/Unrated <!-- #nr -->
|
|
678
|
+
|
|
679
|
+
<!-- /field -->
|
|
680
|
+
|
|
681
|
+
<!-- /group -->
|
|
643
682
|
|
|
644
|
-
|
|
683
|
+
<!-- group id="imdb_ratings" title="IMDB Ratings" -->
|
|
645
684
|
|
|
646
|
-
|
|
685
|
+
<!-- field kind="number" id="imdb_rating" label="IMDB Rating" role="agent" min=1.0 max=10.0 --><!-- /field -->
|
|
647
686
|
|
|
648
|
-
|
|
687
|
+
<!-- instructions ref="imdb_rating" -->
|
|
649
688
|
IMDB user rating (1.0-10.0 scale).
|
|
650
|
-
|
|
689
|
+
<!-- /instructions -->
|
|
651
690
|
|
|
652
|
-
|
|
691
|
+
<!-- field kind="number" id="imdb_votes" label="IMDB Vote Count" role="agent" min=0 --><!-- /field -->
|
|
653
692
|
|
|
654
|
-
|
|
693
|
+
<!-- instructions ref="imdb_votes" -->
|
|
655
694
|
Number of IMDB user votes (e.g., 2800000 for a popular film).
|
|
656
|
-
|
|
695
|
+
<!-- /instructions -->
|
|
657
696
|
|
|
658
|
-
|
|
697
|
+
<!-- /group -->
|
|
659
698
|
|
|
660
|
-
|
|
699
|
+
<!-- group id="rotten_tomatoes_ratings" title="Rotten Tomatoes Ratings" -->
|
|
661
700
|
|
|
662
|
-
|
|
701
|
+
<!-- field kind="number" id="rt_critics_score" label="Tomatometer (Critics)" role="agent" min=0 max=100 --><!-- /field -->
|
|
663
702
|
|
|
664
|
-
|
|
703
|
+
<!-- instructions ref="rt_critics_score" -->
|
|
665
704
|
Tomatometer percentage (0-100).
|
|
666
|
-
|
|
705
|
+
<!-- /instructions -->
|
|
667
706
|
|
|
668
|
-
|
|
707
|
+
<!-- field kind="number" id="rt_critics_count" label="Critics Review Count" role="agent" min=0 --><!-- /field -->
|
|
669
708
|
|
|
670
|
-
|
|
709
|
+
<!-- field kind="number" id="rt_audience_score" label="Audience Score" role="agent" min=0 max=100 --><!-- /field -->
|
|
671
710
|
|
|
672
|
-
|
|
711
|
+
<!-- instructions ref="rt_audience_score" -->
|
|
673
712
|
Audience Score percentage (0-100).
|
|
674
|
-
|
|
713
|
+
<!-- /instructions -->
|
|
675
714
|
|
|
676
|
-
|
|
715
|
+
<!-- /group -->
|
|
677
716
|
|
|
678
|
-
|
|
717
|
+
<!-- group id="metacritic_ratings" title="Metacritic Ratings" -->
|
|
679
718
|
|
|
680
|
-
|
|
719
|
+
<!-- field kind="number" id="metacritic_score" label="Metacritic Score" role="agent" min=0 max=100 --><!-- /field -->
|
|
681
720
|
|
|
682
|
-
|
|
721
|
+
<!-- instructions ref="metacritic_score" -->
|
|
683
722
|
Metascore (0-100 scale). Leave empty if not available.
|
|
684
|
-
|
|
723
|
+
<!-- /instructions -->
|
|
685
724
|
|
|
686
|
-
|
|
725
|
+
<!-- /group -->
|
|
687
726
|
|
|
688
|
-
|
|
727
|
+
<!-- group id="summary" title="Summary" -->
|
|
689
728
|
|
|
690
|
-
|
|
729
|
+
<!-- field kind="string" id="logline" label="One-Line Summary" role="agent" maxLength=300 --><!-- /field -->
|
|
691
730
|
|
|
692
|
-
|
|
731
|
+
<!-- instructions ref="logline" -->
|
|
693
732
|
Brief plot summary in 1-2 sentences, no spoilers.
|
|
694
|
-
|
|
733
|
+
<!-- /instructions -->
|
|
695
734
|
|
|
696
|
-
|
|
735
|
+
<!-- field kind="string_list" id="notable_awards" label="Notable Awards" role="agent" --><!-- /field -->
|
|
697
736
|
|
|
698
|
-
|
|
737
|
+
<!-- instructions ref="notable_awards" -->
|
|
699
738
|
Major awards won. One per line.
|
|
700
739
|
Format: Award | Category | Year
|
|
701
740
|
Example: "Oscar | Best Picture | 1995"
|
|
702
|
-
|
|
741
|
+
<!-- /instructions -->
|
|
703
742
|
|
|
704
|
-
|
|
743
|
+
<!-- /group -->
|
|
705
744
|
|
|
706
|
-
|
|
745
|
+
<!-- /form -->
|
|
707
746
|
```
|
|
708
747
|
|
|
709
748
|
## CLI Quick Reference
|
|
@@ -737,9 +776,10 @@ markform fill form.md --roles=user --interactive # Only fill user-role fields
|
|
|
737
776
|
markform fill form.md --model anthropic/claude-sonnet-4-5 # AI fills agent fields
|
|
738
777
|
|
|
739
778
|
# Export data
|
|
740
|
-
markform export form.md --format=json
|
|
741
|
-
markform export form.md --format=yaml
|
|
742
|
-
markform export form.md --format=markdown #
|
|
779
|
+
markform export form.md --format=json # Export values as JSON
|
|
780
|
+
markform export form.md --format=yaml # Export values as YAML
|
|
781
|
+
markform export form.md --format=markdown # Full rendered markdown (includes instructions)
|
|
782
|
+
markform report form.md # Clean report markdown (values only, no instructions)
|
|
743
783
|
|
|
744
784
|
# Export form structure as JSON Schema
|
|
745
785
|
markform schema form.md # Full schema with x-markform extensions
|
|
@@ -784,6 +824,35 @@ markform fill template.form.md --mock --mock-source filled.form.md
|
|
|
784
824
|
|
|
785
825
|
5. Use `markform inspect` to verify progress and completion
|
|
786
826
|
|
|
827
|
+
## Form Design Guide
|
|
828
|
+
|
|
829
|
+
When designing a form, match each piece of data to the most specific field kind:
|
|
830
|
+
|
|
831
|
+
| Data | Field Kind | When to Use |
|
|
832
|
+
| --- | --- | --- |
|
|
833
|
+
| Free text | `string` | Names, descriptions, summaries |
|
|
834
|
+
| Numeric values | `number` | Financial figures, counts, scores |
|
|
835
|
+
| Year values | `year` | Founding year, release year |
|
|
836
|
+
| Calendar dates | `date` | Deadlines, event dates (YYYY-MM-DD) |
|
|
837
|
+
| Single URL | `url` | Website, profile page |
|
|
838
|
+
| Multiple URLs | `url_list` | Sources, references |
|
|
839
|
+
| List of text items | `string_list` | Tags, competitors, skills |
|
|
840
|
+
| One-of-many choice | `single_select` | Category, status, rating level |
|
|
841
|
+
| Multiple choices | `multi_select` | Features, capabilities, sectors |
|
|
842
|
+
| Structured rows | `table` | Team members, line items, history |
|
|
843
|
+
| Verification items | `checkboxes` | Task lists, checklists, approvals |
|
|
844
|
+
|
|
845
|
+
**Tips:**
|
|
846
|
+
|
|
847
|
+
- Use `required=true` for fields essential to the form’s purpose
|
|
848
|
+
- Add `pattern` for structured strings (tickers, IDs, codes)
|
|
849
|
+
- Use `integer=true` on number fields for counts
|
|
850
|
+
- Set `min`/`max` bounds on numbers and dates when valid ranges are important
|
|
851
|
+
- Use `checkboxMode="explicit"` when every item needs a yes/no answer
|
|
852
|
+
- Add `role="user"` for human-provided inputs, `role="agent"` for AI-researched data
|
|
853
|
+
- Include `<!-- instructions -->` blocks to guide agents on format and sources
|
|
854
|
+
- Organize related fields into `<!-- group -->` blocks
|
|
855
|
+
|
|
787
856
|
## Best Practices
|
|
788
857
|
|
|
789
858
|
1. **Use descriptive IDs**: `company_revenue_m` not `rev` or `field1`
|
|
@@ -796,7 +865,7 @@ markform fill template.form.md --mock --mock-source filled.form.md
|
|
|
796
865
|
|
|
797
866
|
5. **Assign roles**: Separate user input from agent research
|
|
798
867
|
|
|
799
|
-
6. **Document thoroughly**: Use
|
|
868
|
+
6. **Document thoroughly**: Use `<!-- instructions -->` for complex fields
|
|
800
869
|
|
|
801
870
|
## Claude Code Skill Setup
|
|
802
871
|
|