markform 0.0.1 → 0.1.1

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-DBD3Dt4f.mjs","names":["line?: number","col?: number","result: Record<string, unknown>","CHECKBOX_MARKERS: Record<string, CheckboxValue>","value: unknown","items: ParsedOptionItem[]","field: StringField","field: NumberField","numValue: number | null","field: StringListField","items: string[]","options: Option[]","selected: Record<string, CheckboxValue>","field: SingleSelectField","selectedOption: string | null","field: MultiSelectField","selectedOptions: string[]","checkboxMode: CheckboxMode","approvalMode: ApprovalMode","field: CheckboxesField","values: Record<string, CheckboxValue>","children: Field[]","groups: FieldGroup[]","docs: DocumentationBlock[]","formSchema: FormSchema | null","valuesByFieldId: Record<Id, FieldValue>","orderIndex: Id[]","raw: unknown","result: Record<string, unknown>","items: string[]","selected: string[]","warning: string | undefined","patch: Patch","values: Record<OptionId, CheckboxValue>","patches: Patch[]","warnings: string[]","errors: string[]","DEFAULT_CONFIG: HarnessConfig","result","result: InspectIssue[]","clearPatches: ClearFieldPatch[]","patches: Patch[]","patches: Patch[]","sections: string[]","fieldInstructions: string[]","lines: string[]","PROVIDERS: Record<\n ProviderName,\n { package: string; envVar: string; createFn: string }\n>","providerModule: Record<string, (modelId: string) => LanguageModel>","model: LanguageModel","result: FillResult","form: ParsedForm","model: LanguageModel | undefined","inputContextWarnings: string[]","agent: Agent"],"sources":["../src/engine/parse.ts","../src/engine/session.ts","../src/engine/valueCoercion.ts","../src/harness/harness.ts","../src/harness/mockAgent.ts","../src/harness/liveAgent.ts","../src/harness/modelResolver.ts","../src/harness/programmaticFill.ts","../src/index.ts"],"sourcesContent":["/**\n * Markdoc parser for .form.md files.\n *\n * Parses Markdoc documents and extracts form schema, values, and documentation blocks.\n */\n\nimport Markdoc from \"@markdoc/markdoc\";\nimport type { Node } from \"@markdoc/markdoc\";\n\nimport { AGENT_ROLE, DEFAULT_PRIORITY } from \"../settings.js\";\nimport type {\n ApprovalMode,\n CheckboxesField,\n CheckboxesValue,\n CheckboxMode,\n CheckboxValue,\n DocumentationBlock,\n DocumentationTag,\n Field,\n FieldGroup,\n FieldValue,\n FormSchema,\n Id,\n IdIndexEntry,\n MultiSelectField,\n MultiSelectValue,\n NumberField,\n NumberValue,\n Option,\n ParsedForm,\n SingleSelectField,\n SingleSelectValue,\n StringField,\n StringListField,\n StringListValue,\n StringValue,\n ValidatorRef,\n} from \"./coreTypes.js\";\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/** Parse error with source location info */\nexport class ParseError extends Error {\n constructor(\n message: string,\n public readonly line?: number,\n public readonly col?: number\n ) {\n super(message);\n this.name = \"ParseError\";\n }\n}\n\n// =============================================================================\n// Frontmatter Parsing\n// =============================================================================\n\nconst FRONTMATTER_REGEX = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/;\n\ninterface FrontmatterResult {\n frontmatter: Record<string, unknown>;\n body: string;\n}\n\n/**\n * Extract YAML frontmatter from markdown content.\n */\nfunction extractFrontmatter(content: string): FrontmatterResult {\n const match = FRONTMATTER_REGEX.exec(content);\n if (!match) {\n return { frontmatter: {}, body: content };\n }\n\n const yamlContent = match[1];\n const body = content.slice(match[0].length);\n\n // Parse YAML using a simple approach (yaml package will be used later)\n // For now, just extract the raw YAML and we'll parse it properly with the yaml package\n try {\n // Simple parse - we'll use yaml package for proper parsing\n const lines = (yamlContent ?? \"\").split(\"\\n\");\n const result: Record<string, unknown> = {};\n\n for (const line of lines) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0 && !line.startsWith(\" \") && !line.startsWith(\"\\t\")) {\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n // Handle quoted values\n if (value.startsWith('\"') && value.endsWith('\"')) {\n result[key] = value.slice(1, -1);\n } else if (value === \"\") {\n // Nested object marker - for now just mark it\n result[key] = {};\n } else {\n result[key] = value;\n }\n }\n }\n\n return { frontmatter: result, body };\n } catch (_error) {\n throw new ParseError(\"Failed to parse frontmatter YAML\");\n }\n}\n\n// =============================================================================\n// Checkbox Marker Parsing\n// =============================================================================\n\n/** Map checkbox marker to state value */\nconst CHECKBOX_MARKERS: Record<string, CheckboxValue> = {\n \"[ ]\": \"todo\",\n \"[x]\": \"done\",\n \"[X]\": \"done\",\n \"[/]\": \"incomplete\",\n \"[*]\": \"active\",\n \"[-]\": \"na\",\n \"[y]\": \"yes\",\n \"[Y]\": \"yes\",\n \"[n]\": \"no\",\n \"[N]\": \"no\",\n};\n\n// Regex to extract checkbox marker and label from text content\n// Text is like \"[ ] Label\" or \"[x] Label\"\nconst OPTION_TEXT_PATTERN = /^(\\[[^\\]]\\])\\s*(.*?)\\s*$/;\n\ninterface ParsedMarkerText {\n marker: string;\n label: string;\n}\n\n/**\n * Parse option text to extract marker and label.\n * Text is like \"[ ] Label\" or \"[x] Label\".\n */\nfunction parseOptionText(text: string): ParsedMarkerText | null {\n const match = OPTION_TEXT_PATTERN.exec(text);\n if (!match) {\n return null;\n }\n\n const marker = match[1] ?? \"\";\n const label = (match[2] ?? \"\").trim();\n\n return { marker, label };\n}\n\n// =============================================================================\n// Markdoc Tag Processing\n// =============================================================================\n\n/**\n * Check if a node is a tag node with specific name.\n * Works with raw AST nodes (not transformed Tags).\n */\nfunction isTagNode(node: Node, name?: string): boolean {\n if (typeof node !== \"object\" || node === null) {\n return false;\n }\n if (node.type === \"tag\" && node.tag) {\n return name === undefined || node.tag === name;\n }\n return false;\n}\n\n\n/**\n * Get string attribute value or undefined.\n */\nfunction getStringAttr(node: Node, name: string): string | undefined {\n const value: unknown = node.attributes?.[name];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Get number attribute value or undefined.\n */\nfunction getNumberAttr(node: Node, name: string): number | undefined {\n const value: unknown = node.attributes?.[name];\n return typeof value === \"number\" ? value : undefined;\n}\n\n/**\n * Get boolean attribute value or undefined.\n */\nfunction getBooleanAttr(node: Node, name: string): boolean | undefined {\n const value: unknown = node.attributes?.[name];\n return typeof value === \"boolean\" ? value : undefined;\n}\n\n/**\n * Get validator references from validate attribute.\n * Handles both single string and array formats.\n */\nfunction getValidateAttr(node: Node): ValidatorRef[] | undefined {\n const value: unknown = node.attributes?.validate;\n if (value === undefined || value === null) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value as ValidatorRef[];\n }\n if (typeof value === \"string\") {\n return [value];\n }\n if (typeof value === \"object\") {\n // Single object validator ref like { id: \"foo\", param: 1 }\n return [value as ValidatorRef];\n }\n return undefined;\n}\n\n/**\n * Parsed option item from AST.\n */\ninterface ParsedOptionItem {\n /** ID from {% #id %} annotation */\n id: string | null;\n /** Text content (e.g., \"[ ] Label\" or \"[x] Label\") */\n text: string;\n}\n\n/**\n * Extract option items from node children (for option lists).\n * Works with raw AST nodes. Collects text and ID from list items.\n */\nfunction extractOptionItems(node: Node): ParsedOptionItem[] {\n const items: ParsedOptionItem[] = [];\n\n /**\n * Collect all text content from a node tree into a single string.\n */\n function collectText(n: Node): string {\n let text = \"\";\n\n // Text nodes have content in attributes\n if (n.type === \"text\" && typeof n.attributes?.content === \"string\") {\n text += n.attributes.content;\n }\n\n // Softbreak is a newline\n if (n.type === \"softbreak\") {\n text += \"\\n\";\n }\n\n // Recurse into children\n if (n.children && Array.isArray(n.children)) {\n for (const c of n.children) {\n text += collectText(c);\n }\n }\n\n return text;\n }\n\n /**\n * Traverse to find list items and extract their content.\n */\n function traverse(child: Node): void {\n if (!child || typeof child !== \"object\") {\n return;\n }\n\n // List items contain the option text and ID\n if (child.type === \"item\") {\n const text = collectText(child);\n // Markdoc parses {% #id %} as an id attribute on the item\n const id = typeof child.attributes?.id === \"string\" ? child.attributes.id : null;\n if (text.trim()) {\n items.push({ id, text: text.trim() });\n }\n return; // Don't recurse further into item children\n }\n\n // Recurse into children\n if (child.children && Array.isArray(child.children)) {\n for (const c of child.children) {\n traverse(c);\n }\n }\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverse(child);\n }\n }\n\n return items;\n}\n\n/**\n * Extract fence value from node children.\n * Looks for ```value code blocks.\n */\nfunction extractFenceValue(node: Node): string | null {\n function traverse(child: Node): string | null {\n if (!child || typeof child !== \"object\") {\n return null;\n }\n\n // Check if this is a fence node with language=\"value\"\n if (child.type === \"fence\") {\n const lang = child.attributes?.language as string | undefined;\n if (lang === \"value\") {\n return typeof child.attributes?.content === \"string\"\n ? child.attributes.content\n : null;\n }\n }\n\n // Traverse children\n if (child.children && Array.isArray(child.children)) {\n for (const c of child.children) {\n const result = traverse(c);\n if (result !== null) {\n return result;\n }\n }\n }\n\n return null;\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n const result = traverse(child);\n if (result !== null) {\n return result;\n }\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// Field Parsing\n// =============================================================================\n\n/**\n * Get priority attribute value or default to DEFAULT_PRIORITY.\n */\nfunction getPriorityAttr(node: Node): \"high\" | \"medium\" | \"low\" {\n const value = getStringAttr(node, \"priority\");\n if (value === \"high\" || value === \"medium\" || value === \"low\") {\n return value;\n }\n return DEFAULT_PRIORITY;\n}\n\n/**\n * Parse a string-field tag.\n */\nfunction parseStringField(node: Node): { field: StringField; value: StringValue } {\n const id = getStringAttr(node, \"id\");\n const label = getStringAttr(node, \"label\");\n\n if (!id) {\n throw new ParseError(\"string-field missing required 'id' attribute\");\n }\n if (!label) {\n throw new ParseError(`string-field '${id}' missing required 'label' attribute`);\n }\n\n const field: StringField = {\n kind: \"string\",\n id,\n label,\n required: getBooleanAttr(node, \"required\") ?? false,\n priority: getPriorityAttr(node),\n role: getStringAttr(node, \"role\") ?? AGENT_ROLE,\n multiline: getBooleanAttr(node, \"multiline\"),\n pattern: getStringAttr(node, \"pattern\"),\n minLength: getNumberAttr(node, \"minLength\"),\n maxLength: getNumberAttr(node, \"maxLength\"),\n validate: getValidateAttr(node),\n };\n\n const fenceContent = extractFenceValue(node);\n const value: StringValue = {\n kind: \"string\",\n value: fenceContent !== null ? fenceContent.trim() : null,\n };\n\n return { field, value };\n}\n\n/**\n * Parse a number-field tag.\n */\nfunction parseNumberField(node: Node): { field: NumberField; value: NumberValue } {\n const id = getStringAttr(node, \"id\");\n const label = getStringAttr(node, \"label\");\n\n if (!id) {\n throw new ParseError(\"number-field missing required 'id' attribute\");\n }\n if (!label) {\n throw new ParseError(`number-field '${id}' missing required 'label' attribute`);\n }\n\n const field: NumberField = {\n kind: \"number\",\n id,\n label,\n required: getBooleanAttr(node, \"required\") ?? false,\n priority: getPriorityAttr(node),\n role: getStringAttr(node, \"role\") ?? AGENT_ROLE,\n min: getNumberAttr(node, \"min\"),\n max: getNumberAttr(node, \"max\"),\n integer: getBooleanAttr(node, \"integer\"),\n validate: getValidateAttr(node),\n };\n\n const fenceContent = extractFenceValue(node);\n let numValue: number | null = null;\n\n if (fenceContent !== null) {\n const trimmed = fenceContent.trim();\n if (trimmed) {\n const parsed = Number(trimmed);\n if (!Number.isNaN(parsed)) {\n numValue = parsed;\n }\n }\n }\n\n const value: NumberValue = {\n kind: \"number\",\n value: numValue,\n };\n\n return { field, value };\n}\n\n/**\n * Parse a string-list tag.\n */\nfunction parseStringListField(node: Node): { field: StringListField; value: StringListValue } {\n const id = getStringAttr(node, \"id\");\n const label = getStringAttr(node, \"label\");\n\n if (!id) {\n throw new ParseError(\"string-list missing required 'id' attribute\");\n }\n if (!label) {\n throw new ParseError(`string-list '${id}' missing required 'label' attribute`);\n }\n\n const field: StringListField = {\n kind: \"string_list\",\n id,\n label,\n required: getBooleanAttr(node, \"required\") ?? false,\n priority: getPriorityAttr(node),\n role: getStringAttr(node, \"role\") ?? AGENT_ROLE,\n minItems: getNumberAttr(node, \"minItems\"),\n maxItems: getNumberAttr(node, \"maxItems\"),\n itemMinLength: getNumberAttr(node, \"itemMinLength\"),\n itemMaxLength: getNumberAttr(node, \"itemMaxLength\"),\n uniqueItems: getBooleanAttr(node, \"uniqueItems\"),\n validate: getValidateAttr(node),\n };\n\n const fenceContent = extractFenceValue(node);\n const items: string[] = [];\n\n if (fenceContent !== null) {\n const lines = fenceContent.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed) {\n items.push(trimmed);\n }\n }\n }\n\n const value: StringListValue = {\n kind: \"string_list\",\n items,\n };\n\n return { field, value };\n}\n\n/**\n * Parse options from a select/checkbox field.\n */\nfunction parseOptions(\n node: Node,\n fieldId: string\n): { options: Option[]; selected: Record<string, CheckboxValue> } {\n const items = extractOptionItems(node);\n const options: Option[] = [];\n const selected: Record<string, CheckboxValue> = {};\n const seenIds = new Set<string>();\n\n for (const item of items) {\n const parsed = parseOptionText(item.text);\n if (!parsed) {\n continue;\n }\n\n if (!item.id) {\n throw new ParseError(\n `Option in field '${fieldId}' missing ID annotation. Use {% #option_id %}`\n );\n }\n\n if (seenIds.has(item.id)) {\n throw new ParseError(\n `Duplicate option ID '${item.id}' in field '${fieldId}'`\n );\n }\n seenIds.add(item.id);\n\n options.push({ id: item.id, label: parsed.label });\n\n const state = CHECKBOX_MARKERS[parsed.marker];\n if (state !== undefined) {\n selected[item.id] = state;\n }\n }\n\n return { options, selected };\n}\n\n/**\n * Parse a single-select tag.\n */\nfunction parseSingleSelectField(node: Node): { field: SingleSelectField; value: SingleSelectValue } {\n const id = getStringAttr(node, \"id\");\n const label = getStringAttr(node, \"label\");\n\n if (!id) {\n throw new ParseError(\"single-select missing required 'id' attribute\");\n }\n if (!label) {\n throw new ParseError(`single-select '${id}' missing required 'label' attribute`);\n }\n\n const { options, selected } = parseOptions(node, id);\n\n const field: SingleSelectField = {\n kind: \"single_select\",\n id,\n label,\n required: getBooleanAttr(node, \"required\") ?? false,\n priority: getPriorityAttr(node),\n role: getStringAttr(node, \"role\") ?? AGENT_ROLE,\n options,\n validate: getValidateAttr(node),\n };\n\n // Find the selected option (exactly one with done/[x] state)\n let selectedOption: string | null = null;\n for (const [optId, state] of Object.entries(selected)) {\n if (state === \"done\") {\n selectedOption = optId;\n break;\n }\n }\n\n const value: SingleSelectValue = {\n kind: \"single_select\",\n selected: selectedOption,\n };\n\n return { field, value };\n}\n\n/**\n * Parse a multi-select tag.\n */\nfunction parseMultiSelectField(node: Node): { field: MultiSelectField; value: MultiSelectValue } {\n const id = getStringAttr(node, \"id\");\n const label = getStringAttr(node, \"label\");\n\n if (!id) {\n throw new ParseError(\"multi-select missing required 'id' attribute\");\n }\n if (!label) {\n throw new ParseError(`multi-select '${id}' missing required 'label' attribute`);\n }\n\n const { options, selected } = parseOptions(node, id);\n\n const field: MultiSelectField = {\n kind: \"multi_select\",\n id,\n label,\n required: getBooleanAttr(node, \"required\") ?? false,\n priority: getPriorityAttr(node),\n role: getStringAttr(node, \"role\") ?? AGENT_ROLE,\n options,\n minSelections: getNumberAttr(node, \"minSelections\"),\n maxSelections: getNumberAttr(node, \"maxSelections\"),\n validate: getValidateAttr(node),\n };\n\n // Collect all selected options (those with done/[x] state)\n const selectedOptions: string[] = [];\n for (const [optId, state] of Object.entries(selected)) {\n if (state === \"done\") {\n selectedOptions.push(optId);\n }\n }\n\n const value: MultiSelectValue = {\n kind: \"multi_select\",\n selected: selectedOptions,\n };\n\n return { field, value };\n}\n\n/**\n * Parse a checkboxes tag.\n */\nfunction parseCheckboxesField(node: Node): { field: CheckboxesField; value: CheckboxesValue } {\n const id = getStringAttr(node, \"id\");\n const label = getStringAttr(node, \"label\");\n\n if (!id) {\n throw new ParseError(\"checkboxes missing required 'id' attribute\");\n }\n if (!label) {\n throw new ParseError(`checkboxes '${id}' missing required 'label' attribute`);\n }\n\n const { options, selected } = parseOptions(node, id);\n\n const checkboxModeStr = getStringAttr(node, \"checkboxMode\");\n let checkboxMode: CheckboxMode = \"multi\"; // default\n if (checkboxModeStr === \"multi\" || checkboxModeStr === \"simple\" || checkboxModeStr === \"explicit\") {\n checkboxMode = checkboxModeStr;\n }\n\n const approvalModeStr = getStringAttr(node, \"approvalMode\");\n let approvalMode: ApprovalMode = \"none\"; // default\n if (approvalModeStr === \"blocking\") {\n approvalMode = \"blocking\";\n }\n\n const field: CheckboxesField = {\n kind: \"checkboxes\",\n id,\n label,\n required: getBooleanAttr(node, \"required\") ?? false,\n priority: getPriorityAttr(node),\n role: getStringAttr(node, \"role\") ?? AGENT_ROLE,\n checkboxMode,\n minDone: getNumberAttr(node, \"minDone\"),\n options,\n approvalMode,\n validate: getValidateAttr(node),\n };\n\n // Initialize all options to their default state based on mode\n const values: Record<string, CheckboxValue> = {};\n\n for (const opt of options) {\n const state = selected[opt.id];\n if (state === undefined || state === \"todo\") {\n // For explicit mode, \"todo\" (from [ ]) means \"unfilled\"\n values[opt.id] = checkboxMode === \"explicit\" ? \"unfilled\" : \"todo\";\n } else {\n values[opt.id] = state;\n }\n }\n\n const value: CheckboxesValue = {\n kind: \"checkboxes\",\n values,\n };\n\n return { field, value };\n}\n\n/**\n * Parse a field tag and return field schema and value.\n */\nfunction parseField(node: Node): { field: Field; value: FieldValue } | null {\n if (!isTagNode(node)) {\n return null;\n }\n switch (node.tag) {\n case \"string-field\":\n return parseStringField(node);\n case \"number-field\":\n return parseNumberField(node);\n case \"string-list\":\n return parseStringListField(node);\n case \"single-select\":\n return parseSingleSelectField(node);\n case \"multi-select\":\n return parseMultiSelectField(node);\n case \"checkboxes\":\n return parseCheckboxesField(node);\n default:\n return null;\n }\n}\n\n// =============================================================================\n// Group and Form Parsing\n// =============================================================================\n\n/**\n * Parse a field-group tag.\n */\nfunction parseFieldGroup(\n node: Node,\n valuesByFieldId: Record<Id, FieldValue>,\n orderIndex: Id[],\n idIndex: Map<Id, IdIndexEntry>,\n parentId?: Id\n): FieldGroup {\n const id = getStringAttr(node, \"id\");\n const title = getStringAttr(node, \"title\");\n\n if (!id) {\n throw new ParseError(\"field-group missing required 'id' attribute\");\n }\n\n if (idIndex.has(id)) {\n throw new ParseError(`Duplicate ID '${id}'`);\n }\n\n idIndex.set(id, { kind: \"group\", parentId });\n\n const children: Field[] = [];\n\n // Traverse children to find fields\n function processChildren(child: Node): void {\n if (!child || typeof child !== \"object\") {\n return;\n }\n\n const result = parseField(child);\n if (result) {\n if (idIndex.has(result.field.id)) {\n throw new ParseError(`Duplicate ID '${result.field.id}'`);\n }\n\n idIndex.set(result.field.id, { kind: \"field\", parentId: id });\n children.push(result.field);\n valuesByFieldId[result.field.id] = result.value;\n orderIndex.push(result.field.id);\n\n // Add options to idIndex for select/checkbox fields\n if (\"options\" in result.field) {\n for (const opt of result.field.options) {\n const qualifiedRef = `${result.field.id}.${opt.id}`;\n if (idIndex.has(qualifiedRef)) {\n throw new ParseError(`Duplicate option ref '${qualifiedRef}'`);\n }\n idIndex.set(qualifiedRef, {\n kind: \"option\",\n parentId: id,\n fieldId: result.field.id,\n });\n }\n }\n }\n\n if (child.children && Array.isArray(child.children)) {\n for (const c of child.children) {\n processChildren(c);\n }\n }\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n processChildren(child);\n }\n }\n\n return {\n kind: \"field_group\",\n id,\n title,\n validate: getValidateAttr(node),\n children,\n };\n}\n\n/**\n * Parse a form tag.\n */\nfunction parseFormTag(\n node: Node,\n valuesByFieldId: Record<Id, FieldValue>,\n orderIndex: Id[],\n idIndex: Map<Id, IdIndexEntry>\n): FormSchema {\n const id = getStringAttr(node, \"id\");\n const title = getStringAttr(node, \"title\");\n\n if (!id) {\n throw new ParseError(\"form missing required 'id' attribute\");\n }\n\n if (idIndex.has(id)) {\n throw new ParseError(`Duplicate ID '${id}'`);\n }\n\n idIndex.set(id, { kind: \"form\" });\n\n const groups: FieldGroup[] = [];\n\n // Process children to find field-groups\n function findFieldGroups(child: Node): void {\n if (!child || typeof child !== \"object\") {\n return;\n }\n\n if (isTagNode(child, \"field-group\")) {\n const group = parseFieldGroup(\n child,\n valuesByFieldId,\n orderIndex,\n idIndex,\n id\n );\n groups.push(group);\n return;\n }\n\n if (child.children && Array.isArray(child.children)) {\n for (const c of child.children) {\n findFieldGroups(c);\n }\n }\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n findFieldGroups(child);\n }\n }\n\n return { id, title, groups };\n}\n\n// =============================================================================\n// Documentation Block Parsing\n// =============================================================================\n\n/** Valid documentation tag names */\nconst DOC_TAG_NAMES = [\"description\", \"instructions\", \"documentation\"] as const;\n\n/**\n * Extract all documentation blocks from AST.\n * Looks for {% description %}, {% instructions %}, and {% documentation %} tags.\n */\nfunction extractDocBlocks(ast: Node, idIndex: Map<Id, IdIndexEntry>): DocumentationBlock[] {\n const docs: DocumentationBlock[] = [];\n const seenRefs = new Set<string>();\n\n function traverse(node: Node): void {\n if (!node || typeof node !== \"object\") {\n return;\n }\n\n // Check for description, instructions, or documentation tags\n const nodeTag = node.type === \"tag\" && node.tag ? node.tag : null;\n if (nodeTag && (DOC_TAG_NAMES as readonly string[]).includes(nodeTag)) {\n const tag = nodeTag as DocumentationTag;\n const ref = getStringAttr(node, \"ref\");\n\n if (!ref) {\n throw new ParseError(`${tag} block missing required 'ref' attribute`);\n }\n\n // Validate ref exists\n if (!idIndex.has(ref)) {\n throw new ParseError(`${tag} block references unknown ID '${ref}'`);\n }\n\n const uniqueKey = `${ref}:${tag}`;\n\n if (seenRefs.has(uniqueKey)) {\n throw new ParseError(\n `Duplicate ${tag} block for ref='${ref}'`\n );\n }\n seenRefs.add(uniqueKey);\n\n // Extract body content - collect all text from children\n let bodyMarkdown = \"\";\n function extractText(n: Node): void {\n if (n.type === \"text\" && typeof n.attributes?.content === \"string\") {\n bodyMarkdown += n.attributes.content;\n }\n if (n.children && Array.isArray(n.children)) {\n for (const c of n.children) {\n extractText(c);\n }\n }\n }\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n extractText(child);\n }\n }\n\n docs.push({\n tag,\n ref,\n bodyMarkdown: bodyMarkdown.trim(),\n });\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverse(child);\n }\n }\n }\n\n traverse(ast);\n return docs;\n}\n\n// =============================================================================\n// Main Parser\n// =============================================================================\n\n/**\n * Parse a Markform .form.md document.\n *\n * @param markdown - The full markdown content including frontmatter\n * @returns The parsed form representation\n * @throws ParseError if the document is invalid\n */\nexport function parseForm(markdown: string): ParsedForm {\n // Step 1: Extract frontmatter\n const { body } = extractFrontmatter(markdown);\n\n // Step 2: Parse Markdoc AST (raw AST, not transformed)\n const ast = Markdoc.parse(body);\n\n // Step 3: Find the form tag in the raw AST\n let formSchema: FormSchema | null = null;\n const valuesByFieldId: Record<Id, FieldValue> = {};\n const orderIndex: Id[] = [];\n const idIndex = new Map<Id, IdIndexEntry>();\n\n function findFormTag(node: Node): void {\n if (!node || typeof node !== \"object\") {\n return;\n }\n\n if (isTagNode(node, \"form\")) {\n if (formSchema) {\n throw new ParseError(\"Multiple form tags found - only one allowed\");\n }\n formSchema = parseFormTag(node, valuesByFieldId, orderIndex, idIndex);\n return;\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n findFormTag(child);\n }\n }\n }\n\n findFormTag(ast);\n\n if (!formSchema) {\n throw new ParseError(\"No form tag found in document\");\n }\n\n // Step 4: Extract doc blocks (needs idIndex to validate refs)\n const docs = extractDocBlocks(ast, idIndex);\n\n return {\n schema: formSchema,\n valuesByFieldId,\n docs,\n orderIndex,\n idIndex,\n };\n}\n","/**\n * Session module - parsing and serializing session transcripts.\n *\n * Session transcripts are used for golden testing and session replay.\n * They capture the full interaction between the harness and agent.\n */\nimport YAML from \"yaml\";\nimport type { SessionTranscript } from \"./coreTypes\";\nimport { SessionTranscriptSchema } from \"./coreTypes\";\n\n/**\n * Parse a session transcript from YAML string.\n *\n * Converts snake_case keys to camelCase for TypeScript consumption.\n *\n * @param yaml - YAML string containing session transcript\n * @returns Parsed and validated SessionTranscript\n * @throws Error if YAML is invalid or doesn't match schema\n */\nexport function parseSession(yaml: string): SessionTranscript {\n // Parse YAML\n let raw: unknown;\n try {\n raw = YAML.parse(yaml);\n } catch (err) {\n throw new Error(\n `Failed to parse session YAML: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n // Convert snake_case to camelCase\n const converted = toCamelCaseDeep(raw);\n\n // Validate against schema\n const result = SessionTranscriptSchema.safeParse(converted);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => `${e.path.join(\".\")}: ${e.message}`)\n .join(\"; \");\n throw new Error(`Invalid session transcript: ${errors}`);\n }\n\n return result.data;\n}\n\n/**\n * Serialize a session transcript to YAML string.\n *\n * Converts camelCase keys to snake_case for YAML output.\n *\n * @param session - Session transcript to serialize\n * @returns YAML string\n */\nexport function serializeSession(session: SessionTranscript): string {\n // Convert camelCase to snake_case\n const snakeCased = toSnakeCaseDeep(session);\n\n // Serialize to YAML\n return YAML.stringify(snakeCased, {\n indent: 2,\n lineWidth: 0, // Don't wrap lines\n });\n}\n\n// =============================================================================\n// Key Case Conversion Helpers\n// =============================================================================\n\n/**\n * Convert a string from snake_case to camelCase.\n */\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_match, letter: string) =>\n letter.toUpperCase()\n );\n}\n\n/**\n * Convert a string from camelCase to snake_case.\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Recursively convert all object keys from snake_case to camelCase.\n *\n * Preserves keys that are user-defined identifiers (like option IDs in\n * checkboxes `values` objects).\n *\n * @param obj - Object to convert\n * @param preserveKeys - If true, don't convert keys in this object (but still recurse into values)\n */\nfunction toCamelCaseDeep(obj: unknown, preserveKeys = false): unknown {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toCamelCaseDeep(item, false));\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n const record = obj as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(record)) {\n // Determine the key to use\n const resultKey = preserveKeys ? key : snakeToCamel(key);\n\n // Check if this is a \"values\" key in a set_checkboxes patch\n // The \"values\" object contains option IDs as keys which should be preserved\n const isCheckboxValues =\n key === \"values\" &&\n record.op === \"set_checkboxes\";\n\n result[resultKey] = toCamelCaseDeep(value, isCheckboxValues);\n }\n return result;\n }\n\n return obj;\n}\n\n/**\n * Recursively convert all object keys from camelCase to snake_case.\n *\n * Preserves keys that are user-defined identifiers (like option IDs in\n * checkboxes `values` objects).\n *\n * @param obj - Object to convert\n * @param preserveKeys - If true, don't convert keys in this object (but still recurse into values)\n */\nfunction toSnakeCaseDeep(obj: unknown, preserveKeys = false): unknown {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toSnakeCaseDeep(item, false));\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n const record = obj as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(record)) {\n // Determine the key to use\n const resultKey = preserveKeys ? key : camelToSnake(key);\n\n // Check if this is a \"values\" key in a set_checkboxes patch\n // The \"values\" object contains option IDs as keys which should be preserved\n const isCheckboxValues =\n key === \"values\" &&\n record.op === \"set_checkboxes\";\n\n result[resultKey] = toSnakeCaseDeep(value, isCheckboxValues);\n }\n return result;\n }\n\n return obj;\n}\n","/**\n * Unified value coercion layer for converting raw input values to typed Patches.\n *\n * This module provides the single source of truth for:\n * - Field lookup by ID (using idIndex for O(1) lookups)\n * - Coercing raw values to typed Patches with validation\n * - Batch coercion of InputContext with warnings/errors\n */\n\nimport type {\n CheckboxValue,\n Field,\n OptionId,\n ParsedForm,\n Patch,\n} from \"./coreTypes.js\";\n\n// =============================================================================\n// Raw Input Types\n// =============================================================================\n\n/** Raw value that can be coerced to a field value. */\nexport type RawFieldValue =\n | string\n | number\n | boolean\n | string[]\n | Record<string, unknown>\n | null;\n\n/** Input context is a map of field IDs to raw values. */\nexport type InputContext = Record<string, RawFieldValue>;\n\n// =============================================================================\n// Coercion Results\n// =============================================================================\n\nexport type CoercionResult =\n | { ok: true; patch: Patch }\n | { ok: true; patch: Patch; warning: string }\n | { ok: false; error: string };\n\nexport interface CoerceInputContextResult {\n patches: Patch[];\n /** Non-fatal warnings (e.g., \"coerced '123' to number for field X\") */\n warnings: string[];\n /** Fatal errors (e.g., \"field 'foo' not found\") */\n errors: string[];\n}\n\n// =============================================================================\n// Field Lookup\n// =============================================================================\n\n/**\n * Find a field by ID.\n *\n * Uses idIndex for O(1) validation that the ID exists and is a field,\n * then retrieves the Field object from the schema.\n */\nexport function findFieldById(form: ParsedForm, fieldId: string): Field | undefined {\n // O(1) check: verify the ID exists and is a field\n const entry = form.idIndex.get(fieldId);\n if (entry?.kind !== \"field\") {\n return undefined;\n }\n\n // Retrieve the Field object from the schema\n for (const group of form.schema.groups) {\n for (const field of group.children) {\n if (field.id === fieldId) {\n return field;\n }\n }\n }\n\n return undefined;\n}\n\n// =============================================================================\n// Coercion Helpers\n// =============================================================================\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\n// =============================================================================\n// Field-Specific Coercion\n// =============================================================================\n\nfunction coerceToString(\n fieldId: string,\n rawValue: RawFieldValue,\n): CoercionResult {\n if (rawValue === null) {\n return {\n ok: true,\n patch: { op: \"set_string\", fieldId, value: null },\n };\n }\n\n if (typeof rawValue === \"string\") {\n return {\n ok: true,\n patch: { op: \"set_string\", fieldId, value: rawValue },\n };\n }\n\n if (typeof rawValue === \"number\") {\n return {\n ok: true,\n patch: { op: \"set_string\", fieldId, value: String(rawValue) },\n warning: `Coerced number ${rawValue} to string for field '${fieldId}'`,\n };\n }\n\n if (typeof rawValue === \"boolean\") {\n return {\n ok: true,\n patch: { op: \"set_string\", fieldId, value: String(rawValue) },\n warning: `Coerced boolean ${rawValue} to string for field '${fieldId}'`,\n };\n }\n\n return {\n ok: false,\n error: `Cannot coerce ${typeof rawValue} to string for field '${fieldId}'`,\n };\n}\n\nfunction coerceToNumber(\n fieldId: string,\n rawValue: RawFieldValue,\n): CoercionResult {\n if (rawValue === null) {\n return {\n ok: true,\n patch: { op: \"set_number\", fieldId, value: null },\n };\n }\n\n if (typeof rawValue === \"number\") {\n return {\n ok: true,\n patch: { op: \"set_number\", fieldId, value: rawValue },\n };\n }\n\n if (typeof rawValue === \"string\") {\n const parsed = Number(rawValue);\n if (!Number.isNaN(parsed)) {\n return {\n ok: true,\n patch: { op: \"set_number\", fieldId, value: parsed },\n warning: `Coerced string '${rawValue}' to number for field '${fieldId}'`,\n };\n }\n return {\n ok: false,\n error: `Cannot coerce non-numeric string '${rawValue}' to number for field '${fieldId}'`,\n };\n }\n\n return {\n ok: false,\n error: `Cannot coerce ${typeof rawValue} to number for field '${fieldId}'`,\n };\n}\n\nfunction coerceToStringList(\n fieldId: string,\n rawValue: RawFieldValue,\n): CoercionResult {\n if (rawValue === null) {\n return {\n ok: true,\n patch: { op: \"set_string_list\", fieldId, items: [] },\n };\n }\n\n if (isStringArray(rawValue)) {\n return {\n ok: true,\n patch: { op: \"set_string_list\", fieldId, items: rawValue },\n };\n }\n\n if (typeof rawValue === \"string\") {\n return {\n ok: true,\n patch: { op: \"set_string_list\", fieldId, items: [rawValue] },\n warning: `Coerced single string to array for field '${fieldId}'`,\n };\n }\n\n if (Array.isArray(rawValue)) {\n // Try to coerce non-string items\n const items: string[] = [];\n for (const item of rawValue) {\n if (typeof item === \"string\") {\n items.push(item);\n } else if (typeof item === \"number\" || typeof item === \"boolean\") {\n items.push(String(item));\n } else {\n return {\n ok: false,\n error: `Cannot coerce array with non-string items to string_list for field '${fieldId}'`,\n };\n }\n }\n return {\n ok: true,\n patch: { op: \"set_string_list\", fieldId, items },\n warning: `Coerced array items to strings for field '${fieldId}'`,\n };\n }\n\n return {\n ok: false,\n error: `Cannot coerce ${typeof rawValue} to string_list for field '${fieldId}'`,\n };\n}\n\nfunction coerceToSingleSelect(\n field: Field,\n rawValue: RawFieldValue,\n): CoercionResult {\n if (field.kind !== \"single_select\") {\n return { ok: false, error: `Field '${field.id}' is not a single_select field` };\n }\n\n if (rawValue === null) {\n return {\n ok: true,\n patch: { op: \"set_single_select\", fieldId: field.id, selected: null },\n };\n }\n\n if (typeof rawValue !== \"string\") {\n return {\n ok: false,\n error: `single_select field '${field.id}' requires a string option ID, got ${typeof rawValue}`,\n };\n }\n\n const validOptions = new Set(field.options.map((o) => o.id));\n if (!validOptions.has(rawValue)) {\n return {\n ok: false,\n error: `Invalid option '${rawValue}' for single_select field '${field.id}'. Valid options: ${Array.from(validOptions).join(\", \")}`,\n };\n }\n\n return {\n ok: true,\n patch: { op: \"set_single_select\", fieldId: field.id, selected: rawValue },\n };\n}\n\nfunction coerceToMultiSelect(\n field: Field,\n rawValue: RawFieldValue,\n): CoercionResult {\n if (field.kind !== \"multi_select\") {\n return { ok: false, error: `Field '${field.id}' is not a multi_select field` };\n }\n\n if (rawValue === null) {\n return {\n ok: true,\n patch: { op: \"set_multi_select\", fieldId: field.id, selected: [] },\n };\n }\n\n const validOptions = new Set(field.options.map((o) => o.id));\n let selected: string[];\n let warning: string | undefined;\n\n if (typeof rawValue === \"string\") {\n selected = [rawValue];\n warning = `Coerced single string to array for multi_select field '${field.id}'`;\n } else if (isStringArray(rawValue)) {\n selected = rawValue;\n } else {\n return {\n ok: false,\n error: `multi_select field '${field.id}' requires a string or string array, got ${typeof rawValue}`,\n };\n }\n\n // Validate all options\n for (const optId of selected) {\n if (!validOptions.has(optId)) {\n return {\n ok: false,\n error: `Invalid option '${optId}' for multi_select field '${field.id}'. Valid options: ${Array.from(validOptions).join(\", \")}`,\n };\n }\n }\n\n const patch: Patch = { op: \"set_multi_select\", fieldId: field.id, selected };\n return warning ? { ok: true, patch, warning } : { ok: true, patch };\n}\n\nfunction coerceToCheckboxes(\n field: Field,\n rawValue: RawFieldValue,\n): CoercionResult {\n if (field.kind !== \"checkboxes\") {\n return { ok: false, error: `Field '${field.id}' is not a checkboxes field` };\n }\n\n if (rawValue === null) {\n return {\n ok: true,\n patch: { op: \"set_checkboxes\", fieldId: field.id, values: {} },\n };\n }\n\n if (!isPlainObject(rawValue)) {\n return {\n ok: false,\n error: `checkboxes field '${field.id}' requires a Record<string, CheckboxValue>, got ${typeof rawValue}`,\n };\n }\n\n const validOptions = new Set(field.options.map((o) => o.id));\n const checkboxMode = field.checkboxMode;\n const values: Record<OptionId, CheckboxValue> = {};\n\n // Valid checkbox values based on mode\n const validValues = new Set<string>(\n checkboxMode === \"explicit\"\n ? [\"unfilled\", \"yes\", \"no\"]\n : checkboxMode === \"simple\"\n ? [\"todo\", \"done\"]\n : [\"todo\", \"done\", \"incomplete\", \"active\", \"na\"]\n );\n\n for (const [optId, value] of Object.entries(rawValue)) {\n if (!validOptions.has(optId)) {\n return {\n ok: false,\n error: `Invalid option '${optId}' for checkboxes field '${field.id}'. Valid options: ${Array.from(validOptions).join(\", \")}`,\n };\n }\n\n if (typeof value !== \"string\" || !validValues.has(value)) {\n return {\n ok: false,\n error: `Invalid checkbox value '${String(value)}' for option '${optId}' in field '${field.id}'. Valid values for ${checkboxMode} mode: ${Array.from(validValues).join(\", \")}`,\n };\n }\n\n values[optId] = value as CheckboxValue;\n }\n\n return {\n ok: true,\n patch: { op: \"set_checkboxes\", fieldId: field.id, values },\n };\n}\n\n// =============================================================================\n// Main Coercion Functions\n// =============================================================================\n\n/**\n * Coerce a raw value to a Patch for a specific field.\n */\nexport function coerceToFieldPatch(\n form: ParsedForm,\n fieldId: string,\n rawValue: RawFieldValue,\n): CoercionResult {\n const field = findFieldById(form, fieldId);\n if (!field) {\n return { ok: false, error: `Field '${fieldId}' not found` };\n }\n\n switch (field.kind) {\n case \"string\":\n return coerceToString(fieldId, rawValue);\n case \"number\":\n return coerceToNumber(fieldId, rawValue);\n case \"string_list\":\n return coerceToStringList(fieldId, rawValue);\n case \"single_select\":\n return coerceToSingleSelect(field, rawValue);\n case \"multi_select\":\n return coerceToMultiSelect(field, rawValue);\n case \"checkboxes\":\n return coerceToCheckboxes(field, rawValue);\n default: {\n // Exhaustive check\n const _exhaustive: never = field;\n return { ok: false, error: `Unknown field kind: ${(_exhaustive as Field).kind}` };\n }\n }\n}\n\n/**\n * Coerce an entire InputContext to patches.\n *\n * Returns patches for valid entries, collects warnings for coercions,\n * and errors for invalid entries.\n */\nexport function coerceInputContext(\n form: ParsedForm,\n inputContext: InputContext,\n): CoerceInputContextResult {\n const patches: Patch[] = [];\n const warnings: string[] = [];\n const errors: string[] = [];\n\n for (const [fieldId, rawValue] of Object.entries(inputContext)) {\n // Skip null values (no-op, field unchanged)\n if (rawValue === null) {\n continue;\n }\n\n const result = coerceToFieldPatch(form, fieldId, rawValue);\n\n if (result.ok) {\n patches.push(result.patch);\n if (\"warning\" in result && result.warning) {\n warnings.push(result.warning);\n }\n } else {\n errors.push(result.error);\n }\n }\n\n return { patches, warnings, errors };\n}\n","/**\n * Form Harness - Execution harness for form filling.\n *\n * Manages the step protocol for agent-driven form completion:\n * INIT -> STEP -> WAIT -> APPLY -> (repeat) -> COMPLETE\n */\n\nimport { createHash } from \"node:crypto\";\n\nimport { applyPatches } from \"../engine/apply.js\";\nimport { inspect, getFieldsForRoles } from \"../engine/inspect.js\";\nimport { serialize } from \"../engine/serialize.js\";\nimport type {\n ClearFieldPatch,\n HarnessConfig,\n InspectIssue,\n ParsedForm,\n Patch,\n SessionTurn,\n StepResult,\n} from \"../engine/coreTypes.js\";\nimport {\n DEFAULT_MAX_ISSUES,\n DEFAULT_MAX_PATCHES_PER_TURN,\n DEFAULT_MAX_TURNS,\n AGENT_ROLE,\n} from \"../settings.js\";\n\n// =============================================================================\n// Default Configuration\n// =============================================================================\n\nconst DEFAULT_CONFIG: HarnessConfig = {\n maxIssues: DEFAULT_MAX_ISSUES,\n maxPatchesPerTurn: DEFAULT_MAX_PATCHES_PER_TURN,\n maxTurns: DEFAULT_MAX_TURNS,\n};\n\n// =============================================================================\n// Harness State\n// =============================================================================\n\ntype HarnessState = \"init\" | \"step\" | \"wait\" | \"complete\";\n\n// =============================================================================\n// Form Harness Class\n// =============================================================================\n\n/**\n * Form harness for managing agent-driven form filling.\n */\nexport class FormHarness {\n private form: ParsedForm;\n private config: HarnessConfig;\n private state: HarnessState = \"init\";\n private turnNumber = 0;\n private turns: SessionTurn[] = [];\n\n constructor(form: ParsedForm, config: Partial<HarnessConfig> = {}) {\n this.form = form;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Get the current harness state.\n */\n getState(): HarnessState {\n return this.state;\n }\n\n /**\n * Get the current turn number.\n */\n getTurnNumber(): number {\n return this.turnNumber;\n }\n\n /**\n * Get the recorded session turns.\n */\n getTurns(): SessionTurn[] {\n return [...this.turns];\n }\n\n /**\n * Get the current form.\n */\n getForm(): ParsedForm {\n return this.form;\n }\n\n /**\n * Check if the harness has reached max turns.\n */\n hasReachedMaxTurns(): boolean {\n return this.turnNumber >= this.config.maxTurns;\n }\n\n /**\n * Perform a step - inspect the form and return current state.\n *\n * This transitions from INIT/WAIT -> STEP state.\n * Returns the current form state with prioritized issues.\n *\n * On first step with fillMode='overwrite', clears all target role fields\n * so they will be reported as needing to be filled.\n */\n step(): StepResult {\n if (this.state === \"complete\") {\n throw new Error(\"Harness is complete - cannot step\");\n }\n\n // On first step with fillMode='overwrite', clear all target role fields\n if (this.state === \"init\" && this.config.fillMode === \"overwrite\") {\n this.clearTargetRoleFields();\n }\n\n // Increment turn number\n this.turnNumber++;\n\n // Check max turns\n if (this.turnNumber > this.config.maxTurns) {\n this.state = \"complete\";\n const result = inspect(this.form, { targetRoles: this.config.targetRoles });\n return {\n structureSummary: result.structureSummary,\n progressSummary: result.progressSummary,\n issues: [],\n stepBudget: 0,\n isComplete: result.isComplete,\n turnNumber: this.turnNumber,\n };\n }\n\n this.state = \"step\";\n\n // Inspect form to get all issues (filtered by target roles if configured)\n const result = inspect(this.form, { targetRoles: this.config.targetRoles });\n\n // Issue filtering pipeline (order matters):\n // 1. Filter by maxGroupsPerTurn/maxFieldsPerTurn - limits scope diversity\n // 2. Cap by maxIssues - limits total count shown to agent\n const filteredIssues = this.filterIssuesByScope(result.issues);\n const limitedIssues = filteredIssues.slice(0, this.config.maxIssues);\n\n // Calculate step budget\n const stepBudget = Math.min(\n this.config.maxPatchesPerTurn,\n limitedIssues.filter((i) => i.severity === \"required\").length\n );\n\n // If complete, transition to complete state\n if (result.isComplete) {\n this.state = \"complete\";\n } else {\n this.state = \"wait\";\n }\n\n return {\n structureSummary: result.structureSummary,\n progressSummary: result.progressSummary,\n issues: limitedIssues,\n stepBudget,\n isComplete: result.isComplete,\n turnNumber: this.turnNumber,\n };\n }\n\n /**\n * Apply patches to the form.\n *\n * This transitions from WAIT -> STEP/COMPLETE state.\n * Records the turn in the session transcript.\n *\n * @param patches - Patches to apply\n * @param issues - Issues that were shown to the agent (for recording)\n * @returns StepResult after applying patches\n */\n apply(patches: Patch[], issues: InspectIssue[]): StepResult {\n if (this.state !== \"wait\") {\n throw new Error(`Cannot apply in state: ${this.state}`);\n }\n\n if (patches.length > this.config.maxPatchesPerTurn) {\n throw new Error(\n `Too many patches: ${patches.length} > ${this.config.maxPatchesPerTurn}`\n );\n }\n\n // Apply patches\n const result = applyPatches(this.form, patches);\n\n // Compute markdown hash\n const markdown = serialize(this.form);\n const hash = createHash(\"sha256\").update(markdown).digest(\"hex\");\n\n // Record turn\n const requiredIssueCount = result.issues.filter(\n (i) => i.severity === \"required\"\n ).length;\n\n this.turns.push({\n turn: this.turnNumber,\n inspect: { issues },\n apply: { patches },\n after: {\n requiredIssueCount,\n markdownSha256: hash,\n },\n });\n\n // Issue filtering pipeline for next turn (same as step())\n const filteredIssues = this.filterIssuesByScope(result.issues);\n const limitedIssues = filteredIssues.slice(0, this.config.maxIssues);\n\n // Calculate step budget for next turn\n const stepBudget = Math.min(\n this.config.maxPatchesPerTurn,\n limitedIssues.filter((i) => i.severity === \"required\").length\n );\n\n // Check if complete\n if (result.isComplete) {\n this.state = \"complete\";\n } else if (this.turnNumber >= this.config.maxTurns) {\n this.state = \"complete\";\n } else {\n this.state = \"wait\";\n }\n\n return {\n structureSummary: result.structureSummary,\n progressSummary: result.progressSummary,\n issues: limitedIssues,\n stepBudget,\n isComplete: result.isComplete,\n turnNumber: this.turnNumber,\n };\n }\n\n /**\n * Check if the form is complete.\n */\n isComplete(): boolean {\n const result = inspect(this.form, { targetRoles: this.config.targetRoles });\n return result.isComplete;\n }\n\n /**\n * Get the current markdown content of the form.\n */\n getMarkdown(): string {\n return serialize(this.form);\n }\n\n /**\n * Get the SHA256 hash of the current form markdown.\n */\n getMarkdownHash(): string {\n const markdown = serialize(this.form);\n return createHash(\"sha256\").update(markdown).digest(\"hex\");\n }\n\n /**\n * Filter issues based on maxFieldsPerTurn and maxGroupsPerTurn limits.\n *\n * Issues are processed in priority order. An issue is included if:\n * - Adding it doesn't exceed the field limit (for field/option scoped issues)\n * - Adding it doesn't exceed the group limit\n *\n * Form-level issues are always included.\n */\n private filterIssuesByScope(issues: InspectIssue[]): InspectIssue[] {\n const maxFields = this.config.maxFieldsPerTurn;\n const maxGroups = this.config.maxGroupsPerTurn;\n\n // If no limits configured, return all issues\n if (maxFields === undefined && maxGroups === undefined) {\n return issues;\n }\n\n const result: InspectIssue[] = [];\n const seenFields = new Set<string>();\n const seenGroups = new Set<string>();\n\n for (const issue of issues) {\n // Form-level issues always pass\n if (issue.scope === \"form\") {\n result.push(issue);\n continue;\n }\n\n // Extract field ID from ref (for options, it's \"fieldId.optionId\")\n const fieldId = this.getFieldIdFromRef(issue.ref, issue.scope);\n\n // Get the parent group for the field (if any)\n const groupId = fieldId ? this.getGroupForField(fieldId) : undefined;\n\n // Check field limit\n if (maxFields !== undefined && fieldId) {\n if (!seenFields.has(fieldId) && seenFields.size >= maxFields) {\n continue; // Would exceed field limit\n }\n }\n\n // Check group limit\n if (maxGroups !== undefined && groupId) {\n if (!seenGroups.has(groupId) && seenGroups.size >= maxGroups) {\n continue; // Would exceed group limit\n }\n }\n\n // Include the issue and track the field/group\n result.push(issue);\n if (fieldId) {\nseenFields.add(fieldId);\n}\n if (groupId) {\nseenGroups.add(groupId);\n}\n }\n\n return result;\n }\n\n /**\n * Extract field ID from an issue ref.\n */\n private getFieldIdFromRef(\n ref: string,\n scope: InspectIssue[\"scope\"]\n ): string | undefined {\n if (scope === \"field\") {\n return ref;\n }\n if (scope === \"option\") {\n // Option refs are \"fieldId.optionId\"\n const dotIndex = ref.indexOf(\".\");\n return dotIndex > 0 ? ref.slice(0, dotIndex) : undefined;\n }\n // Group-level issues don't have a field\n return undefined;\n }\n\n /**\n * Get the parent group ID for a field.\n */\n private getGroupForField(fieldId: string): string | undefined {\n const entry = this.form.idIndex.get(fieldId);\n if (!entry) {\nreturn undefined;\n}\n\n // If the field has a parent and that parent is a group, return it\n if (entry.parentId) {\n const parentEntry = this.form.idIndex.get(entry.parentId);\n if (parentEntry?.kind === \"group\") {\n return entry.parentId;\n }\n }\n\n return undefined;\n }\n\n /**\n * Clear all fields that match the target roles.\n * Used when fillMode='overwrite' to re-fill already-filled fields.\n */\n private clearTargetRoleFields(): void {\n const targetRoles = this.config.targetRoles ?? [AGENT_ROLE];\n const targetFields = getFieldsForRoles(this.form, targetRoles);\n\n // Create clear patches for all target role fields\n const clearPatches: ClearFieldPatch[] = targetFields.map((field) => ({\n op: \"clear_field\" as const,\n fieldId: field.id,\n }));\n\n // Apply clear patches (this modifies the form in place)\n if (clearPatches.length > 0) {\n applyPatches(this.form, clearPatches);\n }\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a new form harness.\n *\n * @param form - The parsed form to fill\n * @param config - Optional harness configuration\n * @returns A new FormHarness instance\n */\nexport function createHarness(\n form: ParsedForm,\n config?: Partial<HarnessConfig>\n): FormHarness {\n return new FormHarness(form, config);\n}\n","/**\n * Mock Agent - Deterministic agent for testing harness execution.\n *\n * Uses a pre-filled \"completed mock\" form to generate patches\n * that fill the form deterministically.\n */\n\nimport type {\n CheckboxesValue,\n Field,\n FieldValue,\n Id,\n InspectIssue,\n MultiSelectValue,\n NumberValue,\n Patch,\n ParsedForm,\n SingleSelectValue,\n StringListValue,\n StringValue,\n} from \"../engine/coreTypes.js\";\nimport type { Agent } from \"./harnessTypes.js\";\n\n// Re-export Agent type for backwards compatibility\nexport type { Agent } from \"./harnessTypes.js\";\n\n// =============================================================================\n// Mock Agent Implementation\n// =============================================================================\n\n/**\n * Mock agent that generates patches from a pre-filled form.\n */\nexport class MockAgent implements Agent {\n private completedValues: Record<Id, FieldValue>;\n private fieldMap: Map<Id, Field>;\n\n /**\n * Create a mock agent from a completed form.\n *\n * @param completedForm - A fully-filled form to use as source of values\n */\n constructor(completedForm: ParsedForm) {\n this.completedValues = { ...completedForm.valuesByFieldId };\n\n // Build field map for quick lookup\n this.fieldMap = new Map();\n for (const group of completedForm.schema.groups) {\n for (const field of group.children) {\n this.fieldMap.set(field.id, field);\n }\n }\n }\n\n /**\n * Generate patches from the completed mock to address issues.\n *\n * Processes issues in priority order, generating patches for\n * fields that have values in the completed mock.\n */\n async generatePatches(\n issues: InspectIssue[],\n _form: ParsedForm,\n maxPatches: number\n ): Promise<Patch[]> {\n const patches: Patch[] = [];\n const addressedFields = new Set<Id>();\n\n // Process issues in priority order\n for (const issue of issues) {\n if (patches.length >= maxPatches) {\n break;\n }\n\n // Skip non-field issues\n if (issue.scope !== \"field\") {\n continue;\n }\n\n const fieldId = issue.ref;\n\n // Skip if we've already addressed this field\n if (addressedFields.has(fieldId)) {\n continue;\n }\n\n // Get the completed value for this field\n const completedValue = this.completedValues[fieldId];\n if (!completedValue) {\n continue;\n }\n\n // Get field schema\n const field = this.fieldMap.get(fieldId);\n if (!field) {\n continue;\n }\n\n // Generate patch based on field kind\n const patch = this.createPatch(fieldId, field, completedValue);\n if (patch) {\n patches.push(patch);\n addressedFields.add(fieldId);\n }\n }\n\n // Return wrapped in Promise.resolve to satisfy async interface\n return Promise.resolve(patches);\n }\n\n /**\n * Create a patch for a field based on its kind and completed value.\n */\n private createPatch(\n fieldId: Id,\n field: Field,\n value: FieldValue\n ): Patch | null {\n switch (field.kind) {\n case \"string\": {\n const v = value as StringValue;\n return {\n op: \"set_string\",\n fieldId,\n value: v.value,\n };\n }\n\n case \"number\": {\n const v = value as NumberValue;\n return {\n op: \"set_number\",\n fieldId,\n value: v.value,\n };\n }\n\n case \"string_list\": {\n const v = value as StringListValue;\n return {\n op: \"set_string_list\",\n fieldId,\n items: v.items,\n };\n }\n\n case \"single_select\": {\n const v = value as SingleSelectValue;\n return {\n op: \"set_single_select\",\n fieldId,\n selected: v.selected,\n };\n }\n\n case \"multi_select\": {\n const v = value as MultiSelectValue;\n return {\n op: \"set_multi_select\",\n fieldId,\n selected: v.selected,\n };\n }\n\n case \"checkboxes\": {\n const v = value as CheckboxesValue;\n return {\n op: \"set_checkboxes\",\n fieldId,\n values: v.values,\n };\n }\n\n default:\n return null;\n }\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a mock agent from a completed form.\n *\n * @param completedForm - A fully-filled form to use as source of values\n * @returns A new MockAgent instance\n */\nexport function createMockAgent(completedForm: ParsedForm): MockAgent {\n return new MockAgent(completedForm);\n}\n","/**\n * Live Agent - LLM-powered agent for form filling.\n *\n * Uses AI SDK to call an LLM that fills forms autonomously\n * by analyzing issues and generating appropriate patches.\n */\n\nimport type { LanguageModel } from \"ai\";\nimport { generateText, stepCountIs, zodSchema } from \"ai\";\nimport { z } from \"zod\";\n\nimport type {\n DocumentationBlock,\n InspectIssue,\n ParsedForm,\n Patch,\n} from \"../engine/coreTypes.js\";\nimport { PatchSchema } from \"../engine/coreTypes.js\";\nimport { DEFAULT_ROLE_INSTRUCTIONS, AGENT_ROLE } from \"../settings.js\";\nimport type { Agent, LiveAgentConfig } from \"./harnessTypes.js\";\n\n// Re-export types for backwards compatibility\nexport type { LiveAgentConfig } from \"./harnessTypes.js\";\n\n// =============================================================================\n// Live Agent Implementation\n// =============================================================================\n\n/**\n * Live agent that uses an LLM to generate patches.\n */\nexport class LiveAgent implements Agent {\n private model: LanguageModel;\n private maxStepsPerTurn: number;\n private systemPromptAddition?: string;\n private targetRole: string;\n\n constructor(config: LiveAgentConfig) {\n this.model = config.model;\n this.maxStepsPerTurn = config.maxStepsPerTurn ?? 3;\n this.systemPromptAddition = config.systemPromptAddition;\n this.targetRole = config.targetRole ?? AGENT_ROLE;\n }\n\n /**\n * Generate patches using the LLM.\n *\n * Calls the model with the current form state and issues,\n * and extracts patches from the tool calls.\n */\n async generatePatches(\n issues: InspectIssue[],\n form: ParsedForm,\n maxPatches: number\n ): Promise<Patch[]> {\n // Build context prompt with issues and form schema\n const contextPrompt = buildContextPrompt(issues, form, maxPatches);\n\n // Build composed system prompt from form instructions\n let systemPrompt = buildSystemPrompt(form, this.targetRole, issues);\n\n // Append additional context if provided (never overrides form instructions)\n if (this.systemPromptAddition) {\n systemPrompt += \"\\n\\n# Additional Context\\n\" + this.systemPromptAddition;\n }\n\n // Define the patch tool with properly typed parameters\n const patchesSchema = z.object({\n patches: z.array(PatchSchema).max(maxPatches).describe(\n \"Array of patches. Each patch sets a value for one field.\"\n ),\n });\n\n // Create tool using zodSchema wrapper for AI SDK v6 compatibility\n const generatePatchesTool = {\n description:\n \"Generate patches to fill form fields. Each patch sets a field value. \" +\n \"Use the field IDs from the issues list. Return patches for all issues you can address.\",\n inputSchema: zodSchema(patchesSchema),\n };\n\n // Call the model\n const result = await generateText({\n model: this.model,\n system: systemPrompt,\n prompt: contextPrompt,\n tools: { generatePatches: generatePatchesTool },\n stopWhen: stepCountIs(this.maxStepsPerTurn),\n });\n\n // Extract patches from tool calls\n const patches: Patch[] = [];\n for (const step of result.steps) {\n for (const toolCall of step.toolCalls) {\n if (toolCall.toolName === \"generatePatches\" && \"input\" in toolCall) {\n const input = toolCall.input as { patches: Patch[] };\n patches.push(...input.patches);\n }\n }\n }\n\n // Limit to maxPatches\n return patches.slice(0, maxPatches);\n }\n}\n\n// =============================================================================\n// Context Building\n// =============================================================================\n\n/**\n * Default system prompt for the live agent.\n */\nconst DEFAULT_SYSTEM_PROMPT = `You are a form-filling assistant. Your task is to analyze form issues and generate patches to fill in the required fields.\n\nGuidelines:\n1. Focus on required fields first (severity: \"required\")\n2. Use realistic but generic values when specific data is not provided\n3. Match the expected field types exactly\n4. For string fields: use appropriate text\n5. For number fields: use appropriate numeric values\n6. For single_select: choose one valid option ID\n7. For multi_select: choose one or more valid option IDs\n8. For checkboxes: set appropriate states (done/todo for simple, yes/no for explicit)\n\nAlways use the generatePatches tool to submit your field values.`;\n\n/**\n * Extract doc blocks of a specific tag type for a given ref.\n */\nfunction getDocBlocks(\n docs: DocumentationBlock[],\n ref: string,\n tag: string\n): DocumentationBlock[] {\n return docs.filter((d) => d.ref === ref && d.tag === tag);\n}\n\n/**\n * Build a composed system prompt from form instructions.\n *\n * Instruction sources (later ones augment earlier):\n * 1. Base form instructions - Doc blocks with ref=formId and tag=\"instructions\"\n * 2. Role-specific instructions - From form.metadata.roleInstructions[targetRole]\n * 3. Per-field instructions - Doc blocks with ref=fieldId and tag=\"instructions\"\n * 4. System defaults - DEFAULT_ROLE_INSTRUCTIONS[targetRole] or DEFAULT_SYSTEM_PROMPT\n */\nfunction buildSystemPrompt(\n form: ParsedForm,\n targetRole: string,\n issues: InspectIssue[]\n): string {\n const sections: string[] = [];\n\n // Start with base system prompt guidelines\n sections.push(DEFAULT_SYSTEM_PROMPT);\n\n // 1. Form-level instructions (doc blocks with kind=\"instructions\" for the form)\n const formInstructions = getDocBlocks(form.docs, form.schema.id, \"instructions\");\n if (formInstructions.length > 0) {\n sections.push(\"\");\n sections.push(\"# Form Instructions\");\n for (const doc of formInstructions) {\n sections.push(doc.bodyMarkdown.trim());\n }\n }\n\n // 2. Role-specific instructions from frontmatter\n const roleInstructions = form.metadata?.roleInstructions?.[targetRole];\n if (roleInstructions) {\n sections.push(\"\");\n sections.push(`# Instructions for ${targetRole} role`);\n sections.push(roleInstructions);\n } else {\n // Fallback to default role instructions\n const defaultRoleInstr = DEFAULT_ROLE_INSTRUCTIONS[targetRole];\n if (defaultRoleInstr) {\n sections.push(\"\");\n sections.push(`# Role guidance`);\n sections.push(defaultRoleInstr);\n }\n }\n\n // 3. Per-field instructions for fields being addressed\n const fieldIds = new Set(\n issues.filter((i) => i.scope === \"field\").map((i) => i.ref)\n );\n const fieldInstructions: string[] = [];\n\n for (const fieldId of fieldIds) {\n const fieldDocs = getDocBlocks(form.docs, fieldId, \"instructions\");\n if (fieldDocs.length > 0) {\n for (const doc of fieldDocs) {\n fieldInstructions.push(`**${fieldId}:** ${doc.bodyMarkdown.trim()}`);\n }\n }\n }\n\n if (fieldInstructions.length > 0) {\n sections.push(\"\");\n sections.push(\"# Field-specific instructions\");\n sections.push(...fieldInstructions);\n }\n\n return sections.join(\"\\n\");\n}\n\n/**\n * Build a context prompt with issues and form information.\n */\nfunction buildContextPrompt(\n issues: InspectIssue[],\n form: ParsedForm,\n maxPatches: number\n): string {\n const lines: string[] = [];\n\n lines.push(\"# Current Form Issues\");\n lines.push(\"\");\n lines.push(`You need to address up to ${maxPatches} issues. Here are the current issues:`);\n lines.push(\"\");\n\n for (const issue of issues) {\n lines.push(`- **${issue.ref}** (${issue.scope}): ${issue.message}`);\n lines.push(` Severity: ${issue.severity}, Priority: P${issue.priority}`);\n\n // If it's a field issue, include field schema info\n if (issue.scope === \"field\") {\n const field = findField(form, issue.ref);\n if (field) {\n lines.push(` Type: ${field.kind}`);\n if (\"options\" in field && field.options) {\n const optionIds = field.options.map((o) => o.id).join(\", \");\n lines.push(` Options: ${optionIds}`);\n }\n if (field.kind === \"checkboxes\" && \"checkboxMode\" in field) {\n lines.push(` Mode: ${field.checkboxMode ?? \"multi\"}`);\n }\n }\n }\n lines.push(\"\");\n }\n\n lines.push(\"# Instructions\");\n lines.push(\"\");\n lines.push(\"Use the generatePatches tool to submit patches for the fields above.\");\n lines.push(\"Each patch should match the field type:\");\n lines.push(\"- string: { op: \\\"set_string\\\", fieldId: \\\"...\\\", value: \\\"...\\\" }\");\n lines.push(\"- number: { op: \\\"set_number\\\", fieldId: \\\"...\\\", value: 123 }\");\n lines.push(\"- string_list: { op: \\\"set_string_list\\\", fieldId: \\\"...\\\", items: [\\\"...\\\", \\\"...\\\"] }\");\n lines.push(\"- single_select: { op: \\\"set_single_select\\\", fieldId: \\\"...\\\", selected: \\\"option_id\\\" }\");\n lines.push(\"- multi_select: { op: \\\"set_multi_select\\\", fieldId: \\\"...\\\", selected: [\\\"opt1\\\", \\\"opt2\\\"] }\");\n lines.push(\"- checkboxes: { op: \\\"set_checkboxes\\\", fieldId: \\\"...\\\", values: { \\\"opt1\\\": \\\"done\\\", \\\"opt2\\\": \\\"todo\\\" } }\");\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Find a field by ID in the form.\n */\nfunction findField(form: ParsedForm, fieldId: string) {\n for (const group of form.schema.groups) {\n for (const field of group.children) {\n if (field.id === fieldId) {\n return field;\n }\n }\n }\n return null;\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a live agent with the given configuration.\n */\nexport function createLiveAgent(config: LiveAgentConfig): LiveAgent {\n return new LiveAgent(config);\n}\n","/**\n * Model Resolver - Parse and resolve AI SDK model identifiers.\n *\n * Parses model IDs in the format `provider/model-id` and dynamically\n * imports the corresponding AI SDK provider.\n */\n\nimport type { LanguageModel } from \"ai\";\n\nimport type {\n ParsedModelId,\n ProviderInfo,\n ProviderName,\n ResolvedModel,\n} from \"./harnessTypes.js\";\n\n// Re-export types for backwards compatibility\nexport type {\n ParsedModelId,\n ProviderInfo,\n ProviderName,\n ResolvedModel,\n} from \"./harnessTypes.js\";\n\n/**\n * Map of provider names to their npm package and env var.\n */\nconst PROVIDERS: Record<\n ProviderName,\n { package: string; envVar: string; createFn: string }\n> = {\n anthropic: {\n package: \"@ai-sdk/anthropic\",\n envVar: \"ANTHROPIC_API_KEY\",\n createFn: \"createAnthropic\",\n },\n openai: {\n package: \"@ai-sdk/openai\",\n envVar: \"OPENAI_API_KEY\",\n createFn: \"createOpenAI\",\n },\n google: {\n package: \"@ai-sdk/google\",\n envVar: \"GOOGLE_GENERATIVE_AI_API_KEY\",\n createFn: \"createGoogleGenerativeAI\",\n },\n xai: {\n package: \"@ai-sdk/xai\",\n envVar: \"XAI_API_KEY\",\n createFn: \"createXai\",\n },\n deepseek: {\n package: \"@ai-sdk/deepseek\",\n envVar: \"DEEPSEEK_API_KEY\",\n createFn: \"createDeepSeek\",\n },\n};\n\n// =============================================================================\n// Model Resolution\n// =============================================================================\n\n/**\n * Parse a model ID string into provider and model components.\n *\n * @param modelIdString - Model ID in format `provider/model-id`\n * @returns Parsed model identifier\n * @throws Error if format is invalid\n */\nexport function parseModelId(modelIdString: string): ParsedModelId {\n const slashIndex = modelIdString.indexOf(\"/\");\n if (slashIndex === -1) {\n throw new Error(\n `Invalid model ID format: \"${modelIdString}\". Expected format: provider/model-id (e.g., anthropic/claude-sonnet-4-5)`\n );\n }\n\n const provider = modelIdString.slice(0, slashIndex);\n const modelId = modelIdString.slice(slashIndex + 1);\n\n if (!provider || !modelId) {\n throw new Error(\n `Invalid model ID format: \"${modelIdString}\". Both provider and model ID are required.`\n );\n }\n\n const supportedProviders = Object.keys(PROVIDERS);\n if (!supportedProviders.includes(provider)) {\n throw new Error(\n `Unknown provider: \"${provider}\". Supported providers: ${supportedProviders.join(\", \")}`\n );\n }\n\n return {\n provider: provider as ProviderName,\n modelId,\n };\n}\n\n/**\n * Resolve a model ID string to an AI SDK language model.\n *\n * Dynamically imports the provider package and creates the model instance.\n *\n * @param modelIdString - Model ID in format `provider/model-id`\n * @returns Resolved model with provider info\n * @throws Error if provider not installed or API key missing\n */\nexport async function resolveModel(\n modelIdString: string\n): Promise<ResolvedModel> {\n const { provider, modelId } = parseModelId(modelIdString);\n const providerConfig = PROVIDERS[provider];\n\n // Check for API key\n const apiKey = process.env[providerConfig.envVar];\n if (!apiKey) {\n throw new Error(\n `Missing API key for \"${provider}\" provider (model: ${modelIdString}).\\n` +\n `Set the ${providerConfig.envVar} environment variable or add it to your .env file.`\n );\n }\n\n // Dynamically import the provider\n let providerModule: Record<string, (modelId: string) => LanguageModel>;\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n providerModule = await import(providerConfig.package);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes(\"Cannot find module\") || message.includes(\"ERR_MODULE_NOT_FOUND\")) {\n throw new Error(\n `Provider package not installed for model \"${modelIdString}\".\\n` +\n `Install with: pnpm add ${providerConfig.package}`\n );\n }\n throw error;\n }\n\n // Get the createProvider function (e.g., createAnthropic, createOpenAI, createGoogleGenerativeAI)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const createFn = providerModule[providerConfig.createFn] as ((options: { apiKey: string }) => any) | undefined;\n\n let model: LanguageModel;\n\n if (createFn && typeof createFn === \"function\") {\n // Use the factory function with explicit API key\n // The provider instance is callable: providerInstance(modelId) returns a LanguageModel\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n model = createFn({ apiKey })(modelId);\n } else {\n // Fallback: try the simple provider function (for backwards compatibility)\n const providerFn = providerModule[provider] as\n | ((modelId: string) => LanguageModel)\n | undefined;\n if (typeof providerFn !== \"function\") {\n throw new Error(\n `Provider package \"${providerConfig.package}\" does not export expected function \"${provider}\" or \"${providerConfig.createFn}\"`\n );\n }\n model = providerFn(modelId);\n }\n\n return {\n model,\n provider,\n modelId,\n };\n}\n\n/**\n * Get list of supported provider names.\n */\nexport function getProviderNames(): ProviderName[] {\n return Object.keys(PROVIDERS) as ProviderName[];\n}\n\n/**\n * Get provider info for display purposes.\n */\nexport function getProviderInfo(provider: ProviderName): ProviderInfo {\n const config = PROVIDERS[provider];\n return {\n package: config.package,\n envVar: config.envVar,\n };\n}\n","/**\n * Programmatic Fill API - High-level entry point for form filling.\n *\n * Provides a single-function API for external agentic systems to execute\n * form-filling sessions with a single function call.\n */\n\nimport type { LanguageModel } from \"ai\";\n\nimport { applyPatches } from \"../engine/apply.js\";\nimport { parseForm } from \"../engine/parse.js\";\nimport { serialize } from \"../engine/serialize.js\";\nimport type { InspectIssue, ParsedForm } from \"../engine/coreTypes.js\";\nimport { coerceInputContext } from \"../engine/valueCoercion.js\";\nimport {\n AGENT_ROLE,\n DEFAULT_MAX_ISSUES,\n DEFAULT_MAX_PATCHES_PER_TURN,\n DEFAULT_MAX_TURNS,\n} from \"../settings.js\";\nimport { createHarness } from \"./harness.js\";\nimport { createLiveAgent } from \"./liveAgent.js\";\nimport { resolveModel } from \"./modelResolver.js\";\nimport type { Agent, FillOptions, FillResult, FillStatus } from \"./harnessTypes.js\";\n\n// Re-export types for backwards compatibility\nexport type { FillOptions, FillResult, FillStatus, TurnProgress } from \"./harnessTypes.js\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\nfunction buildErrorResult(\n form: ParsedForm,\n errors: string[],\n warnings: string[],\n): FillResult {\n return {\n status: {\n ok: false,\n reason: \"error\",\n message: errors.join(\"; \"),\n },\n markdown: serialize(form),\n values: { ...form.valuesByFieldId },\n form,\n turns: 0,\n totalPatches: 0,\n inputContextWarnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\nfunction buildResult(\n form: ParsedForm,\n turns: number,\n totalPatches: number,\n status: FillStatus,\n inputContextWarnings?: string[],\n remainingIssues?: InspectIssue[],\n): FillResult {\n const result: FillResult = {\n status,\n markdown: serialize(form),\n values: { ...form.valuesByFieldId },\n form,\n turns,\n totalPatches,\n };\n\n if (inputContextWarnings && inputContextWarnings.length > 0) {\n result.inputContextWarnings = inputContextWarnings;\n }\n\n if (remainingIssues && remainingIssues.length > 0) {\n result.remainingIssues = remainingIssues.map((issue) => ({\n ref: issue.ref,\n message: issue.message,\n severity: issue.severity,\n priority: issue.priority,\n }));\n }\n\n return result;\n}\n\n// =============================================================================\n// Main API\n// =============================================================================\n\n/**\n * Fill a form using an LLM agent.\n *\n * This is the primary programmatic entry point for markform. It encapsulates\n * the harness loop with LiveAgent and provides a single-function call for\n * form filling.\n *\n * @param options - Fill options\n * @returns Fill result with status, values, and markdown\n *\n * @example\n * ```typescript\n * import { fillForm } from 'markform';\n *\n * const result = await fillForm({\n * form: formMarkdown,\n * model: 'anthropic/claude-sonnet-4-5',\n * inputContext: {\n * company_name: 'Apple Inc.',\n * },\n * systemPromptAddition: `\n * ## Additional Context\n * ${backgroundInfo}\n * `,\n * onTurnComplete: (progress) => {\n * console.log(`Turn ${progress.turnNumber}: ${progress.requiredIssuesRemaining} remaining`);\n * },\n * });\n *\n * if (result.status.ok) {\n * console.log('Values:', result.values);\n * }\n * ```\n */\nexport async function fillForm(options: FillOptions): Promise<FillResult> {\n // 1. Parse form if string\n let form: ParsedForm;\n try {\n form =\n typeof options.form === \"string\"\n ? parseForm(options.form)\n : structuredClone(options.form);\n } catch (error) {\n // Return error result for parse failures\n const message = error instanceof Error ? error.message : String(error);\n return {\n status: { ok: false, reason: \"error\", message: `Form parse error: ${message}` },\n markdown: typeof options.form === \"string\" ? options.form : \"\",\n values: {},\n form: { schema: { id: \"\", groups: [] }, valuesByFieldId: {}, docs: [], orderIndex: [], idIndex: new Map() },\n turns: 0,\n totalPatches: 0,\n };\n }\n\n // 2. Resolve model if string (skip if _testAgent provided)\n let model: LanguageModel | undefined;\n if (!options._testAgent) {\n try {\n if (typeof options.model === \"string\") {\n const resolved = await resolveModel(options.model);\n model = resolved.model;\n } else {\n model = options.model;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return buildErrorResult(form, [`Model resolution error: ${message}`], []);\n }\n }\n\n // 3. Apply input context using coercion layer\n let totalPatches = 0;\n let inputContextWarnings: string[] = [];\n\n if (options.inputContext) {\n const coercionResult = coerceInputContext(form, options.inputContext);\n\n // Fail fast on input context errors\n if (coercionResult.errors.length > 0) {\n return buildErrorResult(form, coercionResult.errors, coercionResult.warnings);\n }\n\n // Apply coerced patches\n if (coercionResult.patches.length > 0) {\n applyPatches(form, coercionResult.patches);\n totalPatches = coercionResult.patches.length;\n }\n inputContextWarnings = coercionResult.warnings;\n }\n\n // 4. Create harness + agent\n const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;\n const maxPatchesPerTurn = options.maxPatchesPerTurn ?? DEFAULT_MAX_PATCHES_PER_TURN;\n const maxIssues = options.maxIssues ?? DEFAULT_MAX_ISSUES;\n const targetRoles = options.targetRoles ?? [AGENT_ROLE];\n\n const harness = createHarness(form, {\n maxTurns,\n maxPatchesPerTurn,\n maxIssues,\n targetRoles,\n fillMode: options.fillMode,\n });\n\n // Use test agent if provided, otherwise create LiveAgent\n const agent: Agent = options._testAgent ?? createLiveAgent({\n model: model!,\n systemPromptAddition: options.systemPromptAddition,\n targetRole: targetRoles[0] ?? AGENT_ROLE,\n });\n\n // 5. Run harness loop\n let turnCount = 0;\n let stepResult = harness.step();\n\n while (!stepResult.isComplete && !harness.hasReachedMaxTurns()) {\n // Check for cancellation\n if (options.signal?.aborted) {\n return buildResult(\n form,\n turnCount,\n totalPatches,\n { ok: false, reason: \"cancelled\" },\n inputContextWarnings,\n stepResult.issues,\n );\n }\n\n // Generate patches using agent\n const patches = await agent.generatePatches(\n stepResult.issues,\n form,\n maxPatchesPerTurn,\n );\n\n // Re-check for cancellation after agent call (signal may have fired during LLM call)\n if (options.signal?.aborted) {\n return buildResult(\n form,\n turnCount,\n totalPatches,\n { ok: false, reason: \"cancelled\" },\n inputContextWarnings,\n stepResult.issues,\n );\n }\n\n // Apply patches\n stepResult = harness.apply(patches, stepResult.issues);\n totalPatches += patches.length;\n turnCount++;\n\n // Call progress callback (errors don't abort fill)\n if (options.onTurnComplete) {\n try {\n const requiredIssues = stepResult.issues.filter(\n (i) => i.severity === \"required\",\n );\n options.onTurnComplete({\n turnNumber: turnCount,\n issuesShown: stepResult.issues.length,\n patchesApplied: patches.length,\n requiredIssuesRemaining: requiredIssues.length,\n isComplete: stepResult.isComplete,\n });\n } catch {\n // Ignore callback errors\n }\n }\n\n // If not complete, step again\n if (!stepResult.isComplete) {\n stepResult = harness.step();\n }\n }\n\n // 6. Determine final status\n if (stepResult.isComplete) {\n return buildResult(\n form,\n turnCount,\n totalPatches,\n { ok: true },\n inputContextWarnings,\n );\n }\n\n // Hit max turns without completing\n return buildResult(\n form,\n turnCount,\n totalPatches,\n { ok: false, reason: \"max_turns\", message: `Reached maximum turns (${maxTurns})` },\n inputContextWarnings,\n stepResult.issues,\n );\n}\n\n","/**\n * Markform - Agent-friendly, human-readable, editable forms.\n *\n * This is the main library entry point that exports the core engine,\n * types, and utilities for working with .form.md files.\n */\n\n/** Markform version. */\nexport const VERSION = \"0.1.0\";\n\n// =============================================================================\n// Type Exports\n// =============================================================================\n\nexport type {\n // Basic types\n Id,\n OptionId,\n QualifiedOptionRef,\n ValidatorRef,\n // Checkbox types\n MultiCheckboxState,\n SimpleCheckboxState,\n ExplicitCheckboxValue,\n CheckboxValue,\n CheckboxMode,\n // Field types\n FieldKind,\n FieldBase,\n StringField,\n NumberField,\n StringListField,\n Option,\n CheckboxesField,\n SingleSelectField,\n MultiSelectField,\n Field,\n // Form structure\n FieldGroup,\n FormSchema,\n // Field values\n StringValue,\n NumberValue,\n StringListValue,\n CheckboxesValue,\n SingleSelectValue,\n MultiSelectValue,\n FieldValue,\n // Documentation\n DocumentationTag,\n DocumentationBlock,\n // Parsed form\n IdIndexEntry,\n ParsedForm,\n // Validation\n Severity,\n SourcePosition,\n SourceRange,\n ValidationIssue,\n // Inspect\n IssueReason,\n IssueScope,\n InspectIssue,\n // Summaries\n StructureSummary,\n ProgressState,\n CheckboxProgressCounts,\n FieldProgress,\n ProgressCounts,\n ProgressSummary,\n // Results\n InspectResult,\n ApplyResult,\n // Patches\n SetStringPatch,\n SetNumberPatch,\n SetStringListPatch,\n SetCheckboxesPatch,\n SetSingleSelectPatch,\n SetMultiSelectPatch,\n ClearFieldPatch,\n Patch,\n // Harness\n StepResult,\n HarnessConfig,\n SessionTurn,\n SessionFinal,\n SessionTranscript,\n // Frontmatter\n MarkformFrontmatter,\n // Validators\n ValidatorContext,\n ValidatorFn,\n ValidatorRegistry,\n} from \"./engine/coreTypes.js\";\n\n// =============================================================================\n// Schema Exports\n// =============================================================================\n\nexport {\n // Basic schemas\n IdSchema,\n OptionIdSchema,\n ValidatorRefSchema,\n // Checkbox schemas\n MultiCheckboxStateSchema,\n SimpleCheckboxStateSchema,\n ExplicitCheckboxValueSchema,\n CheckboxValueSchema,\n CheckboxModeSchema,\n // Field schemas\n FieldKindSchema,\n OptionSchema,\n StringFieldSchema,\n NumberFieldSchema,\n StringListFieldSchema,\n CheckboxesFieldSchema,\n SingleSelectFieldSchema,\n MultiSelectFieldSchema,\n FieldSchema,\n // Form schemas\n FieldGroupSchema,\n FormSchemaSchema,\n // Value schemas\n StringValueSchema,\n NumberValueSchema,\n StringListValueSchema,\n CheckboxesValueSchema,\n SingleSelectValueSchema,\n MultiSelectValueSchema,\n FieldValueSchema,\n // Documentation schemas\n DocumentationTagSchema,\n DocumentationBlockSchema,\n // Validation schemas\n SeveritySchema,\n SourcePositionSchema,\n SourceRangeSchema,\n ValidationIssueSchema,\n // Inspect schemas\n IssueReasonSchema,\n IssueScopeSchema,\n InspectIssueSchema,\n // Summary schemas\n ProgressStateSchema,\n CheckboxProgressCountsSchema,\n FieldProgressSchema,\n ProgressCountsSchema,\n ProgressSummarySchema,\n StructureSummarySchema,\n // Result schemas\n InspectResultSchema,\n ApplyResultSchema,\n // Patch schemas\n SetStringPatchSchema,\n SetNumberPatchSchema,\n SetStringListPatchSchema,\n SetCheckboxesPatchSchema,\n SetSingleSelectPatchSchema,\n SetMultiSelectPatchSchema,\n ClearFieldPatchSchema,\n PatchSchema,\n // Harness schemas\n StepResultSchema,\n HarnessConfigSchema,\n SessionTurnSchema,\n SessionFinalSchema,\n SessionTranscriptSchema,\n // Frontmatter schema\n MarkformFrontmatterSchema,\n} from \"./engine/coreTypes.js\";\n\n// =============================================================================\n// Engine Exports\n// =============================================================================\n\nexport { parseForm, ParseError } from \"./engine/parse.js\";\nexport { serialize } from \"./engine/serialize.js\";\nexport type { SerializeOptions } from \"./engine/serialize.js\";\nexport {\n computeStructureSummary,\n computeProgressSummary,\n computeFormState,\n isFormComplete,\n computeAllSummaries,\n} from \"./engine/summaries.js\";\nexport type { ComputedSummaries } from \"./engine/summaries.js\";\nexport { validate } from \"./engine/validate.js\";\nexport type { ValidateOptions, ValidateResult } from \"./engine/validate.js\";\nexport { inspect } from \"./engine/inspect.js\";\nexport type { InspectOptions } from \"./engine/inspect.js\";\nexport { parseSession, serializeSession } from \"./engine/session.js\";\nexport { applyPatches } from \"./engine/apply.js\";\n\n// =============================================================================\n// Value Coercion Exports\n// =============================================================================\n\nexport {\n findFieldById,\n coerceToFieldPatch,\n coerceInputContext,\n} from \"./engine/valueCoercion.js\";\nexport type {\n RawFieldValue,\n InputContext,\n CoercionResult,\n CoerceInputContextResult,\n} from \"./engine/valueCoercion.js\";\n\n// =============================================================================\n// Harness Exports\n// =============================================================================\n\nexport { FormHarness, createHarness } from \"./harness/harness.js\";\nexport { MockAgent, createMockAgent } from \"./harness/mockAgent.js\";\nexport { fillForm } from \"./harness/programmaticFill.js\";\nexport type {\n FillOptions,\n FillResult,\n FillStatus,\n TurnProgress,\n} from \"./harness/programmaticFill.js\";\n"],"mappings":"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"}