markform 0.1.4 → 0.1.5

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 (28) hide show
  1. package/README.md +40 -53
  2. package/dist/ai-sdk.d.mts +1 -1
  3. package/dist/ai-sdk.mjs +1 -1
  4. package/dist/{apply-C54EMAJ1.mjs → apply-BCCiJzQr.mjs} +3 -3
  5. package/dist/bin.mjs +3 -3
  6. package/dist/{cli-BhWhn6L9.mjs → cli-D469amuk.mjs} +5 -11
  7. package/dist/cli.mjs +3 -3
  8. package/dist/{coreTypes-cbNTYAcb.d.mts → coreTypes-9XZSNOv6.d.mts} +2 -2
  9. package/dist/index.d.mts +1 -1
  10. package/dist/index.mjs +2 -2
  11. package/dist/{src-BNh7Cx9P.mjs → src-Df0XX7UB.mjs} +19 -6
  12. package/docs/markform-reference.md +19 -19
  13. package/docs/markform-spec.md +20 -20
  14. package/examples/earnings-analysis/earnings-analysis.form.md +86 -808
  15. package/examples/earnings-analysis/earnings-analysis.valid.ts +16 -148
  16. package/examples/movie-research/movie-research-basic.form.md +16 -16
  17. package/examples/movie-research/movie-research-deep.form.md +36 -36
  18. package/examples/movie-research/movie-research-minimal.form.md +4 -4
  19. package/examples/simple/simple-mock-filled.form.md +16 -16
  20. package/examples/simple/simple-skipped-filled.form.md +16 -16
  21. package/examples/simple/simple-with-skips.session.yaml +3 -3
  22. package/examples/simple/simple.form.md +16 -16
  23. package/examples/simple/simple.session.yaml +3 -3
  24. package/examples/startup-deep-research/startup-deep-research.form.md +22 -22
  25. package/examples/startup-research/startup-research-mock-filled.form.md +12 -12
  26. package/examples/startup-research/startup-research.form.md +12 -12
  27. package/package.json +1 -1
  28. package/examples/celebrity-deep-research/celebrity-deep-research.form.md +0 -967
package/README.md CHANGED
@@ -21,6 +21,8 @@ which makes creating new workflows much easier.
21
21
 
22
22
  ## Installation
23
23
 
24
+ Requires Node.js 20+.
25
+
24
26
  ```bash
25
27
  # As a global CLI
26
28
  npm install -g markform
@@ -29,8 +31,6 @@ npm install -g markform
29
31
  npm install markform
30
32
  ```
31
33
 
32
- Requires Node.js 20+ (v24 recommended).
33
-
34
34
  ## Quick Start
35
35
 
36
36
  ```bash
@@ -39,9 +39,12 @@ npx markform examples
39
39
  ```
40
40
 
