markform 0.1.24 → 0.1.25

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 (44) hide show
  1. package/README.md +54 -31
  2. package/dist/ai-sdk.d.mts +1 -1
  3. package/dist/ai-sdk.mjs +2 -2
  4. package/dist/bin.mjs +1 -1
  5. package/dist/{cli-B1DhFYBS.mjs → cli-B1T8kMFt.mjs} +85 -40
  6. package/dist/cli-B1T8kMFt.mjs.map +1 -0
  7. package/dist/cli.mjs +1 -1
  8. package/dist/{coreTypes-GxzWNXap.d.mts → coreTypes-CxpqKpBA.d.mts} +45 -2
  9. package/dist/{coreTypes-CctFK6uE.mjs → coreTypes-DIv9Aabl.mjs} +19 -5
  10. package/dist/coreTypes-DIv9Aabl.mjs.map +1 -0
  11. package/dist/{fillRecord-DeqI2pQ5.d.mts → fillRecord-V3vlyobd.d.mts} +5 -1
  12. package/dist/{fillRecordRenderer-VBQ2vwPV.mjs → fillRecordRenderer-BqRPHPmE.mjs} +47 -15
  13. package/dist/fillRecordRenderer-BqRPHPmE.mjs.map +1 -0
  14. package/dist/index.d.mts +32 -4
  15. package/dist/index.mjs +4 -4
  16. package/dist/{prompts-BCnYaH4_.mjs → prompts-DaPKumGY.mjs} +114 -11
  17. package/dist/prompts-DaPKumGY.mjs.map +1 -0
  18. package/dist/render.d.mts +2 -2
  19. package/dist/render.mjs +1 -1
  20. package/dist/{session-BLjN3BkJ.mjs → session-BW9jtYNV.mjs} +2 -2
  21. package/dist/{session-BLjN3BkJ.mjs.map → session-BW9jtYNV.mjs.map} +1 -1
  22. package/dist/{session-D7C7IlEv.mjs → session-DHyTMP67.mjs} +1 -1
  23. package/dist/{shared-DtorFV21.mjs → shared-BLh342F5.mjs} +1 -1
  24. package/dist/{shared-CuSRYcIB.mjs → shared-BszoSkAO.mjs} +8 -8
  25. package/dist/{shared-CuSRYcIB.mjs.map → shared-BszoSkAO.mjs.map} +1 -1
  26. package/dist/{src-C5OWf1dL.mjs → src-DrXmaOWl.mjs} +155 -27
  27. package/dist/src-DrXmaOWl.mjs.map +1 -0
  28. package/docs/markform-apis.md +19 -7
  29. package/docs/markform-reference.md +247 -178
  30. package/docs/markform-spec.md +81 -33
  31. package/docs/skill/SKILL.md +62 -20
  32. package/examples/markform-demo-playbook.md +342 -0
  33. package/examples/parallel/parallel-research.form.md +2 -6
  34. package/examples/simple/simple-mock-filled.report.md +2 -2
  35. package/examples/simple/simple-skipped-filled.report.md +2 -2
  36. package/examples/twitter-thread/twitter-thread.form.md +5 -5
  37. package/package.json +1 -1
  38. package/dist/cli-B1DhFYBS.mjs.map +0 -1
  39. package/dist/coreTypes-CctFK6uE.mjs.map +0 -1
  40. package/dist/fillRecordRenderer-VBQ2vwPV.mjs.map +0 -1
  41. package/dist/prompts-BCnYaH4_.mjs.map +0 -1
  42. package/dist/src-C5OWf1dL.mjs.map +0 -1
  43. package/examples/startup-research/startup-research-mock-filled.form.md +0 -297
  44. package/examples/startup-research/startup-research.form.md +0 -181
