FOSMVVM Fields Generator
Generate Form Specifications following FOSMVVM patterns.
Conceptual Foundation
For full architecture context, see FOSMVVMArchitecture.md | OpenClaw reference
A Form Specification (implemented as a {Name}Fields protocol) is the single source of truth for user input. It answers:
- 1. What data can the user provide? (properties)
- How should it be presented? (FormField with type, keyboard, autofill semantics)
- What constraints apply? (validation rules)
- What messages should be shown? (localized titles, placeholders, errors)
Why This Matters
The Form Specification is defined once, used everywhere:
CODEBLOCK0
This ensures:
- - Consistent validation - Same rules on client and server
- Shared localization - One YAML file, used everywhere
- Single source of truth - Change once, applies everywhere
Connection to FOSMVVM
Form Specifications integrate with:
- - Localization System - FormField titles/placeholders and validation messages use INLINECODE1
- Validation System - Implements
ValidatableModel protocol - Request System - RequestBody types adopt Fields for validated transmission
- ViewModel System - ViewModels adopt Fields for form rendering
When to Use This Skill
- - Defining a new form (create, edit, filter, search)
- Adding validation to a request body
- Any type that needs to conform to INLINECODE3
- When
fosmvvm-fluent-datamodel-generator needs form fields for a DataModel
What This Skill Generates
A complete Form Specification consists of 3 files:
| File | Purpose |
|---|
| INLINECODE5 | Protocol + FormField definitions + validation methods |
| INLINECODE6 |
@FieldValidationModel struct with
@LocalizedString properties |
|
{Name}FieldsMessages.yml | YAML localization (titles, placeholders, error messages) |
Project Structure Configuration
Replace placeholders with your project's actual paths:
| Placeholder | Description | Example |
|---|
| INLINECODE10 | Shared ViewModels SPM target | INLINECODE11 , INLINECODE12 |
| INLINECODE13 |
Localization resources path |
Sources/Resources |
Expected Structure:
CODEBLOCK1
How to Use This Skill
Invocation:
/fosmvvm-fields-generator
Prerequisites:
- - Form purpose understood from conversation context
- Field requirements discussed (names, types, constraints)
- Entity relationship identified (what is this form creating/editing)
Workflow integration:
This skill is used when defining form validation and user input contracts. The skill references conversation context automatically—no file paths or Q&A needed. Often precedes fosmvvm-fluent-datamodel-generator for form-backed models.
Pattern Implementation
This skill references conversation context to determine Fields protocol structure:
Form Analysis
From conversation context, the skill identifies:
- - Form purpose (create, edit, filter, login, settings)
- Entity relation (User, Idea, Document - what's being created/edited)
- Protocol naming (CreateIdeaFields, UpdateProfile, LoginCredentials)
Field Design
For each field from requirements:
- - Property specification (name, type, optional vs required)
- Presentation type (FormFieldType: text, textArea, select, checkbox)
- Input semantics (FormInputType: email, password, tel, date)
- Constraints (required, length range, value range, date range)
- Localization (title, placeholder, validation error messages)
File Generation Order
- 1. Fields protocol with FormField definitions and validation
- FieldsMessages struct with @LocalizedString properties
- FieldsMessages YAML with localized strings
Context Sources
Skill references information from:
- - Prior conversation: Form requirements, field specifications discussed
- Specification files: If Claude has read form specs into context
- Existing patterns: From codebase analysis of similar Fields protocols
Key Patterns
Protocol Structure
CODEBLOCK2
FormField Definition
CODEBLOCK3
FormField Types Reference
| FormFieldType | Use Case |
|---|
| INLINECODE15 | Single-line input |
| INLINECODE16 |
Multi-line input |
|
.checkbox | Boolean toggle |
|
.select | Dropdown selection |
|
.colorPicker | Color selection |
FormInputType Reference (common ones)
| FormInputType | Keyboard/Autofill |
|---|
| INLINECODE20 | Default keyboard |
| INLINECODE21 |
Email keyboard, email autofill |
|
.password | Secure entry |
|
.tel | Phone keyboard |
|
.url | URL keyboard |
|
.date,
.datetimeLocal | Date picker |
|
.givenName,
.familyName | Name autofill |
Validation Method Pattern
CODEBLOCK4
Messages Struct Pattern
CODEBLOCK5
YAML Structure
CODEBLOCK6
Naming Conventions
| Concept | Convention | Example |
|---|
| Protocol | INLINECODE29 | INLINECODE30 , INLINECODE31 |
| Messages struct |
{Name}FieldsMessages |
IdeaFieldsMessages |
| Messages property |
{name}ValidationMessages |
ideaValidationMessages |
| Field definition |
{fieldName}Field |
contentField |
| Range constant |
{fieldName}Range |
contentRange |
| Validate method |
validate{FieldName} |
validateContent |
| Required message |
{fieldName}RequiredMessage |
contentRequiredMessage |
| OutOfRange message |
{fieldName}OutOfRangeMessage |
contentOutOfRangeMessage |
See Also
Version History
| Version | Date | Changes |
|---|
| 1.0 | 2024-12-24 | Initial skill |
| 2.0 |
2024-12-26 | Rewritten with conceptual foundation; generalized from Kairos-specific |
| 2.1 | 2026-01-24 | Update to context-aware approach (remove file-parsing/Q&A). Skill references conversation context instead of asking questions or accepting file paths. |
FOSMVVM 字段生成器
按照FOSMVVM模式生成表单规范。
概念基础
完整架构上下文请参阅 FOSMVVMArchitecture.md | OpenClaw参考
表单规范(以{Name}Fields协议实现)是用户输入的单一事实来源。它回答了以下问题:
- 1. 用户可以提供什么数据?(属性)
- 应该如何呈现?(包含类型、键盘、自动填充语义的FormField)
- 有哪些约束条件?(验证规则)
- 应该显示什么消息?(本地化的标题、占位符、错误信息)
为什么这很重要
表单规范定义一次,处处使用:
swift
// 同一协议被不同的消费者采用:
struct CreateIdeaRequestBody: ServerRequestBody, IdeaFields { ... } // HTTP传输
@ViewModel struct IdeaFormViewModel: IdeaFields { ... } // 表单渲染
final class Idea: Model, IdeaFields { ... } // 持久化验证
这确保了:
- - 一致的验证 - 客户端和服务器端使用相同的规则
- 共享的本地化 - 一个YAML文件,处处使用
- 单一事实来源 - 修改一处,处处生效
与FOSMVVM的关联
表单规范与以下部分集成:
- - 本地化系统 - FormField的标题/占位符和验证消息使用LocalizableString
- 验证系统 - 实现ValidatableModel协议
- 请求系统 - RequestBody类型采用Fields进行验证传输
- ViewModel系统 - ViewModel采用Fields进行表单渲染
何时使用此技能
- - 定义新表单(创建、编辑、筛选、搜索)
- 为请求体添加验证
- 任何需要符合ValidatableModel的类型
- 当fosmvvm-fluent-datamodel-generator需要DataModel的表单字段时
此技能生成的内容
一个完整的表单规范包含3个文件:
| 文件 | 用途 |
|---|
| {Name}Fields.swift | 协议 + FormField定义 + 验证方法 |
| {Name}FieldsMessages.swift |
包含@LocalizedString属性的@FieldValidationModel结构体 |
| {Name}FieldsMessages.yml | YAML本地化(标题、占位符、错误消息) |
项目结构配置
将占位符替换为项目的实际路径:
| 占位符 | 描述 | 示例 |
|---|
| {ViewModelsTarget} | 共享ViewModel的SPM目标 | ViewModels, SharedViewModels |
| {ResourcesPath} |
本地化资源路径 | Sources/Resources |
预期结构:
Sources/
{ViewModelsTarget}/
FieldModels/
{Name}Fields.swift
{Name}FieldsMessages.swift
{ResourcesPath}/
FieldModels/
{Name}FieldsMessages.yml
如何使用此技能
调用方式:
/fosmvvm-fields-generator
前置条件:
- - 从对话上下文中理解表单目的
- 已讨论字段需求(名称、类型、约束)
- 已识别实体关系(此表单创建/编辑的内容)
工作流集成:
此技能在定义表单验证和用户输入契约时使用。技能自动引用对话上下文——无需文件路径或问答。通常在表单支持模型之前使用fosmvvm-fluent-datamodel-generator。
模式实现
此技能引用对话上下文来确定Fields协议结构:
表单分析
从对话上下文中,技能识别:
- - 表单目的(创建、编辑、筛选、登录、设置)
- 实体关系(User、Idea、Document - 正在创建/编辑的内容)
- 协议命名(CreateIdeaFields、UpdateProfile、LoginCredentials)
字段设计
对于需求中的每个字段:
- - 属性规范(名称、类型、可选 vs 必填)
- 呈现类型(FormFieldType:text、textArea、select、checkbox)
- 输入语义(FormInputType:email、password、tel、date)
- 约束条件(必填、长度范围、值范围、日期范围)
- 本地化(标题、占位符、验证错误消息)
文件生成顺序
- 1. 包含FormField定义和验证的Fields协议
- 包含@LocalizedString属性的FieldsMessages结构体
- 包含本地化字符串的FieldsMessages YAML文件
上下文来源
技能引用以下信息:
- - 先前的对话:讨论过的表单需求、字段规范
- 规范文件:如果Claude已将表单规范读入上下文
- 现有模式:来自类似Fields协议的代码库分析
关键模式
协议结构
swift
public protocol {Name}Fields: ValidatableModel, Codable, Sendable {
var fieldName: FieldType { get set }
var {name}ValidationMessages: {Name}FieldsMessages { get }
}
FormField定义
swift
static var contentField: FormField { .init(
fieldId: .init(id: content),
title: .localized(for: {Name}FieldsMessages.self, propertyName: content, messageKey: title),
placeholder: .localized(for: {Name}FieldsMessages.self, propertyName: content, messageKey: placeholder),
type: .textArea(inputType: .text),
options: [
.required(value: true)
] + FormInputOption.rangeLength(contentRange)
) }
FormField类型参考
| FormFieldType | 使用场景 |
|---|
| .text(inputType:) | 单行输入 |
| .textArea(inputType:) |
多行输入 |
| .checkbox | 布尔切换 |
| .select | 下拉选择 |
| .colorPicker | 颜色选择 |
FormInputType参考(常用)
| FormInputType | 键盘/自动填充 |
|---|
| .text | 默认键盘 |
| .emailAddress |
邮箱键盘,邮箱自动填充 |
| .password | 安全输入 |
| .tel | 电话键盘 |
| .url | URL键盘 |
| .date, .datetimeLocal | 日期选择器 |
| .givenName, .familyName | 姓名自动填充 |
验证方法模式
swift
internal func validateContent(_ fields: [FormFieldBase]?) -> [ValidationResult]? {
guard fields == nil || (fields?.contains(Self.contentField) == true) else {
return nil
}
var result = [ValidationResult]()
if content.isEmpty {
result.append(.init(
status: .error,
field: Self.contentField,
message: {name}ValidationMessages.contentRequiredMessage
))
} else if !Self.contentRange.contains(NSString(string: content).length) {
result.append(.init(
status: .error,
field: Self.contentField,
message: {name}ValidationMessages.contentOutOfRangeMessage
))
}
return result.isEmpty ? nil : result
}
消息结构体模式
swift
@FieldValidationModel public struct {Name}FieldsMessages {
@LocalizedString(content, messageGroup: validationMessages, messageKey: required)
public var contentRequiredMessage
@LocalizedString(content, messageGroup: validationMessages, messageKey: outOfRange)
public var contentOutOfRangeMessage
}
YAML结构
yaml
en:
{Name}FieldsMessages:
content:
title: 内容
placeholder: 请输入您的内容...
validationMessages:
required: 内容为必填项
outOfRange: 内容长度必须在1到10,000个字符之间
命名约定
| 概念 | 约定 | 示例 |
|---|
| 协议 | {Name}Fields | IdeaFields, CreateIdeaFields |
| 消息结构体 |
{Name}FieldsMessages | IdeaFieldsMessages |
| 消息属性 | {name}ValidationMessages | ideaValidationMessages |
| 字段定义 | {fieldName}Field | contentField |
| 范围常量 | {fieldName}Range | contentRange |
| 验证方法 | validate{FieldName} | validateContent |
| 必填消息 | {fieldName}RequiredMessage | contentRequiredMessage |
| 超出范围消息 | {fieldName}OutOfRangeMessage | contentOutOfRangeMessage |
另请参阅