41
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.
42
+ You’ll need at least one [API key](#supported-providers) form a provider with a model
43
+ that supports web search to have LLMs fill in forms.
43
44
 
44
- ### A Minimal Form
45
+ ## Example: Research a Movie
46
+
47
+ ### Form Definition
45
48
 
46
49
  A `.form.md` file is simply a Markdoc file.
47
50
  It combines YAML frontmatter with Markdoc-tagged content:
@@ -65,18 +68,18 @@ markform:
65
68
 
66
69
  ## Movie Research Example
67
70
 
68
- {% field-group id="movie_input" title="Movie Identification" %}
71
+ {% group id="movie_input" title="Movie Identification" %}
69
72
 
70
73
  What movie do you want to research? \[*This field is filled in by the user (`role="user"`).*\]
71
74
 
72
75
  {% field kind="string" id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 %}{% /field %}
73
76
  {% instructions ref="movie" %}Enter the movie title (add year or details for disambiguation).{% /instructions %}
74
77
 
75
- {% /field-group %}
78
+ {% /group %}
76
79
 
77
80
  ## About the Movie
78
81
 
79
- {% field-group id="about_the_movie" title="About the Movie" %}
82
+ {% group id="about_the_movie" title="About the Movie" %}
80
83
 
81
84
  **Title:**
82
85
 
@@ -112,11 +115,13 @@ What movie do you want to research? \[*This field is filled in by the user (`rol
112
115
  {% field kind="string" id="logline" label="One-Line Summary" role="agent" maxLength=300 %}{% /field %}
113
116
  {% instructions ref="logline" %}Brief plot summary in 1-2 sentences, no spoilers.{% /instructions %}
114
117
 
115
- {% /field-group %}
118
+ {% /group %}
116
119
 
117
120
  {% /form %}
118
121
  ```
119
122
 
123
+ ### Form Report Output
124
+
120
125
  Run the `npx markform examples` and select the `Movie Research (Minimal)` example and
121
126
  view the report:
122
127
 
@@ -149,63 +154,26 @@ One-Line Summary:
149
154
  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
155
  ```
151
156
 
152
- See the
153
- [examples/](https://github.com/jlevy/markform/tree/main/packages/markform/examples)
154
- directory for a few more complex form examples.
155
-
156
- **Key concepts:**
157
-
158
- - **Roles**: Define who fills what (`user` for humans, `agent` for AI)
159
-
160
- - **Field kinds**: `string-field`, `number-field`, `date-field`, `year-field`,
161
- `url-field`, `url-list`, `string-list`, `single-select`, `multi-select`, `checkboxes`
162
-
163
- - **Validation**: `required`, `min/max`, `minLength/maxLength`, `pattern`
164
-
165
- - **Structure**: Fields organized in `field-group` containers
166
-
167
- - **Instructions**: Per-field guidance for users or agents
168
-
169
157
  ### More Example Forms
170
158
 
171
159
  The package includes example forms in
172
- [`examples/`](https://github.com/jlevy/markform/tree/main/packages/markform/examples):
160
+ [`examples/`](https://github.com/jlevy/markform/tree/main/packages/markform/examples).
161
+ View them with `markform examples --list` or try these interactively:
173
162
 
174
163
  - [`movie-research/movie-research-minimal.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-minimal.form.md)
175
- \- Quick movie lookup (title, year, rating)
164
+ \- The quick example above.
176
165
 
177
166
  - [`movie-research/movie-research-basic.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-basic.form.md)
178
- \- Standard research with IMDB, Rotten Tomatoes, Metacritic
167
+ \- Standard movie research with IMDB, Rotten Tomatoes, Metacritic.
179
168
 
180
169
  - [`movie-research/movie-research-deep.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/movie-research/movie-research-deep.form.md)
181
- \- Comprehensive analysis with streaming, box office
170
+ \- Comprehensive movie analysis with streaming, box office, analysis.
182
171
 
183
172
  - [`simple/simple.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/simple/simple.form.md)
184
- \- Basic form demonstrating all field kinds
173
+ \- Basic form demonstrating all field kinds.
185
174
 
186
175
  - [`earnings-analysis/earnings-analysis.form.md`](https://github.com/jlevy/markform/blob/main/packages/markform/examples/earnings-analysis/earnings-analysis.form.md)
187
- \- Financial analysis form
188
-
189
- View them with `markform examples --list` or try them interactively.
190
-
191
- ## Supported Providers
192
-
193
- Standard LLMs can be used to fill in forms or create research reports from form
194
- templates. The package currently has support for these models built in, and enables web
195
- search tools for them if possible.
196
-
197
- | Provider | Env Variable | Example Models |
198
- | --- | --- | --- |
199
- | openai | `OPENAI_API_KEY` | gpt-5-mini, gpt-5.1, gpt-5.2 |
200
- | anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-5, claude-opus-4-5 |
201
- | google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.5-flash |
202
- | xai | `XAI_API_KEY` | grok-4, grok-4-fast |
203
- | deepseek | `DEEPSEEK_API_KEY` | deepseek-chat, deepseek-reasoner |
204
-
205
- Set the appropriate environment variable for your provider before running `markform
206
- fill`. See
207
- [`src/settings.ts`](https://github.com/jlevy/markform/blob/main/packages/markform/src/settings.ts)
208
- for the full list of models.
176
+ \- Financial analysis form.
209
177
 
210
178
  ## Why?
211
179
 
@@ -310,6 +278,25 @@ markform models
310
278
  markform --help
311
279
  ```
312
280
 
281
+ ## Supported Providers
282
+
283
+ Standard LLMs can be used to fill in forms or create research reports from form
284
+ templates. The package currently has support for these models built in, and enables web
285
+ search tools for them if possible.
286
+
287
+ | Provider | Env Variable | Example Models |
288
+ | --- | --- | --- |
289
+ | openai | `OPENAI_API_KEY` | gpt-5-mini, gpt-5.1, gpt-5.2 |
290
+ | anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-5, claude-opus-4-5 |
291
+ | google | `GOOGLE_API_KEY` | gemini-2.5-pro, gemini-2.5-flash |
292
+ | xai | `XAI_API_KEY` | grok-4, grok-4-fast |
293
+ | deepseek | `DEEPSEEK_API_KEY` | deepseek-chat, deepseek-reasoner |
294
+
295
+ Set the appropriate environment variable for your provider before running `markform
296
+ fill`. See
297
+ [`src/settings.ts`](https://github.com/jlevy/markform/blob/main/packages/markform/src/settings.ts)
298
+ for the full list of models.
299
+
313
300
  ## Architecture
314
301
 
315
302
  ```mermaid
@@ -317,7 +304,7 @@ flowchart LR
317
304
  subgraph SPEC["<b>MARKFORM SPEC</b>"]
318
305
  direction TB
319
306
 
320
- subgraph L1["<b>LAYER 1: SYNTAX</b><br/>Markdoc tag syntax and frontmatter (form, field-group, string-field, checkboxes, etc.)"]
307
+ subgraph L1["<b>LAYER 1: SYNTAX</b><br/>Markdoc tag syntax and frontmatter (form, group, string-field, checkboxes, etc.)"]
321
308
  end
322
309
 
323
310
  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)"]
package/dist/ai-sdk.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
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";
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-9XZSNOv6.mjs";
4
4
  import { z } from "zod";
5
5
 
6
6
  //#region src/integrations/toolTypes.d.ts
package/dist/ai-sdk.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
2
- import { r as inspect, t as applyPatches, u as serialize } from "./apply-C54EMAJ1.mjs";
2
+ import { r as inspect, t as applyPatches, u as serialize } from "./apply-BCCiJzQr.mjs";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/integrations/vercelAiSdkTools.ts
@@ -811,7 +811,7 @@ function serializeNotes(notes) {
811
811
  /**
812
812
  * Serialize a field group.
813
813
  * Implicit groups (fields placed directly under the form) are serialized
814
- * without the field-group wrapper tags.
814
+ * without the group wrapper tags.
815
815
  */
816
816
  function serializeFieldGroup(group, responses, docs) {
817
817
  const lines = [];
@@ -821,7 +821,7 @@ function serializeFieldGroup(group, responses, docs) {
821
821
  if (group.validate) attrs.validate = group.validate;
822
822
  if (group.report !== void 0) attrs.report = group.report;
823
823
  const attrStr = serializeAttrs(attrs);
824
- lines.push(`{% field-group ${attrStr} %}`);
824
+ lines.push(`{% group ${attrStr} %}`);
825
825
  }
826
826
  const docsByRef = /* @__PURE__ */ new Map();
827
827
  for (const doc of docs) {
@@ -840,7 +840,7 @@ function serializeFieldGroup(group, responses, docs) {
840
840
  }
841
841
  if (!group.implicit) {
842
842
  lines.push("");
843
- lines.push("{% /field-group %}");
843
+ lines.push("{% /group %}");
844
844
  }
845
845
  return lines.join("\n");
846
846
  }
package/dist/bin.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import "./coreTypes-pyctKRgc.mjs";
3
- import "./apply-C54EMAJ1.mjs";
4
- import "./src-BNh7Cx9P.mjs";
3
+ import "./apply-BCCiJzQr.mjs";
4
+ import "./src-Df0XX7UB.mjs";
5
5
  import "./session-uF0e6m6k.mjs";
6
6
  import "./shared-BqPnYXrn.mjs";
7
- import { t as runCli } from "./cli-BhWhn6L9.mjs";
7
+ import { t as runCli } from "./cli-D469amuk.mjs";
8
8
  import { resolve } from "node:path";
9
9
  import { existsSync } from "node:fs";
10
10
  import { config } from "dotenv";
@@ -1,6 +1,6 @@
1
1
  import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
2
- import { A as parseRolesFlag, D as deriveReportPath, E as deriveExportPath, F as hasWebSearchSupport, I as parseModelIdForDisplay, M as WEB_SEARCH_CONFIG, N as formatSuggestedLlms, O as detectFileType, T as USER_ROLE, _ as DEFAULT_MAX_TURNS, b as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, d as serializeRawMarkdown, f as serializeReportMarkdown, g as DEFAULT_MAX_PATCHES_PER_TURN, h as DEFAULT_MAX_ISSUES_PER_TURN, j as SUGGESTED_LLMS, k as getFormsDir, m as DEFAULT_FORMS_DIR, p as AGENT_ROLE, r as inspect, t as applyPatches, u as serialize, v as DEFAULT_PORT, w as REPORT_EXTENSION, x as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN } from "./apply-C54EMAJ1.mjs";
3
- import { a as resolveHarnessConfig, c as getProviderNames, f as createMockAgent, i as runResearch, l as resolveModel, m as createHarness, s as getProviderInfo, t as VERSION, u as createLiveAgent, w as parseForm } from "./src-BNh7Cx9P.mjs";
2
+ import { A as parseRolesFlag, D as deriveReportPath, E as deriveExportPath, F as hasWebSearchSupport, I as parseModelIdForDisplay, M as WEB_SEARCH_CONFIG, N as formatSuggestedLlms, O as detectFileType, T as USER_ROLE, _ as DEFAULT_MAX_TURNS, b as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, d as serializeRawMarkdown, f as serializeReportMarkdown, g as DEFAULT_MAX_PATCHES_PER_TURN, h as DEFAULT_MAX_ISSUES_PER_TURN, j as SUGGESTED_LLMS, k as getFormsDir, m as DEFAULT_FORMS_DIR, p as AGENT_ROLE, r as inspect, t as applyPatches, u as serialize, v as DEFAULT_PORT, w as REPORT_EXTENSION, x as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN } from "./apply-BCCiJzQr.mjs";
3
+ import { a as resolveHarnessConfig, c as getProviderNames, f as createMockAgent, i as runResearch, l as resolveModel, m as createHarness, s as getProviderInfo, t as VERSION, u as createLiveAgent, w as parseForm } from "./src-Df0XX7UB.mjs";
4
4
  import { n as serializeSession } from "./session-uF0e6m6k.mjs";
5
5
  import { a as formatPath, c as logError, d as logTiming, f as logVerbose, g as writeFile, i as formatOutput, l as logInfo, m as readFile$1, n as createSpinner, o as getCommandContext, p as logWarn, r as ensureFormsDir, s as logDryRun, t as OUTPUT_FORMATS, u as logSuccess } from "./shared-BqPnYXrn.mjs";
6
6
  import YAML from "yaml";
@@ -684,12 +684,6 @@ const EXAMPLE_DEFINITIONS = [
684
684
  filename: "startup-deep-research.form.md",
685
685
  path: "startup-deep-research/startup-deep-research.form.md",
686
686
  type: "research"
687
- },
688
- {
689
- id: "celebrity-deep-research",
690
- filename: "celebrity-deep-research.form.md",
691
- path: "celebrity-deep-research/celebrity-deep-research.form.md",
692
- type: "research"
693
687
  }
694
688
  ];
695
689
  /**
@@ -703,7 +697,7 @@ function getExamplesDir() {
703
697
  }
704
698
  /**
705
699
  * Load the content of an example form.
706
- * @param exampleId - The example ID (e.g., 'simple', 'celebrity-deep-research')
700
+ * @param exampleId - The example ID (e.g., 'simple', 'movie-research-deep')
707
701
  * @returns The form content as a string
708
702
  * @throws Error if the example is not found
709
703
  */
@@ -725,7 +719,7 @@ function getExampleById(id) {
725
719
  }
726
720
  /**
727
721
  * Get the absolute path to an example's source file.
728
- * @param exampleId - The example ID (e.g., 'simple', 'celebrity-deep-research')
722
+ * @param exampleId - The example ID (e.g., 'simple', 'movie-research-deep')
729
723
  * @returns The absolute path to the example form file
730
724
  * @throws Error if the example is not found
731
725
  */
@@ -750,7 +744,7 @@ function extractFrontmatter(content) {
750
744
  }
751
745
  /**
752
746
  * Load metadata (title, description) from an example's YAML frontmatter.
753
- * @param exampleId - The example ID (e.g., 'simple', 'celebrity-deep-research')
747
+ * @param exampleId - The example ID (e.g., 'simple', 'movie-research-deep')
754
748
  * @returns Object with title and description from frontmatter
755
749
  */
756
750
  function loadExampleMetadata(exampleId) {
package/dist/cli.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import "./coreTypes-pyctKRgc.mjs";
2
- import "./apply-C54EMAJ1.mjs";
3
- import "./src-BNh7Cx9P.mjs";
2
+ import "./apply-BCCiJzQr.mjs";
3
+ import "./src-Df0XX7UB.mjs";
4
4
  import "./session-uF0e6m6k.mjs";
5
5
  import "./shared-BqPnYXrn.mjs";
6
- import { t as runCli } from "./cli-BhWhn6L9.mjs";
6
+ import { t as runCli } from "./cli-D469amuk.mjs";
7
7
 
8
8
  export { runCli };
@@ -195,8 +195,8 @@ interface FieldGroup {
195
195
  report?: boolean;
196
196
  /**
197
197
  * True if this group was implicitly created for fields placed directly
198
- * under the form (not wrapped in an explicit field-group).
199
- * Implicit groups are serialized without field-group wrapper tags.
198
+ * under the form (not wrapped in an explicit group).
199
+ * Implicit groups are serialized without group wrapper tags.
200
200
  */
201
201
  implicit?: boolean;
202
202
  }
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { $ as InspectIssue, $n as ValidationIssue, $t as SetStringListPatch, A as ExplicitCheckboxValueSchema, An as StringListValueSchema, At as ProgressState, B as FieldResponseSchema, Bn as TableRowPatchSchema, Bt as SessionTurn, C as DateValue, Cn as StepResult, Ct as OptionIdSchema, D as DocumentationTag, Dn as StringListField, Dt as PatchSchema, E as DocumentationBlockSchema, En as StringFieldSchema, Et as Patch, F as FieldKind, Fn as TableColumn, Ft as QualifiedOptionRef, G as FormSchema, Gn as UrlField, Gt as SetDatePatch, H as FieldValue, Hn as TableRowResponseSchema, Ht as SessionTurnStats, I as FieldKindSchema, In as TableColumnSchema, It as SessionFinal, J as HarnessConfig, Jn as UrlListFieldSchema, Jt as SetMultiSelectPatchSchema, K as FormSchemaSchema, Kn as UrlFieldSchema, Kt as SetDatePatchSchema, L as FieldProgress, Ln as TableField, Lt as SessionFinalSchema, M as FieldBase, Mn as StringValueSchema, Mt as ProgressSummary, N as FieldGroup, Nn as StructureSummary, Nt as ProgressSummarySchema, O as DocumentationTagSchema, On as StringListFieldSchema, Ot as ProgressCounts, P as FieldGroupSchema, Pn as StructureSummarySchema, Pt as QualifiedColumnRef, Q as IdSchema, Qn as UrlValueSchema, Qt as SetSingleSelectPatchSchema, R as FieldProgressSchema, Rn as TableFieldSchema, Rt as SessionTranscript, S as DateFieldSchema, Sn as SourceRangeSchema, St as OptionId, T as DocumentationBlock, Tn as StringField, Tt as ParsedForm, U as FieldValueSchema, Un as TableValue, Ut as SetCheckboxesPatch, V as FieldSchema, Vn as TableRowResponse, Vt as SessionTurnSchema, W as FillMode, Wn as TableValueSchema, Wt as SetCheckboxesPatchSchema, X as Id, Xn as UrlListValueSchema, Xt as SetNumberPatchSchema, Y as HarnessConfigSchema, Yn as UrlListValue, Yt as SetNumberPatch, Z as IdIndexEntry, Zn as UrlValue, Zt as SetSingleSelectPatch, _ as ClearFieldPatch, _n as SingleSelectValue, _t as NumberField, a as CellResponse, an as SetUrlListPatch, ar as ValidatorRegistry, at as IssueScope, b as ColumnTypeNameSchema, bn as SourcePositionSchema, bt as NumberValueSchema, c as CheckboxModeSchema, cn as SetUrlPatchSchema, cr as YearValue, ct as MarkformFrontmatterSchema, d as CheckboxValue, dn as Severity, dt as MultiSelectField, en as SetStringListPatchSchema, er as ValidationIssueSchema, et as InspectIssueSchema, f as CheckboxValueSchema, fn as SeveritySchema, ft as MultiSelectFieldSchema, g as CheckboxesValueSchema, gn as SingleSelectFieldSchema, gt as Note, h as CheckboxesValue, hn as SingleSelectField, ht as NodeType, i as ApplyResultSchema, in as SetTablePatchSchema, ir as ValidatorRefSchema, it as IssueReasonSchema, j as Field, jn as StringValue, jt as ProgressStateSchema, k as ExplicitCheckboxValue, kn as StringListValue, kt as ProgressCountsSchema, l as CheckboxProgressCounts, ln as SetYearPatch, lr as YearValueSchema, lt as MultiCheckboxState, m as CheckboxesFieldSchema, mn as SimpleCheckboxStateSchema, mt as MultiSelectValueSchema, n as AnswerStateSchema, nn as SetStringPatchSchema, nr as ValidatorFn, nt as InspectResultSchema, o as CellResponseSchema, on as SetUrlListPatchSchema, or as YearField, ot as IssueScopeSchema, p as CheckboxesField, pn as SimpleCheckboxState, pt as MultiSelectValue, q as FrontmatterHarnessConfig, qn as UrlListField, qt as SetMultiSelectPatch, r as ApplyResult, rn as SetTablePatch, rr as ValidatorRef, rt as IssueReason, s as CheckboxMode, sn as SetUrlPatch, sr as YearFieldSchema, st as MarkformFrontmatter, t as AnswerState, tn as SetStringPatch, tr as ValidatorContext, tt as InspectResult, u as CheckboxProgressCountsSchema, un as SetYearPatchSchema, ut as MultiCheckboxStateSchema, v as ClearFieldPatchSchema, vn as SingleSelectValueSchema, vt as NumberFieldSchema, w as DateValueSchema, wn as StepResultSchema, wt as OptionSchema, x as DateField, xn as SourceRange, xt as Option, y as ColumnTypeName, yn as SourcePosition, yt as NumberValue, z as FieldResponse, zn as TableRowPatch, zt as SessionTranscriptSchema } from "./coreTypes-cbNTYAcb.mjs";
3
+ import { $ as InspectIssue, $n as ValidationIssue, $t as SetStringListPatch, A as ExplicitCheckboxValueSchema, An as StringListValueSchema, At as ProgressState, B as FieldResponseSchema, Bn as TableRowPatchSchema, Bt as SessionTurn, C as DateValue, Cn as StepResult, Ct as OptionIdSchema, D as DocumentationTag, Dn as StringListField, Dt as PatchSchema, E as DocumentationBlockSchema, En as StringFieldSchema, Et as Patch, F as FieldKind, Fn as TableColumn, Ft as QualifiedOptionRef, G as FormSchema, Gn as UrlField, Gt as SetDatePatch, H as FieldValue, Hn as TableRowResponseSchema, Ht as SessionTurnStats, I as FieldKindSchema, In as TableColumnSchema, It as SessionFinal, J as HarnessConfig, Jn as UrlListFieldSchema, Jt as SetMultiSelectPatchSchema, K as FormSchemaSchema, Kn as UrlFieldSchema, Kt as SetDatePatchSchema, L as FieldProgress, Ln as TableField, Lt as SessionFinalSchema, M as FieldBase, Mn as StringValueSchema, Mt as ProgressSummary, N as FieldGroup, Nn as StructureSummary, Nt as ProgressSummarySchema, O as DocumentationTagSchema, On as StringListFieldSchema, Ot as ProgressCounts, P as FieldGroupSchema, Pn as StructureSummarySchema, Pt as QualifiedColumnRef, Q as IdSchema, Qn as UrlValueSchema, Qt as SetSingleSelectPatchSchema, R as FieldProgressSchema, Rn as TableFieldSchema, Rt as SessionTranscript, S as DateFieldSchema, Sn as SourceRangeSchema, St as OptionId, T as DocumentationBlock, Tn as StringField, Tt as ParsedForm, U as FieldValueSchema, Un as TableValue, Ut as SetCheckboxesPatch, V as FieldSchema, Vn as TableRowResponse, Vt as SessionTurnSchema, W as FillMode, Wn as TableValueSchema, Wt as SetCheckboxesPatchSchema, X as Id, Xn as UrlListValueSchema, Xt as SetNumberPatchSchema, Y as HarnessConfigSchema, Yn as UrlListValue, Yt as SetNumberPatch, Z as IdIndexEntry, Zn as UrlValue, Zt as SetSingleSelectPatch, _ as ClearFieldPatch, _n as SingleSelectValue, _t as NumberField, a as CellResponse, an as SetUrlListPatch, ar as ValidatorRegistry, at as IssueScope, b as ColumnTypeNameSchema, bn as SourcePositionSchema, bt as NumberValueSchema, c as CheckboxModeSchema, cn as SetUrlPatchSchema, cr as YearValue, ct as MarkformFrontmatterSchema, d as CheckboxValue, dn as Severity, dt as MultiSelectField, en as SetStringListPatchSchema, er as ValidationIssueSchema, et as InspectIssueSchema, f as CheckboxValueSchema, fn as SeveritySchema, ft as MultiSelectFieldSchema, g as CheckboxesValueSchema, gn as SingleSelectFieldSchema, gt as Note, h as CheckboxesValue, hn as SingleSelectField, ht as NodeType, i as ApplyResultSchema, in as SetTablePatchSchema, ir as ValidatorRefSchema, it as IssueReasonSchema, j as Field, jn as StringValue, jt as ProgressStateSchema, k as ExplicitCheckboxValue, kn as StringListValue, kt as ProgressCountsSchema, l as CheckboxProgressCounts, ln as SetYearPatch, lr as YearValueSchema, lt as MultiCheckboxState, m as CheckboxesFieldSchema, mn as SimpleCheckboxStateSchema, mt as MultiSelectValueSchema, n as AnswerStateSchema, nn as SetStringPatchSchema, nr as ValidatorFn, nt as InspectResultSchema, o as CellResponseSchema, on as SetUrlListPatchSchema, or as YearField, ot as IssueScopeSchema, p as CheckboxesField, pn as SimpleCheckboxState, pt as MultiSelectValue, q as FrontmatterHarnessConfig, qn as UrlListField, qt as SetMultiSelectPatch, r as ApplyResult, rn as SetTablePatch, rr as ValidatorRef, rt as IssueReason, s as CheckboxMode, sn as SetUrlPatch, sr as YearFieldSchema, st as MarkformFrontmatter, t as AnswerState, tn as SetStringPatch, tr as ValidatorContext, tt as InspectResult, u as CheckboxProgressCountsSchema, un as SetYearPatchSchema, ut as MultiCheckboxStateSchema, v as ClearFieldPatchSchema, vn as SingleSelectValueSchema, vt as NumberFieldSchema, w as DateValueSchema, wn as StepResultSchema, wt as OptionSchema, x as DateField, xn as SourceRange, xt as Option, y as ColumnTypeName, yn as SourcePosition, yt as NumberValue, z as FieldResponse, zn as TableRowPatch, zt as SessionTranscriptSchema } from "./coreTypes-9XZSNOv6.mjs";
4
4
  import "@markdoc/markdoc";
5
5
  import { LanguageModel, Tool } from "ai";
6
6
 
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { $ as SetUrlPatchSchema, A as MultiCheckboxStateSchema, B as ProgressSummarySchema, C as HarnessConfigSchema, Ct as ValidatorRefSchema, D as IssueReasonSchema, E as InspectResultSchema, F as OptionIdSchema, G as SetDatePatchSchema, H as SessionTranscriptSchema, I as OptionSchema, J as SetSingleSelectPatchSchema, K as SetMultiSelectPatchSchema, L as PatchSchema, M as MultiSelectValueSchema, N as NumberFieldSchema, O as IssueScopeSchema, P as NumberValueSchema, Q as SetUrlListPatchSchema, R as ProgressCountsSchema, S as FormSchemaSchema, St as ValidationIssueSchema, T as InspectIssueSchema, Tt as YearValueSchema, U as SessionTurnSchema, V as SessionFinalSchema, W as SetCheckboxesPatchSchema, X as SetStringPatchSchema, Y as SetStringListPatchSchema, Z as SetTablePatchSchema, _ as FieldKindSchema, _t as TableValueSchema, a as CheckboxProgressCountsSchema, at as SourcePositionSchema, b as FieldSchema, bt as UrlListValueSchema, c as CheckboxesValueSchema, ct as StringFieldSchema, d as DateFieldSchema, dt as StringValueSchema, et as SetYearPatchSchema, f as DateValueSchema, ft as StructureSummarySchema, g as FieldGroupSchema, gt as TableRowResponseSchema, h as ExplicitCheckboxValueSchema, ht as TableRowPatchSchema, i as CheckboxModeSchema, it as SingleSelectValueSchema, j as MultiSelectFieldSchema, k as MarkformFrontmatterSchema, l as ClearFieldPatchSchema, lt as StringListFieldSchema, m as DocumentationTagSchema, mt as TableFieldSchema, n as ApplyResultSchema, nt as SimpleCheckboxStateSchema, o as CheckboxValueSchema, ot as SourceRangeSchema, p as DocumentationBlockSchema, pt as TableColumnSchema, q as SetNumberPatchSchema, r as CellResponseSchema, rt as SingleSelectFieldSchema, s as CheckboxesFieldSchema, st as StepResultSchema, t as AnswerStateSchema, tt as SeveritySchema, u as ColumnTypeNameSchema, ut as StringListValueSchema, v as FieldProgressSchema, vt as UrlFieldSchema, w as IdSchema, wt as YearFieldSchema, x as FieldValueSchema, xt as UrlValueSchema, y as FieldResponseSchema, yt as UrlListFieldSchema, z as ProgressStateSchema } from "./coreTypes-pyctKRgc.mjs";
2
- import { a as computeAllSummaries, c as computeStructureSummary, i as validate, l as isFormComplete, o as computeFormState, r as inspect, s as computeProgressSummary, t as applyPatches, u as serialize } from "./apply-C54EMAJ1.mjs";
3
- import { C as serializeScopeRef, D as parseRawTable, E as parseMarkdownTable, O as ParseError, S as parseScopeRef, T as parseCellValue, _ as findFieldById, a as resolveHarnessConfig, b as isFieldRef, d as MockAgent, f as createMockAgent, g as coerceToFieldPatch, h as coerceInputContext, i as runResearch, m as createHarness, n as isResearchForm, o as fillForm, p as FormHarness, r as validateResearchForm, t as VERSION, v as getFieldId, w as parseForm, x as isQualifiedRef, y as isCellRef } from "./src-BNh7Cx9P.mjs";
2
+ import { a as computeAllSummaries, c as computeStructureSummary, i as validate, l as isFormComplete, o as computeFormState, r as inspect, s as computeProgressSummary, t as applyPatches, u as serialize } from "./apply-BCCiJzQr.mjs";
3
+ import { C as serializeScopeRef, D as parseRawTable, E as parseMarkdownTable, O as ParseError, S as parseScopeRef, T as parseCellValue, _ as findFieldById, a as resolveHarnessConfig, b as isFieldRef, d as MockAgent, f as createMockAgent, g as coerceToFieldPatch, h as coerceInputContext, i as runResearch, m as createHarness, n as isResearchForm, o as fillForm, p as FormHarness, r as validateResearchForm, t as VERSION, v as getFieldId, w as parseForm, x as isQualifiedRef, y as isCellRef } from "./src-Df0XX7UB.mjs";
4
4
  import { n as serializeSession, t as parseSession } from "./session-uF0e6m6k.mjs";
5
5
 
6
6
  export { AnswerStateSchema, ApplyResultSchema, CellResponseSchema, CheckboxModeSchema, CheckboxProgressCountsSchema, CheckboxValueSchema, CheckboxesFieldSchema, CheckboxesValueSchema, ClearFieldPatchSchema, ColumnTypeNameSchema, DateFieldSchema, DateValueSchema, DocumentationBlockSchema, DocumentationTagSchema, ExplicitCheckboxValueSchema, FieldGroupSchema, FieldKindSchema, FieldProgressSchema, FieldResponseSchema, FieldSchema, FieldValueSchema, FormHarness, FormSchemaSchema, HarnessConfigSchema, IdSchema, InspectIssueSchema, InspectResultSchema, IssueReasonSchema, IssueScopeSchema, MarkformFrontmatterSchema, MockAgent, MultiCheckboxStateSchema, MultiSelectFieldSchema, MultiSelectValueSchema, NumberFieldSchema, NumberValueSchema, OptionIdSchema, OptionSchema, ParseError, PatchSchema, ProgressCountsSchema, ProgressStateSchema, ProgressSummarySchema, SessionFinalSchema, SessionTranscriptSchema, SessionTurnSchema, SetCheckboxesPatchSchema, SetDatePatchSchema, SetMultiSelectPatchSchema, SetNumberPatchSchema, SetSingleSelectPatchSchema, SetStringListPatchSchema, SetStringPatchSchema, SetTablePatchSchema, SetUrlListPatchSchema, SetUrlPatchSchema, SetYearPatchSchema, SeveritySchema, SimpleCheckboxStateSchema, SingleSelectFieldSchema, SingleSelectValueSchema, SourcePositionSchema, SourceRangeSchema, StepResultSchema, StringFieldSchema, StringListFieldSchema, StringListValueSchema, StringValueSchema, StructureSummarySchema, TableColumnSchema, TableFieldSchema, TableRowPatchSchema, TableRowResponseSchema, TableValueSchema, UrlFieldSchema, UrlListFieldSchema, UrlListValueSchema, UrlValueSchema, VERSION, ValidationIssueSchema, ValidatorRefSchema, YearFieldSchema, YearValueSchema, applyPatches, coerceInputContext, coerceToFieldPatch, computeAllSummaries, computeFormState, computeProgressSummary, computeStructureSummary, createHarness, createMockAgent, fillForm, findFieldById, getFieldId, inspect, isCellRef, isFieldRef, isFormComplete, isQualifiedRef, isResearchForm, parseCellValue, parseForm, parseMarkdownTable, parseRawTable, parseScopeRef, parseSession, resolveHarnessConfig, runResearch, serialize, serializeScopeRef, serializeSession, validate, validateResearchForm };
@@ -1,5 +1,5 @@
1
1
  import { L as PatchSchema } from "./coreTypes-pyctKRgc.mjs";
2
- import { C as DEFAULT_ROLE_INSTRUCTIONS, P as getWebSearchConfig, S as DEFAULT_ROLES, _ as DEFAULT_MAX_TURNS, b as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, g as DEFAULT_MAX_PATCHES_PER_TURN, h as DEFAULT_MAX_ISSUES_PER_TURN, n as getFieldsForRoles, p as AGENT_ROLE, r as inspect, t as applyPatches, u as serialize, x as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN, y as DEFAULT_PRIORITY } from "./apply-C54EMAJ1.mjs";
2
+ import { C as DEFAULT_ROLE_INSTRUCTIONS, P as getWebSearchConfig, S as DEFAULT_ROLES, _ as DEFAULT_MAX_TURNS, b as DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN, g as DEFAULT_MAX_PATCHES_PER_TURN, h as DEFAULT_MAX_ISSUES_PER_TURN, n as getFieldsForRoles, p as AGENT_ROLE, r as inspect, t as applyPatches, u as serialize, x as DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN, y as DEFAULT_PRIORITY } from "./apply-BCCiJzQr.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { z } from "zod";
5
5
  import Markdoc from "@markdoc/markdoc";
@@ -1169,6 +1169,18 @@ function parseField(node) {
1169
1169
  *
1170
1170
  * Parses Markdoc documents and extracts form schema, values, and documentation blocks.
1171
1171
  */
1172
+ /**
1173
+ * Valid tag names inside a form.
1174
+ * Any other tag will produce a ParseError.
1175
+ */
1176
+ const VALID_FORM_TAGS = new Set([
1177
+ "group",
1178
+ "field",
1179
+ "note",
1180
+ "description",
1181
+ "instructions",
1182
+ "documentation"
1183
+ ]);
1172
1184
  const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
1173
1185
  /**
1174
1186
  * Parse harness configuration from frontmatter.
@@ -1227,14 +1239,14 @@ function extractFrontmatter(content) {
1227
1239
  }
1228
1240
  }
1229
1241
  /**
1230
- * Parse a field-group tag.
1242
+ * Parse a group tag.
1231
1243
  */
1232
1244
  function parseFieldGroup(node, responsesByFieldId, orderIndex, idIndex, parentId) {
1233
1245
  const id = getStringAttr(node, "id");
1234
1246
  const title = getStringAttr(node, "title");
1235
- if (!id) throw new ParseError("field-group missing required 'id' attribute");
1247
+ if (!id) throw new ParseError("group missing required 'id' attribute");
1236
1248
  if (idIndex.has(id)) throw new ParseError(`Duplicate ID '${id}'`);
1237
- if (getStringAttr(node, "state") !== void 0) throw new ParseError(`Field-group '${id}' has state attribute. state attribute is not allowed on field-groups.`);
1249
+ if (getStringAttr(node, "state") !== void 0) throw new ParseError(`Field-group '${id}' has state attribute. state attribute is not allowed on groups.`);
1238
1250
  idIndex.set(id, {
1239
1251
  nodeType: "group",
1240
1252
  parentId
@@ -1275,7 +1287,7 @@ function parseFieldGroup(node, responsesByFieldId, orderIndex, idIndex, parentId
1275
1287
  }
1276
1288
  /**
1277
1289
  * Parse a form tag.
1278
- * Handles both explicit field-groups and fields placed directly under the form.
1290
+ * Handles both explicit groups and fields placed directly under the form.
1279
1291
  */
1280
1292
  function parseFormTag(node, responsesByFieldId, orderIndex, idIndex) {
1281
1293
  const id = getStringAttr(node, "id");
@@ -1287,7 +1299,8 @@ function parseFormTag(node, responsesByFieldId, orderIndex, idIndex) {
1287
1299
  const ungroupedFields = [];
1288
1300
  function processContent(child) {
1289
1301
  if (!child || typeof child !== "object") return;
1290
- if (isTagNode(child, "field-group")) {
1302
+ if (isTagNode(child) && !VALID_FORM_TAGS.has(child.tag)) throw new ParseError(`Unknown tag '${child.tag}' inside form`);
1303
+ if (isTagNode(child, "group")) {
1291
1304
  const group = parseFieldGroup(child, responsesByFieldId, orderIndex, idIndex, id);
1292
1305
  groups.push(group);
1293
1306
  return;
@@ -39,11 +39,11 @@ markform:
39
39
 
40
40
  {% form id="form_id" title="Form Title" %}
41
41
 
42
- {% field-group id="group_id" title="Group Title" %}
42
+ {% group id="group_id" title="Group Title" %}
43
43
 
44
44
  <!-- fields go here -->
45
45
 
46
- {% /field-group %}
46
+ {% /group %}
47
47
 
48
48
  {% /form %}
49
49
  ```
@@ -399,7 +399,7 @@ A focused research form for gathering ratings and key statistics for any film.
399
399
  Pulls from IMDB, Rotten Tomatoes, and Metacritic.
400
400
  {% /description %}
401
401
 
402
- {% field-group id="movie_input" title="Movie Identification" %}
402
+ {% group id="movie_input" title="Movie Identification" %}
403
403
 
404
404
  {% field kind="string" id="movie" label="Movie" role="user" required=true minLength=1 maxLength=300 %}{% /field %}
405
405
 
@@ -407,9 +407,9 @@ Pulls from IMDB, Rotten Tomatoes, and Metacritic.
407
407
  Enter the movie title (add any details to help identify, like "Barbie 2023" or "the Batman movie with Robert Pattinson")
408
408
  {% /instructions %}
409
409
 
410
- {% /field-group %}
410
+ {% /group %}
411
411
 
412
- {% field-group id="title_identification" title="Title Identification" %}
412
+ {% group id="title_identification" title="Title Identification" %}
413
413
 
414
414
  {% field kind="string" id="full_title" label="Full Title" role="agent" required=true %}{% /field %}
415
415
 
@@ -417,9 +417,9 @@ Enter the movie title (add any details to help identify, like "Barbie 2023" or "
417
417
  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").
418
418
  {% /instructions %}
419
419
 
420
- {% /field-group %}
420
+ {% /group %}
421
421
 
422
- {% field-group id="sources" title="Sources" %}
422
+ {% group id="sources" title="Sources" %}
423
423
 
424
424
  {% field kind="url" id="imdb_url" label="IMDB URL" role="agent" required=true %}{% /field %}
425
425
 
@@ -439,9 +439,9 @@ Direct link to the movie's Rotten Tomatoes page.
439
439
  Direct link to the movie's Metacritic page.
440
440
  {% /instructions %}
441
441
 
442
- {% /field-group %}
442
+ {% /group %}
443
443
 
444
- {% field-group id="basic_details" title="Basic Details" %}
444
+ {% group id="basic_details" title="Basic Details" %}
445
445
 
446
446
  {% field kind="number" id="year" label="Release Year" role="agent" required=true min=1888 max=2030 %}{% /field %}
447
447
 
@@ -462,9 +462,9 @@ One director per line. Most films have one; some have two or more co-directors.
462
462
  - [ ] NR/Unrated {% #nr %}
463
463
  {% /field %}
464
464
 
465
- {% /field-group %}
465
+ {% /group %}
466
466
 
467
- {% field-group id="imdb_ratings" title="IMDB Ratings" %}
467
+ {% group id="imdb_ratings" title="IMDB Ratings" %}
468
468
 
469
469
  {% field kind="number" id="imdb_rating" label="IMDB Rating" role="agent" min=1.0 max=10.0 %}{% /field %}
470
470
 
@@ -478,9 +478,9 @@ IMDB user rating (1.0-10.0 scale).
478
478
  Number of IMDB user votes (e.g., 2800000 for a popular film).
479
479
  {% /instructions %}
480
480
 
481
- {% /field-group %}
481
+ {% /group %}
482
482
 
483
- {% field-group id="rotten_tomatoes_ratings" title="Rotten Tomatoes Ratings" %}
483
+ {% group id="rotten_tomatoes_ratings" title="Rotten Tomatoes Ratings" %}
484
484
 
485
485
  {% field kind="number" id="rt_critics_score" label="Tomatometer (Critics)" role="agent" min=0 max=100 %}{% /field %}
486
486
 
@@ -496,9 +496,9 @@ Tomatometer percentage (0-100).
496
496
  Audience Score percentage (0-100).
497
497
  {% /instructions %}
498
498
 
499
- {% /field-group %}
499
+ {% /group %}
500
500
 
501
- {% field-group id="metacritic_ratings" title="Metacritic Ratings" %}
501
+ {% group id="metacritic_ratings" title="Metacritic Ratings" %}
502
502
 
503
503
  {% field kind="number" id="metacritic_score" label="Metacritic Score" role="agent" min=0 max=100 %}{% /field %}
504
504
 
@@ -506,9 +506,9 @@ Audience Score percentage (0-100).
506
506
  Metascore (0-100 scale). Leave empty if not available.
507
507
  {% /instructions %}
508
508
 
509
- {% /field-group %}
509
+ {% /group %}
510
510
 
511
- {% field-group id="summary" title="Summary" %}
511
+ {% group id="summary" title="Summary" %}
512
512
 
513
513
  {% field kind="string" id="logline" label="One-Line Summary" role="agent" maxLength=300 %}{% /field %}
514
514
 
@@ -524,7 +524,7 @@ Format: Award | Category | Year
524
524
  Example: "Oscar | Best Picture | 1995"
525
525
  {% /instructions %}
526
526
 
527
- {% /field-group %}
527
+ {% /group %}
528
528
 
529
529
  {% /form %}
530
530
  ```
@@ -595,7 +595,7 @@ markform fill template.form.md --mock --mock-source filled.form.md
595
595
 
596
596
  3. **Set constraints**: Use `min`, `max`, `minLength`, `pattern` to validate
597
597
 
598
- 4. **Group logically**: Related fields in the same `field-group`
598
+ 4. **Group logically**: Related fields in the same `group`
599
599
 
600
600
  5. **Assign roles**: Separate user input from agent research
601
601