@@ -0,0 +1,342 @@
1
+ # Markform End-to-End Example: S&P 500 Company Research
2
+
3
+ ## About This Playbook
4
+
5
+ ### Purpose
6
+
7
+ This playbook walks an agent through a complete Markform workflow to demonstrate its
8
+ features: from a research idea to a validated, filled, exported structured report with
9
+ typed JSON/YAML data and a JSON Schema.
10
+
11
+ ### Playbook Format
12
+
13
+ **If you’re a human:** You can read this to get a sense for how you and agents can use
14
+ Markform.
15
+
16
+ **If you’re an agent:** Follow this playbook step by step.
17
+
18
+ This playbook works in two ways:
19
+
20
+ 1. **Agent instructions:** Steps an agent can follow start to finish.
21
+ 2. **User narration:** “Tell the user” blocks keep the user informed at each phase.
22
+
23
+ Notes:
24
+ - An agent must have access to use `markform` as a CLI.
25
+ - Commands give output and/or errors.
26
+ For example, every `markform set` command should output `Form updated: <path>`.
27
+ - An agent or the user can review the result.
28
+
29
+ ### Playbook Scope
30
+
31
+ **Scenario:** Research an S&P 500 company (default: Apple Inc.). The user provides a
32
+ company name; the agent designs a form from scratch, fills it with researched data,
33
+ validates, and exports.
34
+
35
+ This playbook has the agent *manually* fill each field the granular `next` → `set` loop,
36
+ researching data along the way.
37
+ This exercises all CLI operations and `set` capabilities.
38
+
39
+ Markform also supports fully automated filling via `markform fill`, where an LLM drives
40
+ the `next` → `set` loop autonomously.
41
+ That’s out of scope here — this playbook is about the agent researching and filling each
42
+ field itself. Run `markform examples` to see automated filling in action.
43
+
44
+ ## Phase 0: Prerequisites
45
+
46
+ Before proceeding, confirm you have what’s needed:
47
+
48
+ 1. **Shell access** to run `npm` and `markform` CLI commands
49
+ 2. **Web search** or other research tools to look up company data
50
+ 3. **File read/write** access to create and edit form files in `/tmp/markform-qa/`
51
+
52
+ If anything is missing, tell the user what’s needed before continuing.
53
+
54
+ ### Choose the Company
55
+
56
+ If the user has already specified a company, skip to Phase 1.
57
+
58
+ Otherwise:
59
+
60
+ > **Tell the user:** "I have a playbook that walks through Markform, a CLI for
61
+ > structured, validated forms.
62
+ > I’ll design a research form for an S&P 500 company, fill it with real data, validate
63
+ > it, and export the results.
64
+ >
65
+ > Is there a company you’d like me to research?
66
+ > If you aren’t sure, I’ll just pick Apple (AAPL) as an example."
67
+
68
+ Wait for the user’s response.
69
+ Use their chosen company (default: Apple Inc.).
70
+
71
+ ## Phase 1: Install Markform
72
+
73
+ > **Tell the user:** “I’ll install (or update) Markform: a CLI for structured, validated
74
+ > forms that agents fill via tool calls.”
75
+
76
+ ```bash
77
+ npm install -g markform@latest
78
+ markform --version
79
+ ```
80
+
81
+ > **Tell the user:** “Markform [version] is installed.”
82
+
83
+ ## Phase 2: Define the Research Scope
84
+
85
+ > **Tell the user:** “We’ll build a structured research form for an S&P 500 company.
86
+ > Unlike free-form notes, a form ensures revenue is a number, the ticker matches a
87
+ > pattern, segments are a typed table, and URLs are validated: all enforced
88
+ > automatically. Let me outline what to capture.”
89
+
90
+ Draft a plain markdown outline of research questions covering at least these areas:
91
+
92
+ 1. **Identification:** Company name, ticker, GICS sector, headquarters, founding year,
93
+ website
94
+ 2. **Financials:** Fiscal year, revenue, net income, market cap, employee count
95
+ 3. **Business segments:** Revenue breakdown by segment with percentages
96
+ 4. **Leadership:** Key executives with name, title, year appointed
97
+ 5. **Competitive position:** Competitors, competitive moats, market position summary
98
+ 6. **Sources & verification:** Source URLs, research date, verification checklist, notes
99
+ 7. **Source provenance:** A comprehensive table of all sources consulted during
100
+ research, with four columns: source name, what information it was used for, notes on
101
+ source quality or reliability, and URL. This turns the form into a verifiable audit
102
+ trail — every fact is traceable back to its origin.
103
+
104
+ Save as `/tmp/markform-qa/research-outline.md`.
105
+
106
+ > **Tell the user:** "I’ve saved the research outline to
107
+ > `/tmp/markform-qa/research-outline.md`. Next I’ll convert it into a Markform: a
108
+ > structured form with typed, validated fields."
109
+
110
+ ## Phase 3: Build the Markform
111
+
112
+ ### Step 3.1: Learn the Syntax
113
+
114
+ > **Tell the user:** “I’ll read the Markform reference to learn how to turn this outline
115
+ > into a validated form.”
116
+
117
+ ```bash
118
+ markform docs
119
+ ```
120
+
121
+ Read the full output.
122
+ It covers file structure, all 11 field kinds, validation rules, CLI commands, and
123
+ includes a complete example form.
124
+
125
+ ### Step 3.2: Study an Example
126
+
127
+ ```bash
128
+ markform examples --name simple --forms-dir /tmp/markform-qa/ref
129
+ ```
130
+
131
+ Read the example form to see how field kinds, groups, and validation look in practice.
132
+
133
+ > **Tip:** Run `markform examples --list` to see all bundled examples.
134
+ > You can copy any example with `markform examples --name <id>` for additional
135
+ > reference.
136
+
137
+ ### Step 3.3: Convert to Markform
138
+
139
+ > **Tell the user:** “I’ll convert the outline into a Markform using the field kinds and
140
+ > validation rules described in the docs.”
141
+
142
+ Convert the research outline into `/tmp/markform-qa/sp500-research.form.md`. Use the
143
+ “Form Design Guide” and “Best Practices” sections from `markform docs` as reference for
144
+ choosing field kinds, adding validation, and structuring the form.
145
+
146
+ The last field in the form should be a source provenance table — a comprehensive list of
147
+ sources with four columns: source name, information used, notes on quality, and URL. Use
148
+ a `url`-typed column for the URL so it gets validated.
149
+ This table is `required` — no research report is complete without attribution.
150
+
151
+ ### Step 3.4: Validate and Fix
152
+
153
+ > **Tell the user:** “I’ll validate the form structure and fix any issues.”
154
+
155
+ ```bash
156
+ markform validate /tmp/markform-qa/sp500-research.form.md
157
+ ```
158
+
159
+ If issues appear beyond `required_missing` (expected: the form is empty), fix the
160
+ `.form.md` and re-validate.
161
+ Repeat until clean.
162
+
163
+ ```bash
164
+ markform inspect /tmp/markform-qa/sp500-research.form.md
165
+ ```
166
+
167
+ > **Tell the user:** “Form structure is valid: [N] fields across [N] groups, ready to
168
+ > fill.”
169
+
170
+ ## Phase 4: Fill the Form
171
+
172
+ The core workflow: run `next` to see what to fill, use `set` to fill it, repeat.
173
+
174
+ ### Step 4.1: Set the User Input
175
+
176
+ > **Tell the user:** "The company name field has `role='user'`: it’s the one
177
+ > human-provided input.
178
+ > I’ll set it to start the research."
179
+
180
+ ```bash
181
+ markform set /tmp/markform-qa/sp500-research.form.md <company_name_id> "Apple Inc."
182
+ markform status /tmp/markform-qa/sp500-research.form.md
183
+ ```
184
+
185
+ ### Step 4.2: The next → set Loop
186
+
187
+ > **Tell the user:** "`next` is the field advisor: it prioritizes what to fill and shows
188
+ > `set` examples. I’ll follow its advice, research the data, and repeat."
189
+
190
+ ```bash
191
+ markform next /tmp/markform-qa/sp500-research.form.md
192
+ ```
193
+
194
+ Research accurate data and fill fields using `set`. Continue the `next` → `set` loop
195
+ until the form is complete.
196
+
197
+ As you fill each group of fields, also populate the source provenance table: append a
198
+ row for each source you consulted, recording what information it provided and its URL.
199
+ This ensures every fact in the form is traceable.
200
+
201
+ **Use each of these operations at least once during filling to show the full range of
202
+ `set` capabilities:**
203
+
204
+ | Operation | Example |
205
+ | --- | --- |
206
+ | Single set | `markform set <file> <id> "value"` |
207
+ | Batch set | `markform set <file> --values '{"a": 1, "b": "text"}'` |
208
+ | Table append | `markform set <file> <tableId> --append '{"col": "val"}'` |
209
+ | Table batch set | `markform set <file> <tableId> '[{...}, {...}]'` |
210
+ | Table delete + re-append | `--delete <index>` then `--append` replacement |
211
+ | Validation error | Set an invalid value (e.g., lowercase ticker): verify it's stored but flagged invalid |
212
+ | String list | `markform set <file> <id> '["a", "b", "c"]'` |
213
+ | Multi-select | `markform set <file> <id> '["opt1", "opt2"]'` |
214
+ | Explicit checkboxes | `markform set <file> <id> '{"item1": "yes", "item2": "no"}'` |
215
+ | Skip optional field | `markform set <file> <id> --skip --reason "..."` |
216
+
217
+ > **Tell the user:** After the validation error: "`set` stores the value but `validate`
218
+ > flags it as invalid.
219
+ > Some constraints (like pattern matching) are checked eagerly by `validate`; semantic
220
+ > issues may surface later.
221
+ > Fix the value and confirm with `validate`."
222
+
223
+ ### Step 4.3: Confirm Completion
224
+
225
+ ```bash
226
+ markform next /tmp/markform-qa/sp500-research.form.md
227
+ ```
228
+
229
+ **Checkpoint:** Should report form complete, 0 required fields remaining.
230
+
231
+ ## Phase 5: Validate and Export
232
+
233
+ > **Tell the user:** “Form is complete.
234
+ > Let me validate and export.”
235
+
236
+ ```bash
237
+ markform validate /tmp/markform-qa/sp500-research.form.md
238
+ ```
239
+
240
+ **Checkpoint:** Form State `complete`, `invalid=0`, no issues.
241
+
242
+ ```bash
243
+ markform dump /tmp/markform-qa/sp500-research.form.md
244
+ markform export /tmp/markform-qa/sp500-research.form.md --format=markdown
245
+ markform report /tmp/markform-qa/sp500-research.form.md
246
+ markform export /tmp/markform-qa/sp500-research.form.md --format=json
247
+ markform export /tmp/markform-qa/sp500-research.form.md --format=yaml
248
+ markform schema /tmp/markform-qa/sp500-research.form.md --pure
249
+ ```
250
+
251
+ > **Tell the user:** "Exported as:
252
+ > - **Markdown (export):** full rendered form including field instructions — useful as a
253
+ > standalone document or for review
254
+ > - **Markdown (report):** clean results only, no instructions — useful as a deliverable
255
+ > - **JSON/YAML:** typed structured data for databases or APIs
256
+ > - **JSON Schema:** form structure for code generation or external validation
257
+ >
258
+ > Every fact in the report is traceable: the source provenance table records where each
259
+ > piece of information came from, with validated URLs.
260
+ > The form doesn’t just add structure — it adds reliability."
261
+
262
+ ## Phase 6: Advanced Operations
263
+
264
+ ### Step 6.1: Clear and Re-fill
265
+
266
+ > **Tell the user:** “Any field can be cleared and re-filled for corrections.”
267
+
268
+ Clear a number field, verify it shows as unanswered, then set a new value.
269
+
270
+ ### Step 6.2: List Append and Delete
271
+
272
+ > **Tell the user:** “Lists support incremental append and delete without replacing the
273
+ > whole list.”
274
+
275
+ Append a URL to the source list, then delete an entry by index.
276
+
277
+ ### Step 6.3: Set with --report
278
+
279
+ > **Tell the user:** "`--report` returns JSON with apply status, form state, progress,
280
+ > and remaining issues after each change."
281
+
282
+ ```bash
283
+ markform set /tmp/markform-qa/sp500-research.form.md <url_list_id> --append "https://example.com" --report --format json
284
+ ```
285
+
286
+ ### Step 6.4: Confirm Still Complete
287
+
288
+ ```bash
289
+ markform next /tmp/markform-qa/sp500-research.form.md
290
+ ```
291
+
292
+ **Expected:** Form is complete.
293
+
294
+ ## Phase 7: Review the Source
295
+
296
+ > **Tell the user:** "The filled `.form.md` is both human-readable and
297
+ > machine-parseable. On GitHub, comment tags are invisible: it looks like a clean
298
+ > document. But every value is typed, validated, and programmatically accessible."
299
+
300
+ ```bash
301
+ cat /tmp/markform-qa/sp500-research.form.md
302
+ ```
303
+
304
+ ## Phase 8: Present the Report
305
+
306
+ > **Tell the user:** “Here’s the completed research report.”
307
+
308
+ Generate the report and render it directly in the chat as formatted markdown:
309
+
310
+ ```bash
311
+ markform report /tmp/markform-qa/sp500-research.form.md
312
+ ```
313
+
314
+ Output the full markdown content to the chat window so the user sees a nicely formatted
315
+ report — headings, tables, lists — with instructions and internal markup stripped away.
316
+
317
+ Also export the structured data as YAML:
318
+
319
+ ```bash
320
+ markform export /tmp/markform-qa/sp500-research.form.md --format=yaml > /tmp/markform-qa/sp500-research.yml
321
+ ```
322
+
323
+ > **Tell the user:** "The structured data is also saved as YAML at
324
+ > `/tmp/markform-qa/sp500-research.yml` — ready to feed into databases, APIs, or other
325
+ > tools."
326
+
327
+ Then open the form in a web browser:
328
+
329
+ ```bash
330
+ markform serve /tmp/markform-qa/sp500-research.form.md
331
+ ```
332
+
333
+ > **Tell the user:** "I’ve also opened the report in your web browser.
334
+ > You can browse it in several tabs:
335
+ > - **Form:** the rendered form as it appears on GitHub
336
+ > - **Report:** a filtered view that strips instructions and internal markup
337
+ > - **Edit:** an interactive version where fields can be filled in the browser
338
+ > - **Source:** the raw `.form.md` with all Markform tags visible
339
+ > - **Values:** exported field values as YAML
340
+ > - **Schema:** the JSON Schema describing the form structure
341
+ >
342
+ > Each tab has a unique URL (hash route) so you can link directly to a specific view."
@@ -11,12 +11,11 @@ markform:
11
11
  role_instructions:
