@wangs-ui/skills 1.1.0-alpha.3 → 1.1.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as listSkills, n as updateSkills, r as addSkills, t as removeSkills } from "./src-XyTMubnF.js";
2
+ import { i as listSkills, n as updateSkills, r as addSkills, t as removeSkills } from "./src-CtM02kKf.js";
3
3
  import path from "node:path";
4
4
  import { parseArgs } from "node:util";
5
5
  //#region bin.ts
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getAgentSkillDirs, c as isSkillInstalled, d as loadAllSkills, i as listSkills, l as removeSkill, n as updateSkills, o as getInstalledSkills, r as addSkills, s as installSkill, t as removeSkills, u as getSkill } from "./src-XyTMubnF.js";
1
+ import { a as getAgentSkillDirs, c as isSkillInstalled, d as loadAllSkills, i as listSkills, l as removeSkill, n as updateSkills, o as getInstalledSkills, r as addSkills, s as installSkill, t as removeSkills, u as getSkill } from "./src-CtM02kKf.js";
2
2
  export { addSkills, getAgentSkillDirs, getInstalledSkills, getSkill, installSkill, isSkillInstalled, listSkills, loadAllSkills, removeSkill, removeSkills, updateSkills };
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: create-form
3
- description: Architecture, validation workflows, and MCP discovery protocol for building forms and input controls with @wangs-ui/react-core.
3
+ description: Architecture, validation workflows, strongly-typed forms (useForm, useDialogForm, useWatchField), and MCP discovery protocol for building forms and input controls with @wangs-ui/react-core.
4
4
  ---
5
5
 
6
6
  # Skill: Form Architecture & Validation Workflows
7
7
 
8
- Use this skill when building forms, data entry panels, settings pages, or multipart forms in Wangs UI applications.
8
+ Use this skill when building forms, data entry panels, modal forms, settings pages, or multipart forms in Wangs UI applications.
9
9
 
10
10
  ---
11
11
 
@@ -18,6 +18,7 @@ Do **NOT** hardcode or guess prop names, field configurations, or validation opt
18
18
  ```json
19
19
  get-documentation({ "id": "form" })
20
20
  get-documentation({ "id": "field" })
21
+ get-documentation({ "id": "dialogform" })
21
22
  get-documentation({ "id": "input" })
22
23
  get-documentation({ "id": "numberinput" })
23
24
  get-documentation({ "id": "select" })
@@ -39,29 +40,157 @@ get-documentation-for-story({ "id": "fileupload", "storyName": "Default" })
39
40
  ### Inspect Knowledge Graph & Usages:
40
41
 
41
42
  ```json
