{
  "title": "JSON schema for Blockstudio settings",
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "users": {
      "type": "object",
      "description": "Settings related to allowed users with access to the settings and editor.",
      "properties": {
        "ids": {
          "id": "userIds",
          "type": "array",
          "default": [],
          "items": {
            "type": "integer"
          },
          "description": "List of user IDs with access to the settings and editor.",
          "descriptionFilter": "This filter allows you to enable the editor for specific user IDs.",
          "help": "Comma separated list of user IDs. Example: 1,2,3",
          "example": [
            1
          ]
        },
        "roles": {
          "id": "userRoles",
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          },
          "description": "List of user roles with access to the settings and editor.",
          "descriptionFilter": "This filter allows you to enable the editor for specific user roles.",
          "help": "Comma separated list of user roles. Example: administrator,editor",
          "example": [
            "administrator",
            "editor"
          ]
        }
      }
    },
    "assets": {
      "type": "object",
      "description": "Settings related to asset management.",
      "properties": {
        "enqueue": {
          "type": "boolean",
          "default": true,
          "description": "Enqueue assets in frontend and editor.",
          "descriptionFilter": "This filter allows you to enable/disable the enqueueing of assets in frontend and editor.",
          "example": false
        },
        "reset": {
          "type": "object",
          "default": {
            "enabled": false,
            "fullWidth": []
          },
          "description": "Control removal of WordPress core block styles and editor reset parity.",
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": false,
              "description": "Remove WordPress core block styles on the frontend and in the editor, and restore common utility-class display and position values in the editor canvas.",
              "descriptionFilter": "This filter allows you to enable/disable the removal of WordPress core block styles and the editor utility layout reset.",
              "example": true
            },
            "fullWidth": {
              "type": "array",
              "default": [],
              "items": {
                "type": "string"
              },
              "description": "Post types where the editor uses full-width layout by removing classic editor constraints.",
              "descriptionFilter": "This filter allows you to control which post types use full-width editing.",
              "example": [
                "page"
              ]
            }
          }
        },
        "minify": {
          "type": "object",
          "description": "Settings related to asset minification.",
          "properties": {
            "css": {
              "type": "boolean",
              "default": false,
              "description": "Minify CSS.",
              "descriptionFilter": "This filter allows you to enable/disable the minification of CSS.",
              "example": true
            },
            "js": {
              "type": "boolean",
              "default": false,
              "description": "Minify JS.",
              "descriptionFilter": "This filter allows you to enable/disable the minification of JS.",
              "example": true
            }
          }
        },
        "process": {
          "type": "object",
          "description": "Settings related to asset processing.",
          "properties": {
            "scss": {
              "type": "boolean",
              "default": false,
              "description": "Process SCSS in .css files.",
              "descriptionFilter": "This filter allows you to enable/disable the processing of SCSS in .css files.",
              "example": true
            },
            "scssFiles": {
              "type": "boolean",
              "default": true,
              "description": "Process .scss files to CSS.",
              "descriptionFilter": "This filter allows you to enable/disable the processing of .scss files to CSS.",
              "example": true
            }
          }
        }
      },
      "additionalProperties": true
    },
    "cache": {
      "type": "object",
      "description": "Settings related to Blockstudio runtime caching.",
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": true,
          "description": "Enable Blockstudio file-backed runtime, block registration, and editor asset caches.",
          "descriptionFilter": "This filter allows you to enable/disable all Blockstudio file-backed runtime and editor asset caches.",
          "example": false
        },
        "path": {
          "type": "string",
          "default": "blockstudio/cache",
          "description": "Cache directory. Relative paths resolve from WP_CONTENT_DIR; absolute paths are used as provided.",
          "descriptionFilter": "This filter allows you to change the Blockstudio file-backed cache directory.",
          "example": "cache/blockstudio"
        }
      },
      "additionalProperties": true
    },
    "content": {
      "type": "object",
      "description": "Settings for Content Sync, the WP-CLI driven projection of allowlisted WordPress content to portable files.",
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": false,
          "description": "Enable Content Sync configuration for this theme.",
          "descriptionFilter": "This filter allows you to enable/disable Content Sync.",
          "example": true
        },
        "id": {
          "type": "string",
          "default": "default",
          "description": "Content-set identity stored on synced entities. Prune and ownership checks are scoped to this value.",
          "descriptionFilter": "This filter allows you to set the Content Sync ownership namespace.",
          "example": "docs"
        },
        "path": {
          "type": "string",
          "default": "content",
          "description": "Theme-relative directory where Content Sync reads and writes files.",
          "descriptionFilter": "This filter allows you to set the Content Sync file directory.",
          "example": "content"
        },
        "includePageSyncManaged": {
          "type": "boolean",
          "default": false,
          "description": "Include Page Sync managed posts. Their post_content remains owned by Page Sync.",
          "descriptionFilter": "This filter allows you to include or exclude Page Sync managed posts.",
          "example": false
        },
        "authors": {
          "type": "string",
          "enum": [
            "ignore",
            "login"
          ],
          "default": "ignore",
          "description": "Author portability mode. Use ignore to omit authors or login to store author logins and resolve existing users on push.",
          "descriptionFilter": "This filter allows you to configure Content Sync author handling.",
          "example": "ignore"
        },
        "postTypes": {
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          },
          "description": "Allowlisted post types to sync. Empty means no post types are synced.",
          "descriptionFilter": "This filter allows you to configure Content Sync post type allowlists.",
          "example": [
            "team_member"
          ]
        },
        "meta": {
          "type": "object",
          "description": "Postmeta allowlist, exclude list, and declared reference rewriting rules.",
          "properties": {
            "include": {
              "type": "array",
              "default": [],
              "items": {
                "type": "string"
              },
              "description": "Glob patterns for meta keys that may be projected to files.",
              "example": [
                "_my_*"
              ]
            },
            "exclude": {
              "type": "array",
              "default": [
                "_edit_lock",
                "_edit_last",
                "_wp_old_slug"
              ],
              "items": {
                "type": "string"
              },
              "description": "Glob patterns for meta keys that must never be projected, even if included.",
              "example": [
                "_edit_lock",
                "_edit_last",
                "_wp_old_slug"
              ]
            },
            "references": {
              "type": "object",
              "default": {},
              "description": "Declared meta references. Only these keys and paths are rewritten between local IDs and portable UIDs.",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "post",
                      "attachment",
                      "term"
                    ],
                    "description": "Referenced entity type.",
                    "example": "attachment"
                  },
                  "path": {
                    "type": "string",
                    "description": "Optional dot path inside structured meta. Use * to map every array item.",
                    "example": "image.id"
                  }
                },
                "required": [
                  "kind"
                ]
              },
              "example": {
                "_thumbnail_id": {
                  "kind": "attachment"
                },
                "_related_posts": {
                  "kind": "post",
                  "path": "*"
                },
                "_hero": {
                  "kind": "attachment",
                  "path": "image.id"
                }
              }
            }
          },
          "additionalProperties": true
        },
        "taxonomies": {
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          },
          "description": "Allowlisted registered taxonomies whose terms and post relationships are synced. Taxonomy definitions are not captured.",
          "descriptionFilter": "This filter allows you to configure Content Sync taxonomy allowlists.",
          "example": [
            "category",
            "post_tag"
          ]
        },
        "media": {
          "type": "string",
          "enum": [
            "manifest",
            "none"
          ],
          "default": "manifest",
          "description": "Attachment reference behavior. manifest records referenced attachments and validates them on push; none drops attachment references.",
          "descriptionFilter": "This filter allows you to configure Content Sync media handling.",
          "example": "manifest"
        }
      },
      "additionalProperties": true
    },
    "tailwind": {
      "type": "object",
      "description": "Settings related to Tailwind.",
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": false,
          "description": "Enable Tailwind.",
          "descriptionFilter": "This filter allows you to enable/disable Tailwind.",
          "example": true
        },
        "config": {
          "type": "string",
          "default": "",
          "description": "Tailwind CSS configuration using v4 CSS-first syntax.",
          "descriptionFilter": "This filter allows you to add a custom Tailwind CSS configuration.",
          "element": "textarea",
          "example": "@theme { --color-primary: pink; }"
        }
      },
      "additionalProperties": true
    },
    "ui": {
      "type": "object",
      "description": "Settings related to bundled UI components.",
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": false,
          "description": "Enable bundled UI components.",
          "descriptionFilter": "This filter allows you to enable/disable bundled UI components.",
          "example": true
        }
      },
      "additionalProperties": true
    },
    "editor": {
      "type": "object",
      "description": "Settings related to the editor.",
      "properties": {
        "formatOnSave": {
          "type": "boolean",
          "default": false,
          "description": "Format code upon saving.",
          "descriptionFilter": "This filter allows you to enable/disable the formatting of code upon saving.",
          "example": true
        },
        "assets": {
          "id": "editorAssets",
          "type": "array",
          "default": [],
          "description": "Additional asset IDs to be enqueued.",
          "descriptionFilter": "This filter allows you to enqueue additional assets in the editor.",
          "example": [
            "my-stylesheet",
            "another-stylesheet"
          ]
        },
        "markup": {
          "type": [
            "string",
            "boolean"
          ],
          "element": "textarea",
          "default": "",
          "description": "Additional markup to be added to the end of the editor.",
          "descriptionFilter": "This filter allows you to add additional markup to the end of the editor.",
          "example": "<style>body { background: black; }</style>"
        }
      },
      "additionalProperties": true
    },
    "blockEditor": {
      "type": "object",
      "description": "Settings related to Gutenberg.",
      "properties": {
        "disableLoading": {
          "type": "boolean",
          "default": false,
          "description": "Disable loading of blocks inside the Block Editor.",
          "descriptionFilter": "This filter allows you to disable the loading of blocks inside the Block Editor.",
          "example": true
        },
        "enhance": {
          "type": "boolean",
          "default": false,
          "description": "Enable Blockstudio editor affordances such as cleaner focus styles and hover/selection outlines.",
          "descriptionFilter": "This filter allows you to enable Blockstudio editor affordances such as cleaner focus styles and hover/selection outlines.",
          "example": true
        },
        "cssClasses": {
          "id": "blockEditorCssClasses",
          "type": "array",
          "default": [],
          "description": "Stylesheets whose CSS classes should be available for choice in the class field.",
          "descriptionFilter": "This filter allows you to add stylesheets whose classes should be available for choice in the class field.",
          "example": [
            "my-stylesheet",
            "another-stylesheet"
          ]
        },
        "cssVariables": {
          "id": "blockEditorCssVariables",
          "type": "array",
          "default": [],
          "description": "Stylesheets whose CSS variables should be available for autocompletion in the code field.",
          "descriptionFilter": "This filter allows you to add stylesheets whose CSS variables should be available for autocompletion in the code field.",
          "example": [
            "my-stylesheet",
            "another-stylesheet"
          ]
        },
        "blocks": {
          "type": "object",
          "description": "Global block editor policies that map to WordPress PHP block editor hooks.",
          "properties": {
            "allow": {
              "type": "array",
              "default": [],
              "items": {
                "type": "string"
              },
              "description": "Block names that are allowed in the inserter. Supports wildcards such as core/*.",
              "descriptionFilter": "This filter allows you to control the block names that are allowed in the inserter.",
              "example": [
                "core/*",
                "acf/*",
                "my-theme/*"
              ]
            },
            "deny": {
              "type": "array",
              "default": [],
              "items": {
                "type": "string"
              },
              "description": "Block names that are removed from the inserter. Supports wildcards such as core/embed.",
              "descriptionFilter": "This filter allows you to remove block names from the inserter.",
              "example": [
                "core/embed",
                "core/freeform"
              ]
            },
            "directory": {
              "type": "boolean",
              "default": true,
              "description": "Enable the WordPress block directory assets in the editor.",
              "descriptionFilter": "This filter allows you to enable or disable the WordPress block directory assets in the editor.",
              "example": false
            },
            "categories": {
              "type": "object",
              "description": "Filter, rename, and order block inserter categories by slug.",
              "properties": {
                "allow": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Block category slugs that should remain available. Empty means all categories are allowed.",
                  "descriptionFilter": "This filter allows you to control which block category slugs remain available.",
                  "example": [
                    "text",
                    "media",
                    "design"
                  ]
                },
                "deny": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Block category slugs that should be removed from the inserter.",
                  "descriptionFilter": "This filter allows you to remove block category slugs from the inserter.",
                  "example": [
                    "embed"
                  ]
                },
                "rename": {
                  "type": "object",
                  "default": {},
                  "description": "Map block category slugs to replacement labels.",
                  "descriptionFilter": "This filter allows you to rename block category labels by slug.",
                  "additionalProperties": {
                    "type": "string"
                  },
                  "example": {
                    "text": "Writing",
                    "design": "Layout"
                  }
                },
                "order": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Block category slugs that should be moved to the beginning of the inserter in the provided order.",
                  "descriptionFilter": "This filter allows you to order block category slugs in the inserter.",
                  "example": [
                    "my-theme",
                    "text",
                    "media"
                  ]
                }
              },
              "additionalProperties": true
            },
            "styles": {
              "type": "object",
              "description": "Policies for PHP-registered block styles.",
              "properties": {
                "deny": {
                  "type": "object",
                  "default": {},
                  "description": "Map block names to PHP-registered block style names that should be unregistered. Use * as a style name to remove all registered styles for a block.",
                  "descriptionFilter": "This filter allows you to unregister PHP-registered block styles by block name.",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "example": {
                    "my-theme/card": [
                      "outline"
                    ],
                    "my-theme/media": [
                      "framed"
                    ]
                  }
                }
              },
              "additionalProperties": true
            },
            "legacyWidgets": {
              "type": "object",
              "description": "Policies for the legacy widget block.",
              "properties": {
                "hide": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Legacy widget IDs that should be hidden from the legacy widget block.",
                  "descriptionFilter": "This filter allows you to hide additional legacy widgets from the legacy widget block.",
                  "example": [
                    "archives",
                    "calendar"
                  ]
                }
              },
              "additionalProperties": true
            }
          },
          "additionalProperties": true
        },
        "patterns": {
          "type": "object",
          "description": "Global pattern inserter policies that map to WordPress PHP pattern hooks.",
          "properties": {
            "core": {
              "type": "boolean",
              "default": true,
              "description": "Enable WordPress core block patterns.",
              "descriptionFilter": "This filter allows you to enable or disable WordPress core block patterns.",
              "example": false
            },
            "remote": {
              "type": "boolean",
              "default": true,
              "description": "Enable remote patterns from the WordPress pattern directory.",
              "descriptionFilter": "This filter allows you to enable or disable remote patterns from the WordPress pattern directory.",
              "example": false
            },
            "theme": {
              "type": "boolean",
              "default": true,
              "description": "Enable theme-provided block patterns.",
              "descriptionFilter": "This filter allows you to enable or disable theme-provided block patterns.",
              "example": false
            },
            "blockstudio": {
              "type": "boolean",
              "default": true,
              "description": "Enable Blockstudio file-based patterns.",
              "descriptionFilter": "This filter allows you to enable or disable Blockstudio file-based patterns.",
              "example": false
            },
            "categories": {
              "type": "object",
              "description": "Filter, rename, and order block pattern categories by slug.",
              "properties": {
                "allow": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Pattern category slugs that should remain available. Empty means all categories are allowed.",
                  "descriptionFilter": "This filter allows you to control which pattern category slugs remain available.",
                  "example": [
                    "featured",
                    "buttons",
                    "columns"
                  ]
                },
                "deny": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Pattern category slugs that should be removed from the pattern inserter.",
                  "descriptionFilter": "This filter allows you to remove pattern category slugs from the pattern inserter.",
                  "example": [
                    "gallery"
                  ]
                },
                "rename": {
                  "type": "object",
                  "default": {},
                  "description": "Map pattern category slugs to replacement labels.",
                  "descriptionFilter": "This filter allows you to rename pattern category labels by slug.",
                  "additionalProperties": {
                    "type": "string"
                  },
                  "example": {
                    "featured": "Featured Layouts"
                  }
                },
                "order": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Pattern category slugs that should be moved to the beginning of the inserter in the provided order.",
                  "descriptionFilter": "This filter allows you to order pattern category slugs in the inserter.",
                  "example": [
                    "featured",
                    "buttons"
                  ]
                }
              },
              "additionalProperties": true
            }
          },
          "additionalProperties": true
        },
        "media": {
          "type": "object",
          "description": "Global media policies for the block editor.",
          "properties": {
            "openverse": {
              "type": "boolean",
              "default": true,
              "description": "Enable the Openverse media category in the block editor media inserter.",
              "descriptionFilter": "This filter allows you to enable or disable the Openverse media category in the block editor media inserter.",
              "example": false
            },
            "imageSizes": {
              "type": "object",
              "description": "Filter image size choices shown in editor media controls.",
              "properties": {
                "allow": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Image size names that should remain available. Empty means all image sizes are allowed.",
                  "descriptionFilter": "This filter allows you to control which image size names remain available in editor media controls.",
                  "example": [
                    "thumbnail",
                    "large"
                  ]
                },
                "deny": {
                  "type": "array",
                  "default": [],
                  "items": {
                    "type": "string"
                  },
                  "description": "Image size names that should be removed from editor media controls.",
                  "descriptionFilter": "This filter allows you to remove image size names from editor media controls.",
                  "example": [
                    "medium_large"
                  ]
                }
              },
              "additionalProperties": true
            }
          },
          "additionalProperties": true
        }
      },
      "additionalProperties": true
    },
    "ai": {
      "id": "aiLlmMd",
      "type": "object",
      "description": "Settings related to AI-powered context generation.",
      "properties": {
        "enableContextGeneration": {
          "type": "boolean",
          "default": false,
          "description": "Enables the automatic creation of a comprehensive context file for use with large language model (LLM) tools (e.g., Cursor). This file compiles current installation data: all available block definitions and paths, Blockstudio-specific settings, relevant block schemas, and combined Blockstudio documentation, providing a ready-to-use resource for prompt engineering and AI code development.",
          "descriptionFilter": "This filter allows you to enable or disable context file generation for LLM tool integration. When enabled, the context file assembles up-to-date block data, Blockstudio settings of the current install, all relevant schemas, and Blockstudio documentation into a single source for use with AI development tools.",
          "example": true
        }
      },
      "additionalProperties": true
    },
    "blockTags": {
      "type": "object",
      "description": "Settings for bs: tag rendering. Controls page-level replacement of <bs:block-name> tags with rendered block output. Template-level rendering is always active.",
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": false,
          "description": "Enable page-level bs: tag rendering in post content and widget areas.",
          "descriptionFilter": "This filter allows you to enable/disable page-level block tag rendering.",
          "example": true
        },
        "allow": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "default": [],
          "description": "Allowlist of block name patterns. Supports wildcards via fnmatch(). When set, only matching blocks render via tags.",
          "example": [
            "mytheme/*",
            "bsui/*"
          ]
        },
        "deny": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "default": [],
          "description": "Denylist of block name patterns. Supports wildcards via fnmatch(). Matching blocks are excluded from tag rendering. Takes precedence over allow.",
          "example": [
            "mytheme/internal-*"
          ]
        },
        "prefixes": {
          "type": "object",
          "default": {},
          "description": "Prefix to namespace shorthands for block tags. Each key is a lowercase prefix without dashes, and each value is a namespace string or ordered namespace array.",
          "descriptionFilter": "This filter allows you to register prefix to namespace shorthands for block tags.",
          "example": {
            "dv": [
              "divine-homepage",
              "bsui"
            ]
          }
        }
      },
      "additionalProperties": true
    },
    "dev": {
      "type": "object",
      "description": "Settings related to developer tools.",
      "properties": {
        "grab": {
          "type": "object",
          "description": "Settings related to the element grabber.",
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": false,
              "description": "Enable the element grabber.",
              "descriptionFilter": "This filter allows you to enable/disable the element grabber.",
              "example": false
            }
          }
        },
        "perf": {
          "type": "boolean",
          "default": false,
          "description": "Enable the performance profiler. Shows Server-Timing headers and a debug panel on every page load.",
          "descriptionFilter": "This filter allows you to enable/disable the performance profiler.",
          "example": false
        },
        "canvas": {
          "type": "object",
          "description": "Settings related to the canvas.",
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": false,
              "description": "Enable the canvas.",
              "descriptionFilter": "This filter allows you to enable/disable the canvas.",
              "example": false
            },
            "adminBar": {
              "type": "boolean",
              "default": true,
              "description": "Show the WordPress admin bar when viewing the canvas.",
              "descriptionFilter": "This filter allows you to show/hide the WordPress admin bar on the canvas.",
              "example": true
            }
          }
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true
}