12
12
  agent: Research the company and fill in all fields.
13
13
  ---
14
-
15
14
  <!-- form id="company_research" title="Company Research (Parallel)" -->
16
15
 
17
16
  <!-- description ref="company_research" -->
18
- A company research form that uses for concurrent deep research
19
- and to sequence synthesis after data gathering.
17
+ A company research form that uses `parallel` for concurrent deep research and `order` to
18
+ sequence synthesis after data gathering.
20
19
  <!-- /description -->
21
20
 
22
21
  <!-- group id="overview" order=0 -->
@@ -56,6 +55,3 @@ and to sequence synthesis after data gathering.
56
55
  <!-- /group -->
57
56
 
58
57
  <!-- /form -->
59
-
60
-
61
-
@@ -58,8 +58,8 @@ Medium
58
58
 
59
59
  **Confirmations (Explicit Mode):**
60
60
 
61
- - [x] Data has been backed up
62
- - [ ] Stakeholders notified
61
+ - Data has been backed up: Yes
62
+ - Stakeholders notified: No
63
63
 
64
64
  ## URL Fields
65
65
 
@@ -57,8 +57,8 @@ High
57
57
 
58
58
  **Confirmations (Explicit Mode):**
59
59
 
60
- - [x] Data has been backed up
61
- - [ ] Stakeholders notified
60
+ - Data has been backed up: Yes
61
+ - Stakeholders notified: No
62
62
 
