markform 0.1.13 → 0.1.15
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 +14 -5
- package/dist/ai-sdk.d.mts +3 -2
- package/dist/ai-sdk.mjs +4 -3
- package/dist/ai-sdk.mjs.map +1 -0
- package/dist/{apply-D5FLd9Yp.mjs → apply-D44qg6-W.mjs} +69 -8
- package/dist/apply-D44qg6-W.mjs.map +1 -0
- package/dist/bin.mjs +3 -2
- package/dist/bin.mjs.map +1 -0
- package/dist/{cli-BQO5bzfd.mjs → cli-CwSCme2s.mjs} +676 -122
- package/dist/cli-CwSCme2s.mjs.map +1 -0
- package/dist/cli.d.mts +2 -1
- package/dist/cli.mjs +1 -1
- package/dist/{coreTypes-2Duxp-Wo.d.mts → coreTypes-CnKsB1H3.d.mts} +6 -2
- package/dist/{coreTypes-Big8sgih.mjs → coreTypes-DiCddBKu.mjs} +4 -2
- package/dist/coreTypes-DiCddBKu.mjs.map +1 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +4 -4
- package/dist/{session-7QJlUeNg.mjs → session-B7aR6hno.mjs} +1 -1
- package/dist/{session-CrhOG4eH.mjs → session-XDrocA3j.mjs} +3 -2
- package/dist/session-XDrocA3j.mjs.map +1 -0
- package/dist/{shared-D3dNi-Gn.mjs → shared-CCq4haEV.mjs} +9 -1
- package/dist/shared-CCq4haEV.mjs.map +1 -0
- package/dist/shared-fUKfJ1UA.mjs +4 -0
- package/dist/{src-DuA3kv-E.mjs → src-By5auN7M.mjs} +123 -41
- package/dist/src-By5auN7M.mjs.map +1 -0
- package/docs/markform-reference.md +11 -0
- package/docs/markform-spec.md +11 -0
- package/examples/rejection-test/rejection-test.session.yaml +176 -72
- package/examples/simple/simple-mock-filled.report.md +9 -7
- package/examples/simple/simple-skipped-filled.report.md +6 -4
- package/examples/simple/simple-with-skips.session.yaml +286 -130
- package/examples/simple/simple.session.yaml +286 -130
- package/package.json +9 -3
- package/dist/shared-CNqwaxUt.mjs +0 -4
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Markform
|
|
2
2
|
|
|
3
|
-
[](https://github.com/jlevy/markform/actions/
|
|
4
|
-
](https://github.com/jlevy/markform/actions/runs/20873942679)
|
|
4
|
+
[](https://github.com/jlevy/markform/actions/runs/20873942679)
|
|
5
|
+
[](https://www.npmjs.com/package/markform)
|
|
6
|
+
[](https://x.com/ojoshe)
|
|
6
7
|
|
|
7
8
|
**Markform** is a text format for defining structured forms that humans can read,
|
|
8
9
|
machines can parse, and agents can fill via tool calls.
|
|
@@ -821,8 +822,16 @@ Or see [markdoc/language-server](https://github.com/markdoc/language-server).
|
|
|
821
822
|
|
|
822
823
|
## License
|
|
823
824
|
|
|
824
|
-
|
|
825
|
-
|
|
825
|
+
The **Markform Specification** ([`docs/markform-spec.md`](docs/markform-spec.md),
|
|
826
|
+
[`docs/markform-reference.md`](docs/markform-reference.md)) is licensed under
|
|
827
|
+
[CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/). You may freely implement this
|
|
828
|
+
specification in your own software under any license.
|
|
829
|
+
|
|
830
|
+
The **Reference Implementation** (all code in this repository) is licensed under
|
|
831
|
+
[AGPL-3.0-or-later](./LICENSE). [Contact me](https://github.com/jlevy) for commercial
|
|
832
|
+
licensing options.
|
|
833
|
+
|
|
834
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution terms.
|
|
826
835
|
|
|
827
836
|
[markdoc-overview]: https://markdoc.dev/docs/overview
|
|
828
837
|
[stripe-markdoc]: https://stripe.com/blog/markdoc
|
package/dist/ai-sdk.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { At as PatchSchema, Dt as ParsedForm, Ot as Patch, Q as Id, V as FieldResponse, dr as ValidatorRegistry, q as FormSchema, r as ApplyResult, rt as InspectResult } from "./coreTypes-
|
|
2
|
+
import { At as PatchSchema, Dt as ParsedForm, Ot as Patch, Q as Id, V as FieldResponse, dr as ValidatorRegistry, q as FormSchema, r as ApplyResult, rt as InspectResult } from "./coreTypes-CnKsB1H3.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
//#region src/integrations/toolTypes.d.ts
|
|
@@ -126,4 +126,5 @@ interface CreateMarkformToolsOptions {
|
|
|
126
126
|
*/
|
|
127
127
|
declare function createMarkformTools(options: CreateMarkformToolsOptions): MarkformToolSet;
|
|
128
128
|
//#endregion
|
|
129
|
-
export { type ApplyToolResult, CreateMarkformToolsOptions, type ExportToolResult, type GetMarkdownToolResult, type InspectToolResult, MarkformSessionStore, type MarkformTool, type MarkformToolSet, PatchSchema, createMarkformTools };
|
|
129
|
+
export { type ApplyToolResult, CreateMarkformToolsOptions, type ExportToolResult, type GetMarkdownToolResult, type InspectToolResult, MarkformSessionStore, type MarkformTool, type MarkformToolSet, PatchSchema, createMarkformTools };
|
|
130
|
+
//# sourceMappingURL=ai-sdk.d.mts.map
|
package/dist/ai-sdk.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { L as PatchSchema } from "./coreTypes-
|
|
3
|
-
import { d as serializeForm, i as inspect, t as applyPatches } from "./apply-
|
|
2
|
+
import { L as PatchSchema } from "./coreTypes-DiCddBKu.mjs";
|
|
3
|
+
import { d as serializeForm, i as inspect, t as applyPatches } from "./apply-D44qg6-W.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
//#region src/integrations/vercelAiSdkTools.ts
|
|
@@ -165,4 +165,5 @@ function createMarkformTools(options) {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
//#endregion
|
|
168
|
-
export { MarkformSessionStore, PatchSchema, createMarkformTools };
|
|
168
|
+
export { MarkformSessionStore, PatchSchema, createMarkformTools };
|
|
169
|
+
//# sourceMappingURL=ai-sdk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.mjs","names":["toolset: MarkformToolSet"],"sources":["../src/integrations/vercelAiSdkTools.ts"],"sourcesContent":["/**\n * AI SDK Integration for Markform.\n *\n * Provides Vercel AI SDK compatible tools for agent-driven form filling.\n * Use createMarkformTools() to create a toolset that wraps the Markform engine.\n *\n * @example\n * ```typescript\n * import { createMarkformTools, MarkformSessionStore } from 'markform/ai-sdk';\n * import { generateText } from 'ai';\n *\n * const store = new MarkformSessionStore(parsedForm);\n * const tools = createMarkformTools({ sessionStore: store });\n *\n * const { text } = await generateText({\n * model: openai('gpt-4'),\n * prompt: 'Fill out this form...',\n * tools,\n * });\n * ```\n */\n\nimport { z } from 'zod';\nimport type { ParsedForm, Patch, ValidatorRegistry } from '../engine/coreTypes.js';\nimport { inspect } from '../engine/inspect.js';\nimport { applyPatches } from '../engine/apply.js';\nimport { serializeForm } from '../engine/serialize.js';\nimport { PatchSchema } from '../engine/coreTypes.js';\n\n// =============================================================================\n// Session Store\n// =============================================================================\n\n/**\n * Session store for managing form state during AI interactions.\n *\n * The AI SDK tools operate on a shared form instance through this store.\n * Create one store per form-filling session.\n */\nexport class MarkformSessionStore {\n private form: ParsedForm;\n private validatorRegistry: ValidatorRegistry;\n\n constructor(form: ParsedForm, validatorRegistry?: ValidatorRegistry) {\n this.form = form;\n this.validatorRegistry = validatorRegistry ?? {};\n }\n\n /**\n * Get the current form.\n */\n getForm(): ParsedForm {\n return this.form;\n }\n\n /**\n * Get the validator registry.\n */\n getValidatorRegistry(): ValidatorRegistry {\n return this.validatorRegistry;\n }\n\n /**\n * Update the form values.\n */\n updateForm(form: ParsedForm): void {\n this.form = form;\n }\n}\n\n// =============================================================================\n// Tool Creation Options\n// =============================================================================\n\n/**\n * Options for creating Markform AI SDK tools.\n */\nexport interface CreateMarkformToolsOptions {\n /**\n * Session store managing the form state.\n */\n sessionStore: MarkformSessionStore;\n\n /**\n * Whether to include the markform_get_markdown tool.\n * Defaults to true.\n */\n includeGetMarkdown?: boolean;\n}\n\n// =============================================================================\n// Tool Types (imported from toolTypes.ts)\n// =============================================================================\n\nimport type {\n ApplyToolResult,\n ExportToolResult,\n GetMarkdownToolResult,\n InspectToolResult,\n MarkformTool,\n MarkformToolSet,\n} from './toolTypes.js';\n\n// Re-export types for backwards compatibility\nexport type {\n ApplyToolResult,\n ExportToolResult,\n GetMarkdownToolResult,\n InspectToolResult,\n MarkformTool,\n MarkformToolSet,\n} from './toolTypes.js';\n\n// =============================================================================\n// Zod Schemas for Tool Inputs\n// =============================================================================\n\n/**\n * Input schema for markform_inspect tool (no parameters).\n */\nconst InspectInputSchema = z\n .object({})\n .describe('No input parameters required. Call this tool to inspect the current form state.');\n\n/**\n * Input schema for markform_apply tool.\n */\nconst ApplyInputSchema = z\n .object({\n patches: z\n .array(PatchSchema)\n .min(1)\n .max(20)\n .describe(\n 'Array of patches to apply to the form. Each patch sets or clears a field value. ' +\n 'Operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, ' +\n 'set_checkboxes, set_url, set_url_list, set_date, set_year, set_table, clear_field, skip_field, abort_field. ' +\n 'Example: [{ \"op\": \"set_string\", \"fieldId\": \"name\", \"value\": \"Alice\" }]',\n ),\n })\n .describe('Apply patches to update form field values.');\n\n/**\n * Input schema for markform_export tool (no parameters).\n */\nconst ExportInputSchema = z\n .object({})\n .describe(\n 'No input parameters required. Call this tool to export the form schema and current values as JSON.',\n );\n\n/**\n * Input schema for markform_get_markdown tool (no parameters).\n */\nconst GetMarkdownInputSchema = z\n .object({})\n .describe(\n 'No input parameters required. Call this tool to get the canonical Markdown representation of the current form.',\n );\n\n// =============================================================================\n// Tool Factory\n// =============================================================================\n\n/**\n * Create Markform AI SDK tools for agent-driven form filling.\n *\n * Returns a toolset compatible with Vercel AI SDK's generateText and streamText.\n *\n * @param options - Tool creation options including session store\n * @returns MarkformToolSet containing all tools\n *\n * @example\n * ```typescript\n * import { parseForm } from 'markform';\n * import { createMarkformTools, MarkformSessionStore } from 'markform/ai-sdk';\n *\n * const form = parseForm(markdownContent);\n * const store = new MarkformSessionStore(form);\n * const tools = createMarkformTools({ sessionStore: store });\n *\n * // Use with AI SDK\n * const result = await generateText({\n * model: yourModel,\n * tools,\n * prompt: 'Fill out this form based on the user information...',\n * });\n * ```\n */\nexport function createMarkformTools(options: CreateMarkformToolsOptions): MarkformToolSet {\n const { sessionStore, includeGetMarkdown = true } = options;\n\n // markform_inspect - Get current form state with issues\n const markform_inspect: MarkformTool<Record<string, never>, InspectToolResult> = {\n description:\n 'Inspect the current form state. Returns structure summary, progress summary, validation issues, ' +\n 'and completion status. Use this to understand what fields need to be filled and what issues exist. ' +\n \"Issues are sorted by priority (1 = highest). Focus on 'required' severity issues first.\",\n inputSchema: InspectInputSchema,\n execute: () => {\n const form = sessionStore.getForm();\n const result = inspect(form);\n\n const requiredCount = result.issues.filter((i) => i.severity === 'required').length;\n const message = result.isComplete\n ? 'Form is complete. All required fields are filled.'\n : `Form has ${requiredCount} required issue(s) to resolve.`;\n\n return Promise.resolve({\n success: true,\n data: result,\n message,\n });\n },\n };\n\n // markform_apply - Apply patches to update form values\n const markform_apply: MarkformTool<{ patches: Patch[] }, ApplyToolResult> = {\n description:\n 'Apply patches to update form field values. Valid patches are applied even if some fail. ' +\n 'Single values are automatically coerced to arrays for list fields. ' +\n 'Returns applied patches, warnings for coerced values, and rejected patches separately. ' +\n 'Patch operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, ' +\n 'set_checkboxes, set_url, set_url_list, set_date, set_year, set_table, clear_field, skip_field, abort_field.',\n inputSchema: ApplyInputSchema,\n execute: ({ patches }) => {\n const form = sessionStore.getForm();\n const result = applyPatches(form, patches);\n\n // Update the store with the modified form\n sessionStore.updateForm(form);\n\n const warningNote = result.warnings.length > 0 ? ` (${result.warnings.length} coerced)` : '';\n const remaining = result.issues.filter((i) => i.severity === 'required').length;\n\n const message =\n result.applyStatus === 'applied'\n ? `Applied ${patches.length} patch(es)${warningNote}. ${\n result.isComplete\n ? 'Form is now complete!'\n : `${remaining} required issue(s) remaining.`\n }`\n : result.applyStatus === 'partial'\n ? `Applied ${result.appliedPatches.length}/${patches.length} patches${warningNote}. ` +\n `${result.rejectedPatches.length} rejected.`\n : `All patches rejected. Check field IDs and value types.`;\n\n return Promise.resolve({\n success: result.applyStatus !== 'rejected',\n data: result,\n message,\n });\n },\n };\n\n // markform_export - Export schema and values as JSON\n const markform_export: MarkformTool<Record<string, never>, ExportToolResult> = {\n description:\n 'Export the form schema and current values as JSON. Use this to get a machine-readable ' +\n 'representation of the form structure and all field values. Useful for processing or analysis.',\n inputSchema: ExportInputSchema,\n execute: () => {\n const form = sessionStore.getForm();\n\n // Count answered fields\n const answeredCount = Object.values(form.responsesByFieldId).filter(\n (response) => response.state === 'answered',\n ).length;\n\n return Promise.resolve({\n success: true,\n data: {\n schema: form.schema,\n values: form.responsesByFieldId,\n },\n message: `Exported form with ${form.schema.groups.length} group(s) and ${answeredCount} answered field(s).`,\n });\n },\n };\n\n // Build the toolset\n const toolset: MarkformToolSet = {\n markform_inspect,\n markform_apply,\n markform_export,\n };\n\n // Optionally include markform_get_markdown\n if (includeGetMarkdown) {\n const markform_get_markdown: MarkformTool<Record<string, never>, GetMarkdownToolResult> = {\n description:\n 'Get the canonical Markdown representation of the current form. ' +\n 'Use this to see the complete form with all current values in Markform format. ' +\n 'The output is deterministic and round-trip safe.',\n inputSchema: GetMarkdownInputSchema,\n execute: () => {\n const form = sessionStore.getForm();\n const markdown = serializeForm(form);\n\n return Promise.resolve({\n success: true,\n data: {\n markdown,\n },\n message: `Generated Markdown (${markdown.length} characters).`,\n });\n },\n };\n\n toolset.markform_get_markdown = markform_get_markdown;\n }\n\n return toolset;\n}\n\n// =============================================================================\n// Convenience Exports\n// =============================================================================\n\nexport { PatchSchema } from '../engine/coreTypes.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAa,uBAAb,MAAkC;CAChC,AAAQ;CACR,AAAQ;CAER,YAAY,MAAkB,mBAAuC;AACnE,OAAK,OAAO;AACZ,OAAK,oBAAoB,qBAAqB,EAAE;;;;;CAMlD,UAAsB;AACpB,SAAO,KAAK;;;;;CAMd,uBAA0C;AACxC,SAAO,KAAK;;;;;CAMd,WAAW,MAAwB;AACjC,OAAK,OAAO;;;;;;AAsDhB,MAAM,qBAAqB,EACxB,OAAO,EAAE,CAAC,CACV,SAAS,kFAAkF;;;;AAK9F,MAAM,mBAAmB,EACtB,OAAO,EACN,SAAS,EACN,MAAM,YAAY,CAClB,IAAI,EAAE,CACN,IAAI,GAAG,CACP,SACC,2WAID,EACJ,CAAC,CACD,SAAS,6CAA6C;;;;AAKzD,MAAM,oBAAoB,EACvB,OAAO,EAAE,CAAC,CACV,SACC,qGACD;;;;AAKH,MAAM,yBAAyB,EAC5B,OAAO,EAAE,CAAC,CACV,SACC,iHACD;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BH,SAAgB,oBAAoB,SAAsD;CACxF,MAAM,EAAE,cAAc,qBAAqB,SAAS;CA2FpD,MAAMA,UAA2B;EAC/B,kBAzF+E;GAC/E,aACE;GAGF,aAAa;GACb,eAAe;IAEb,MAAM,SAAS,QADF,aAAa,SAAS,CACP;IAE5B,MAAM,gBAAgB,OAAO,OAAO,QAAQ,MAAM,EAAE,aAAa,WAAW,CAAC;IAC7E,MAAM,UAAU,OAAO,aACnB,sDACA,YAAY,cAAc;AAE9B,WAAO,QAAQ,QAAQ;KACrB,SAAS;KACT,MAAM;KACN;KACD,CAAC;;GAEL;EAqEC,gBAlE0E;GAC1E,aACE;GAKF,aAAa;GACb,UAAU,EAAE,cAAc;IACxB,MAAM,OAAO,aAAa,SAAS;IACnC,MAAM,SAAS,aAAa,MAAM,QAAQ;AAG1C,iBAAa,WAAW,KAAK;IAE7B,MAAM,cAAc,OAAO,SAAS,SAAS,IAAI,KAAK,OAAO,SAAS,OAAO,aAAa;IAC1F,MAAM,YAAY,OAAO,OAAO,QAAQ,MAAM,EAAE,aAAa,WAAW,CAAC;IAEzE,MAAM,UACJ,OAAO,gBAAgB,YACnB,WAAW,QAAQ,OAAO,YAAY,YAAY,IAChD,OAAO,aACH,0BACA,GAAG,UAAU,mCAEnB,OAAO,gBAAgB,YACrB,WAAW,OAAO,eAAe,OAAO,GAAG,QAAQ,OAAO,UAAU,YAAY,IAC7E,OAAO,gBAAgB,OAAO,cACjC;AAER,WAAO,QAAQ,QAAQ;KACrB,SAAS,OAAO,gBAAgB;KAChC,MAAM;KACN;KACD,CAAC;;GAEL;EA+BC,iBA5B6E;GAC7E,aACE;GAEF,aAAa;GACb,eAAe;IACb,MAAM,OAAO,aAAa,SAAS;IAGnC,MAAM,gBAAgB,OAAO,OAAO,KAAK,mBAAmB,CAAC,QAC1D,aAAa,SAAS,UAAU,WAClC,CAAC;AAEF,WAAO,QAAQ,QAAQ;KACrB,SAAS;KACT,MAAM;MACJ,QAAQ,KAAK;MACb,QAAQ,KAAK;MACd;KACD,SAAS,sBAAsB,KAAK,OAAO,OAAO,OAAO,gBAAgB,cAAc;KACxF,CAAC;;GAEL;EAOA;AAGD,KAAI,mBAqBF,SAAQ,wBApBkF;EACxF,aACE;EAGF,aAAa;EACb,eAAe;GAEb,MAAM,WAAW,cADJ,aAAa,SAAS,CACC;AAEpC,UAAO,QAAQ,QAAQ;IACrB,SAAS;IACT,MAAM,EACJ,UACD;IACD,SAAS,uBAAuB,SAAS,OAAO;IACjD,CAAC;;EAEL;AAKH,QAAO"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import YAML from "yaml";
|
|
3
3
|
|
|
4
4
|
//#region src/errors.ts
|
|
5
|
-
const VERSION = "0.1.
|
|
5
|
+
const VERSION = "0.1.15";
|
|
6
6
|
/**
|
|
7
7
|
* Base error class for all markform errors.
|
|
8
8
|
* Consumers can catch this to handle any markform error.
|
|
@@ -496,6 +496,47 @@ function priorityKeyComparator(priorityKeys) {
|
|
|
496
496
|
});
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
+
//#endregion
|
|
500
|
+
//#region src/utils/urlFormat.ts
|
|
501
|
+
/**
|
|
502
|
+
* Create a friendly abbreviated display name for a URL.
|
|
503
|
+
* - Drops "www." prefix from domain
|
|
504
|
+
* - Adds first portion of path (up to maxPathChars) if present
|
|
505
|
+
* - Adds ellipsis (…) if path is truncated
|
|
506
|
+
*
|
|
507
|
+
* @param url - The URL to abbreviate
|
|
508
|
+
* @param maxPathChars - Maximum characters to include from the path (default: 12)
|
|
509
|
+
* @returns Friendly abbreviated URL (e.g., "example.com/docs/api…")
|
|
510
|
+
*/
|
|
511
|
+
function friendlyUrlAbbrev(url, maxPathChars = 12) {
|
|
512
|
+
try {
|
|
513
|
+
const parsed = new URL(url);
|
|
514
|
+
let hostname = parsed.hostname;
|
|
515
|
+
if (hostname.startsWith("www.")) hostname = hostname.slice(4);
|
|
516
|
+
const path = parsed.pathname.slice(1);
|
|
517
|
+
if (!path) return hostname;
|
|
518
|
+
if (path.length <= maxPathChars) return `${hostname}/${path}`;
|
|
519
|
+
return `${hostname}/${path.slice(0, maxPathChars)}…`;
|
|
520
|
+
} catch {
|
|
521
|
+
let result = url;
|
|
522
|
+
result = result.replace(/^https?:\/\//, "");
|
|
523
|
+
result = result.replace(/^www\./, "");
|
|
524
|
+
const maxLen = 30;
|
|
525
|
+
if (result.length > maxLen) return result.slice(0, maxLen) + "…";
|
|
526
|
+
return result;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Format a URL as a markdown link with a friendly abbreviated display text.
|
|
531
|
+
* The full URL is preserved as the link target.
|
|
532
|
+
*
|
|
533
|
+
* @param url - The URL to format
|
|
534
|
+
* @returns Markdown link in format [friendly-abbrev](url)
|
|
535
|
+
*/
|
|
536
|
+
function formatUrlAsMarkdownLink(url) {
|
|
537
|
+
return `[${friendlyUrlAbbrev(url)}](${url})`;
|
|
538
|
+
}
|
|
539
|
+
|
|
499
540
|
//#endregion
|
|
500
541
|
//#region src/engine/serialize.ts
|
|
501
542
|
/**
|
|
@@ -899,12 +940,14 @@ function serializeYearField(field, response) {
|
|
|
899
940
|
}
|
|
900
941
|
/**
|
|
901
942
|
* Serialize a cell value for table output.
|
|
943
|
+
* URL-typed columns are formatted as markdown links with domain as display text.
|
|
902
944
|
*/
|
|
903
|
-
function serializeCellValue(cell,
|
|
945
|
+
function serializeCellValue(cell, columnType) {
|
|
904
946
|
if (cell.state === "skipped") return cell.reason ? `%SKIP:${cell.reason}%` : "%SKIP%";
|
|
905
947
|
if (cell.state === "aborted") return cell.reason ? `%ABORT:${cell.reason}%` : "%ABORT%";
|
|
906
948
|
if (cell.value === void 0 || cell.value === null) return "";
|
|
907
949
|
if (typeof cell.value === "number") return String(cell.value);
|
|
950
|
+
if (columnType === "url") return formatUrlAsMarkdownLink(cell.value);
|
|
908
951
|
return cell.value;
|
|
909
952
|
}
|
|
910
953
|
/**
|
|
@@ -1179,9 +1222,10 @@ function serializeFieldRaw(field, responses) {
|
|
|
1179
1222
|
case "multi_select": {
|
|
1180
1223
|
const multiValue = value;
|
|
1181
1224
|
const selectedSet = new Set(multiValue?.selected ?? []);
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1184
|
-
|
|
1225
|
+
for (const opt of field.options) {
|
|
1226
|
+
const marker = selectedSet.has(opt.id) ? "x" : " ";
|
|
1227
|
+
lines.push(`- [${marker}] ${opt.label}`);
|
|
1228
|
+
}
|
|
1185
1229
|
break;
|
|
1186
1230
|
}
|
|
1187
1231
|
case "checkboxes": {
|
|
@@ -1194,13 +1238,13 @@ function serializeFieldRaw(field, responses) {
|
|
|
1194
1238
|
}
|
|
1195
1239
|
case "url": {
|
|
1196
1240
|
const urlValue = value;
|
|
1197
|
-
if (urlValue?.value) lines.push(urlValue.value);
|
|
1241
|
+
if (urlValue?.value) lines.push(formatUrlAsMarkdownLink(urlValue.value));
|
|
1198
1242
|
else lines.push("_(empty)_");
|
|
1199
1243
|
break;
|
|
1200
1244
|
}
|
|
1201
1245
|
case "url_list": {
|
|
1202
1246
|
const urlListValue = value;
|
|
1203
|
-
if (urlListValue?.items && urlListValue.items.length > 0) for (const item of urlListValue.items) lines.push(`- ${item}`);
|
|
1247
|
+
if (urlListValue?.items && urlListValue.items.length > 0) for (const item of urlListValue.items) lines.push(`- ${formatUrlAsMarkdownLink(item)}`);
|
|
1204
1248
|
else lines.push("_(empty)_");
|
|
1205
1249
|
break;
|
|
1206
1250
|
}
|
|
@@ -2685,6 +2729,22 @@ function normalizePatch(form, patch, index) {
|
|
|
2685
2729
|
}
|
|
2686
2730
|
if (patch.op === "set_checkboxes" && field.kind === "checkboxes") {
|
|
2687
2731
|
if (!patch.value) return { patch };
|
|
2732
|
+
if (Array.isArray(patch.value)) {
|
|
2733
|
+
const defaultState = field.checkboxMode === "explicit" ? "yes" : "done";
|
|
2734
|
+
const values = {};
|
|
2735
|
+
for (const item of patch.value) if (typeof item === "string") values[item] = defaultState;
|
|
2736
|
+
if (patch.value.length === 0) return { patch: {
|
|
2737
|
+
...patch,
|
|
2738
|
+
value: values
|
|
2739
|
+
} };
|
|
2740
|
+
return {
|
|
2741
|
+
patch: {
|
|
2742
|
+
...patch,
|
|
2743
|
+
value: values
|
|
2744
|
+
},
|
|
2745
|
+
warning: createWarning(index, field.id, "array_to_checkboxes", `Coerced array to checkboxes object with '${defaultState}' state`)
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2688
2748
|
let needsNormalization = false;
|
|
2689
2749
|
for (const value of Object.values(patch.value)) if (typeof value === "boolean") {
|
|
2690
2750
|
needsNormalization = true;
|
|
@@ -3062,4 +3122,5 @@ function applyPatches(form, patches) {
|
|
|
3062
3122
|
}
|
|
3063
3123
|
|
|
3064
3124
|
//#endregion
|
|
3065
|
-
export { isParseError as $, deriveExportPath as A, parseModelIdForDisplay as B, DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN as C, MAX_FORMS_IN_MENU as D, DEFAULT_ROLE_INSTRUCTIONS as E, SUGGESTED_LLMS as F, MarkformParseError as G, MarkformConfigError as H, WEB_SEARCH_CONFIG as I, ParseError as J, MarkformPatchError as K, formatSuggestedLlms as L, deriveSchemaPath as M, detectFileType as N, REPORT_EXTENSION as O, parseRolesFlag as P, isMarkformError as Q, getWebSearchConfig as R, DEFAULT_PRIORITY as S, DEFAULT_ROLES as T, MarkformError as U, MarkformAbortError as V, MarkformLlmError as W, isConfigError as X, isAbortError as Y, isLlmError as Z, DEFAULT_MAX_ISSUES_PER_TURN as _, validate as a, DEFAULT_MAX_TURNS as b, computeProgressSummary as c, serializeForm as d, isPatchError as et, serializeRawMarkdown as f, DEFAULT_FORMS_DIR as g,
|
|
3125
|
+
export { isParseError as $, deriveExportPath as A, parseModelIdForDisplay as B, DEFAULT_RESEARCH_MAX_ISSUES_PER_TURN as C, MAX_FORMS_IN_MENU as D, DEFAULT_ROLE_INSTRUCTIONS as E, SUGGESTED_LLMS as F, MarkformParseError as G, MarkformConfigError as H, WEB_SEARCH_CONFIG as I, ParseError as J, MarkformPatchError as K, formatSuggestedLlms as L, deriveSchemaPath as M, detectFileType as N, REPORT_EXTENSION as O, parseRolesFlag as P, isMarkformError as Q, getWebSearchConfig as R, DEFAULT_PRIORITY as S, DEFAULT_ROLES as T, MarkformError as U, MarkformAbortError as V, MarkformLlmError as W, isConfigError as X, isAbortError as Y, isLlmError as Z, DEFAULT_MAX_ISSUES_PER_TURN as _, validate as a, DEFAULT_MAX_TURNS as b, computeProgressSummary as c, serializeForm as d, isPatchError as et, serializeRawMarkdown as f, DEFAULT_FORMS_DIR as g, AGENT_ROLE as h, inspect as i, deriveReportPath as j, USER_ROLE as k, computeStructureSummary as l, friendlyUrlAbbrev as m, getAllFields as n, isValidationError as nt, computeAllSummaries as o, serializeReport as p, MarkformValidationError as q, getFieldsForRoles as r, computeFormState as s, applyPatches as t, isRetryableError as tt, isFormComplete as u, DEFAULT_MAX_PATCHES_PER_TURN as v, DEFAULT_RESEARCH_MAX_PATCHES_PER_TURN as w, DEFAULT_PORT as x, DEFAULT_MAX_STEPS_PER_TURN as y, hasWebSearchSupport as z };
|
|
3126
|
+
//# sourceMappingURL=apply-D44qg6-W.mjs.map
|