42
- query_graph({ "query": "useFormControl" })
43
- query_graph({ "query": "Field" })
43
+ query_graph({ "query": "useForm" })
44
+ query_graph({ "query": "useDialogForm" })
45
+ query_graph({ "query": "useWatchField" })
44
46
  ```
45
47
 
46
48
  ---
47
49
 
48
- ## 2. Form Architecture & State Principles
50
+ ## 2. Form Architecture & Latest API Patterns
51
+
52
+ ### Pattern A: Strongly Typed Forms with `useForm<T>()`
53
+
54
+ For standard page forms, use `useForm<T>()` from `@wangs-ui/react-core/primitive/form`. It returns a strongly-typed `Form`, `Field`, and `control` where `Field`'s `name` prop is constrained to dot-path keys of `T` (`Path<T>`) with full IDE autocomplete and type inference.
55
+
56
+ ```tsx
57
+ import Button from '@wangs-ui/react-core/primitive/button';
58
+ import { useForm } from '@wangs-ui/react-core/primitive/form';
59
+ import Input from '@wangs-ui/react-core/primitive/input';
60
+ import { useI18n } from '@wangs-ui/react-i18n';
61
+
62
+ interface UserFormData {
63
+ name: string;
64
+ email: string;
65
+ address: {
66
+ city: string;
67
+ };
68
+ }
69
+
70
+ export function UserFormPage() {
71
+ const { t } = useI18n();
72
+ // Strongly-typed Form, Field, and control bound to UserFormData
73
+ const { Form, Field, control } = useForm<UserFormData>();
74
+
75
+ return (
76
+ <Form control={control} onSubmit={(values) => console.log(values)}>
77
+ <Field required label={t('Full Name')} name="name">
78
+ {({ fieldProps }) => <Input {...fieldProps} placeholder={t('Enter full name')} />}
79
+ </Field>
80
+
81
+ {/* Autocompletes nested dot-path keys */}
82
+ <Field required label={t('City')} name="address.city">
83
+ {({ fieldProps }) => <Input {...fieldProps} placeholder={t('Enter city')} />}
84
+ </Field>
85
+
86
+ <div className="flex gap-2">
87
+ <Button
88
+ label={t('Reset')}
89
+ type="button"
90
+ severity="secondary"
91
+ onClick={() => control.reset()}
92
+ />
93
+ <Button label={t('Submit')} type="submit" />
94
+ </div>
95
+ </Form>
96
+ );
97
+ }
98
+ ```
99
+
100
+ ---
101
+
102
+ ### Pattern B: Modal Forms with `useDialogForm<T>()`
103
+
104
+ For modal/dialog forms, use `useDialogForm<T>()` from `@wangs-ui/react-core/primitive/dialogform`. It combines a modal `Dialog` with form provider lifecycle, providing automatic modal close on success (`closeOnSubmit`), validation interception, and native Enter-key submission.
105
+
106
+ ```tsx
107
+ import Button from '@wangs-ui/react-core/primitive/button';
108
+ import { useDialogForm } from '@wangs-ui/react-core/primitive/dialogform';
109
+ import Input from '@wangs-ui/react-core/primitive/input';
110
+ import { useI18n } from '@wangs-ui/react-i18n';
111
+ import { useState } from 'react';
112
+
113
+ interface EditProfileData {
114
+ fullName: string;
115
+ email: string;
116
+ }
117
+
118
+ export function EditProfileModal() {
119
+ const { t } = useI18n();
120
+ const [open, setOpen] = useState(false);
121
+ const { DialogForm, Field, control } = useDialogForm<EditProfileData>();
122
+
123
+ return (
124
+ <>
125
+ <Button label={t('Edit Profile')} onClick={() => setOpen(true)} />
126
+
127
+ <DialogForm
128
+ closeOnSubmit
129
+ control={control}
130
+ header={t('Edit Profile')}
131
+ open={open}
132
+ onOpenChange={setOpen}
133
+ onSubmit={(values) => console.log('Saved:', values)}
134
+ footer={
135
+ <div className="flex w-full justify-end gap-2">
136
+ <Button
137
+ label={t('Cancel')}
138
+ severity="secondary"
139
+ type="button"
140
+ variant="outline"
141
+ onClick={() => setOpen(false)}
142
+ />
143
+ <Button label={t('Save Changes')} type="submit" />
144
+ </div>
145
+ }
146
+ >
147
+ <div className="flex flex-col gap-4">
148
+ <Field required label={t('Full Name')} name="fullName">
149
+ {({ fieldProps }) => <Input {...fieldProps} placeholder="John Doe" />}
150
+ </Field>
151
+ <Field required label={t('Email')} name="email">
152
+ {({ fieldProps }) => (
153
+ <Input {...fieldProps} type="email" placeholder="you@example.com" />
154
+ )}
155
+ </Field>
156
+ </div>
157
+ </DialogForm>
158
+ </>
159
+ );
160
+ }
161
+ ```
162
+
163
+ ---
164
+
165
+ ### Pattern C: Real-Time Field Watching with `useWatchField`
166
+
167
+ To observe real-time field changes without causing the entire form to re-render, use `useWatchField` from `@wangs-ui/form/react`.
168
+
169
+ ```tsx
170
+ import { useWatchField } from '@wangs-ui/form/react';
171
+
172
+ function FormSummaryWatcher({ control }) {
173
+ // Subscribes only to 'username' value changes
174
+ const username = useWatchField({ control, name: 'username' });
175
+
176
+ return <div>Current Username: {username}</div>;
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 3. Submission Types
49
183
 
50
- 1. **State & Control**:
51
- - Standard REST payload forms use `useFormControl` with JSON mode.
52
- - Multipart file upload workflows use `useFormControl` with FormData mode.
53
- 2. **Field Composition**:
54
- - Form inputs are wrapped with `<Field>` layout containers for unified label, tooltip, helper text, and error rendering.
55
- - Exact props, slot rendering functions, and field binding options must be retrieved via MCP (`get-documentation({ "id": "field" })`).
56
- 3. **Server Validation Error Mapping**:
57
- - Backend validation responses (e.g. `422 Unprocessable Entity`) are mapped back into the form instance via `formControl.setError()`.
58
- 4. **Submission Lifecycle**:
59
- - In-flight network requests should manage loading state on submit actions and prevent accidental reset during mutations.
184
+ | Config | Use case |
185
+ | -------------------------------------------------------------------- | ------------------------- |
186
+ | `useForm<T>()` / `useDialogForm<T>()` | Default JSON submission |
187
+ | `useForm<T, 'multipart/form-data'>({ type: 'multipart/form-data' })` | File uploads (`FormData`) |
60
188
 
61
189
  ---
62
190
 
63
- ## 3. Mandatory Implementation Rules
191
+ ## 4. Mandatory Implementation Rules
64
192
 
65
- 1. **Always Query MCP First**: Never guess input props or event signatures; obtain the exact types from `get-documentation`.
66
- 2. **Strict Subpath Imports**: All components must be imported via their granular subpath (`@wangs-ui/react-core/primitive/*`, `@wangs-ui/form`).
193
+ 1. **Always Query MCP First**: Retrieve exact component and prop types via `get-documentation`.
194
+ 2. **Strict Subpath Imports**: Import primitive components via granular subpaths (`@wangs-ui/react-core/primitive/form`, `@wangs-ui/react-core/primitive/dialogform`, `@wangs-ui/react-core/primitive/field`).
67
195
  3. **Translate All Visible Strings**: Every field label, placeholder, helper text, and error message must be wrapped in `t('...')` from `@wangs-ui/react-i18n`.
196
+ 4. **Server Validation Error Mapping**: Map backend validation errors (e.g., 422 HTTP status) back into the form via `control.setError('fieldName', 'Error message')`.
@@ -3,7 +3,7 @@ import fs from "node:fs";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { cancel, intro, isCancel, multiselect, outro } from "@clack/prompts";
5
5
  //#region skills/create-form/SKILL.md?raw
6
- var SKILL_default$7 = "---\nname: create-form\ndescription: Architecture, validation workflows, and MCP discovery protocol for building forms and input controls with @wangs-ui/react-core.\n---\n\n# Skill: Form Architecture & Validation Workflows\n\nUse this skill when building forms, data entry panels, settings pages, or multipart forms in Wangs UI applications.\n\n---\n\n## 1. MCP Inspection Protocol (Mandatory Single Source of Truth)\n\nDo **NOT** hardcode or guess prop names, field configurations, or validation options. Retrieve active component definitions and live implementation stories directly from MCP:\n\n### Inspect Component & Form Contracts:\n\n```json\nget-documentation({ \"id\": \"form\" })\nget-documentation({ \"id\": \"field\" })\nget-documentation({ \"id\": \"input\" })\nget-documentation({ \"id\": \"numberinput\" })\nget-documentation({ \"id\": \"select\" })\nget-documentation({ \"id\": \"multiselect\" })\nget-documentation({ \"id\": \"datepicker\" })\nget-documentation({ \"id\": \"fileupload\" })\n```\n\n### Inspect Live Story Implementations:\n\n```json\nget-documentation-for-story({ \"id\": \"form\", \"storyName\": \"Default\" })\nget-documentation-for-story({ \"id\": \"field\", \"storyName\": \"Default\" })\nget-documentation-for-story({ \"id\": \"select\", \"storyName\": \"Basic\" })\nget-documentation-for-story({ \"id\": \"datepicker\", \"storyName\": \"Default\" })\nget-documentation-for-story({ \"id\": \"fileupload\", \"storyName\": \"Default\" })\n```\n\n### Inspect Knowledge Graph & Usages:\n\n```json\nquery_graph({ \"query\": \"useFormControl\" })\nquery_graph({ \"query\": \"Field\" })\n```\n\n---\n\n## 2. Form Architecture & State Principles\n\n1. **State & Control**:\n - Standard REST payload forms use `useFormControl` with JSON mode.\n - Multipart file upload workflows use `useFormControl` with FormData mode.\n2. **Field Composition**:\n - Form inputs are wrapped with `<Field>` layout containers for unified label, tooltip, helper text, and error rendering.\n - Exact props, slot rendering functions, and field binding options must be retrieved via MCP (`get-documentation({ \"id\": \"field\" })`).\n3. **Server Validation Error Mapping**:\n - Backend validation responses (e.g. `422 Unprocessable Entity`) are mapped back into the form instance via `formControl.setError()`.\n4. **Submission Lifecycle**:\n - In-flight network requests should manage loading state on submit actions and prevent accidental reset during mutations.\n\n---\n\n## 3. Mandatory Implementation Rules\n\n1. **Always Query MCP First**: Never guess input props or event signatures; obtain the exact types from `get-documentation`.\n2. **Strict Subpath Imports**: All components must be imported via their granular subpath (`@wangs-ui/react-core/primitive/*`, `@wangs-ui/form`).\n3. **Translate All Visible Strings**: Every field label, placeholder, helper text, and error message must be wrapped in `t('...')` from `@wangs-ui/react-i18n`.\n";
6
+ var SKILL_default$7 = "---\nname: create-form\ndescription: Architecture, validation workflows, strongly-typed forms (useForm, useDialogForm, useWatchField), and MCP discovery protocol for building forms and input controls with @wangs-ui/react-core.\n---\n\n# Skill: Form Architecture & Validation Workflows\n\nUse this skill when building forms, data entry panels, modal forms, settings pages, or multipart forms in Wangs UI applications.\n\n---\n\n## 1. MCP Inspection Protocol (Mandatory Single Source of Truth)\n\nDo **NOT** hardcode or guess prop names, field configurations, or validation options. Retrieve active component definitions and live implementation stories directly from MCP:\n\n### Inspect Component & Form Contracts:\n\n```json\nget-documentation({ \"id\": \"form\" })\nget-documentation({ \"id\": \"field\" })\nget-documentation({ \"id\": \"dialogform\" })\nget-documentation({ \"id\": \"input\" })\nget-documentation({ \"id\": \"numberinput\" })\nget-documentation({ \"id\": \"select\" })\nget-documentation({ \"id\": \"multiselect\" })\nget-documentation({ \"id\": \"datepicker\" })\nget-documentation({ \"id\": \"fileupload\" })\n```\n\n### Inspect Live Story Implementations:\n\n```json\nget-documentation-for-story({ \"id\": \"form\", \"storyName\": \"Default\" })\nget-documentation-for-story({ \"id\": \"field\", \"storyName\": \"Default\" })\nget-documentation-for-story({ \"id\": \"select\", \"storyName\": \"Basic\" })\nget-documentation-for-story({ \"id\": \"datepicker\", \"storyName\": \"Default\" })\nget-documentation-for-story({ \"id\": \"fileupload\", \"storyName\": \"Default\" })\n```\n\n### Inspect Knowledge Graph & Usages:\n\n```json\nquery_graph({ \"query\": \"useForm\" })\nquery_graph({ \"query\": \"useDialogForm\" })\nquery_graph({ \"query\": \"useWatchField\" })\n```\n\n---\n\n## 2. Form Architecture & Latest API Patterns\n\n### Pattern A: Strongly Typed Forms with `useForm<T>()`\n\nFor standard page forms, use `useForm<T>()` from `@wangs-ui/react-core/primitive/form`. It returns a strongly-typed `Form`, `Field`, and `control` where `Field`'s `name` prop is constrained to dot-path keys of `T` (`Path<T>`) with full IDE autocomplete and type inference.\n\n```tsx\nimport Button from '@wangs-ui/react-core/primitive/button';\nimport { useForm } from '@wangs-ui/react-core/primitive/form';\nimport Input from '@wangs-ui/react-core/primitive/input';\nimport { useI18n } from '@wangs-ui/react-i18n';\n\ninterface UserFormData {\n name: string;\n email: string;\n address: {\n city: string;\n };\n}\n\nexport function UserFormPage() {\n const { t } = useI18n();\n // Strongly-typed Form, Field, and control bound to UserFormData\n const { Form, Field, control } = useForm<UserFormData>();\n\n return (\n <Form control={control} onSubmit={(values) => console.log(values)}>\n <Field required label={t('Full Name')} name=\"name\">\n {({ fieldProps }) => <Input {...fieldProps} placeholder={t('Enter full name')} />}\n </Field>\n\n {/* Autocompletes nested dot-path keys */}\n <Field required label={t('City')} name=\"address.city\">\n {({ fieldProps }) => <Input {...fieldProps} placeholder={t('Enter city')} />}\n </Field>\n\n <div className=\"flex gap-2\">\n <Button\n label={t('Reset')}\n type=\"button\"\n severity=\"secondary\"\n onClick={() => control.reset()}\n />\n <Button label={t('Submit')} type=\"submit\" />\n </div>\n </Form>\n );\n}\n```\n\n---\n\n### Pattern B: Modal Forms with `useDialogForm<T>()`\n\nFor modal/dialog forms, use `useDialogForm<T>()` from `@wangs-ui/react-core/primitive/dialogform`. It combines a modal `Dialog` with form provider lifecycle, providing automatic modal close on success (`closeOnSubmit`), validation interception, and native Enter-key submission.\n\n```tsx\nimport Button from '@wangs-ui/react-core/primitive/button';\nimport { useDialogForm } from '@wangs-ui/react-core/primitive/dialogform';\nimport Input from '@wangs-ui/react-core/primitive/input';\nimport { useI18n } from '@wangs-ui/react-i18n';\nimport { useState } from 'react';\n\ninterface EditProfileData {\n fullName: string;\n email: string;\n}\n\nexport function EditProfileModal() {\n const { t } = useI18n();\n const [open, setOpen] = useState(false);\n const { DialogForm, Field, control } = useDialogForm<EditProfileData>();\n\n return (\n <>\n <Button label={t('Edit Profile')} onClick={() => setOpen(true)} />\n\n <DialogForm\n closeOnSubmit\n control={control}\n header={t('Edit Profile')}\n open={open}\n onOpenChange={setOpen}\n onSubmit={(values) => console.log('Saved:', values)}\n footer={\n <div className=\"flex w-full justify-end gap-2\">\n <Button\n label={t('Cancel')}\n severity=\"secondary\"\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n />\n <Button label={t('Save Changes')} type=\"submit\" />\n </div>\n }\n >\n <div className=\"flex flex-col gap-4\">\n <Field required label={t('Full Name')} name=\"fullName\">\n {({ fieldProps }) => <Input {...fieldProps} placeholder=\"John Doe\" />}\n </Field>\n <Field required label={t('Email')} name=\"email\">\n {({ fieldProps }) => (\n <Input {...fieldProps} type=\"email\" placeholder=\"you@example.com\" />\n )}\n </Field>\n </div>\n </DialogForm>\n </>\n );\n}\n```\n\n---\n\n### Pattern C: Real-Time Field Watching with `useWatchField`\n\nTo observe real-time field changes without causing the entire form to re-render, use `useWatchField` from `@wangs-ui/form/react`.\n\n```tsx\nimport { useWatchField } from '@wangs-ui/form/react';\n\nfunction FormSummaryWatcher({ control }) {\n // Subscribes only to 'username' value changes\n const username = useWatchField({ control, name: 'username' });\n\n return <div>Current Username: {username}</div>;\n}\n```\n\n---\n\n## 3. Submission Types\n\n| Config | Use case |\n| -------------------------------------------------------------------- | ------------------------- |\n| `useForm<T>()` / `useDialogForm<T>()` | Default JSON submission |\n| `useForm<T, 'multipart/form-data'>({ type: 'multipart/form-data' })` | File uploads (`FormData`) |\n\n---\n\n## 4. Mandatory Implementation Rules\n\n1. **Always Query MCP First**: Retrieve exact component and prop types via `get-documentation`.\n2. **Strict Subpath Imports**: Import primitive components via granular subpaths (`@wangs-ui/react-core/primitive/form`, `@wangs-ui/react-core/primitive/dialogform`, `@wangs-ui/react-core/primitive/field`).\n3. **Translate All Visible Strings**: Every field label, placeholder, helper text, and error message must be wrapped in `t('...')` from `@wangs-ui/react-i18n`.\n4. **Server Validation Error Mapping**: Map backend validation errors (e.g., 422 HTTP status) back into the form via `control.setError('fieldName', 'Error message')`.\n";
7
7
  //#endregion
8
8
  //#region skills/data-table/SKILL.md?raw
9
9
  var SKILL_default$6 = "---\nname: data-table\ndescription: Architecture, workflows, and MCP discovery protocol for building DataTables with sorting, pagination, filtering, selection, and export.\n---\n\n# Skill: DataTable Architecture & Integration Workflows\n\nUse this skill when implementing data grids, server-paginated tables, filterable listing views, or batch management interfaces with `@wangs-ui/react-core`.\n\n---\n\n## 1. MCP Inspection Protocol (Mandatory Single Source of Truth)\n\nDo **NOT** guess table prop names or hardcode table structures. Query the MCP server dynamically to inspect exact TypeScript signatures, live story implementations, and companion controls:\n\n### Inspect Component Contracts:\n\n```json\nget-documentation({ \"id\": \"datatable\" })\nget-documentation({ \"id\": \"exportbutton\" })\nget-documentation({ \"id\": \"filtercontainer\" })\nget-documentation({ \"id\": \"bulkactionbutton\" })\n```\n\n### Inspect Live Story Implementations:\n\n```json\nget-documentation-for-story({ \"id\": \"datatable\", \"storyName\": \"Basic\" })\nget-documentation-for-story({ \"id\": \"datatable\", \"storyName\": \"ServerPagination\" })\nget-documentation-for-story({ \"id\": \"datatable\", \"storyName\": \"Sortable\" })\nget-documentation-for-story({ \"id\": \"datatable\", \"storyName\": \"MultipleSelection\" })\nget-documentation-for-story({ \"id\": \"datatable\", \"storyName\": \"CustomColumn\" })\nget-documentation-for-story({ \"id\": \"exportbutton\", \"storyName\": \"WithTable\" })\n```\n\n### Inspect Knowledge Graph & Usages:\n\n```json\nquery_graph({ \"query\": \"DataTable\" })\nquery_graph({ \"query\": \"useDataTableFetch\" })\n```\n\n---\n\n## 2. Core Architecture & Mental Model\n\nThe Wangs UI `DataTable` is built on a modular, headless-first architecture:\n\n1. **Declarative Column Definitions (`TableColumn<T>[]`)**:\n Columns are configured as typed array objects, not as JSX children. Check `get-documentation({ \"id\": \"datatable\" })` for column field types.\n2. **Table Instance Hook (`useDataTable`)**:\n Coordinates table state (sorting, pagination, selection, column ordering, pinning, visibility).\n3. **Data Fetching Hook (`useDataTableFetch`)**:\n Feeds server-side data, handles loading indicators, manages query parameters (`search`, `filter`, `sort`, `page`, `limit`), and debounces requests automatically.\n4. **Ecosystem Companions**:\n - `FilterContainer` & `FilterToggleButton`: Filter popovers and faceted search.\n - `ExportButton`: Client/server export to Excel, CSV, PDF, or Print.\n - `BulkActionButton`: Contextual batch actions triggered when rows are selected.\n - `CustomColumn`: User-controlled column ordering, visibility toggling, and pinning.\n\n---\n\n## 3. Mandatory Implementation Rules\n\n1. **Query MCP for Current Code Patterns**: Always run `get-documentation-for-story` for `datatable` before drafting code.\n2. **Strict Subpath Imports**: Import via `@wangs-ui/react-core/primitive/datatable` and companion primitive paths.\n3. **Always Translate Visible Copy**: All column header labels, empty state messages, and action button labels must be wrapped in `t('...')` from `@wangs-ui/react-i18n`.\n4. **Stable Row Identity**: Always configure a unique key identifier for stable selection and row identity.\n";
@@ -144,7 +144,7 @@ function removeSkill(skillId, baseDir = process.cwd()) {
144
144
  //#endregion
145
145
  //#region src/commands/list.ts
146
146
  function listSkills(baseDir = process.cwd()) {
147
- intro(`\x1b[1m\x1b[36m📦 Wangs UI Consumer Skills Registry\x1b[0m (v1.1.0-alpha.2)`);
147
+ intro(`\x1b[1m\x1b[36m📦 Wangs UI Consumer Skills Registry\x1b[0m (v1.1.0-alpha.4)`);
148
148
  const allSkills = loadAllSkills();
149
149
  const targetDirs = getAgentSkillDirs(baseDir);
150
150
  if (allSkills.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wangs-ui/skills",
3
- "version": "1.1.0-alpha.3",
3
+ "version": "1.1.0-alpha.7",
4
4
  "description": "CLI to install, update, and manage modular AI agent skills for Wangs UI React applications",
5
5
  "keywords": [
6
6
  "agents",
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: create-form
3
- description: Architecture, validation workflows, and MCP discovery protocol for building forms and input controls with @wangs-ui/react-core.
3
+ description: Architecture, validation workflows, strongly-typed forms (useForm, useDialogForm, useWatchField), and MCP discovery protocol for building forms and input controls with @wangs-ui/react-core.
4
4
  ---
5
5
 
6
6
  # Skill: Form Architecture & Validation Workflows
7
7
 
8
- Use this skill when building forms, data entry panels, settings pages, or multipart forms in Wangs UI applications.
8
+ Use this skill when building forms, data entry panels, modal forms, settings pages, or multipart forms in Wangs UI applications.
9
9
 
10
10
  ---
11
11
 
@@ -18,6 +18,7 @@ Do **NOT** hardcode or guess prop names, field configurations, or validation opt
18
18
  ```json
19
19
  get-documentation({ "id": "form" })
20
20
  get-documentation({ "id": "field" })
21
+ get-documentation({ "id": "dialogform" })
21
22
  get-documentation({ "id": "input" })
22
23
  get-documentation({ "id": "numberinput" })
23
24
  get-documentation({ "id": "select" })
@@ -39,29 +40,157 @@ get-documentation-for-story({ "id": "fileupload", "storyName": "Default" })
39
40
  ### Inspect Knowledge Graph & Usages:
40
41
 
41
42
  ```json
42
- query_graph({ "query": "useFormControl" })
43
- query_graph({ "query": "Field" })
43
+ query_graph({ "query": "useForm" })
44
+ query_graph({ "query": "useDialogForm" })
45
+ query_graph({ "query": "useWatchField" })
44
46
  ```
45
47
 
46
48
  ---
47
49
 
48
- ## 2. Form Architecture & State Principles
50
+ ## 2. Form Architecture & Latest API Patterns
51
+
52
+ ### Pattern A: Strongly Typed Forms with `useForm<T>()`
53
+
54
+ For standard page forms, use `useForm<T>()` from `@wangs-ui/react-core/primitive/form`. It returns a strongly-typed `Form`, `Field`, and `control` where `Field`'s `name` prop is constrained to dot-path keys of `T` (`Path<T>`) with full IDE autocomplete and type inference.
55
+
56
+ ```tsx
57
+ import Button from '@wangs-ui/react-core/primitive/button';
58
+ import { useForm } from '@wangs-ui/react-core/primitive/form';
59
+ import Input from '@wangs-ui/react-core/primitive/input';
60
+ import { useI18n } from '@wangs-ui/react-i18n';
61
+
62
+ interface UserFormData {
63
+ name: string;
64
+ email: string;
65
+ address: {
66
+ city: string;
67
+ };
68
+ }
69
+
70
+ export function UserFormPage() {
71
+ const { t } = useI18n();
72
+ // Strongly-typed Form, Field, and control bound to UserFormData
73
+ const { Form, Field, control } = useForm<UserFormData>();
74
+
75
+ return (
76
+ <Form control={control} onSubmit={(values) => console.log(values)}>
77
+ <Field required label={t('Full Name')} name="name">
78
+ {({ fieldProps }) => <Input {...fieldProps} placeholder={t('Enter full name')} />}
79
+ </Field>
80
+
81
+ {/* Autocompletes nested dot-path keys */}
82
+ <Field required label={t('City')} name="address.city">
83
+ {({ fieldProps }) => <Input {...fieldProps} placeholder={t('Enter city')} />}
84
+ </Field>
85
+
86
+ <div className="flex gap-2">
87
+ <Button
88
+ label={t('Reset')}
89
+ type="button"
90
+ severity="secondary"
91
+ onClick={() => control.reset()}
92
+ />
93
+ <Button label={t('Submit')} type="submit" />
94
+ </div>
95
+ </Form>
96
+ );
97
+ }
98
+ ```
99
+
100
+ ---
101
+
102
+ ### Pattern B: Modal Forms with `useDialogForm<T>()`
103
+
104
+ For modal/dialog forms, use `useDialogForm<T>()` from `@wangs-ui/react-core/primitive/dialogform`. It combines a modal `Dialog` with form provider lifecycle, providing automatic modal close on success (`closeOnSubmit`), validation interception, and native Enter-key submission.
105
+
106
+ ```tsx
107
+ import Button from '@wangs-ui/react-core/primitive/button';
108
+ import { useDialogForm } from '@wangs-ui/react-core/primitive/dialogform';
109
+ import Input from '@wangs-ui/react-core/primitive/input';
110
+ import { useI18n } from '@wangs-ui/react-i18n';
111
+ import { useState } from 'react';
112
+
113
+ interface EditProfileData {
114
+ fullName: string;
115
+ email: string;
116
+ }
117
+
118
+ export function EditProfileModal() {
119
+ const { t } = useI18n();
120
+ const [open, setOpen] = useState(false);
121
+ const { DialogForm, Field, control } = useDialogForm<EditProfileData>();
122
+
123
+ return (
124
+ <>
125
+ <Button label={t('Edit Profile')} onClick={() => setOpen(true)} />
126
+
127
+ <DialogForm
128
+ closeOnSubmit
129
+ control={control}
130
+ header={t('Edit Profile')}
131
+ open={open}
132
+ onOpenChange={setOpen}
133
+ onSubmit={(values) => console.log('Saved:', values)}
134
+ footer={
135
+ <div className="flex w-full justify-end gap-2">
136
+ <Button
137
+ label={t('Cancel')}
138
+ severity="secondary"
139
+ type="button"
140
+ variant="outline"
141
+ onClick={() => setOpen(false)}
142
+ />
143
+ <Button label={t('Save Changes')} type="submit" />
144
+ </div>
145
+ }
146
+ >
147
+ <div className="flex flex-col gap-4">
148
+ <Field required label={t('Full Name')} name="fullName">
149
+ {({ fieldProps }) => <Input {...fieldProps} placeholder="John Doe" />}
150
+ </Field>
151
+ <Field required label={t('Email')} name="email">
152
+ {({ fieldProps }) => (
153
+ <Input {...fieldProps} type="email" placeholder="you@example.com" />
154
+ )}
155
+ </Field>
156
+ </div>
157
+ </DialogForm>
158
+ </>
159
+ );
160
+ }
161
+ ```
162
+
163
+ ---
164
+
165
+ ### Pattern C: Real-Time Field Watching with `useWatchField`
166
+
167
+ To observe real-time field changes without causing the entire form to re-render, use `useWatchField` from `@wangs-ui/form/react`.
168
+
169
+ ```tsx
170
+ import { useWatchField } from '@wangs-ui/form/react';
171
+
172
+ function FormSummaryWatcher({ control }) {
173
+ // Subscribes only to 'username' value changes
174
+ const username = useWatchField({ control, name: 'username' });
175
+
176
+ return <div>Current Username: {username}</div>;
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 3. Submission Types
49
183
 
50
- 1. **State & Control**:
51
- - Standard REST payload forms use `useFormControl` with JSON mode.
52
- - Multipart file upload workflows use `useFormControl` with FormData mode.
53
- 2. **Field Composition**:
54
- - Form inputs are wrapped with `<Field>` layout containers for unified label, tooltip, helper text, and error rendering.
55
- - Exact props, slot rendering functions, and field binding options must be retrieved via MCP (`get-documentation({ "id": "field" })`).
56
- 3. **Server Validation Error Mapping**:
57
- - Backend validation responses (e.g. `422 Unprocessable Entity`) are mapped back into the form instance via `formControl.setError()`.
58
- 4. **Submission Lifecycle**:
59
- - In-flight network requests should manage loading state on submit actions and prevent accidental reset during mutations.
184
+ | Config | Use case |
185
+ | -------------------------------------------------------------------- | ------------------------- |
186
+ | `useForm<T>()` / `useDialogForm<T>()` | Default JSON submission |
187
+ | `useForm<T, 'multipart/form-data'>({ type: 'multipart/form-data' })` | File uploads (`FormData`) |
60
188
 
61
189
  ---
62
190
 
63
- ## 3. Mandatory Implementation Rules
191
+ ## 4. Mandatory Implementation Rules
64
192
 
65
- 1. **Always Query MCP First**: Never guess input props or event signatures; obtain the exact types from `get-documentation`.
66
- 2. **Strict Subpath Imports**: All components must be imported via their granular subpath (`@wangs-ui/react-core/primitive/*`, `@wangs-ui/form`).
193
+ 1. **Always Query MCP First**: Retrieve exact component and prop types via `get-documentation`.
194
+ 2. **Strict Subpath Imports**: Import primitive components via granular subpaths (`@wangs-ui/react-core/primitive/form`, `@wangs-ui/react-core/primitive/dialogform`, `@wangs-ui/react-core/primitive/field`).
67
195
  3. **Translate All Visible Strings**: Every field label, placeholder, helper text, and error message must be wrapped in `t('...')` from `@wangs-ui/react-i18n`.
196
+ 4. **Server Validation Error Mapping**: Map backend validation errors (e.g., 422 HTTP status) back into the form via `control.setError('fieldName', 'Error message')`.