63
63
  ## URL Fields
64
64
 
@@ -154,7 +154,7 @@ Extract every insight, claim, or idea worth sharing.
154
154
  <!-- field kind="table" id="insights_table" label="Insights" role="agent" required=true
155
155
  columnIds=["insight", "why_matters", "type"]
156
156
  columnLabels=["Insight/Claim", "Why It Matters", "Type"]
157
- columnTypes=["string", "string", "string"]
157
+ columnTypes=["string", "string", {"type": "string", "enum": ["thesis", "supporting", "example", "context", "contrarian", "actionable"]}]
158
158
  minRows=5 maxRows=20 -->
159
159
 
160
160
  | Insight/Claim | Why It Matters | Type |
@@ -188,7 +188,7 @@ Not every insight makes the thread. Rank by impact and assign roles.
188
188
  <!-- field kind="table" id="priority_table" label="Ranked Insights" role="agent" required=true
189
189
  columnIds=["rank", "insight_summary", "role", "include"]
190
190
  columnLabels=["Rank", "Insight (summary)", "Thread Role", "Include?"]
191
- columnTypes=["number", "string", "string", "string"]
191
+ columnTypes=[{"type": "number", "min": 1, "integer": true}, "string", {"type": "string", "enum": ["hook", "context", "main_point", "example", "pivot", "summary", "cta"]}, {"type": "string", "enum": ["yes", "no"]}]
192
192
  minRows=5 maxRows=15 -->
