@ikas/code-components-mcp 1.4.0-beta.216 → 1.4.0-beta.217
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/data/framework.json +2 -2
- package/data/storefront-api.json +1 -1
- package/data/storefront-types.json +1 -1
- package/dist/index.js +148 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/data/framework.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"ikas-config": {
|
|
18
18
|
"title": "ikas.config.json Schema",
|
|
19
19
|
"description": "Configuration file that defines components, their props, and metadata",
|
|
20
|
-
"content": "The `ikas.config.json` file is the central configuration for your code components project.\n\n```json\n{\n \"name\": \"my-project\",\n \"version\": \"1.0.0\",\n \"globalStyles\": \"./src/global.css\",\n \"components\": [\n {\n \"id\": \"my-component\",\n \"name\": \"My Component\",\n \"entry\": \"./src/components/MyComponent/index.tsx\",\n \"styles\": \"./src/components/MyComponent/styles.css\",\n \"props\": [\n {\n \"name\": \"title\",\n \"displayName\": \"Title\",\n \"type\": \"TEXT\",\n \"required\": true,\n \"defaultValue\": \"Hello\",\n \"description\": \"The main heading text\"\n }\n ]\n },\n {\n \"id\": \"hero-banner\",\n \"name\": \"Hero Banner\",\n \"type\": \"section\",\n \"entry\": \"./src/components/HeroBanner/index.tsx\",\n \"styles\": \"./src/components/HeroBanner/styles.css\",\n \"props\": [\n {\n \"name\": \"heading\",\n \"displayName\": \"Heading\",\n \"type\": \"TEXT\",\n \"required\": true,\n \"defaultValue\": \"Welcome\"\n }\n ]\n }\n ]\n}\n```\n\n### Top-level fields:\n- `name` (string): Project name\n- `version` (string): Project version\n- `globalStyles` (string, optional): Path to a global CSS file (e.g., `\"./src/global.css\"`). See `get_framework_guide(\"global-css\")` for details\n- `components` (array): List of component definitions\n\n### Component fields:\n- `id` (string): Unique identifier (kebab-case)\n- `name` (string): Display name in the editor\n- `type` (string, optional): `\"component\"` (default) or `\"section\"` — sections are page-level containers (e.g. header, hero banner, footer), components are child elements placed inside sections (e.g. button, card, badge)\n- `entry` (string): Path to the component's entry file (index.tsx)\n- `styles` (string): Path to the component's CSS file\n- `props` (array): List of prop definitions\n- `isHeader` (boolean, optional): Mark this section as the store's header. Only for `type: \"section\"`. At most one component should have `isHeader: true`\n- `isFooter` (boolean, optional): Mark this section as the store's footer. Only for `type: \"section\"`. At most one component should have `isFooter: true`\n\n### Prop fields:\n- `name` (string): Prop name used in code (camelCase)\n- `displayName` (string): Label shown in the editor UI\n- `type` (string): One of the available prop types\n- `required` (boolean): Whether the prop must be set\n- `defaultValue` (any): Default value matching the prop type. NOT allowed for dynamic merchant-data types (IMAGE, IMAGE_LIST, VIDEO, PRODUCT, PRODUCT_LIST, PRODUCT_ATTRIBUTE, PRODUCT_ATTRIBUTE_LIST, BRAND, BRAND_LIST, CATEGORY, CATEGORY_LIST, BLOG, BLOG_LIST, BLOG_CATEGORY, BLOG_CATEGORY_LIST, RAFFLE, RAFFLE_LIST) — they resolve from store data at render time, so the CLI rejects a default on these and the editor strips it\n- `description` (string): Help text shown in editor\n- `groupId` (string, optional): Assign this prop to a prop group (references a group's `id`)\n- `requiredProp` (string, optional): Show this prop in the editor panel only while the named BOOLEAN/ENUM prop on the same component satisfies the condition. A prop NAME, not an id. See `get_framework_guide(\"conditional-visibility\")`\n- `requiredPropValue` (boolean, optional): For a BOOLEAN `requiredProp` — which state shows this prop (defaults to `true`)\n- `requiredEnumOptionValue` (string, optional): For an ENUM `requiredProp` — the option value that shows this prop\n\n### Prop Groups (optional):\nAdd `propGroups` array on a component to organize props into collapsible groups in the editor.\n- `id` (string): Unique group identifier within the component\n- `name` (string): Display name in editor\n- `description` (string, optional): Group description\n- `children` (array, optional): Nested groups (max 1 level)\n- `requiredProp` / `requiredPropValue` / `requiredEnumOptionValue` (optional): Gate the whole group — it and everything under it are shown only while the named BOOLEAN/ENUM prop satisfies the condition. See `get_framework_guide(\"conditional-visibility\")`\n\nSee `get_framework_guide(\"prop-groups\")` for full details and examples.\n\n### Header & Footer Flags\nFor section-type components that serve as the store's header or footer, set `isHeader: true` or `isFooter: true`:\n```json\n{\n \"id\": \"header\",\n \"name\": \"Header\",\n \"type\": \"section\",\n \"isHeader\": true,\n \"entry\": \"./src/components/Header/index.tsx\",\n \"styles\": \"./src/components/Header/styles.css\",\n \"props\": [...]\n}\n```\nThese flags tell the editor to treat the wrapper section as a common header/footer, which affects page composition (header/footer appear on all pages automatically).",
|
|
20
|
+
"content": "The `ikas.config.json` file is the central configuration for your code components project.\n\n```json\n{\n \"name\": \"my-project\",\n \"version\": \"1.0.0\",\n \"globalStyles\": \"./src/global.css\",\n \"components\": [\n {\n \"id\": \"my-component\",\n \"name\": \"My Component\",\n \"entry\": \"./src/components/MyComponent/index.tsx\",\n \"styles\": \"./src/components/MyComponent/styles.css\",\n \"props\": [\n {\n \"name\": \"title\",\n \"displayName\": \"Title\",\n \"type\": \"TEXT\",\n \"required\": true,\n \"defaultValue\": \"Hello\",\n \"description\": \"The main heading text\"\n }\n ]\n },\n {\n \"id\": \"hero-banner\",\n \"name\": \"Hero Banner\",\n \"type\": \"section\",\n \"entry\": \"./src/components/HeroBanner/index.tsx\",\n \"styles\": \"./src/components/HeroBanner/styles.css\",\n \"props\": [\n {\n \"name\": \"heading\",\n \"displayName\": \"Heading\",\n \"type\": \"TEXT\",\n \"required\": true,\n \"defaultValue\": \"Welcome\"\n }\n ]\n }\n ]\n}\n```\n\n### Top-level fields:\n- `name` (string): Project name\n- `version` (string): Project version\n- `globalStyles` (string, optional): Path to a global CSS file (e.g., `\"./src/global.css\"`). See `get_framework_guide(\"global-css\")` for details\n- `components` (array): List of component definitions\n\n### Component fields:\n- `id` (string): Unique identifier (kebab-case)\n- `name` (string): Display name in the editor\n- `type` (string, optional): `\"component\"` (default) or `\"section\"` — sections are page-level containers (e.g. header, hero banner, footer), components are child elements placed inside sections (e.g. button, card, badge)\n- `entry` (string): Path to the component's entry file (index.tsx)\n- `styles` (string): Path to the component's CSS file\n- `props` (array): List of prop definitions\n- `isHeader` (boolean, optional): Mark this section as the store's header. Only for `type: \"section\"`. At most one component should have `isHeader: true`\n- `isFooter` (boolean, optional): Mark this section as the store's footer. Only for `type: \"section\"`. At most one component should have `isFooter: true`\n\n### Prop fields:\n- `name` (string): Prop name used in code (camelCase)\n- `displayName` (string): Label shown in the editor UI\n- `type` (string): One of the available prop types\n- `required` (boolean): Whether the prop must be set\n- `defaultValue` (any): Default value matching the prop type. NOT allowed for dynamic merchant-data types (IMAGE, IMAGE_LIST, VIDEO, PRODUCT, PRODUCT_LIST, PRODUCT_ATTRIBUTE, PRODUCT_ATTRIBUTE_LIST, BRAND, BRAND_LIST, CATEGORY, CATEGORY_LIST, BLOG, BLOG_LIST, BLOG_CATEGORY, BLOG_CATEGORY_LIST, RAFFLE, RAFFLE_LIST) — they resolve from store data at render time, so the CLI rejects a default on these and the editor strips it\n- `description` (string): Help text shown in editor\n- `groupId` (string, optional): Assign this prop to a prop group (references a group's `id`)\n- `requiredProp` (string, optional): Show this prop in the editor panel only while the named BOOLEAN/ENUM prop on the same component satisfies the condition. A prop NAME, not an id. See `get_framework_guide(\"conditional-visibility\")`\n- `requiredPropValue` (boolean, optional): For a BOOLEAN `requiredProp` — which state shows this prop (defaults to `true`)\n- `requiredEnumOptionValue` (string, optional): For an ENUM `requiredProp` — the option value that shows this prop\n\n### Prop Groups (optional):\nAdd `propGroups` array on a component to organize props into collapsible groups in the editor.\n- `id` (string): Unique group identifier within the component\n- `name` (string): Display name in editor\n- `description` (string, optional): Group description\n- `children` (array, optional): Nested groups (max 1 level)\n- `requiredProp` / `requiredPropValue` / `requiredEnumOptionValue` (optional): Gate the whole group — it and everything under it are shown only while the named BOOLEAN/ENUM prop satisfies the condition. See `get_framework_guide(\"conditional-visibility\")`\n\nSee `get_framework_guide(\"prop-groups\")` for full details and examples.\n\n### Translations (optional)\nTechnical texts are shown in the editor's own language. The base fields (`name`, `displayName`, `description`) are the default texts; `translations` holds another editor language's texts keyed by locale (`en`). A store language's default prop values go under the component's `translations.<locale>.propValues` (by prop name) \u2014 they seed the section's values in that language.\n```json\n{\n \"id\": \"hero-banner\",\n \"name\": \"Kapak B\u00f6l\u00fcm\u00fc\",\n \"translations\": {\n \"en\": { \"name\": \"Hero Banner\", \"propValues\": { \"heading\": \"Welcome\" } },\n \"de\": { \"propValues\": { \"heading\": \"Willkommen\" } }\n },\n \"props\": [\n {\n \"name\": \"heading\", \"displayName\": \"Ba\u015fl\u0131k\", \"type\": \"TEXT\", \"defaultValue\": \"Ho\u015f geldiniz\",\n \"translations\": { \"en\": { \"displayName\": \"Heading\", \"description\": \"The section heading\" } }\n }\n ],\n \"propGroups\": [\n { \"id\": \"content\", \"name\": \"\u0130\u00e7erik\", \"translations\": { \"en\": { \"name\": \"Content\" } } }\n ]\n}\n```\nThe config gives the default texts. A text edited on the editor's \"Editor Texts\" page stays over the config (a reset button puts the config's text back); while `ikas theme dev` is running, the edited texts and a component's edited default and language values are written to the config on their own (on connecting and on every save). The editor's value wins over a hand edit of the same field in the config; a field not edited in the editor follows the config. To translate from an agent, use the editor's translations page tools (`list_translations`, `update_translations`, `manage_translation_languages`) rather than editing `translations` in the config by hand: they go through the editor and on to the config.\n\n### Header & Footer Flags\nFor section-type components that serve as the store's header or footer, set `isHeader: true` or `isFooter: true`:\n```json\n{\n \"id\": \"header\",\n \"name\": \"Header\",\n \"type\": \"section\",\n \"isHeader\": true,\n \"entry\": \"./src/components/Header/index.tsx\",\n \"styles\": \"./src/components/Header/styles.css\",\n \"props\": [...]\n}\n```\nThese flags tell the editor to treat the wrapper section as a common header/footer, which affects page composition (header/footer appear on all pages automatically).",
|
|
21
21
|
"tags": [
|
|
22
22
|
"config",
|
|
23
23
|
"configuration",
|
|
@@ -224,7 +224,7 @@
|
|
|
224
224
|
"ai-workflow": {
|
|
225
225
|
"title": "AI Agent Workflow for Building ikas Components",
|
|
226
226
|
"description": "Step-by-step guide for AI coding agents building ikas storefront components using CLI commands and MCP tools",
|
|
227
|
-
"content": "## AI Agent Workflow\n\nThis is the recommended step-by-step workflow for AI agents building ikas code components. Follow these steps in order for reliable, error-free results.\n\n**IMPORTANT: NEVER create or edit `types.ts` manually — it is auto-generated by the CLI.** The CLI commands below update BOTH `ikas.config.json` AND `types.ts` automatically.\n\n### Step 1: Create Component with Props\n\nUse `get_section_template(sectionType)` to get a starter template — it includes a ready-to-run CLI command with `--props`.\n\n**Important:** When creating a section, always include a `backgroundColor` COLOR prop (default: `#ffffff`). Optionally consider adding `textColor` for text elements directly on the section background.\n\n**Important:** When creating a header or footer section, use `--isHeader` or `--isFooter` flags on the `add-component` command. This marks the section as the store's common header/footer so it appears on all pages automatically:\n```bash\nnpx ikas-component config add-component --name \"Header\" --type section --isHeader --props '[...]'\nnpx ikas-component config add-component --name \"Footer\" --type section --isFooter --props '[...]'\n```\n\n**Important:** Ensure ALL user-visible text (headings, buttons, labels, empty states, loading text) is exposed as TEXT props. Never hardcode text strings in JSX. Use `defaultValue` for English defaults. For button loading states, use two separate props (e.g., `submitButtonText` + `submittingButtonText`). Group text props under a \"Texts\" propGroup when 5+ props exist.\n\nThen run the single `add-component --props` command to create the component scaffold WITH all props in one step:\n```bash\nnpx ikas-component config add-component --name \"HeroSection\" --type section --props '[{\"name\":\"title\",\"displayName\":\"Title\",\"type\":\"TEXT\",\"required\":true},{\"name\":\"backgroundImage\",\"displayName\":\"Background Image\",\"type\":\"IMAGE\"},{\"name\":\"showButton\",\"displayName\":\"Show Button\",\"type\":\"BOOLEAN\"}]'\n```\n\nThis creates the component directory with `index.tsx`, `types.ts` (with correct Props interface), `styles.css`, updates `ikas.config.json`, and updates the barrel export. The output is JSON:\n```json\n{\"success\": true, \"componentId\": \"abc123-hero-section\", \"componentName\": \"HeroSection\", \"type\": \"section\", \"propsCount\": 3, \"files\": [...]}\n```\n\nThe `--props` flag accepts a JSON array of prop objects. Each prop needs `name` + `type` at minimum. `displayName` is auto-generated from camelCase name if omitted (e.g. `backgroundImage` → `\"Background Image\"`).\n\nTo add more props later, use `add-prop`:\n```bash\nnpx ikas-component config add-prop --component \"HeroSection\" --name \"subtitle\" --displayName \"Subtitle\" --type TEXT\n```\n\n### Step 2: Get Reference Material\n\nBefore writing component code, use MCP tools to get the right patterns:\n- `get_section_template(sectionType)` — Get the API integration pattern reference for common section types (product-detail, cart, login, header, footer, etc.). Study the function calls and data access patterns only.\n- `get_framework_guide(\"common-pitfalls\")` — Review common mistakes to avoid\n- `get_framework_guide(\"component-structure\")` — Review component structure patterns\n- `get_function_doc(functionName)` — Look up exact function signatures before using them\n- `get_model_guide(typeName)` — Get comprehensive info about a model type\n\n### Step 2.5: Design Your Component (IMPORTANT)\n\nBefore writing code, plan an ORIGINAL visual design:\n- Do NOT reproduce layout, CSS class names, or HTML structure from templates/examples\n- Templates and examples demonstrate correct API usage only — they are not designs to copy\n- **KEEP from references:** imports, function calls, data access patterns, form handling flows, type casts, null safety patterns\n- **CREATE fresh:** all JSX/HTML structure, all CSS class names and rules, all visual layout and spacing, all UX patterns (loading states, empty states, transitions, responsive breakpoints)\n- Think about the specific store's brand and design language when creating your component\n\n### Step 3: Write the Component Code\n\nEdit `src/components/{ComponentName}/index.tsx` with the implementation. **Do NOT edit `types.ts`** — it was already generated correctly in Step 1. Key rules:\n- Import props from `./types` (auto-generated in Step 1)\n- Import storefront functions from `@ikas/bp-storefront`\n- Root export should use named + default export: `export function X({ ... }: Props) { ... }` + `export default X;`\n- Only wrap sub-components with `observer()` when they independently read MobX stores\n- Use optional chaining for all props: `props.title ?? \"Default\"`\n- Use `as unknown as boolean` cast for functions like `hasProductStock`, `isAddToCartEnabled`\n- **Sections MUST apply backgroundColor**: destructure `backgroundColor = \"#ffffff\"` and add `style={backgroundColor ? { backgroundColor } : undefined}` on the root `<section>` element\n\n### Step 3.5: Organize Props into Groups (if 5+ props)\n\nIf the component has 5 or more props, organize them into groups for better editor UX:\n```bash\nnpx ikas-component config add-prop-group --component \"HeroSection\" --id content --name \"Content\"\nnpx ikas-component config add-prop-group --component \"HeroSection\" --id appearance --name \"Appearance\"\nnpx ikas-component config update-prop --component \"HeroSection\" --prop title --group content\nnpx ikas-component config update-prop --component \"HeroSection\" --prop backgroundImage --group appearance\n```\n\n### Step 3.6: Hide Props That Do Not Apply (optional)\n\nWhen a prop only makes sense while another setting is on, gate it instead of leaving it in the panel\nall the time. A prop or a whole group can be conditioned on a `BOOLEAN` or `ENUM` prop of the same\ncomponent — the control is drawn only while the condition holds, and a `required` prop hidden this\nway stops blocking a publish (its value is still stored and still passed to your component):\n```bash\n# badgeText shows only while the showBadge toggle is on\nnpx ikas-component config update-prop --component \"HeroSection\" --prop badgeText --requiredProp showBadge\n# the whole \"Badge\" group follows the same toggle\nnpx ikas-component config update-prop-group --component \"HeroSection\" --id badge --requiredProp showBadge\n# columns shows only for the \"grid\" option of the layout ENUM prop\nnpx ikas-component config update-prop --component \"HeroSection\" --prop columns --requiredProp layout --requiredEnumOptionValue grid\n```\nSee `get_framework_guide(\"conditional-visibility\")` for the rules (the CLI rejects self-gates,\ncycles, non-BOOLEAN/ENUM governing props, and a group gated by a prop inside it).\n\n### Step 4: Write Styles\n\nEdit `src/components/{ComponentName}/styles.css`. Key rules:\n- Use class selectors only (`.my-class`), never bare element selectors\n- CSS is auto-scoped at build time — no manual namespacing needed\n- Keep a sub-component's CSS in its OWN folder's `styles.css`. Every command (`dev`, `publish`, `build`) collects the sibling `styles.css` of each imported sub-component automatically. Never copy a sub-component's rules into the parent's `styles.css`, and never `import \"./styles.css\"` from TSX.\n- For sections: `width: 100%; padding: 64px 24px;` with inner max-width container\n\n### Step 5: Verify with Type Checking\n\nRun the lightweight type checker:\n```bash\nnpx ikas-component check --json\n```\n\nSuccess output:\n```json\n{\"success\": true, \"errors\": []}\n```\n\nError output:\n```json\n{\"success\": false, \"errorCount\": 2, \"errors\": [{\"file\": \"src/components/Hero/index.tsx\", \"line\": 15, \"column\": 3, \"code\": \"TS2339\", \"message\": \"Property 'title' does not exist on type 'Props'\"}]}\n```\n\n### Step 6: Fix Errors and Re-check\n\nFor each error:\n1. Read the file and line number from the error\n2. Fix the issue (common fixes below)\n3. Re-run `npx ikas-component check --json`\n\n**Common error fixes:**\n- `Property 'x' does not exist on type 'Props'` — Prop wasn't added via CLI. Run `npx ikas-component config add-prop`.\n- `Cannot find module '@ikas/bp-storefront'` — Normal in type-check if node_modules not fully installed. Focus on component-level errors.\n- `Type 'X' is not assignable to type 'Y'` — Check function signature with `get_function_doc()`.\n\n### Step 7: Full Build Validation\n\nOnce type checking passes, run the full build:\n```bash\nnpx ikas-component build\n```\n\nThis runs type checking + esbuild compilation + CSS scoping. It catches what `check` cannot: deep `@ikas/bp-storefront/dist/...` imports and disallowed external packages are esbuild-level errors, invisible to `tsc`.\n\n`build` is a VALIDATION step only — nothing reads its `dist/` output. The editor gets components over the `dev` WebSocket (`import_section`), and releases go out via `publish`. So do NOT restructure source code to make `dist/` look a certain way, and do not treat a difference between `dist/` and the editor's copy as a bug: `build` compiles each component in isolation, so by design it has no shared chunks, no `canvasClientJs`, and no `global.css`.\n\n### Quick Reference: CLI Commands\n\n| Command | Purpose |\n|---------|--------|\n| `npx ikas-component config add-component --name X --type section --props '[...]'` | **Primary** — create component with all props |\n| `npx ikas-component config add-component --name X --type section --isHeader --props '[...]'` | Create header section |\n| `npx ikas-component config add-component --name X --type section --isFooter --props '[...]'` | Create footer section |\n| `npx ikas-component config add-component --name X --type section` | Create component with no props |\n| `npx ikas-component config add-prop --component X --name y --displayName Y --type TEXT` | Add a prop incrementally |\n| `npx ikas-component config update-prop --component X --prop y --required true` | Update a prop |\n| `npx ikas-component config remove-prop --component X --prop y` | Remove a prop |\n| `npx ikas-component config remove-component --name X` | Remove a component |\n| `npx ikas-component config list` | List all components and props |\n| `npx ikas-component check --json` | Type-check with JSON output |\n| `npx ikas-component build` | Full production build |\n\n### Quick Reference: MCP Tools\n\n| Tool | When to Use |\n|------|------------|\n| `get_section_template(type)` | Starting a new section — get API integration pattern reference + CLI command (create original design, don't copy layout) |\n| `get_framework_guide(topic)` | Understanding patterns, pitfalls, architecture |\n| `get_function_doc(name)` | Looking up exact function signature |\n| `get_model_guide(type)` | Working with a model type (IkasProduct, IkasCart, etc.) |\n| `get_prop_types()` | Checking available prop types for ikas.config.json |\n| `search_docs(query)` | Finding relevant functions/docs by keyword |\n\n### Reuse the theme's global settings\n\nBefore hardcoding colors or typography, call `list_theme_globals` to discover the theme's existing global variables and design tokens, and read them at runtime via `getThemeColors()` / `getThemeSetting()` / `getThemeTypography()` from `@ikas/bp-storefront`. You can also create new ones with `create_theme_global`. See `get_framework_guide(\"theme-globals\")`.",
|
|
227
|
+
"content": "## AI Agent Workflow\n\nThis is the recommended step-by-step workflow for AI agents building ikas code components. Follow these steps in order for reliable, error-free results.\n\n**IMPORTANT: NEVER create or edit `types.ts` manually — it is auto-generated by the CLI.** The CLI commands below update BOTH `ikas.config.json` AND `types.ts` automatically.\n\n### Step 1: Create Component with Props\n\nUse `get_section_template(sectionType)` to get a starter template — it includes a ready-to-run CLI command with `--props`.\n\n**Important:** When creating a section, always include a `backgroundColor` COLOR prop (default: `#ffffff`). Optionally consider adding `textColor` for text elements directly on the section background.\n\n**Important:** When creating a header or footer section, use `--isHeader` or `--isFooter` flags on the `add-component` command. This marks the section as the store's common header/footer so it appears on all pages automatically:\n```bash\nnpx ikas-component config add-component --name \"Header\" --type section --isHeader --props '[...]'\nnpx ikas-component config add-component --name \"Footer\" --type section --isFooter --props '[...]'\n```\n\n**Important:** Ensure ALL user-visible text (headings, buttons, labels, empty states, loading text) is exposed as TEXT props. Never hardcode text strings in JSX. Use `defaultValue` for English defaults. For button loading states, use two separate props (e.g., `submitButtonText` + `submittingButtonText`). Group text props under a \"Texts\" propGroup when 5+ props exist.\n\nThen run the single `add-component --props` command to create the component scaffold WITH all props in one step:\n```bash\nnpx ikas-component config add-component --name \"HeroSection\" --type section --props '[{\"name\":\"title\",\"displayName\":\"Title\",\"type\":\"TEXT\",\"required\":true},{\"name\":\"backgroundImage\",\"displayName\":\"Background Image\",\"type\":\"IMAGE\"},{\"name\":\"showButton\",\"displayName\":\"Show Button\",\"type\":\"BOOLEAN\"}]'\n```\n\nThis creates the component directory with `index.tsx`, `types.ts` (with correct Props interface), `styles.css`, updates `ikas.config.json`, and updates the barrel export. The output is JSON:\n```json\n{\"success\": true, \"componentId\": \"abc123-hero-section\", \"componentName\": \"HeroSection\", \"type\": \"section\", \"propsCount\": 3, \"files\": [...]}\n```\n\nThe `--props` flag accepts a JSON array of prop objects. Each prop needs `name` + `type` at minimum. `displayName` is auto-generated from camelCase name if omitted (e.g. `backgroundImage` → `\"Background Image\"`).\n\nTo add more props later, use `add-prop`:\n```bash\nnpx ikas-component config add-prop --component \"HeroSection\" --name \"subtitle\" --displayName \"Subtitle\" --type TEXT\n```\n\n### Step 2: Get Reference Material\n\nBefore writing component code, use MCP tools to get the right patterns:\n- `get_section_template(sectionType)` — Get the API integration pattern reference for common section types (product-detail, cart, login, header, footer, etc.). Study the function calls and data access patterns only.\n- `get_framework_guide(\"common-pitfalls\")` — Review common mistakes to avoid\n- `get_framework_guide(\"component-structure\")` — Review component structure patterns\n- `get_function_doc(functionName)` — Look up exact function signatures before using them\n- `get_model_guide(typeName)` — Get comprehensive info about a model type\n\n### Step 2.5: Design Your Component (IMPORTANT)\n\nBefore writing code, plan an ORIGINAL visual design:\n- Do NOT reproduce layout, CSS class names, or HTML structure from templates/examples\n- Templates and examples demonstrate correct API usage only — they are not designs to copy\n- **KEEP from references:** imports, function calls, data access patterns, form handling flows, type casts, null safety patterns\n- **CREATE fresh:** all JSX/HTML structure, all CSS class names and rules, all visual layout and spacing, all UX patterns (loading states, empty states, transitions, responsive breakpoints)\n- Think about the specific store's brand and design language when creating your component\n\n### Step 3: Write the Component Code\n\nEdit `src/components/{ComponentName}/index.tsx` with the implementation. **Do NOT edit `types.ts`** — it was already generated correctly in Step 1. Key rules:\n- Import props from `./types` (auto-generated in Step 1)\n- Import storefront functions from `@ikas/bp-storefront`\n- Root export should use named + default export: `export function X({ ... }: Props) { ... }` + `export default X;`\n- Only wrap sub-components with `observer()` when they independently read MobX stores\n- Use optional chaining for all props: `props.title ?? \"Default\"`\n- Use `as unknown as boolean` cast for functions like `hasProductStock`, `isAddToCartEnabled`\n- **Sections MUST apply backgroundColor**: destructure `backgroundColor = \"#ffffff\"` and add `style={backgroundColor ? { backgroundColor } : undefined}` on the root `<section>` element\n\n### Step 3.5: Organize Props into Groups (if 5+ props)\n\nIf the component has 5 or more props, organize them into groups for better editor UX:\n```bash\nnpx ikas-component config add-prop-group --component \"HeroSection\" --id content --name \"Content\"\nnpx ikas-component config add-prop-group --component \"HeroSection\" --id appearance --name \"Appearance\"\nnpx ikas-component config update-prop --component \"HeroSection\" --prop title --group content\nnpx ikas-component config update-prop --component \"HeroSection\" --prop backgroundImage --group appearance\n```\n\n### Step 3.6: Hide Props That Do Not Apply (optional)\n\nWhen a prop only makes sense while another setting is on, gate it instead of leaving it in the panel\nall the time. A prop or a whole group can be conditioned on a `BOOLEAN` or `ENUM` prop of the same\ncomponent — the control is drawn only while the condition holds, and a `required` prop hidden this\nway stops blocking a publish (its value is still stored and still passed to your component):\n```bash\n# badgeText shows only while the showBadge toggle is on\nnpx ikas-component config update-prop --component \"HeroSection\" --prop badgeText --requiredProp showBadge\n# the whole \"Badge\" group follows the same toggle\nnpx ikas-component config update-prop-group --component \"HeroSection\" --id badge --requiredProp showBadge\n# columns shows only for the \"grid\" option of the layout ENUM prop\nnpx ikas-component config update-prop --component \"HeroSection\" --prop columns --requiredProp layout --requiredEnumOptionValue grid\n```\nSee `get_framework_guide(\"conditional-visibility\")` for the rules (the CLI rejects self-gates,\ncycles, non-BOOLEAN/ENUM governing props, and a group gated by a prop inside it).\n\n### Step 4: Write Styles\n\nEdit `src/components/{ComponentName}/styles.css`. Key rules:\n- Use class selectors only (`.my-class`), never bare element selectors\n- CSS is auto-scoped at build time — no manual namespacing needed\n- Keep a sub-component's CSS in its OWN folder's `styles.css`. Every command (`dev`, `publish`, `build`) collects the sibling `styles.css` of each imported sub-component automatically. Never copy a sub-component's rules into the parent's `styles.css`, and never `import \"./styles.css\"` from TSX.\n- For sections: `width: 100%; padding: 64px 24px;` with inner max-width container\n\n### Step 5: Verify with Type Checking\n\nRun the lightweight type checker:\n```bash\nnpx ikas-component check --json\n```\n\nSuccess output:\n```json\n{\"success\": true, \"errors\": []}\n```\n\nError output:\n```json\n{\"success\": false, \"errorCount\": 2, \"errors\": [{\"file\": \"src/components/Hero/index.tsx\", \"line\": 15, \"column\": 3, \"code\": \"TS2339\", \"message\": \"Property 'title' does not exist on type 'Props'\"}]}\n```\n\n### Step 6: Fix Errors and Re-check\n\nFor each error:\n1. Read the file and line number from the error\n2. Fix the issue (common fixes below)\n3. Re-run `npx ikas-component check --json`\n\n**Common error fixes:**\n- `Property 'x' does not exist on type 'Props'` — Prop wasn't added via CLI. Run `npx ikas-component config add-prop`.\n- `Cannot find module '@ikas/bp-storefront'` — Normal in type-check if node_modules not fully installed. Focus on component-level errors.\n- `Type 'X' is not assignable to type 'Y'` — Check function signature with `get_function_doc()`.\n\n### Step 7: Full Build Validation\n\nOnce type checking passes, run the full build:\n```bash\nnpx ikas-component build\n```\n\nThis runs type checking + esbuild compilation + CSS scoping. It catches what `check` cannot: deep `@ikas/bp-storefront/dist/...` imports and disallowed external packages are esbuild-level errors, invisible to `tsc`.\n\n`build` is a VALIDATION step only — nothing reads its `dist/` output. The editor gets components over the `dev` WebSocket (`import_section`), and releases go out via `publish`. So do NOT restructure source code to make `dist/` look a certain way, and do not treat a difference between `dist/` and the editor's copy as a bug: `build` compiles each component in isolation, so by design it has no shared chunks, no `canvasClientJs`, and no `global.css`.\n\n### Quick Reference: CLI Commands\n\n| Command | Purpose |\n|---------|--------|\n| `npx ikas-component config add-component --name X --type section --props '[...]'` | **Primary** — create component with all props |\n| `npx ikas-component config add-component --name X --type section --isHeader --props '[...]'` | Create header section |\n| `npx ikas-component config add-component --name X --type section --isFooter --props '[...]'` | Create footer section |\n| `npx ikas-component config add-component --name X --type section` | Create component with no props |\n| `npx ikas-component config add-prop --component X --name y --displayName Y --type TEXT` | Add a prop incrementally |\n| `npx ikas-component config update-prop --component X --prop y --required true` | Update a prop |\n| `npx ikas-component config remove-prop --component X --prop y --yes` | Remove a prop (only after the user agreed) |\n| `npx ikas-component config remove-component --name X --yes` | Remove a component and its folder (only after the user agreed) |\n| `npx ikas-component config list` | List all components and props |\n| `npx ikas-component check --json` | Type-check with JSON output |\n| `npx ikas-component build` | Full production build |\n\n### Quick Reference: MCP Tools\n\n| Tool | When to Use |\n|------|------------|\n| `get_section_template(type)` | Starting a new section — get API integration pattern reference + CLI command (create original design, don't copy layout) |\n| `get_framework_guide(topic)` | Understanding patterns, pitfalls, architecture |\n| `get_function_doc(name)` | Looking up exact function signature |\n| `get_model_guide(type)` | Working with a model type (IkasProduct, IkasCart, etc.) |\n| `get_prop_types()` | Checking available prop types for ikas.config.json |\n| `search_docs(query)` | Finding relevant functions/docs by keyword |\n\n### Reuse the theme's global settings\n\nBefore hardcoding colors or typography, call `list_theme_globals` to discover the theme's existing global variables and design tokens, and read them at runtime via `getThemeColors()` / `getThemeSetting()` / `getThemeTypography()` from `@ikas/bp-storefront`. You can also create new ones with `create_theme_global`. See `get_framework_guide(\"theme-globals\")`.",
|
|
228
228
|
"tags": [
|
|
229
229
|
"ai",
|
|
230
230
|
"workflow",
|
package/data/storefront-api.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -3839,7 +3839,7 @@ server.tool("add_sections_to_page", "Place MANY sections on a page in a SINGLE c
|
|
|
3839
3839
|
.describe("Absolute path to the code-component project."),
|
|
3840
3840
|
page_id: z.string().describe("Target page id (from `list_editor_pages`)."),
|
|
3841
3841
|
sections: z
|
|
3842
|
-
.array(z.
|
|
3842
|
+
.array(z.strictObject({
|
|
3843
3843
|
component_id: z
|
|
3844
3844
|
.string()
|
|
3845
3845
|
.describe("Imported (or built) section-type code component id."),
|
|
@@ -3850,7 +3850,7 @@ server.tool("add_sections_to_page", "Place MANY sections on a page in a SINGLE c
|
|
|
3850
3850
|
.optional()
|
|
3851
3851
|
.describe("Zero-based insertion index; appends when omitted."),
|
|
3852
3852
|
updates: z
|
|
3853
|
-
.array(z.
|
|
3853
|
+
.array(z.strictObject({
|
|
3854
3854
|
prop_id: z
|
|
3855
3855
|
.string()
|
|
3856
3856
|
.optional()
|
|
@@ -4046,7 +4046,7 @@ server.tool("update_section_prop", 'Change a single prop value of a section plac
|
|
|
4046
4046
|
.optional()
|
|
4047
4047
|
.describe("Bind this prop to a project GLOBAL variable (Theme Setting) as a LIVE dynamic value instead of writing a static `value` — the prop then always reflects that global's current value (edited in Theme Settings). Pass the global's `name` (its `variableName`, the `_<id>` form) from `list_theme_globals`. Provide `value` OR `bind_global`, not both. Writing a static `value` to a prop that is bound to a global (see `bindings` in `get_section_values`) REPLACES the binding — the prop stops following the global, and the result carries `unboundGlobal` + a `warning`. To change what a bound prop shows, update the global (`update_theme_global`) instead. Bindable globals include TEXT / RICH_TEXT / NUMBER / BOOLEAN / IMAGE / COLOR / BORDER / SHADOW / ENUM settings; pick a global whose type matches the prop (an ENUM prop only binds an ENUM setting of the same enum type). (This is the general theme-global binding; a COLOR prop can alternatively take an inline `{ \"patternValueId\" }` for theme colors.)"),
|
|
4048
4048
|
list_path: z
|
|
4049
|
-
.array(z.
|
|
4049
|
+
.array(z.strictObject({ propId: z.string(), index: z.number() }))
|
|
4050
4050
|
.optional()
|
|
4051
4051
|
.describe("Only with `bind_global`: bind a prop of a COMPONENT_LIST child instead of a section-level prop. An array of `{ propId, index }` steps from the section down to the target child; `prop_id` is then the CHILD's prop id (from `get_component_props`)."),
|
|
4052
4052
|
port: z
|
|
@@ -4117,12 +4117,12 @@ server.tool("update_page_sections", "Fill MANY placed sections of a page in a SI
|
|
|
4117
4117
|
.describe("Absolute path to the code-component project."),
|
|
4118
4118
|
page_id: z.string().describe("Target page id (from list_editor_pages)."),
|
|
4119
4119
|
sections: z
|
|
4120
|
-
.array(z.
|
|
4120
|
+
.array(z.strictObject({
|
|
4121
4121
|
element_id: z
|
|
4122
4122
|
.string()
|
|
4123
4123
|
.describe("Placed-section elementId (from list_page_sections)."),
|
|
4124
4124
|
updates: z
|
|
4125
|
-
.array(z.
|
|
4125
|
+
.array(z.strictObject({
|
|
4126
4126
|
prop_id: z
|
|
4127
4127
|
.string()
|
|
4128
4128
|
.optional()
|
|
@@ -4140,7 +4140,7 @@ server.tool("update_page_sections", "Fill MANY placed sections of a page in a SI
|
|
|
4140
4140
|
.optional()
|
|
4141
4141
|
.describe("Bind this prop to a project GLOBAL variable (Theme Setting) as a live dynamic value instead of a static value. The global's `name` (variableName) from list_theme_globals. Provide value OR bind_global."),
|
|
4142
4142
|
list_path: z
|
|
4143
|
-
.array(z.
|
|
4143
|
+
.array(z.strictObject({ propId: z.string(), index: z.number() }))
|
|
4144
4144
|
.optional()
|
|
4145
4145
|
.describe("Only with bind_global: `{ propId, index }` steps down to a COMPONENT_LIST child; prop_id is then the child's prop id."),
|
|
4146
4146
|
}))
|
|
@@ -4181,7 +4181,7 @@ server.tool("upload_images", "Upload MANY images in one call (batch upload_image
|
|
|
4181
4181
|
.string()
|
|
4182
4182
|
.describe("Absolute path to the code-component project."),
|
|
4183
4183
|
images: z
|
|
4184
|
-
.array(z.
|
|
4184
|
+
.array(z.strictObject({
|
|
4185
4185
|
file_path: z
|
|
4186
4186
|
.string()
|
|
4187
4187
|
.optional()
|
|
@@ -4543,17 +4543,134 @@ server.tool("enable_ready_made_pages", 'Turn one GROUP of ikas-rendered ready-ma
|
|
|
4543
4543
|
enabled: z
|
|
4544
4544
|
.boolean()
|
|
4545
4545
|
.describe("true to enable the group, false to disable it."),
|
|
4546
|
+
confirm: z
|
|
4547
|
+
.boolean()
|
|
4548
|
+
.optional()
|
|
4549
|
+
.describe(`Disabling only (it removes pages). ${CONFIRM_PARAM_DESCRIPTION}`),
|
|
4546
4550
|
port: z
|
|
4547
4551
|
.number()
|
|
4548
4552
|
.optional()
|
|
4549
4553
|
.describe("Dev server WebSocket port (default 5201)."),
|
|
4550
|
-
}, async ({ project_root, group, enabled, port }) => {
|
|
4554
|
+
}, async ({ project_root, group, enabled, confirm, port }) => {
|
|
4555
|
+
if (!enabled && confirm !== true)
|
|
4556
|
+
return destructiveConfirmRefusal();
|
|
4551
4557
|
const args = [
|
|
4552
4558
|
"enable-builtin-pages",
|
|
4553
4559
|
"--group",
|
|
4554
4560
|
group,
|
|
4555
4561
|
"--enabled",
|
|
4556
4562
|
String(enabled),
|
|
4563
|
+
...(enabled ? [] : ["--yes"]),
|
|
4564
|
+
...(port ? ["--port", String(port)] : []),
|
|
4565
|
+
];
|
|
4566
|
+
return callEditorAction(project_root, args);
|
|
4567
|
+
});
|
|
4568
|
+
// Tool: list_translations
|
|
4569
|
+
server.tool("list_translations", 'Read the editor\'s translations page — everything its two sides hold. `mode: "store"` = store content: sections\' and components\' translatable prop values (TEXT, RICH_TEXT, IMAGE, IMAGE_LIST, VIDEO) and element texts, the storefront\'s common texts (`common`, per store language only), the global texts/images (`global`). `mode: "editor"` = the editor texts: item names, prop labels/descriptions, group names/descriptions, and the global settings\' names (`global`: one item per settings list). Locales: "default" is the base texts every language falls back to (no record); otherwise a store language (store mode) or an added editor language (editor mode). Without `area`: the languages, the addable ones, routing languages, and each language\'s translated/total by area — start here. With `area` + `locale`: the area\'s items with progress. With `item_id`: the item\'s fields — `key` (what update_translations takes), `kind` (the value\'s shape), `source` (the text it is translated from), `value` (now), `required`, and `editedOverAsset` when the field holds an edit over a design asset\'s value (resettable). `only_missing: true` keeps the empty fields. Requires `ikas theme dev` running with the editor connected.', {
|
|
4570
|
+
project_root: z
|
|
4571
|
+
.string()
|
|
4572
|
+
.describe("Absolute path to the code-component project."),
|
|
4573
|
+
mode: z.enum(["store", "editor"]).describe("store = store content; editor = editor texts."),
|
|
4574
|
+
area: z
|
|
4575
|
+
.enum(["sections", "components", "common", "global"])
|
|
4576
|
+
.optional()
|
|
4577
|
+
.describe("The page's sidebar list (editor mode has no `common`). Omit for the languages and progress."),
|
|
4578
|
+
locale: z
|
|
4579
|
+
.string()
|
|
4580
|
+
.optional()
|
|
4581
|
+
.describe('"default" or a language code. Required with `area`.'),
|
|
4582
|
+
item_id: z
|
|
4583
|
+
.string()
|
|
4584
|
+
.optional()
|
|
4585
|
+
.describe("An item id from the area's list: returns its fields."),
|
|
4586
|
+
only_missing: z
|
|
4587
|
+
.boolean()
|
|
4588
|
+
.optional()
|
|
4589
|
+
.describe("With item_id: only the fields without a value in `locale`."),
|
|
4590
|
+
port: z
|
|
4591
|
+
.number()
|
|
4592
|
+
.optional()
|
|
4593
|
+
.describe("Dev server WebSocket port (default 5201)."),
|
|
4594
|
+
}, async ({ project_root, mode, area, locale, item_id, only_missing, port }) => {
|
|
4595
|
+
const args = [
|
|
4596
|
+
"list-translations",
|
|
4597
|
+
"--mode",
|
|
4598
|
+
mode,
|
|
4599
|
+
...(area ? ["--area", area] : []),
|
|
4600
|
+
...(locale ? ["--locale", locale] : []),
|
|
4601
|
+
...(item_id ? ["--item", item_id] : []),
|
|
4602
|
+
...(only_missing ? ["--only-missing"] : []),
|
|
4603
|
+
...(port ? ["--port", String(port)] : []),
|
|
4604
|
+
];
|
|
4605
|
+
return callEditorAction(project_root, args);
|
|
4606
|
+
});
|
|
4607
|
+
// Tool: update_translations
|
|
4608
|
+
server.tool("update_translations", 'Write translations in ONE language through the editor\'s translations page, as a batch: each edit is `{ area, item_id, key, value }`, or `{ area, item_id, key, reset: true }` to put back the design asset\'s value of a field listed with `editedOverAsset`. Take `key` and `kind` from `list_translations` with `item_id` — never guess keys. VALUES BY KIND: text = a string; richText = an HTML string (e.g. "<p>Hi</p>"); image = `{ "id": "<image id>", "altText"?: string }` (id from `upload_image`); imageList = `{ "images": [{ "id": ... }] }`; video = `{ "video": { "id": ... }, "thumbnailImage"?: { "id": ... }, "autoplay"?, "controls"?, "loop"?, "muted"?: boolean }`; globalImage = `{ "id": ... }`; `null` empties the field (a cleared common text takes ikas\'s own back). STRICT: every edit is checked before anything is written — the language must be added, the item and key must exist, the value must match the kind (unknown keys rejected), a default name/label cannot be empty, and a global setting\'s default name must pass the page\'s rules; one bad edit and NOTHING is written (the reply lists each error). The batch is one undo step in the editor; the open translations page reloads (or warns its unsaved edits). Edits of the connected project\'s code components are written on to its ikas.config.json. Translate from `source`, keep HTML structure in rich text, do not translate brand names.', {
|
|
4609
|
+
project_root: z
|
|
4610
|
+
.string()
|
|
4611
|
+
.describe("Absolute path to the code-component project."),
|
|
4612
|
+
mode: z.enum(["store", "editor"]).describe("store = store content; editor = editor texts."),
|
|
4613
|
+
locale: z
|
|
4614
|
+
.string()
|
|
4615
|
+
.describe('"default" (the base texts) or an added language code.'),
|
|
4616
|
+
edits: z
|
|
4617
|
+
.array(z.strictObject({
|
|
4618
|
+
area: z.enum(["sections", "components", "common", "global"]),
|
|
4619
|
+
item_id: z.string(),
|
|
4620
|
+
key: z.string(),
|
|
4621
|
+
value: z.any().optional(),
|
|
4622
|
+
reset: z.literal(true).optional(),
|
|
4623
|
+
}))
|
|
4624
|
+
.min(1)
|
|
4625
|
+
.describe("The edits; a field at most once."),
|
|
4626
|
+
port: z
|
|
4627
|
+
.number()
|
|
4628
|
+
.optional()
|
|
4629
|
+
.describe("Dev server WebSocket port (default 5201)."),
|
|
4630
|
+
}, async ({ project_root, mode, locale, edits, port }) => {
|
|
4631
|
+
const args = [
|
|
4632
|
+
"update-translations",
|
|
4633
|
+
"--mode",
|
|
4634
|
+
mode,
|
|
4635
|
+
"--locale",
|
|
4636
|
+
locale,
|
|
4637
|
+
"--edits",
|
|
4638
|
+
JSON.stringify(edits),
|
|
4639
|
+
...(port ? ["--port", String(port)] : []),
|
|
4640
|
+
];
|
|
4641
|
+
return callEditorAction(project_root, args);
|
|
4642
|
+
});
|
|
4643
|
+
// Tool: manage_translation_languages
|
|
4644
|
+
server.tool("manage_translation_languages", 'Add languages to the editor\'s translations page or delete one, as its language settings do. `mode: "store"`: store languages — any language code (`list_translations` lists the addable ones); a new one gets ikas\'s built-in common texts. `mode: "editor"`: the editor languages the editor texts are translated into (tr/en). Pass `add` (codes) OR `remove` (one code). DESTRUCTIVE removal: it deletes every text in that language (and with `remove_page_values`, a routing language\'s page values) — ask the user first and pass `confirm: true` only after they agreed. Adding is one undo step.', {
|
|
4645
|
+
project_root: z
|
|
4646
|
+
.string()
|
|
4647
|
+
.describe("Absolute path to the code-component project."),
|
|
4648
|
+
mode: z.enum(["store", "editor"]).describe("store = store languages; editor = editor languages."),
|
|
4649
|
+
add: z
|
|
4650
|
+
.array(z.string())
|
|
4651
|
+
.optional()
|
|
4652
|
+
.describe("Language codes to add (e.g. [\"de\", \"fr\"])."),
|
|
4653
|
+
remove: z.string().optional().describe("The language code to delete."),
|
|
4654
|
+
remove_page_values: z
|
|
4655
|
+
.boolean()
|
|
4656
|
+
.optional()
|
|
4657
|
+
.describe("With remove on a store language that has a storefront routing: also remove its page values."),
|
|
4658
|
+
confirm: z.boolean().optional().describe(CONFIRM_PARAM_DESCRIPTION),
|
|
4659
|
+
port: z
|
|
4660
|
+
.number()
|
|
4661
|
+
.optional()
|
|
4662
|
+
.describe("Dev server WebSocket port (default 5201)."),
|
|
4663
|
+
}, async ({ project_root, mode, add, remove, remove_page_values, confirm, port }) => {
|
|
4664
|
+
if (remove !== undefined && confirm !== true)
|
|
4665
|
+
return destructiveConfirmRefusal();
|
|
4666
|
+
const args = [
|
|
4667
|
+
"translation-languages",
|
|
4668
|
+
"--mode",
|
|
4669
|
+
mode,
|
|
4670
|
+
...(add ? ["--add", add.join(",")] : []),
|
|
4671
|
+
...(remove !== undefined
|
|
4672
|
+
? ["--remove", remove, "--yes", ...(remove_page_values ? ["--remove-page-values"] : [])]
|
|
4673
|
+
: []),
|
|
4557
4674
|
...(port ? ["--port", String(port)] : []),
|
|
4558
4675
|
];
|
|
4559
4676
|
return callEditorAction(project_root, args);
|
|
@@ -4644,6 +4761,9 @@ const EDITOR_WORKFLOW_GUIDE = [
|
|
|
4644
4761
|
"",
|
|
4645
4762
|
"## Validation",
|
|
4646
4763
|
"Values are validated server-side (deeply, including nested children). Wrong shape or wrong semantics (double-encoded string, { value } wrapper on an object prop, props vs propValues, missing/duplicate id, wrong reference key, nonexistent component id, unknown prop name) are REJECTED with an explanatory error instead of being stored silently. Read the error and fix the value; if unsure of a shape, read it with get_section_values and match it.",
|
|
4764
|
+
"",
|
|
4765
|
+
"## Translations (other languages)",
|
|
4766
|
+
"update_section_prop writes the base value only. A section's texts in another language, the common and global texts, the editor texts (names, labels) and the languages themselves are the translations page's: list_translations (start without an area: languages and progress) → list_translations with area/locale/item_id for the field keys → update_translations (a checked batch in one language) → manage_translation_languages to add a language (deleting one needs the user's OK).",
|
|
4647
4767
|
].join("\n");
|
|
4648
4768
|
server.tool("get_editor_workflow", "Read this FIRST when the user wants to place a section on a page or fill/edit a section's content (text, image, link, slides, component lists) in the live editor. Returns the complete step-by-step workflow for the live-editor tools (list_editor_pages, list_imported_sections, import_section, add_section_to_page, list_page_sections, update_section_prop, upload_image), the per-prop-type value shapes, the COMPONENT_LIST read-modify-write rules, how COMMON (global) header/footer sections keep one theme-wide set of values on the INDEX page (and how not to overwrite them), and how validation/auto-import behave. Use it to avoid the common mistake of writing component code to set a value a section already supports.", {}, async () => {
|
|
4649
4769
|
return {
|
|
@@ -5271,12 +5391,15 @@ server.tool("delete_theme_global", 'Delete a theme global setting from the conne
|
|
|
5271
5391
|
.string()
|
|
5272
5392
|
.optional()
|
|
5273
5393
|
.describe("design-token id, or for colorSchemeSlot the slot id from `list_theme_globals` → colorSchemes.schemes."),
|
|
5394
|
+
confirm: z.boolean().describe(CONFIRM_PARAM_DESCRIPTION),
|
|
5274
5395
|
port: z
|
|
5275
5396
|
.number()
|
|
5276
5397
|
.optional()
|
|
5277
5398
|
.describe("Dev server WebSocket port (default 5201)."),
|
|
5278
|
-
}, async ({ project_root, kind, name, id, port }) => {
|
|
5279
|
-
|
|
5399
|
+
}, async ({ project_root, kind, name, id, confirm, port }) => {
|
|
5400
|
+
if (confirm !== true)
|
|
5401
|
+
return destructiveConfirmRefusal();
|
|
5402
|
+
const p = [...(port ? ["--port", String(port)] : []), "--yes"];
|
|
5280
5403
|
const args = kind === "globalVariable"
|
|
5281
5404
|
? ["delete-global-variable", "--name", String(name ?? ""), ...p]
|
|
5282
5405
|
: [
|
|
@@ -5290,7 +5413,22 @@ server.tool("delete_theme_global", 'Delete a theme global setting from the conne
|
|
|
5290
5413
|
return callEditorAction(project_root, args);
|
|
5291
5414
|
});
|
|
5292
5415
|
// --- Start server ---
|
|
5416
|
+
/**
|
|
5417
|
+
* Every tool's arguments are checked strictly: an unknown argument (a typo, an invented field) is an error the
|
|
5418
|
+
* agent sees, not one dropped in silence while the call goes on without it.
|
|
5419
|
+
*/
|
|
5420
|
+
function makeToolArgumentsStrict() {
|
|
5421
|
+
// The SDK builds a lenient object from each tool's fields; the same fields make the strict one (nested
|
|
5422
|
+
// objects are declared with `z.strictObject`).
|
|
5423
|
+
const tools = server._registeredTools;
|
|
5424
|
+
for (const tool of Object.values(tools)) {
|
|
5425
|
+
const shape = tool.inputSchema?.shape ?? tool.inputSchema?._zod?.def?.shape;
|
|
5426
|
+
if (shape)
|
|
5427
|
+
tool.inputSchema = z.strictObject(shape);
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5293
5430
|
async function main() {
|
|
5431
|
+
makeToolArgumentsStrict();
|
|
5294
5432
|
const transport = new StdioServerTransport();
|
|
5295
5433
|
await server.connect(transport);
|
|
5296
5434
|
}
|