markform 0.1.2 → 0.1.4

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 (35) hide show
  1. package/README.md +97 -42
  2. package/dist/ai-sdk.d.mts +2 -2
  3. package/dist/ai-sdk.mjs +5 -5
  4. package/dist/{apply-BfAGTHMh.mjs → apply-C54EMAJ1.mjs} +383 -26
  5. package/dist/bin.mjs +6 -6
  6. package/dist/{cli-B3NVm6zL.mjs → cli-BhWhn6L9.mjs} +456 -141
  7. package/dist/cli.mjs +6 -6
  8. package/dist/{coreTypes-BXhhz9Iq.d.mts → coreTypes-cbNTYAcb.d.mts} +1878 -325
  9. package/dist/{coreTypes-Dful87E0.mjs → coreTypes-pyctKRgc.mjs} +79 -5
  10. package/dist/index.d.mts +146 -9
  11. package/dist/index.mjs +5 -5
  12. package/dist/session-B_stoXQn.mjs +4 -0
  13. package/dist/{session-Bqnwi9wp.mjs → session-uF0e6m6k.mjs} +9 -5
  14. package/dist/{shared-N_s1M-_K.mjs → shared-BqPnYXrn.mjs} +82 -1
  15. package/dist/shared-CZsyShck.mjs +3 -0
  16. package/dist/{src-BXRkGFpG.mjs → src-BNh7Cx9P.mjs} +801 -121
  17. package/docs/markform-apis.md +194 -0
  18. package/{DOCS.md → docs/markform-reference.md} +111 -50
  19. package/{SPEC.md → docs/markform-spec.md} +342 -91
  20. package/examples/celebrity-deep-research/celebrity-deep-research.form.md +196 -141
  21. package/examples/earnings-analysis/earnings-analysis.form.md +236 -226
  22. package/examples/movie-research/movie-research-basic.form.md +25 -21
  23. package/examples/movie-research/movie-research-deep.form.md +74 -62
  24. package/examples/movie-research/movie-research-minimal.form.md +29 -34
  25. package/examples/simple/simple-mock-filled.form.md +93 -29
  26. package/examples/simple/simple-skipped-filled.form.md +91 -29
  27. package/examples/simple/simple-with-skips.session.yaml +93 -25
  28. package/examples/simple/simple.form.md +74 -20
  29. package/examples/simple/simple.session.yaml +98 -25
  30. package/examples/startup-deep-research/startup-deep-research.form.md +108 -81
  31. package/examples/startup-research/startup-research-mock-filled.form.md +43 -43
  32. package/examples/startup-research/startup-research.form.md +24 -24
  33. package/package.json +18 -27
  34. package/dist/session-DdAtY2Ni.mjs +0 -4
  35. package/dist/shared-D7gf27Tr.mjs +0 -3
package/README.md CHANGED
@@ -41,7 +41,7 @@ npx markform examples
41
41
  This walks you through an example form interactively, with optional AI agent filling.