193
193
 
194
194
  | Rank | Insight (summary) | Thread Role | Include? |
@@ -237,7 +237,7 @@ Map the prioritized insights into a tweet-by-tweet structure.
237
237
  <!-- field kind="table" id="structure_table" label="Thread Structure" role="agent" required=true
238
238
  columnIds=["tweet_num", "role", "content_plan", "source_insight"]
239
239
  columnLabels=["#", "Role", "Content Plan", "From Insight"]
240
- columnTypes=["number", "string", "string", "string"]
240
+ columnTypes=[{"type": "number", "min": 1, "integer": true}, {"type": "string", "enum": ["hook", "context", "main_point", "example", "pivot", "summary", "cta"]}, "string", "string"]
241
241
  minRows=5 maxRows=20 -->
242
242
 
243
243
  | # | Role | Content Plan | From Insight |
@@ -266,7 +266,7 @@ Write each tweet following the structure plan.
266
266
  <!-- field kind="table" id="drafts_table" label="Tweet Drafts" role="agent" required=true
267
267
  columnIds=["tweet_num", "draft_content", "char_count", "issues"]
268
268
  columnLabels=["#", "Draft Content", "Chars", "Issues"]
269
- columnTypes=["number", "string", "number", "string"]
269
+ columnTypes=[{"type": "number", "min": 1, "integer": true}, {"type": "string", "maxLength": 280}, {"type": "number", "min": 1, "max": 280, "integer": true}, "string"]
270
270
  minRows=5 maxRows=20 -->
271
271
 
272
272
  | # | Draft Content | Chars | Issues |
@@ -299,7 +299,7 @@ Verify each tweet against quality criteria.
299
299
  <!-- field kind="table" id="review_table" label="Tweet Review" role="agent" required=true
300
300
  columnIds=["tweet_num", "under_280", "clear", "flows", "standalone", "revision_needed"]
301
301
  columnLabels=["#", "≤280?", "Clear?", "Flows?", "Standalone?", "Revision"]
302
- columnTypes=["number", "string", "string", "string", "string", "string"]
302
+ columnTypes=[{"type": "number", "min": 1, "integer": true}, {"type": "string", "enum": ["yes", "no"]}, {"type": "string", "enum": ["yes", "no"]}, {"type": "string", "enum": ["yes", "no", "na"]}, {"type": "string", "enum": ["yes", "no"]}, "string"]
303
303
  minRows=5 maxRows=20 -->
304
304
 
305
305
  | # | ≤280? | Clear? | Flows? | Standalone? | Revision |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markform",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "description": "Markdown forms for token-friendly workflows",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "author": "Joshua Levy",