42
42
  You’ll need at least one [API key](#supported-providers) to have LLMs fill in forms.
43
43
 
44
- ### A Simple Form
44
+ ### A Minimal Form
45
45
 
46
46
  A `.form.md` file is simply a Markdoc file.
47
47
  It combines YAML frontmatter with Markdoc-tagged content:
@@ -50,71 +50,115 @@ It combines YAML frontmatter with Markdoc-tagged content:
50
50
  ---
51
51
  markform:
52
52
  spec: MF/0.1
53
- title: Movie Research (Simple)
54
- roles: # Who can fill fields
53
+ title: Movie Research (Minimal)
54
+ description: Quick movie lookup with just the essentials (title, year, ratings, summary).
55
+ roles:
55
56
  - user
56
57
  - agent
57
- role_instructions: # Instructions shown to each role
58
+ role_instructions:
58
59
  user: "Enter the movie title."
59
- agent: "Research the movie and fill in the details from IMDB."
60
+ agent: |
61
+ Quickly identify the movie and fill in basic info from IMDB.
62
+ This is a minimal lookup - just get the core facts.
60
63
  ---
64
+ {% form id="movie_research_minimal" title="Movie Research (Minimal)" %}
61
65
 
62
- {% form id="movie_research" title="Movie Research" %}
66
+ ## Movie Research Example
63
67
 
64
- {% field-group id="input" title="Input" %}
68
+ {% field-group id="movie_input" title="Movie Identification" %}
65
69
 
66
- <!-- User fills this field -->
70
+ What movie do you want to research? \[*This field is filled in by the user (`role="user"`).*\]
67
71
 
68
- {% string-field id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 %}{% /string-field %}
72
+ {% field kind="string" id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 %}{% /field %}
73
+ {% instructions ref="movie" %}Enter the movie title (add year or details for disambiguation).{% /instructions %}
69
74
 
70
- {% instructions ref="movie" %}
75
+ {% /field-group %}
71
76
 
72
- <!-- Guidance for filling the field -->
77
+ ## About the Movie
73
78
 
74
- Enter the movie title (add any details to help identify, like "Barbie 2023" or "the Batman movie with Robert Pattinson").
75
- {% /instructions %}
79
+ {% field-group id="about_the_movie" title="About the Movie" %}
76
80
 
77
- {% /field-group %}
81
+ **Title:**
82
+
83
+ {% field kind="string" id="full_title" label="Full Title" role="agent" required=true %}{% /field %}
84
+ {% instructions ref="full_title" %}Official title, including subtitle if any.{% /instructions %}
78
85
 
79
- {% field-group id="details" title="Movie Details" %}
86
+ **Release year:**
80
87
 
81
- <!-- Agent researches and fills these fields -->
88
+ {% field kind="number" id="year" label="Release Year" role="agent" required=true min=1888 max=2030 %}{% /field %}
82
89
 
83
- {% string-field id="full_title" label="Full Title" role="agent" required=true %}{% /string-field %}
90
+ **IMDB:**
84
91
 
85
- {% number-field id="year" label="Release Year" role="agent" min=1888 max=2030 %}{% /number-field %}
92
+ {% field kind="url" id="imdb_url" label="IMDB URL" role="agent" required=true %}{% /field %}
86
93
 
87
- {% single-select id="mpaa_rating" label="MPAA Rating" role="agent" %}
94
+ **MPAA rating:**
95
+
96
+ {% field kind="single_select" id="mpaa_rating" label="MPAA Rating" role="agent" %}
88
97
  - [ ] G {% #g %}
89
98
  - [ ] PG {% #pg %}
90
99
  - [ ] PG-13 {% #pg_13 %}
91
100
  - [ ] R {% #r %}
92
101
  - [ ] NC-17 {% #nc_17 %}
93
102
  - [ ] NR/Unrated {% #nr %}
94
- {% /single-select %}
103
+ {% /field %}
104
+
105
+ **IMDB rating:**
95
106
 
96
- {% url-field id="imdb_url" label="IMDB URL" role="agent" %}{% /url-field %}
107
+ {% field kind="number" id="imdb_rating" label="IMDB Rating" role="agent" min=1.0 max=10.0 %}{% /field %}
108
+ {% instructions ref="imdb_rating" %}IMDB user rating (1.0-10.0 scale).{% /instructions %}
97
109
 
98
- {% number-field id="imdb_rating" label="IMDB Rating" role="agent" min=1.0 max=10.0 %}{% /number-field %}
110
+ **Summary:**
99
111
 
100
- {% string-field id="logline" label="Summary" role="agent" maxLength=200 %}{% /string-field %}
112
+ {% field kind="string" id="logline" label="One-Line Summary" role="agent" maxLength=300 %}{% /field %}
113
+ {% instructions ref="logline" %}Brief plot summary in 1-2 sentences, no spoilers.{% /instructions %}
101
114
 
102
115
  {% /field-group %}
103
116
 
104
117
  {% /form %}
105
118
  ```
106
119
 
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.
120
+ Run the `npx markform examples` and select the `Movie Research (Minimal)` example and
121
+ view the report:
122
+
123
+ ```markdown
124
+ # Movie Research (Minimal)
125
+
126
+ ## Movie Identification
127
+
128
+ Movie:
129
+ shawshank redemption
130
+
131
+ ## About the Movie
132
+
133
+ Full Title:
134
+ The Shawshank Redemption
135
+
136
+ Release Year:
137
+ 1994
138
+
139
+ IMDB URL:
140
+ https://www.imdb.com/title/tt0111161/
141
+
142
+ MPAA Rating:
143
+ R
144
+
145
+ IMDB Rating:
146
+ 9.3
147
+
148
+ One-Line Summary:
149
+ Convicted banker Andy Dufresne is sent to Shawshank State Penitentiary, where he forms an unexpected friendship with inmate Red while holding onto hope and striving to maintain his dignity in a corrupt prison system.
150
+ ```
151
+
152
+ See the
153
+ [examples/](https://github.com/jlevy/markform/tree/main/packages/markform/examples)
154
+ directory for a few more complex form examples.
111
155
 
112
156
  **Key concepts:**
113
157
 
114
158
  - **Roles**: Define who fills what (`user` for humans, `agent` for AI)
115
159
 
116
- - **Field types**: `string-field`, `number-field`, `url-field`, `string-list`,
117
- `single-select`, `multi-select`, `checkboxes`
160
+ - **Field kinds**: `string-field`, `number-field`, `date-field`, `year-field`,
161
+ `url-field`, `url-list`, `string-list`, `single-select`, `multi-select`, `checkboxes`
118
162
 
119
163
  - **Validation**: `required`, `min/max`, `minLength/maxLength`, `pattern`
120
164
 
@@ -137,7 +181,7 @@ The package includes example forms in
137
181
  \- Comprehensive analysis with streaming, box office
138
182
 
139
183
  - [`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
184
+ \- Basic form demonstrating all field kinds
141
185
 
142
186
  - [`earnings-analysis/earnings-analysis.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/earnings-analysis/earnings-analysis.form.md)
143
187
  \- Financial analysis form
@@ -250,9 +294,12 @@ markform serve my-form.form.md
250
294
  # Quick reference for writing forms (agent-friendly)
251
295
  markform docs
252
296
 
253
- # Full specification (SPEC.md)
297
+ # Full specification
254
298
  markform spec
255
299
 
300
+ # TypeScript and AI SDK API documentation
301
+ markform apis
302
+
256
303
  # This README
257
304
  markform readme
258
305
 
@@ -282,7 +329,9 @@ flowchart LR
282
329
  subgraph L4["<b>LAYER 4: TOOL API & INTERFACES</b><br/>Abstract API for agents and humans (TypeScript and AI SDK integration)"]
283
330
  end
284
331
 
285
- L4 --> L3 --> L2 --> L1
332
+ L4 -->
333
+
334
+ L3 --> L2 --> L1
286
335
  end
287
336
 
288
337
  subgraph IMPL["<b>THIS IMPLEMENTATION</b>"]
@@ -389,7 +438,8 @@ But it’s been useful for me already.
389
438
 
390
439
  It’s all written by LLMs but using a strongly spec-driven process, using rules from
391
440
  [Speculate](https://github.com/jlevy/speculate).
392
- See [the spec](SPEC.md) and the architecture docs and specs in [docs/](docs/).
441
+ See [the spec](docs/markform-spec.md) and the architecture docs and specs in
442
+ [docs/](docs/).
393
443
 
394
444
  ### What are the goals of Markform?
395
445
 
@@ -444,12 +494,13 @@ Not really. The closest alternatives are:
444
494
  human-friendly UI. But these do not have a human-friendly text format for use by
445
495
  agents as well as humans.
446
496
 
447
- | Approach | Human-readable | Agent-editable | Custom validations |
448
- | --- | :---: | :---: | :---: |
449
- | Plain Markdown | ✅ | ⚠️ fragile | ❌ |
450
- | JSON Schema | | ✅ | ✅ |
451
- | PDF Forms, SaaS tools | ⚠️ | | ⚠️ |
452
- | **Markform** | ✅ | | ✅ |
497
+ | Approach | Has GUI | Human-readable text format | Agent-editable | APIs and validation rules |
498
+ | --- | :---: | :---: | :---: | :---: |
499
+ | Plain Markdown | ☑️ existing tools | ✅ | ⚠️ fragile | ❌ |
500
+ | JSON with schema | ☑️ existing tools | ⚠️ hey it’s JSON | ✅ | ✅ |
501
+ | SaaS tools (Typeform, Docusign, PDF forms) | ✅ | ⚠️ rarely | ⚠️ if they add it | ⚠️ if they add it |
502
+ | Excel/Google Sheets | ✅ | .xlsx | ⚠️ with tools | ✅ |
503
+ | **Markform** | ☑️ existing tools | ✅ | ✅ | ✅ |
453
504
 
454
505
  ### What are example use cases?
455
506
 
@@ -494,11 +545,15 @@ Or see [markdoc/language-server](https://github.com/markdoc/language-server).
494
545
  ## Documentation
495
546
 
496
547
  - **[Quick
497
- Reference](https://github.com/jlevy/markform/blob/main/packages/markform/DOCS.md)**
548
+ Reference](https://github.com/jlevy/markform/blob/main/docs/markform-reference.md)**
498
549
  (or run `markform docs`) - Concise syntax reference (agent-friendly)
499
550
 
500
- - **[Markform Spec](https://github.com/jlevy/markform/blob/main/SPEC.md)** (or run
501
- `markform spec`) - Complete syntax and semantics
551
+ - **[Markform Spec](https://github.com/jlevy/markform/blob/main/docs/markform-spec.md)**
552
+ (or run `markform spec`) - Complete syntax and semantics
553
+
554
+ - **[API
555
+ Documentation](https://github.com/jlevy/markform/blob/main/docs/markform-apis.md)**
556
+ (or run `markform apis`) - TypeScript and AI SDK APIs
502
557
 
503
558
  - **[Design
504
559
  Doc](https://github.com/jlevy/markform/blob/main/docs/project/architecture/current/arch-markform-design.md)**
package/dist/ai-sdk.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { H as Id, L as FormSchema, Sn as ValidatorRegistry, _t as ParsedForm, j as FieldResponse, q as InspectResult, r as ApplyResult, vt as Patch, yt as PatchSchema } from "./coreTypes-BXhhz9Iq.mjs";
3
+ import { Dt as PatchSchema, Et as Patch, G as FormSchema, Tt as ParsedForm, X as Id, ar as ValidatorRegistry, r as ApplyResult, tt as InspectResult, z as FieldResponse } from "./coreTypes-cbNTYAcb.mjs";
4
4
  import { z } from "zod";
5
5
 
6
6
  //#region src/integrations/toolTypes.d.ts
@@ -62,7 +62,7 @@ interface MarkformToolSet {
62
62
  markform_get_markdown?: MarkformTool<Record<string, never>, GetMarkdownToolResult>;
63
63
  }
64
64
  //#endregion
65
- //#region src/integrations/ai-sdk.d.ts
65
+ //#region src/integrations/vercelAiSdkTools.d.ts
66
66
  /**
67
67
  * Session store for managing form state during AI interactions.
68
68
  *
package/dist/ai-sdk.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { N as PatchSchema } from "./coreTypes-Dful87E0.mjs";
2
- import { r as inspect, t as applyPatches, u as serialize } from "./apply-BfAGTHMh.mjs";
1
+ import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
2
+ import { r as inspect, t as applyPatches, u as serialize } from "./apply-C54EMAJ1.mjs";
3
3
  import { z } from "zod";
4
4
 
5
- //#region src/integrations/ai-sdk.ts
5
+ //#region src/integrations/vercelAiSdkTools.ts
6
6
  /**
7
7
  * AI SDK Integration for Markform.
8
8
  *
@@ -63,7 +63,7 @@ const InspectInputSchema = z.object({}).describe("No input parameters required.
63
63
  /**
64
64
  * Input schema for markform_apply tool.
65
65
  */
66
- const ApplyInputSchema = z.object({ patches: z.array(PatchSchema).min(1).max(20).describe("Array of patches to apply to the form. Each patch sets or clears a field value. Operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, set_checkboxes, clear_field. Example: [{ \"op\": \"set_string\", \"fieldId\": \"name\", \"value\": \"Alice\" }]") }).describe("Apply patches to update form field values.");
66
+ const ApplyInputSchema = z.object({ patches: z.array(PatchSchema).min(1).max(20).describe("Array of patches to apply to the form. Each patch sets or clears a field value. Operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, set_checkboxes, set_url, set_url_list, set_date, set_year, set_table, clear_field, skip_field, abort_field. Example: [{ \"op\": \"set_string\", \"fieldId\": \"name\", \"value\": \"Alice\" }]") }).describe("Apply patches to update form field values.");
67
67
  /**
68
68
  * Input schema for markform_export tool (no parameters).
69
69
  */
@@ -115,7 +115,7 @@ function createMarkformTools(options) {
115
115
  }
116
116
  },
117
117
  markform_apply: {
118
- description: "Apply patches to update form field values. Use this after inspecting the form to set values for fields that need to be filled. Patches are applied as a transaction - all succeed or all fail. Returns the updated form state and any remaining issues. Patch operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, set_checkboxes, clear_field.",
118
+ description: "Apply patches to update form field values. Use this after inspecting the form to set values for fields that need to be filled. Patches are applied as a transaction - all succeed or all fail. Returns the updated form state and any remaining issues. Patch operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, set_checkboxes, set_url, set_url_list, set_date, set_year, set_table, clear_field, skip_field, abort_field.",
119
119
  inputSchema: ApplyInputSchema,
120
120
  execute: ({ patches }) => {
121
121
  const form = sessionStore.getForm();