🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

FastMode CMS - Host, Deploy, Manage Websites for Free

by @arihgoldstein

Build, deploy, and host websites for free with full CMS. Create a live website from scratch, deploy it to the cloud with free hosting, free SSL, and custom d...

Versionv1.5.3
Downloads1,403
Stars⭐ 2
TERMINAL
clawhub install fastmode

πŸ“– About This Skill


name: fastmode description: Create, deploy, and host a website for free. Build a complete website from scratch and deploy it to the cloud with free hosting, free SSL, and custom domains β€” all from the terminal. Full CMS included: manage blog posts, team members, pages, products, portfolios, services, testimonials, FAQs, or any structured content. Add and edit CMS content, sync database schemas, validate HTML templates, invite clients to a white-label portal, and push live deployments. Convert any existing HTML site into a CMS-powered site. One-time browser login for OAuth, then every operation runs entirely in the terminal β€” designed for AI agents to go from zero to a publicly accessible website in minutes. metadata: {"openclaw":{"emoji":"⚑","homepage":"https://fastmode.ai","requires":{"bins":["fastmode"]},"install":[{"id":"npm","kind":"npm","package":"fastmode-cli","bins":["fastmode"]}]}} user-invokable: true

FastMode CLI β€” Complete Agent Reference

FastMode lets you create a live website, deploy it to the cloud, and manage all its content β€” entirely from the command line. One-time browser login for OAuth authentication, then every operation runs in the terminal. No local servers, no manual dashboards.

  • Free cloud hosting β€” every site gets a live URL at yoursite.fastmode.ai
  • Free SSL β€” HTTPS included automatically
  • Custom domains β€” connect any domain (e.g. www.example.com)
  • Full CMS β€” any content structure (blog, team, products, portfolios, anything)
  • Agent-native β€” every operation works via CLI, zero human intervention needed

  • Table of Contents

    1. End-to-End Workflow 2. CRITICAL: Before You Build Anything 3. Website Analysis 4. Command Reference 5. Project Resolution 6. Schema & Field Types 7. Content Items 8. Client Portal Management 9. Package Structure 10. Manifest Format 11. Template Syntax (includes SEO rules, image handling, forms, inline editing) 12. Deployment & Build Status 13. Validation 14. Common Mistakes & How to Fix Them 15. Pre-Deployment Checklist 15. Error Handling & Exit Codes


    End-to-End Workflow

    This is the complete sequence to go from nothing to a live website.

    # 1. Authenticate (one-time β€” credentials persist at ~/.fastmode/credentials.json)
    fastmode login

    2. Create a project (gets a free hosted URL instantly)

    fastmode projects create "Acme Corp" fastmode use "Acme Corp"

    3. Define content structure (write schema.json, then sync it)

    fastmode schema sync -f schema.json

    4. Add content

    fastmode items create posts -n "Welcome" -d '{"title": "Welcome to Acme", "body": "

    We build great things.

    "}' fastmode items create team -n "Jane Doe" -d '{"role": "Founder", "bio": "

    Visionary leader.

    "}'

    5. Build HTML templates with {{tokens}}, package into a zip, validate, deploy

    fastmode validate package site.zip fastmode deploy site.zip

    Deploy waits for build to finish and reports success or failure with error details

    6. If the build failed, check what went wrong

    fastmode status

    Fix the issue, then re-deploy


    CRITICAL: Before You Build Anything

    STOP. Before writing ANY HTML, templates, or manifest.json, complete these steps.

    Step 1: Check for Existing Projects

    fastmode projects
    

    This lists all the user's existing FastMode projects.

    Step 2: Decide β€” Existing or New Project

    If projects exist: Ask the user: "Is this website for one of your existing projects, or should I create a new one?" Let the user choose.

    If NO projects exist: This is a new user β€” ask: "What would you like to name your new project?"

    Step 3a: For EXISTING Projects

    1. User selects the project from the list 2. Run fastmode use "Project Name" to set it as default 3. Run fastmode schema show to get the current collections and fields 4. Use this schema to build templates with the correct field names

    Step 3b: For NEW Projects

    1. Ask for the project name if you don't have it 2. Run fastmode projects create "Project Name" 3. Run fastmode use "Project Name" 4. You'll create the schema later with fastmode schema sync 5. Optionally generate sample content: fastmode generate-samples

    Checkpoint β€” Confirm Before Continuing

    | Requirement | How to Get It | |-------------|---------------| | Project selected/created | fastmode projects / fastmode projects create | | Default set | fastmode use "Project Name" | | Schema known (existing) | fastmode schema show |

    If you don't have a project set, DO NOT PROCEED. Go back to Step 1.

    WHY THIS MATTERS:

  • For existing projects: The schema determines which fields to use in templates β€” get it wrong and the build fails
  • For new projects: You need the project before you can deploy
  • Always: The user must confirm which project to use β€” never assume

  • Website Analysis (Do This Before Writing Code)

    Before writing any HTML or templates, analyze the site:

    1. Map ALL URLs β€” document every page path (/, /about, /blog, /blog/post-slug, etc.) 2. Categorize each page β€” Static (fixed content), List (shows multiple items), or Detail (single item from a collection) 3. Identify collections β€” repeating content that should be CMS-managed (blog posts, team members, products, testimonials, etc.) 4. Document assets β€” all CSS, JS, image, and font file locations 5. PRESERVE original URLs β€” if the site uses /resources for articles, keep /resources. Do NOT change it to /blog. Use the manifest's path configuration.


    Command Reference

    Authentication

    fastmode login                          # Open browser for OAuth device flow
    fastmode logout                         # Delete ~/.fastmode/credentials.json
    fastmode whoami                         # Show current user email and name
    

  • login uses OAuth 2.0 device authorization flow: opens a browser window where the user approves access on fastmode.ai, then credentials are saved automatically. The browser is only needed for this one-time login step.
  • OAuth scopes: The token grants access to the user's FastMode projects only (project management, schema editing, content CRUD, deployments). No third-party service access is requested.
  • Credentials persist at ~/.fastmode/credentials.json with restricted file permissions (0o600 β€” owner read/write only). Treat this file as a sensitive secret.
  • Tokens auto-refresh. If a token expires, the next command will refresh it silently using the stored refresh token.
  • If credentials are missing or invalid, most commands will trigger the login flow automatically.
  • logout deletes ~/.fastmode/credentials.json and revokes the stored tokens.
  • Projects

    fastmode projects                       # List all projects (default action)
    fastmode projects list                  # Same as above
    fastmode projects create "Name"         # Create a new project
    fastmode projects create "Name" --subdomain custom-sub  # Custom subdomain
    fastmode projects create "Name" --force                  # Skip similar-name check
    fastmode use                   # Set default project for all commands
    

  • projects create checks for existing projects with similar names. Use --force to skip.
  • Subdomain auto-generated from name if not provided (lowercase, hyphens, max 30 chars).
  • use stores the default in ~/.fastmode/config.json. Does NOT validate the project exists.
  • Schema

    fastmode schema show                    # Show all collections and fields
    fastmode schema show -p "Project Name"  # Specify project
    fastmode schema sync -f schema.json     # Create collections and fields from JSON file
    fastmode schema field-types             # List all available field types (no auth needed)
    

  • schema show requires authentication and a project.
  • schema sync reads a local JSON file and creates/updates the schema. Skips duplicates. Two-phase: creates collections first, then fields (handles relation dependencies).
  • schema field-types works without authentication.
  • Content Items

    fastmode items list                           # List all items
    fastmode items list posts --limit 10 --sort publishedAt --order desc
    fastmode items get                      # Get single item
    fastmode items create  -n "Name" -d '{"field": "value"}'
    fastmode items create posts -n "Title" -f data.json       # Data from file
    fastmode items create posts -n "Draft Post" -d '{}' --draft
    fastmode items update   -d '{"field": "new value"}'
    fastmode items update posts my-post -n "New Title"
    fastmode items update posts my-post --publish             # Publish a draft
    fastmode items update posts my-post --unpublish           # Revert to draft
    fastmode items delete   --confirm       # REQUIRES --confirm
    fastmode items relations                      # Show linkable items for relation fields
    fastmode items relations posts --field author             # Options for specific field
    

    See the Content Items section below for detailed rules on data formats, relation fields, and drafts.

    Client Portal Management

    fastmode clients list                              # List portal clients with access
    fastmode clients invite client@example.com         # Invite with default permissions
    fastmode clients invite client@example.com -n "Jane" --permissions cms.read,cms.write
    fastmode clients invitations                       # List pending invitations
    fastmode clients update-permissions  --permissions cms.read,editor
    fastmode clients revoke  --confirm       # REQUIRES --confirm
    fastmode clients cancel-invite  --confirm  # REQUIRES --confirm
    

    See the Client Portal Management section below for details on permissions, invite flow, and examples.

    Deployment & Build Status

    fastmode deploy site.zip                # Deploy and wait for build to finish
    fastmode deploy site.zip --force        # Skip GitHub sync check
    fastmode deploy site.zip --no-wait      # Upload only, don't wait for build
    fastmode deploy site.zip --timeout 300000  # Custom timeout in ms (default: 120000)
    fastmode status                         # Check current build/deploy status
    fastmode deploys                        # List deployment history
    fastmode deploys --limit 5             # Limit number of results
    

    See Deployment & Build Status below for the full deploy lifecycle.

    Validation

    fastmode validate manifest manifest.json
    fastmode validate template index.html -t custom_index
    fastmode validate template post.html -t custom_detail -c posts
    fastmode validate template post.html -t custom_detail -c posts -p "My Project"
    fastmode validate template about.html -t static_page
    fastmode validate package site.zip
    

  • Template types: custom_index (collection listing), custom_detail (single item), static_page (fixed page).
  • -c specifies the collection slug (required for custom_index and custom_detail).
  • -p validates tokens against the actual project schema (reports missing fields).
  • All validation commands exit with code 1 on errors β€” safe for CI/CD pipelines.
  • Documentation & Examples

    fastmode examples                 # Code examples for a specific pattern
    fastmode guide                          # Full website conversion guide
    fastmode guide templates                # Template syntax guide
    fastmode guide common_mistakes          # Common pitfalls to avoid
    fastmode generate-samples               # Generate placeholder content for empty collections
    fastmode generate-samples -c posts team # Specific collections only
    

    Available example types: manifest_basic, manifest_custom_paths, blog_index_template, blog_post_template, team_template, downloads_template, form_handling, asset_paths, data_edit_keys, each_loop, conditional_if, nested_fields, featured_posts, parent_context, equality_comparison, comparison_helpers, youtube_embed, nested_collection_loop, loop_variables, common_mistakes.

    Available guide sections: full, first_steps, analysis, structure, seo, manifest, templates, tokens, forms, assets, checklist, common_mistakes.


    Project Resolution

    Every project-scoped command (schema, items, deploy, status, etc.) needs a project. Resolution order:

    1. -p / --project flag β€” explicit on the command: -p "My Project" or -p abc123-uuid 2. FASTMODE_PROJECT environment variable β€” set in shell: export FASTMODE_PROJECT="My Project" 3. Default project β€” saved by fastmode use "My Project" in ~/.fastmode/config.json

    If none is set, the command prints an error and exits with code 1:

    Error: No project specified.
    Use -p , set FASTMODE_PROJECT env var, or run: fastmode use 
    

    Project identifiers can be:

  • UUID β€” used directly (e.g. 550e8400-e29b-41d4-a716-446655440000)
  • Project name β€” resolved via API (exact match first, then partial match, case-insensitive)

  • Schema & Field Types

    Creating a Schema

    Write a schema.json file and sync it:

    fastmode schema sync -f schema.json
    

    schema.json Format

    {
      "collections": [
        {
          "slug": "posts",
          "name": "Blog Posts",
          "nameSingular": "Blog Post",
          "fields": [
            { "slug": "title", "name": "Title", "type": "text", "isRequired": true },
            { "slug": "excerpt", "name": "Excerpt", "type": "textarea" },
            { "slug": "body", "name": "Body", "type": "richText" },
            { "slug": "featured-image", "name": "Featured Image", "type": "image" },
            { "slug": "category", "name": "Category", "type": "select", "options": "News, Tutorial, Update" },
            { "slug": "tags", "name": "Tags", "type": "multiSelect", "options": "JavaScript, Python, DevOps, AI" },
            { "slug": "featured", "name": "Featured", "type": "boolean" },
            { "slug": "author", "name": "Author", "type": "relation", "referenceCollection": "team" }
          ]
        },
        {
          "slug": "team",
          "name": "Team Members",
          "nameSingular": "Team Member",
          "fields": [
            { "slug": "role", "name": "Role", "type": "text" },
            { "slug": "bio", "name": "Bio", "type": "richText" },
            { "slug": "photo", "name": "Photo", "type": "image" },
            { "slug": "email", "name": "Email", "type": "email" }
          ]
        }
      ]
    }
    

    To add fields to existing collections, use fieldsToAdd:

    {
      "fieldsToAdd": [
        {
          "collectionSlug": "posts",
          "fields": [
            { "slug": "reading-time", "name": "Reading Time", "type": "number" }
          ]
        }
      ]
    }
    

    You can combine collections and fieldsToAdd in the same file. Duplicate collections and fields are automatically skipped.

    Available Field Types

    | Type | Description | Template Usage | Notes | |------|-------------|----------------|-------| | text | Single-line text | {{field}} | Titles, names, short strings | | textarea | Multi-line plain text | {{field}} | Descriptions, excerpts | | richText | Formatted HTML content | {{{field}}} | MUST use triple braces | | number | Numeric value | {{field}} | Prices, counts, order | | boolean | True/false toggle | {{#if field}} | Toggles, flags | | date | Date only | {{field}} | Birth dates, event dates | | datetime | Date and time | {{field}} | Timestamps | | image | Image file/URL | {{field}} | Renders as URL | | file | Downloadable file (max 10MB) | {{field}} | Link as | | url | Web link | {{field}} | External URLs | | videoEmbed | YouTube/Vimeo/Wistia/Loom | {{field}} | Embed URL | | email | Email with validation | {{field}} | Validated email addresses | | select | Single dropdown | {{field}} | Requires "options": "A, B, C" | | multiSelect | Multiple selections | {{field}} | Requires "options": "A, B, C" | | relation | Link to another collection | {{field.name}} | Requires "referenceCollection": "slug" |

    Relation Fields β€” CRITICAL

    Relation fields link items between collections (e.g. a post has an author from the team collection). When creating or updating items with relation fields:

  • You MUST use the item's UUID, not its name or slug
  • Use fastmode items relations to get the available IDs
  • Example: fastmode items relations posts --field author shows team member IDs
  • # First, find the author's item ID
    fastmode items relations posts --field author
    

    Output shows: ID: 550e8400-..., Name: Jane Doe, Slug: jane-doe

    Then use that ID when creating a post

    fastmode items create posts -n "My Post" -d '{"title": "My Post", "author": "550e8400-e29b-41d4-a716-446655440000"}'

    WRONG: "author": "Jane Doe" β€” this will NOT work. CORRECT: "author": "550e8400-e29b-41d4-a716-446655440000" β€” use the UUID.


    Content Items

    Creating Items

    fastmode items create  -n "Item Name" -d '{"field": "value"}'
    

    | Flag | Description | |------|-------------| | -n, --name | Required. Item name/title. | | -s, --slug | URL slug. Auto-generated from name if omitted. | | -d, --data | Field data as JSON string. | | -f, --file | Read field data from a JSON file (takes precedence over -d). | | -p, --project | Project ID or name. | | --draft | Create as unpublished draft. |

    Data rules:

  • -d value must be valid JSON. Keys are field slugs.
  • -f reads from a JSON file. If both -f and -d are given, -f wins.
  • If neither -d nor -f is given, the item is created with just the name (no field data).
  • Rich text fields accept raw HTML: "body": "

    Title

    Content here.

    "
  • Relation fields require UUIDs (see above).
  • Without --draft, items are published immediately (publishedAt set to now).
  • Updating Items

    fastmode items update   -d '{"field": "new value"}'
    

    | Flag | Description | |------|-------------| | -n, --name | New name/title. | | -d, --data | Updated fields as JSON. Only provided fields change β€” others are preserved. | | -f, --file | Read updated data from a JSON file. | | -p, --project | Project ID or name. | | --publish | Set publishedAt to now (make item live). | | --unpublish | Set publishedAt to null (revert to draft). |

    Update is a partial merge. Only the fields you provide in -d are changed. All other fields remain as they are.

    Deleting Items

    fastmode items delete   --confirm
    

    The --confirm flag is required. Without it, the command refuses to run and exits with code 1. This is a safety measure β€” deletion is permanent and cannot be undone.

    Always ask the user for confirmation before deleting.

    Draft / Publish Mechanics

    | Action | Command | |--------|---------| | Create as published (default) | fastmode items create posts -n "Title" -d '{...}' | | Create as draft | fastmode items create posts -n "Title" -d '{...}' --draft | | Publish a draft | fastmode items update posts my-slug --publish | | Unpublish (revert to draft) | fastmode items update posts my-slug --unpublish |

  • Draft items have publishedAt: null and are not visible on the live site.
  • Published items have a publishedAt timestamp and appear on the live site.
  • Without --draft, new items are published immediately.

  • Client Portal Management

    The client portal lets you give external clients (your customers, collaborators) limited access to manage content on your FastMode site. Clients get their own login, separate from your admin account, with configurable permissions.

    How It Works

    1. You invite a client by email β€” they receive a unique invite link 2. Client clicks the link β€” creates a password and gets portal access 3. Client manages content β€” based on the permissions you assigned 4. You control access β€” update permissions or revoke access at any time

    The portal is auto-enabled on the project when you send the first invitation. No manual setup needed.

    Available Permissions

    | Permission | Description | |------------|-------------| | cms.read | View collection items | | cms.write | Create, edit, archive, and delete items | | editor | Access the visual editor | | forms.read | View form submissions | | dns | Manage DNS settings | | api | Access API and integrations | | notifications | Manage notification rules | | billing | View plans and manage billing |

    Default permissions (used when none specified): cms.read, cms.write, editor, forms.read

    Inviting Clients

    # Invite with default permissions
    fastmode clients invite client@example.com

    Invite with a name

    fastmode clients invite client@example.com -n "Jane Smith"

    Invite with specific permissions

    fastmode clients invite client@example.com -n "Jane Smith" --permissions cms.read,forms.read

    Invite with all permissions

    fastmode clients invite client@example.com --permissions cms.read,cms.write,editor,forms.read,dns,api,notifications,billing

    The command returns an invite URL β€” share this with the client. The link expires in 7 days.

    Important:

  • Each email can only be invited once per project
  • If a client already has access, the invite will fail
  • If a pending invitation already exists for the email, the invite will fail
  • Listing Clients and Invitations

    # See who has portal access
    fastmode clients list

    See pending (unaccepted) invitations

    fastmode clients invitations

    clients list shows the access ID for each client β€” you need this ID to update permissions or revoke access.

    Updating Permissions

    # First, get the access ID from the list
    fastmode clients list

    Update permissions (replaces ALL existing permissions)

    fastmode clients update-permissions --permissions cms.read,cms.write,editor

    Permissions are replaced entirely β€” if a client had cms.read,cms.write,editor,forms.read and you set --permissions cms.read, they will ONLY have cms.read.

    Revoking Access

    # Revoke a client's portal access (requires --confirm)
    fastmode clients revoke  --confirm
    

    The --confirm flag is required. Without it, the command refuses to run.

    Always ask the user for confirmation before revoking access.

    Revoking access is a soft delete β€” the client's account still exists but they cannot access this project's portal. Their active sessions are terminated immediately.

    Canceling Invitations

    # Cancel a pending invitation (requires --confirm)
    fastmode clients cancel-invite  --confirm
    

    The invitation link will no longer work. Use fastmode clients invitations to get the invitation ID.

    Typical Workflow

    # 1. Invite your client
    fastmode clients invite designer@agency.com -n "Design Agency" --permissions cms.read,cms.write,editor

    2. Share the invite URL from the output with the client

    3. Later, check who has access

    fastmode clients list

    4. Restrict a client to read-only

    fastmode clients update-permissions abc12345 --permissions cms.read

    5. Remove a client who no longer needs access

    fastmode clients revoke abc12345 --confirm


    Package Structure

    The deployment package is a .zip file with this exact structure:

    site.zip
    β”œβ”€β”€ manifest.json              # REQUIRED β€” defines pages and CMS templates
    β”œβ”€β”€ pages/                     # Static HTML pages
    β”‚   β”œβ”€β”€ index.html             # Homepage (REQUIRED β€” must have path "/")
    β”‚   β”œβ”€β”€ about.html
    β”‚   └── contact.html
    β”œβ”€β”€ templates/                 # CMS-powered templates (if using collections)
    β”‚   β”œβ”€β”€ posts_index.html       # Blog listing page
    β”‚   β”œβ”€β”€ posts_detail.html      # Single blog post page
    β”‚   └── team_index.html        # Team listing page
    └── public/                    # ALL static assets (CSS, JS, images, fonts)
        β”œβ”€β”€ css/
        β”‚   └── style.css
        β”œβ”€β”€ js/
        β”‚   └── main.js
        └── images/
            β”œβ”€β”€ logo.png
            └── favicon.ico
    

    Strict Rules

    1. manifest.json MUST be at the root of the zip. 2. Static pages go in pages/. One HTML file per page. 3. CMS templates go in templates/. Convention: {collection}_index.html and {collection}_detail.html. 4. ALL static assets go in public/. CSS, JavaScript, images, fonts β€” everything. 5. Reference assets with /public/ prefix in HTML. Example: . 6. A homepage is required. One page must have "path": "/" in the manifest.

    Critical: Asset Paths

    WRONG β€” will 404:

    
    
    
    
    

    CORRECT:

    
    
    Logo
    

    This also applies inside CSS files β€” background images AND fonts:

    /* WRONG */
    background-image: url('../images/bg.jpg');
    background-image: url('images/bg.jpg');
    src: url('../fonts/custom.woff2');

    /* CORRECT */ background-image: url('/public/images/bg.jpg'); src: url('/public/fonts/custom.woff2');

    Asset path conversion table:

    | Original Path | Converted Path | |---------------|----------------| | css/style.css | /public/css/style.css | | ../css/style.css | /public/css/style.css | | ./images/logo.png | /public/images/logo.png | | /images/logo.png | /public/images/logo.png | | ../fonts/custom.woff | /public/fonts/custom.woff |

    External URLs (Google Fonts, CDNs, etc.) stay unchanged.


    Manifest Format

    The manifest.json file defines the site structure. It uses a FLAT format for CMS templates (not nested).

    Basic Example (Static Only)

    {
      "pages": [
        { "path": "/", "file": "pages/index.html", "title": "Home" },
        { "path": "/about", "file": "pages/about.html", "title": "About" },
        { "path": "/contact", "file": "pages/contact.html", "title": "Contact" }
      ]
    }
    

    With CMS Collections

    {
      "pages": [
        { "path": "/", "file": "pages/index.html", "title": "Home" },
        { "path": "/about", "file": "pages/about.html", "title": "About" }
      ],
      "cmsTemplates": {
        "postsIndex": "templates/posts_index.html",
        "postsIndexPath": "/blog",
        "postsDetail": "templates/posts_detail.html",
        "postsDetailPath": "/blog",
        "teamIndex": "templates/team_index.html",
        "teamIndexPath": "/team"
      }
    }
    

    CMS Template Keys β€” FLAT Format

    Each collection needs 2-4 keys in cmsTemplates. The format is {collectionSlug}Index, {collectionSlug}IndexPath, {collectionSlug}Detail, {collectionSlug}DetailPath.

    | Key | Required | Description | |-----|----------|-------------| | {slug}Index | Yes | Path to the collection listing template file | | {slug}IndexPath | Yes | URL path for the listing page (e.g. /blog) | | {slug}Detail | No | Path to the single item template file | | {slug}DetailPath | No | URL path prefix for item pages (e.g. /blog β†’ /blog/item-slug) |

    Example for a "services" collection:

    "cmsTemplates": {
      "servicesIndex": "templates/services_index.html",
      "servicesIndexPath": "/services",
      "servicesDetail": "templates/services_detail.html",
      "servicesDetailPath": "/services"
    }
    

    Common Manifest Mistakes β€” AI Agents Frequently Get This Wrong

    AI agents frequently use a nested object format or "collections" key that FastMode does NOT support. Read carefully.

    WRONG β€” using "collections" key (MOST COMMON AI MISTAKE):

    {
      "collections": {
        "posts": {
          "indexPath": "/blog",
          "indexFile": "collections/posts/index.html",
          "detailPath": "/blog/:slug",
          "detailFile": "collections/posts/detail.html"
        }
      }
    }
    

    WRONG β€” nested objects inside cmsTemplates:

    "cmsTemplates": {
      "posts": {
        "indexPath": "/blog",
        "detailPath": "/blog"
      }
    }
    

    WRONG β€” singular slug names:

    "postIndex": "..."   // Should be "postsIndex"
    "postDetail": "..."  // Should be "postsDetail"
    

    CORRECT β€” flat keys using cmsTemplates, matching the collection slug exactly:

    "cmsTemplates": {
      "postsIndex": "templates/posts_index.html",
      "postsIndexPath": "/blog",
      "postsDetail": "templates/posts_detail.html",
      "postsDetailPath": "/blog"
    }
    

    Key rules:

  • Use cmsTemplates, NOT collections
  • Use FLAT keys: {slug}Index, {slug}Detail, {slug}IndexPath, {slug}DetailPath
  • Do NOT nest objects inside collection names
  • Use fastmode validate manifest manifest.json to catch these errors before deploying
  • Optional: Head/Body Injection

    {
      "pages": [...],
      "cmsTemplates": {...},
      "defaultHeadHtml": "",
      "defaultBodyEndHtml": ""
    }
    


    Template Syntax

    FastMode templates use Handlebars-style tokens. There are three types of templates:

  • Static pages (pages/): Fixed HTML with optional data-edit-key attributes for inline CMS editing and optional {{#each}} loops for dynamic content.
  • Index templates (templates/): Collection listing pages. MUST contain at least one {{#each collectionSlug}} loop.
  • Detail templates (templates/): Single item pages. MUST contain CMS tokens like {{name}}, {{{body}}}, etc.
  • SEO Tags β€” Do NOT Include

    FastMode automatically manages all SEO meta tags. Including them in your HTML will cause duplicate tags (bad for SEO ranking). Remove ALL of these from your templates:

    | Tag | Why to Remove | |-----|---------------| | ... | Managed via CMS Settings | | | Managed via CMS Settings | | | Managed via CMS Settings | | | Open Graph auto-generated | | | Twitter cards auto-generated | | | Favicon managed in settings | | | Favicon managed in settings | | | Managed by FastMode | | | Managed in settings |

    Correct structure:

    
      
      
      
      
      
      
    
    

    Built-in Fields (Every Item Has These)

    | Token | Description | Example | |-------|-------------|---------| | {{name}} | Item name/title |

    {{name}}

    | | {{slug}} | URL slug |
    | | {{url}} | Full URL to detail page | Read more | | {{publishedAt}} | Publish date | | | {{createdAt}} | Creation date | | | {{updatedAt}} | Last modified date | |

    Regular Fields β€” Double Braces {{field}}

    Used for text, number, date, image, url, email, select, boolean fields:

    {{name}}

    {{excerpt}}

    {{name}} Category: {{category}} Visit

    Rich Text Fields β€” Triple Braces {{{field}}}

    CRITICAL: Rich text fields contain HTML. You MUST use triple braces {{{ }}} so the HTML renders correctly. Double braces will escape the HTML and display raw tags as text.

    
    
    {{{body}}}
    {{{bio}}}

    {{body}}

    Loops β€” {{#each collection}}

    Used in index templates and static pages to iterate over collection items.

    Basic loop:

    {{#each posts}}
      
    {{/each}}
    

    Loop modifiers:

    | Modifier | Description | Example | |----------|-------------|---------| | limit=N | Maximum items | {{#each posts limit=6}} | | sort="field" | Sort by field | {{#each posts sort="publishedAt"}} | | order="asc\|desc" | Sort direction | {{#each posts sort="name" order="asc"}} | | featured=true | Only featured items | {{#each posts featured=true limit=3}} | | where="field.slug:{{slug}}" | Filter by relation | {{#each posts where="author.slug:{{slug}}"}} |

    Combined modifiers:

    
    {{#each posts featured=true limit=3 sort="publishedAt" order="desc"}}
      
    {{name}}
    {{/each}}

    Loop Variables

    Available only inside {{#each}} blocks:

    | Variable | Description | Example | |----------|-------------|---------| | {{@index}} | Zero-based index (0, 1, 2...) | Item {{@index}} | | {{@first}} | True for the first item | {{#if @first}}hero{{/if}} | | {{@last}} | True for the last item | {{#unless @last}},{{/unless}} | | {{@length}} | Total number of items | Showing {{@length}} items |

    Do NOT use loop variables outside {{#each}} blocks β€” they will produce warnings and undefined values.

    {{#each posts}}
      {{#if @first}}
        

    {{name}}

    {{else}}

    {{name}}

    {{/if}} {{/each}}

    Conditionals β€” {{#if}}, {{#unless}}

    
    {{#if image}}
      {{name}}
    {{/if}}

    {{#if thumbnail}} {{else}}

    No image
    {{/if}}

    {{#unless posts}}

    No posts yet.

    {{/unless}}

    Equality & Comparison Helpers

    
    {{#if (eq status "published")}}
      Published
    {{/if}}

    {{#unless (eq slug ../slug)}} {{name}} {{/unless}}

    {{#if (lt @index 1)}} {{#if (gt @index 0)}} {{#if (lte price 100)}} {{#if (gte stock 5)}} {{#if (ne status "draft")}}

    Hero + grid layout pattern:

    {{#each posts}}
      {{#if (lt @index 1)}}
        

    {{name}}

    {{else}} {{#if (lt @index 4)}} {{else}}
    {{name}}
    {{/if}} {{/if}} {{/each}}

    Relation Fields β€” Dot Notation

    Access fields on related items using dot notation:

    {{#each posts}}
      

    {{name}}

    {{#if author}} By {{author.name}} {{#if author.photo}} {{author.name}} {{/if}} {{/if}}
    {{/each}}

    Available: {{relation.name}}, {{relation.slug}}, {{relation.url}}, {{relation.anyField}}.

    Parent Context β€” ../

    Inside a loop, access the parent scope (the current page's item) with ../:

    
    

    {{name}}

    Posts by {{name}}

    {{#each posts}} {{#if (eq author.name ../name)}} {{/if}} {{/each}}

    Nested Loops with @root.

    When nesting loops, use @root. to reference root-level collections:

    {{#each categories}}
      

    {{name}}

    {{#each @root.posts where="category.slug:{{slug}}"}} {{name}} {{/each}} {{/each}}

    Inline Editing β€” data-edit-key (CRITICAL for Static Pages)

    Without data-edit-key attributes, static pages have NO editable content in the CMS dashboard. Every text element that should be editable MUST have one.

    
    

    Welcome to Our Site

    We build amazing things.

    Our story began in 2020...

    About Us

    First paragraph...

    Second paragraph...

    Our Blog

    Naming convention: {page}-{section}-{element}

    Examples: home-hero-title, about-team-heading, contact-form-intro, services-cta-button

    Rules:

  • Keys must be unique across the entire site (not just the page).
  • Use lowercase with hyphens.
  • For different pages, prefix with the page name.
  • Static pages without edit keys will appear in the CMS but have nothing editable.
  • Video Embeds

    {{#if video}}
      
    {{/if}}
    

    The referrerpolicy="strict-origin-when-cross-origin" attribute is required for YouTube embeds β€” without it, videos may show Error 150/153.

    Images β€” Static vs CMS Content

    There are two types of images and they are handled differently:

    1. Static/UI images β€” logos, icons, decorative backgrounds bundled with the site:

    
    Company Logo
    
    

    2. CMS content images β€” post images, team photos, product images managed through the CMS:

    
    {{#if image}}
      {{name}}
    {{/if}}
    

    Rule of thumb: If it's site branding/design β†’ keep static. If it's content that changes per item β†’ use CMS tokens.

    Always wrap CMS images in {{#if}} β€” not every item may have an image:

    {{#if image}}
      {{name}}
    {{else}}
      
    {{/if}}

    Common mistake β€” mixing static and CMS images:

    
    {{#each products}}
      Product  
      

    {{name}}

    {{/each}}

    {{#each products}} {{#if image}} {{name}} {{/if}}

    {{name}}

    {{/each}}

    Forms

    Rules:

  • data-form-name attribute is required.
  • action must point to /_forms/{formName}.
  • All inputs must have name attributes.
  • A submit button is required.
  • CRITICAL: Remove Original Form Handlers

    If the source site has JavaScript that handles form submissions, you MUST remove or replace it. Original site JS often does e.preventDefault() and shows a "fake" success toast β€” the data goes nowhere.

    // PROBLEM: This blocks real submissions!
    form.addEventListener('submit', (e) => {
      e.preventDefault();
      showToast('Message sent!');  // FAKE! Data not saved!
    });
    

    Option A (simplest): Remove the original JavaScript form handler entirely. The native

    will submit correctly.

    Option B (keep JS UX): Replace the handler with one that actually POSTs to FastMode:

    form.addEventListener('submit', async (e) => {
      e.preventDefault();
      const formName = form.dataset.formName;
      const response = await fetch('/_forms/' + formName, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(Object.fromEntries(new FormData(form)))
      });
      if (response.ok) {
        form.reset();
        alert('Message sent!');  // NOW it's real!
      }
    });
    


    Deployment & Build Status

    How Deployment Works

    1. Upload: fastmode deploy site.zip reads the zip, validates it, and uploads it to the server. 2. Build: The server processes the package (renders templates, publishes pages). This happens asynchronously. 3. Wait: By default, deploy polls for build status every 3 seconds until the build completes or times out (default 2 minutes). 4. Result: Success message with page count and version, or failure message with error details.

    Deploy Flags

    | Flag | Description | |------|-------------| | --force | Skip the GitHub connection check. Use if the project has GitHub connected but you want to deploy via CLI anyway. | | --no-wait | Upload only β€” don't wait for the build to finish. Useful for fire-and-forget. | | --timeout | Custom build timeout in milliseconds. Default: 120000 (2 minutes). |

    Checking Build Status

    After every deploy or content change, check the build status:

    fastmode status
    

    If the build failed, status shows:

  • The error message
  • Build logs
  • What went wrong
  • Always run fastmode status after deploying to verify the build succeeded.

    If a build fails: 1. Run fastmode status to see the error 2. Fix the issue (template errors, invalid tokens, missing files, etc.) 3. Re-deploy with fastmode deploy site.zip

    Deploy History

    fastmode deploys                # Show last 10 deployments
    fastmode deploys --limit 5     # Show last 5
    

    Shows status, version, duration, source, and errors for each deployment.

    Exit Codes

  • deploy: Exits 1 if the build fails (when waiting).
  • status: Exits 1 if the latest deploy shows "Failed".
  • Both: Exit 1 if no project is specified.

  • Validation

    Always validate before deploying. Validation catches errors that would cause build failures.

    Validation Workflow

    # 1. Validate the manifest
    fastmode validate manifest manifest.json

    2. Validate each template

    fastmode validate template pages/index.html -t static_page fastmode validate template templates/posts_index.html -t custom_index -c posts fastmode validate template templates/posts_detail.html -t custom_detail -c posts

    3. Validate the complete package

    fastmode validate package site.zip

    What Gets Checked

    Manifest validation:

  • Valid JSON syntax
  • pages array exists and is not empty
  • Homepage (path /) exists
  • All file paths are valid
  • cmsTemplates format is correct (flat keys, not nested)
  • Template validation:

  • Balanced tags: {{#each}} has matching {{/each}}, {{#if}} has {{/if}}
  • Index templates have at least one {{#each}} loop
  • Detail templates have CMS tokens
  • Rich text fields use triple braces {{{field}}}
  • Loop variables only used inside loops
  • Asset paths use /public/ prefix
  • Forms have required attributes
  • YouTube iframes have referrerpolicy
  • Package validation:

  • manifest.json exists at root
  • All referenced files exist in the zip
  • Assets are in public/ (not assets/ or root)
  • Templates are in templates/ (not collections/)
  • All templates pass individual validation
  • Validation with Schema Check

    Add -p to validate tokens against the actual project schema:

    fastmode validate template templates/posts_detail.html -t custom_detail -c posts -p "My Project"
    

    This reports which tokens reference fields that don't exist in the schema yet, with instructions to create them via fastmode schema sync.


    Common Mistakes & How to Fix Them

    1. Assets return 404

    Problem: CSS, JS, or images don't load. Cause: Files are in /assets/ instead of /public/, or paths don't include /public/. Fix: Move all static files to the public/ folder. Reference them as /public/css/style.css.

    2. Rich text shows as raw HTML

    Problem: Content displays

    Hello

    as text instead of rendering it. Cause: Using double braces {{body}} on a rich text field. Fix: Use triple braces {{{body}}} for all richText fields.

    3. Collection listing page is blank

    Problem: Index template shows no items. Cause: Missing {{#each collectionSlug}} loop. Fix: Add a loop: {{#each posts}}...{{/each}}.

    4. All detail pages look the same

    Problem: Every item page shows identical content. Cause: Detail template has no CMS tokens β€” just static HTML. Fix: Use tokens like {{name}}, {{{body}}}, {{image}} in the detail template.

    5. Manifest uses wrong format

    Problem: Build fails with manifest errors. Cause: Using nested objects or "collections" instead of flat "cmsTemplates" keys. Fix: Use flat format: "postsIndex", "postsIndexPath", "postsDetail", "postsDetailPath".

    6. Relation field is empty after create

    Problem: Created an item with a relation field but it's null. Cause: Used the item's name instead of its UUID. Fix: Run fastmode items relations --field to get the UUID, then use that.

    7. Forms don't submit

    Problem: Form appears to submit (shows toast/alert) but no data is received. Cause: Original JavaScript calls preventDefault() and shows a fake success message. Fix: Remove any form JavaScript that blocks submission. Use data-form-name and action="/_forms/formName".

    8. Static pages can't be edited in CMS

    Problem: Pages appear in the CMS but have no editable content. Cause: Missing data-edit-key attributes on text elements. Fix: Add data-edit-key="unique-key" to every text element that should be editable.

    9. Deploy blocked by GitHub

    Problem: deploy refuses to upload, says GitHub is connected. Cause: Project has GitHub auto-deploy enabled. Fix: Use --force flag: fastmode deploy site.zip --force.

    10. Build fails after deploy

    Problem: Upload succeeds but build fails. Fix: Run fastmode status to see the error. Common causes: invalid tokens, missing template files, malformed manifest. Fix the issue and re-deploy.

    11. Template URLs don't match manifest

    Problem: Links in templates point to wrong paths. Cause: Template hardcodes /posts/ but manifest sets "postsIndexPath": "/blog". Fix: Make sure hardcoded links in templates match the paths defined in manifest.json.

    12. Loop variables undefined

    Problem: {{@index}} or {{@first}} shows nothing. Cause: Used outside of a {{#each}} block. Fix: Only use loop variables inside {{#each}}...{{/each}}.

    13. Duplicate SEO meta tags

    Problem: SEO tags show up twice in the rendered HTML. Cause: HTML templates include </code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><meta name="description"></code>, or Open Graph tags. <strong style="color:#e5e7eb">Fix:</strong> Remove all SEO tags from templates. FastMode manages them automatically via CMS Settings. See the <a href="#seo-tags--do-not-include" target="_blank" rel="noopener" style="color:#6366f1">SEO Tags section</a> above.</p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">14. CSS background images and fonts broken</h4></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Problem:</strong> Background images or custom fonts don't load. <strong style="color:#e5e7eb">Cause:</strong> CSS files use relative paths like <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">url('../images/bg.jpg')</code> or <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">url('../fonts/custom.woff')</code>. <strong style="color:#e5e7eb">Fix:</strong> Update all paths inside CSS files to use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">/public/</code> prefix: <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">url('/public/images/bg.jpg')</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">url('/public/fonts/custom.woff2')</code>.</p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">15. Hardcoded example content instead of CMS tokens</h4></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Problem:</strong> Index page shows static placeholder cards instead of real CMS data. <strong style="color:#e5e7eb">Cause:</strong> Template has hardcoded HTML cards instead of <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{#each}}</code> loops with CMS tokens. <strong style="color:#e5e7eb">Fix:</strong> Replace hardcoded content blocks with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{#each collection}}...{{/each}}</code> loops using CMS field tokens.</p><p style="margin:8px 0"><hr style="border:none;border-top:1px solid #1e1e3f;margin:12px 0"></p><p style="margin:8px 0"><h3 style="color:#e5e7eb;margin:18px 0 8px;font-size:1.05em">Pre-Deployment Checklist</h3></p><p style="margin:8px 0">Run through this checklist before every deploy:</p><p style="margin:8px 0"><strong style="color:#e5e7eb">Structure:</strong> <li style="color:#94a3b8;margin:3px 0">[ ] <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">manifest.json</code> at package root</li> <li style="color:#94a3b8;margin:3px 0">[ ] Static pages in <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">pages/</code> folder</li> <li style="color:#94a3b8;margin:3px 0">[ ] CMS templates in <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">templates/</code> folder</li> <li style="color:#94a3b8;margin:3px 0">[ ] ALL assets in <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">public/</code> folder (not <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">assets/</code>)</li></p><p style="margin:8px 0"><strong style="color:#e5e7eb">SEO (CRITICAL):</strong> <li style="color:#94a3b8;margin:3px 0">[ ] NO <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><title></code> tags in HTML</li> <li style="color:#94a3b8;margin:3px 0">[ ] NO <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><meta name="description"></code> tags</li> <li style="color:#94a3b8;margin:3px 0">[ ] NO <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><meta property="og:*"></code> tags</li> <li style="color:#94a3b8;margin:3px 0">[ ] NO <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><link rel="icon"></code> tags</li></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Manifest:</strong> <li style="color:#94a3b8;margin:3px 0">[ ] Homepage page with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">"path": "/"</code> exists</li> <li style="color:#94a3b8;margin:3px 0">[ ] CMS templates use flat <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">cmsTemplates</code> keys (NOT nested, NOT <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">collections</code>)</li> <li style="color:#94a3b8;margin:3px 0">[ ] Paths match original site URLs</li></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Templates:</strong> <li style="color:#94a3b8;margin:3px 0">[ ] Index templates have <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{#each}}</code> loops</li> <li style="color:#94a3b8;margin:3px 0">[ ] Detail templates have CMS tokens (<code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{name}}</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{{body}}}</code>, etc.)</li> <li style="color:#94a3b8;margin:3px 0">[ ] Rich text fields use triple braces <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{{field}}}</code></li> <li style="color:#94a3b8;margin:3px 0">[ ] All <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{#each}}</code> have matching <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{/each}}</code></li> <li style="color:#94a3b8;margin:3px 0">[ ] All <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{#if}}</code> have matching <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{/if}}</code></li> <li style="color:#94a3b8;margin:3px 0">[ ] Static UI images use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">/public/</code> paths</li> <li style="color:#94a3b8;margin:3px 0">[ ] Content images use CMS tokens with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">{{#if}}</code> wrappers</li></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Static Pages:</strong> <li style="color:#94a3b8;margin:3px 0">[ ] <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">data-edit-key</code> on every editable text element</li> <li style="color:#94a3b8;margin:3px 0">[ ] Keys are unique across the entire site</li> <li style="color:#94a3b8;margin:3px 0">[ ] Forms have <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">data-form-name</code> and <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">action="/_forms/{name}"</code></li> <li style="color:#94a3b8;margin:3px 0">[ ] Original form JavaScript handlers removed or replaced</li></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Assets:</strong> <li style="color:#94a3b8;margin:3px 0">[ ] All HTML asset paths use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">/public/</code> prefix</li> <li style="color:#94a3b8;margin:3px 0">[ ] CSS <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">background-image</code> and font <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">url()</code> paths use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">/public/</code> prefix</li> <li style="color:#94a3b8;margin:3px 0">[ ] External URLs (Google Fonts, CDNs) unchanged</li></p><p style="margin:8px 0"><strong style="color:#e5e7eb">Validation:</strong> <pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em">fastmode validate manifest manifest.json fastmode validate template <each-template> -t <type> [-c <collection>] fastmode validate package site.zip </code></pre></p><p style="margin:8px 0"><hr style="border:none;border-top:1px solid #1e1e3f;margin:12px 0"></p><p style="margin:8px 0"><h3 style="color:#e5e7eb;margin:18px 0 8px;font-size:1.05em">Error Handling & Exit Codes</h3></p><p style="margin:8px 0">All commands exit with code <strong style="color:#e5e7eb">0</strong> on success and code <strong style="color:#e5e7eb">1</strong> on failure.</p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">Commands that exit 1</h4></p><p style="margin:8px 0">| Scenario | Commands | |----------|----------| | No project specified | All project-scoped commands | | File not found | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">schema sync</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">items create -f</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">validate *</code> | | Invalid JSON | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">schema sync</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">items create -d</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">items update -d</code> | | Validation errors | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">validate manifest</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">validate template</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">validate package</code> | | Build failed | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">deploy</code> (when waiting), <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">status</code> | | Delete without <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--confirm</code> | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">items delete</code> |</p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">Error Messages</h4></p><p style="margin:8px 0"><pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em">Error: No project specified. Use -p <id-or-name>, set FASTMODE_PROJECT env var, or run: fastmode use <project> </code></pre></p><p style="margin:8px 0"><pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em">Error: File not found: schema.json </code></pre></p><p style="margin:8px 0"><pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em">Error: Invalid JSON in --data argument </code></pre></p><p style="margin:8px 0"><pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em">Error: Deletion requires the --confirm flag. This action cannot be undone. </code></pre></p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">Authentication Errors</h4></p><p style="margin:8px 0">Most commands auto-trigger <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode login</code> if credentials are missing or expired. If authentication fails: 1. Run <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode login</code> manually 2. Complete the browser flow 3. Retry the command</p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">File Locations</h4></p><p style="margin:8px 0">| Path | Purpose | |------|---------| | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">~/.fastmode/credentials.json</code> | OAuth tokens (auto-created by <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">login</code>) | | <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">~/.fastmode/config.json</code> | Default project setting (created by <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">use</code>) |</p><p style="margin:8px 0">Both files have restricted permissions (0o600 β€” owner read/write only).</p><p style="margin:8px 0"><hr style="border:none;border-top:1px solid #1e1e3f;margin:12px 0"></p><p style="margin:8px 0"><h3 style="color:#e5e7eb;margin:18px 0 8px;font-size:1.05em">Notes</h3></p><p style="margin:8px 0"><li style="color:#94a3b8;margin:3px 0">All project-scoped commands use your default project (set with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode use</code>). Override with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">-p <name-or-id></code>.</li> <li style="color:#94a3b8;margin:3px 0">Item data (<code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">-d</code>) must be valid JSON. For complex data, write a file and use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">-f data.json</code>.</li> <li style="color:#94a3b8;margin:3px 0">Rich text fields accept HTML content (e.g. <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><p></code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><h2></code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><ul></code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><a></code>). Always use triple braces in templates.</li> <li style="color:#94a3b8;margin:3px 0">Relation fields require item IDs (UUIDs). Use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode items relations</code> to find available IDs.</li> <li style="color:#94a3b8;margin:3px 0">The <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--draft</code> flag creates unpublished items. Use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--publish</code>/<code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--unpublish</code> to change status.</li> <li style="color:#94a3b8;margin:3px 0">Every site gets free hosting, free SSL, and a <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">.fastmode.ai</code> subdomain. Custom domains can be configured.</li> <li style="color:#94a3b8;margin:3px 0">After deploying or making content changes, always run <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode status</code> to verify the build succeeded.</li> <li style="color:#94a3b8;margin:3px 0">Use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode examples <type></code> and <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode guide [section]</code> for built-in documentation and code snippets.</li></p><p style="margin:8px 0"><hr style="border:none;border-top:1px solid #1e1e3f;margin:12px 0"></p><p style="margin:8px 0"><h3 style="color:#e5e7eb;margin:18px 0 8px;font-size:1.05em">Package Provenance</h3></p><p style="margin:8px 0"><li style="color:#94a3b8;margin:3px 0"><strong style="color:#e5e7eb">npm package:</strong> <a href="https://www.npmjs.com/package/fastmode-cli" target="_blank" rel="noopener" style="color:#6366f1">fastmode-cli</a></li> <li style="color:#94a3b8;margin:3px 0"><strong style="color:#e5e7eb">Source code:</strong> <a href="https://github.com/arihgoldstein/fastmode-mcp" target="_blank" rel="noopener" style="color:#6366f1">github.com/arihgoldstein/fastmode-mcp</a></li> <li style="color:#94a3b8;margin:3px 0"><strong style="color:#e5e7eb">Website:</strong> <a href="https://fastmode.ai" target="_blank" rel="noopener" style="color:#6366f1">fastmode.ai</a></li> <li style="color:#94a3b8;margin:3px 0"><strong style="color:#e5e7eb">Author:</strong> Arih Goldstein</li> <li style="color:#94a3b8;margin:3px 0"><strong style="color:#e5e7eb">License:</strong> MIT</li> </p></div></section><section class="skill-card" style="margin-bottom:20px"><h2 style="color:#f8fafc;font-size:1.2em;font-weight:800;margin:0 0 16px;display:flex;align-items:center;gap:8px">πŸ“‹ Tips & Best Practices</h2><div style="font-size:.92em;color:#94a3b8;line-height:1.75"><p style="margin:8px 0"><li style="color:#94a3b8;margin:3px 0">All project-scoped commands use your default project (set with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode use</code>). Override with <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">-p <name-or-id></code>.</li> <li style="color:#94a3b8;margin:3px 0">Item data (<code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">-d</code>) must be valid JSON. For complex data, write a file and use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">-f data.json</code>.</li> <li style="color:#94a3b8;margin:3px 0">Rich text fields accept HTML content (e.g. <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><p></code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><h2></code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><ul></code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em"><a></code>). Always use triple braces in templates.</li> <li style="color:#94a3b8;margin:3px 0">Relation fields require item IDs (UUIDs). Use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode items relations</code> to find available IDs.</li> <li style="color:#94a3b8;margin:3px 0">The <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--draft</code> flag creates unpublished items. Use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--publish</code>/<code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">--unpublish</code> to change status.</li> <li style="color:#94a3b8;margin:3px 0">Every site gets free hosting, free SSL, and a <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">.fastmode.ai</code> subdomain. Custom domains can be configured.</li> <li style="color:#94a3b8;margin:3px 0">After deploying or making content changes, always run <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode status</code> to verify the build succeeded.</li> <li style="color:#94a3b8;margin:3px 0">Use <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode examples <type></code> and <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em">fastmode guide [section]</code> for built-in documentation and code snippets.</li></p><p style="margin:8px 0"><hr style="border:none;border-top:1px solid #1e1e3f;margin:12px 0"></p></div></section><section class="skill-card" style="margin-bottom:20px"><h2 style="color:#f8fafc;font-size:1.2em;font-weight:800;margin:0 0 16px;display:flex;align-items:center;gap:8px">πŸ“¦ Core Types</h2><div></div></section><section class="skill-card" style="margin-bottom:20px"><h2 style="color:#f8fafc;font-size:1.2em;font-weight:800;margin:0 0 16px;display:flex;align-items:center;gap:8px">πŸ”’ Constraints</h2><div style="font-size:.92em;color:#94a3b8;line-height:1.75"><p style="margin:8px 0"><pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">fastmode validate manifest manifest.json fastmode validate template index.html -t custom_index fastmode validate template post.html -t custom_detail -c posts fastmode validate template post.html -t custom_detail -c posts -p "My Project" fastmode validate template about.html -t static_page fastmode validate package site.zip </code></pre></p><p style="margin:8px 0"><li style="color:#94a3b8;margin:3px 0">Template types: <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">custom_index</code> (collection listing), <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">custom_detail</code> (single item), <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">static_page</code> (fixed page).</li> <li style="color:#94a3b8;margin:3px 0"><code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">-c</code> specifies the collection slug (required for <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">custom_index</code> and <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">custom_detail</code>).</li> <li style="color:#94a3b8;margin:3px 0"><code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">-p</code> validates tokens against the actual project schema (reports missing fields).</li> <li style="color:#94a3b8;margin:3px 0">All validation commands exit with code 1 on errors β€” safe for CI/CD pipelines.</li></p><p style="margin:8px 0"><h4 style="color:#d1d5db;margin:14px 0 6px;font-size:.95em">Documentation & Examples</h4></p><p style="margin:8px 0"><pre style="background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0"><code style="color:#a5f3fc;background:none;padding:0;font-size:1em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">fastmode examples <type> # Code examples for a specific pattern fastmode guide # Full website conversion guide fastmode guide templates # Template syntax guide fastmode guide common_mistakes # Common pitfalls to avoid fastmode generate-samples # Generate placeholder content for empty collections fastmode generate-samples -c posts team # Specific collections only </code></pre></p><p style="margin:8px 0">Available example types: <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">manifest_basic</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">manifest_custom_paths</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">blog_index_template</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">blog_post_template</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">team_template</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">downloads_template</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">form_handling</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">asset_paths</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">data_edit_keys</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">each_loop</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">conditional_if</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">nested_fields</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">featured_posts</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">parent_context</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">equality_comparison</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">comparison_helpers</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">youtube_embed</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">nested_collection_loop</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">loop_variables</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">common_mistakes</code>.</p><p style="margin:8px 0">Available guide sections: <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">full</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">first_steps</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">analysis</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">structure</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">seo</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">manifest</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">templates</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">tokens</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">forms</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">assets</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">checklist</code>, <code style="background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em" style="background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em">common_mistakes</code>.</p><p style="margin:8px 0"><hr style="border:none;border-top:1px solid #1e1e3f;margin:12px 0"></p></div></section></div><div class="two-col-side"></div></div></div><script> document.querySelectorAll('.copy-btn, .script-copy-btn').forEach(btn => { btn.addEventListener('click', () => { const cmd = btn.getAttribute('data-cmd'); if (!cmd) return; navigator.clipboard.writeText(cmd).then(() => { const orig = btn.textContent; btn.textContent = 'Copied!'; setTimeout(() => btn.textContent = orig, 1500); }).catch(() => {}); }); }); </script><!--$--><!--/$--></main><footer style="background:var(--bg-primary);border-top:1px solid var(--border-secondary);margin-top:60px"><div style="border-top:1px solid var(--border-light);max-width:1200px;margin:0 auto;padding:24px 20px"><div style="display:flex;justify-content:space-between;flex-wrap:wrap;gap:24px;margin-bottom:24px"><div><div style="font-weight:700;color:var(--text-muted);margin-bottom:8px">BytesAgain</div><div style="color:var(--text-muted3);font-size:.82em;max-width:200px">Discover the best AI agent skills for your workflow.</div></div><div><div style="color:var(--text-muted);font-size:.75em;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px">Explore</div><div style="margin-bottom:6px"><a href="/skills" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Skills</a></div><div style="margin-bottom:6px"><a href="/articles" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Articles</a></div><div style="margin-bottom:6px"><a href="/use-case" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Cases</a></div></div><div><div style="color:var(--text-muted);font-size:.75em;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px">Company</div><div style="margin-bottom:6px"><a href="/about" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">About</a></div><div style="margin-bottom:6px"><a href="/contact" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Contact</a></div><div style="margin-bottom:6px"><a href="/privacy-policy" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Privacy Policy</a></div><div style="margin-bottom:6px"><a href="/terms" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Terms</a></div><div style="margin-bottom:6px"><a href="/feedback" style="color:var(--text-muted2);text-decoration:none;font-size:.85em">Feedback</a></div></div></div><div style="border-top:1px solid var(--border-light);padding-top:16px"><div style="color:var(--text-muted4);font-size:.8em;margin-bottom:8px">Β© <!-- -->2026<!-- --> BytesAgain. All rights reserved.</div><div style="color:var(--text-muted5);font-size:.75em;line-height:1.6;max-width:720px">BytesAgain is an independent skill directory. We index and link to third-party content (ClawHub, GitHub, LobeHub, Dify, etc.) for informational purposes only. All trademarks, skill names, and content are the property of their respective owners. BytesAgain does not claim ownership of any indexed content.</div></div></div></footer><button style="position:fixed;bottom:28px;right:28px;z-index:1000;width:48px;height:48px;border-radius:50%;border:none;cursor:pointer;background:linear-gradient(135deg,#667eea,#00d4ff);color:#fff;font-size:1.3em;box-shadow:0 4px 20px #667eea66;display:flex;align-items:center;justify-content:center;transition:transform .2s">πŸ’¬</button><script src="/_next/static/chunks/0ze4gu236oq96.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[62894,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"LangProvider\"]\n3:I[89220,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"ThemeProvider\"]\n4:I[16988,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\ne:I[68027,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\",1]\n:HL[\"/_next/static/chunks/051nc0vy_6.rl.css?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"style\"]\n:HL[\"/_next/static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n5:Td5e,"])</script><script>self.__next_f.push([1,"[{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"BytesAgain\",\"url\":\"https://bytesagain.com\",\"description\":\"Search 60,000+ verified AI agent skills via MCP API or REST. Supports 7 languages. Free, no auth required.\",\"inLanguage\":[\"en\",\"zh\",\"es\",\"fr\",\"de\",\"ja\",\"ko\"],\"potentialAction\":{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https://bytesagain.com/skills?q={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}},{\"@context\":\"https://schema.org\",\"@type\":\"Organization\",\"name\":\"BytesAgain\",\"url\":\"https://bytesagain.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://bytesagain.com/og-image.png\"},\"description\":\"AI agent skill directory. Search 60,000+ skills, 1,000+ use cases, and community requests.\",\"foundingDate\":\"2026\",\"foundingLocation\":{\"@type\":\"Place\",\"name\":\"Global\"},\"sameAs\":[\"https://x.com/bytesagain\",\"https://github.com/bytesagain/ai-skills\",\"https://clawhub.ai/profile/bytesagain\"],\"contactPoint\":{\"@type\":\"ContactPoint\",\"email\":\"hello@bytesagain.com\",\"contactType\":\"customer support\"},\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"value\":1}},{\"@context\":\"https://schema.org\",\"@type\":\"WebApplication\",\"name\":\"BytesAgain AI Skills Search\",\"url\":\"https://bytesagain.com\",\"applicationCategory\":\"DeveloperApplication\",\"operatingSystem\":\"Web\",\"description\":\"Search engine and MCP API for 60,000+ AI agent skills. Semantic search, role recommendations, and use case packs.\",\"offers\":{\"@type\":\"Offer\",\"price\":\"0\",\"priceCurrency\":\"USD\"},\"featureList\":[\"Search 60,000+ AI agent skills\",\"Role-based recommendations for developers, creators, and traders\",\"1,000+ curated use case packs\",\"Free MCP API and REST API\",\"Multi-language search (EN, ZH, ES, FR, DE, JA, KO)\"],\"potentialAction\":{\"@type\":\"SearchAction\",\"target\":\"https://bytesagain.com/skills?q={search_term_string}\",\"query-input\":\"required name=search_term_string\"},\"dateModified\":\"2026-07-17\"},{\"@context\":\"https://schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"What is BytesAgain?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"BytesAgain is a curated directory of 60,000+ AI agent skills from ClawHub, GitHub, LobeHub, and Dify. Search skills by keyword in 7 languages, browse by role (developer, creator, trader, marketer) or by use case.\"}},{\"@type\":\"Question\",\"name\":\"How do I find AI skills on BytesAgain?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Use the search bar on BytesAgain.com to search by keyword in 7 languages. You can also browse by role (developer, creator, trader, marketer) or by use case. Each skill shows install instructions for Claude, Cursor, OpenClaw, Continue, and more.\"}},{\"@type\":\"Question\",\"name\":\"Is BytesAgain free?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes, BytesAgain is completely free. No registration required for searching skills. The MCP API is also free with rate limits.\"}},{\"@type\":\"Question\",\"name\":\"Does BytesAgain have an API for AI agents?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes! BytesAgain provides a free MCP SSE endpoint at /api/mcp/sse for AI agents, plus a REST API at /api/mcp?action=search\u0026q=\u003cquery\u003e. No authentication needed.\"}},{\"@type\":\"Question\",\"name\":\"Can I request a new AI skill on BytesAgain?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes! Visit the Requests page on BytesAgain.com to submit a skill request. Your request will be visible to the community and notified to the site admin.\"}}]}]"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"skill\",\"fastmode\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"skill\",{\"children\":[[\"slug\",\"fastmode\",\"d\",null],{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/051nc0vy_6.rl.css?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"link\",null,{\"rel\":\"llms\",\"href\":\"/llms.txt\"}],[\"$\",\"link\",null,{\"rel\":\"llms-full\",\"href\":\"/llms-full.txt\"}],[\"$\",\"script\",null,{\"async\":true,\"src\":\"https://www.googletagmanager.com/gtag/js?id=G-3C1MM9FWYF\"}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n window.dataLayer = window.dataLayer || [];\\n function gtag(){dataLayer.push(arguments);}\\n gtag('js', new Date());\\n gtag('config', 'G-3C1MM9FWYF');\\n \"}}]]}],[\"$\",\"body\",null,{\"className\":\"geist_9e050971-module__05dp7a__className\",\"style\":{\"margin\":0},\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[[\"$\",\"div\",null,{\"style\":{\"width\":\"100%\",\"background\":\"var(--bg-subscribe)\",\"borderBottom\":\"1px solid var(--border-primary)\",\"padding\":\"8px 20px\",\"textAlign\":\"center\",\"fontSize\":\".82em\",\"color\":\"#818cf8\"},\"children\":[\"🎁 \",[\"$\",\"strong\",null,{\"style\":{\"color\":\"var(--text-primary)\"},\"children\":\"Get the FREE AI Skills Starter Guide\"}],\" β€” \",[\"$\",\"a\",null,{\"href\":\"/register\",\"style\":{\"color\":\"#00d4ff\",\"textDecoration\":\"underline\"},\"children\":\"Subscribe β†’\"}]]}],[\"$\",\"$L4\",null,{}],[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"$5\"}}],\"$L6\",\"$L7\",\"$L8\"]}]}]}]]}]]}],{\"children\":[\"$L9\",{\"children\":[\"$La\",{\"children\":[\"$Lb\",{},null,false,null]},null,false,\"$@c\"]},null,false,\"$@c\"]},null,false,null],\"$Ld\",false]],\"m\":\"$undefined\",\"G\":[\"$e\",[\"$Lf\"]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"10:I[39756,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\n11:I[37457,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\n12:I[22016,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0ka051yepewro.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"\"]\n13:I[90940,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\n14:I[16397,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\n16:I[97367,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"OutletBoundary\"]\n17:\"$Sreact.suspense\"\n1a:I[97367,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"ViewportBoundary\"]\n1c:I[97367,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"MetadataBoundary\"]\n"])</script><script>self.__next_f.push([1,"6:[\"$\",\"main\",null,{\"children\":[\"$\",\"$L10\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L11\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"main\",null,{\"style\":{\"minHeight\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"background\":\"#050611\",\"color\":\"#e5e7eb\"},\"children\":[[\"$\",\"style\",null,{\"children\":\"\\n .nf-box { text-align: center; padding: 60px 32px; }\\n .nf-code { font-size: 6rem; font-weight: 900; color: #22d3ee; line-height: 1; margin: 0; }\\n .nf-title { font-size: 1.8rem; font-weight: 800; margin: 12px 0 8px; }\\n .nf-desc { color: var(--text-muted2); font-size: 1rem; margin-bottom: 32px; max-width: 440px; }\\n .nf-link { display: inline-block; padding: 12px 28px; background: linear-gradient(135deg,#34d399,#22d3ee); color: #000; font-weight: 900; border-radius: 12px; text-decoration: none; }\\n \"}],[\"$\",\"div\",null,{\"className\":\"nf-box\",\"children\":[[\"$\",\"p\",null,{\"className\":\"nf-code\",\"children\":\"404\"}],[\"$\",\"h1\",null,{\"className\":\"nf-title\",\"children\":\"Page Not Found\"}],[\"$\",\"p\",null,{\"className\":\"nf-desc\",\"children\":\"The skill or page you're looking for doesn't exist or has been moved.\"}],[\"$\",\"$L12\",null,{\"className\":\"nf-link\",\"href\":\"/\",\"children\":\"Back to BytesAgain\"}]]}]]}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]\n"])</script><script>self.__next_f.push([1,"7:[\"$\",\"$L13\",null,{}]\n8:[\"$\",\"$L14\",null,{}]\n9:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L10\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L11\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\na:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L10\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L11\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\nb:[\"$\",\"$1\",\"c\",{\"children\":[\"$L15\",[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/12w5ognupk9fb.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L16\",null,{\"children\":[\"$\",\"$17\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@18\"}]}]]}]\n19:[]\nc:\"$W19\"\nd:[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L1a\",null,{\"children\":\"$L1b\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L1c\",null,{\"children\":[\"$\",\"$17\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L1d\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}]\nf:[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/051nc0vy_6.rl.css?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]\n"])</script><script>self.__next_f.push([1,"1b:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"1e:I[27201,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"IconMark\"]\n18:null\n"])</script><script>self.__next_f.push([1,"1d:[[\"$\",\"title\",\"0\",{\"children\":\"FastMode CMS - Host, Deploy, Manage Websites for Free β€” AI Agent Skill | BytesAgain | BytesAgain\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Build, deploy, and host websites for free with full CMS. Create a live website from scratch, deploy it to the cloud with free hosting, free SSL, and custom d...\"}],[\"$\",\"meta\",\"2\",{\"name\":\"robots\",\"content\":\"index, follow\"}],[\"$\",\"meta\",\"3\",{\"name\":\"googlebot\",\"content\":\"index, follow, max-image-preview:large, max-snippet:-1\"}],[\"$\",\"meta\",\"4\",{\"name\":\"llms-txt\",\"content\":\"https://bytesagain.com/llms.txt\"}],[\"$\",\"meta\",\"5\",{\"name\":\"llms-full-txt\",\"content\":\"https://bytesagain.com/llms-full.txt\"}],[\"$\",\"link\",\"6\",{\"rel\":\"canonical\",\"href\":\"https://bytesagain.com/skill/fastmode\"}],[\"$\",\"meta\",\"7\",{\"name\":\"baidu-site-verification\",\"content\":\"codeva-0evUqX1TFs\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:title\",\"content\":\"FastMode CMS - Host, Deploy, Manage Websites for Free β€” AI Agent Skill | BytesAgain\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:description\",\"content\":\"Build, deploy, and host websites for free with full CMS. Create a live website from scratch, deploy it to the cloud with free hosting, free SSL, and custom d...\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:url\",\"content\":\"https://bytesagain.com/skill/fastmode\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:site_name\",\"content\":\"BytesAgain\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:image\",\"content\":\"https://bytesagain.com/social-preview.png\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:title\",\"content\":\"FastMode CMS - Host, Deploy, Manage Websites for Free β€” AI Agent Skill | BytesAgain\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:description\",\"content\":\"Build, deploy, and host websites for free with full CMS. Create a live website from scratch, deploy it to the cloud with free hosting, free SSL, and custom d...\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image\",\"content\":\"https://bytesagain.com/social-preview.png\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"22\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.0x3dzn~oxb6tn.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$L1e\",\"23\",{}]]\n"])</script><script>self.__next_f.push([1,"1f:T1562,"])</script><script>self.__next_f.push([1,"\n .skill-page { max-width: 1100px; margin: 0 auto; padding: 32px 20px 80px; }\n .two-col { display: flex; gap: 32px; align-items: flex-start; }\n .two-col-main { flex: 1; min-width: 0; }\n .two-col-side { width: 300px; flex-shrink: 0; }\n @media (max-width: 860px) {\n .two-col { flex-direction: column; }\n .two-col-side { width: 100%; }\n }\n .breadcrumb { font-size: .82em; color: var(--text-muted2); margin-bottom: 28px; }\n .breadcrumb a { color: #818cf8; text-decoration: none; }\n .breadcrumb a:hover { text-decoration: underline; }\n .skill-card { background: var(--bg-card); border: 1px solid var(--border-card); border-radius: 20px; padding: 28px; margin-bottom: 24px; }\n .skill-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }\n .skill-badges { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\n .skill-top-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }\n .badge { display: inline-flex; align-items: center; gap: 5px; font-size: .75em; font-weight: 600; padding: 4px 12px; border-radius: 999px; border: 1px solid transparent; }\n .skill-title { font-size: 1.6em; font-weight: 800; color: var(--text-primary); margin: 0 0 4px; line-height: 1.2; }\n .skill-owner { font-size: .82em; color: var(--text-muted2); margin: 0 0 14px; }\n .skill-owner span { color: #818cf8; }\n .skill-desc { font-size: .92em; color: var(--text-secondary); line-height: 1.65; margin: 0 0 16px; }\n .skill-meta { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; padding-bottom: 16px; border-bottom: 1px solid var(--border-card); }\n .meta-item { display: flex; flex-direction: column; gap: 2px; }\n .meta-label { font-size: .7em; color: var(--text-muted5); text-transform: uppercase; letter-spacing: 1px; font-weight: 600; }\n .meta-value { font-size: .92em; color: var(--text-muted2); font-weight: 600; }\n .tags-row { display: flex; gap: 6px; flex-wrap: wrap; }\n .tag { font-size: .75em; color: #6366f1; background: #6366f115; border: 1px solid #6366f130; border-radius: 6px; padding: 3px 10px; text-decoration: none; }\n .tag:hover { background: #6366f125; }\n .install-box { background: var(--bg-deep); border: 1px solid var(--border-card); border-radius: 12px; overflow: hidden; margin-bottom: 24px; }\n .install-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; border-bottom: 1px solid var(--border-card); }\n .install-dots { display: flex; gap: 6px; }\n .dot { width: 10px; height: 10px; border-radius: 50%; }\n .install-label { font-size: .72em; color: var(--text-muted5); font-family: monospace; letter-spacing: 1px; }\n .install-body { padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }\n .install-cmd { color: var(--text-code);\n font-family: 'Courier New', monospace; font-size: 1em; }\n .copy-btn { font-size: .75em; color: #6366f1; background: #6366f115; border: 1px solid #6366f130; border-radius: 6px; padding: 5px 12px; cursor: pointer; white-space: nowrap; transition: all .15s; }\n .copy-btn:hover { background: #6366f125; }\n .btn-secondary { display: inline-flex; align-items: center; gap: 8px; padding: 13px 24px; background: transparent; border: 1px solid var(--border-card); border-radius: 10px; color: #6b7280; text-decoration: none; font-weight: 600; font-size: .95em; transition: all .15s; }\n .btn-secondary:hover { border-color: #818cf8; color: #818cf8; }\n .ours-badge { display: inline-flex; align-items: center; gap: 6px; font-size: .72em; font-weight: 700; color: #22d3ee; background: #22d3ee10; border: 1px solid #22d3ee30; border-radius: 999px; padding: 4px 14px; }\n .section-card { background: var(--bg-card); border: 1px solid var(--border-card); border-radius: 16px; padding: 22px 24px; margin-bottom: 20px; }\n .section-title { color: var(--text-primary); font-size: 1.08em; font-weight: 800; margin: 0 0 12px; display: flex; align-items: center; gap: 8px; }\n /* Script box */\n .script-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 14px; background: var(--bg-input); border-bottom: 1px solid var(--border-card); }\n .script-filename { font-size: .72em; color: var(--text-muted2); font-family: 'Courier New', monospace; }\n .script-copy-btn { font-size: .72em; color: #6366f1; background: none; border: 1px solid #6366f130; border-radius: 4px; padding: 2px 10px; cursor: pointer; }\n .script-copy-btn:hover { background: #6366f115; }\n .script-body { padding: 14px 16px; font-family: 'Courier New', monospace; font-size: .82em; line-height: 1.6; color: var(--text-code); overflow-x: auto; max-height: 420px; overflow-y: auto; white-space: pre; }\n /* Articles */\n .article-card { display: block; background: var(--bg-secondary); border: 1px solid var(--border-primary); border-radius: 10px; padding: 14px 16px; text-decoration: none; transition: border-color .15s; }\n .article-card:hover { border-color: #6366f1; }\n @media (max-width: 600px) {\n .skill-card { padding: 20px; }\n .skill-title { font-size: 1.5em; }\n }\n "])</script><script>self.__next_f.push([1,"15:[[\"$\",\"style\",null,{\"children\":\"$1f\"}],\"$L20\",\"$L21\"]\n"])</script><script>self.__next_f.push([1,"22:I[78297,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/12w5ognupk9fb.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\n23:T22401,"])</script><script>self.__next_f.push([1,"\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\nname: fastmode\ndescription: Create, deploy, and host a website for free. Build a complete website from scratch and deploy it to the cloud with free hosting, free SSL, and custom domains β€” all from the terminal. Full CMS included: manage blog posts, team members, pages, products, portfolios, services, testimonials, FAQs, or any structured content. Add and edit CMS content, sync database schemas, validate HTML templates, invite clients to a white-label portal, and push live deployments. Convert any existing HTML site into a CMS-powered site. One-time browser login for OAuth, then every operation runs entirely in the terminal β€” designed for AI agents to go from zero to a publicly accessible website in minutes.\nmetadata: {\"openclaw\":{\"emoji\":\"⚑\",\"homepage\":\"https://fastmode.ai\",\"requires\":{\"bins\":[\"fastmode\"]},\"install\":[{\"id\":\"npm\",\"kind\":\"npm\",\"package\":\"fastmode-cli\",\"bins\":[\"fastmode\"]}]}}\nuser-invokable: true\n\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eFastMode CLI β€” Complete Agent Reference\u003c/h2\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eFastMode lets you create a live website, deploy it to the cloud, and manage all its content β€” entirely from the command line. One-time browser login for OAuth authentication, then every operation runs in the terminal. No local servers, no manual dashboards.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eFree cloud hosting\u003c/strong\u003e β€” every site gets a live URL at \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eyoursite.fastmode.ai\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eFree SSL\u003c/strong\u003e β€” HTTPS included automatically\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCustom domains\u003c/strong\u003e β€” connect any domain (e.g. \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ewww.example.com\u003c/code\u003e)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eFull CMS\u003c/strong\u003e β€” any content structure (blog, team, products, portfolios, anything)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAgent-native\u003c/strong\u003e β€” every operation works via CLI, zero human intervention needed\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eTable of Contents\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. \u003ca href=\"#end-to-end-workflow\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eEnd-to-End Workflow\u003c/a\u003e\n2. \u003ca href=\"#critical-before-you-build-anything\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eCRITICAL: Before You Build Anything\u003c/a\u003e\n3. \u003ca href=\"#website-analysis-do-this-before-writing-code\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eWebsite Analysis\u003c/a\u003e\n4. \u003ca href=\"#command-reference\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eCommand Reference\u003c/a\u003e\n5. \u003ca href=\"#project-resolution\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eProject Resolution\u003c/a\u003e\n6. \u003ca href=\"#schema--field-types\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eSchema \u0026 Field Types\u003c/a\u003e\n7. \u003ca href=\"#content-items\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eContent Items\u003c/a\u003e\n8. \u003ca href=\"#client-portal-management\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eClient Portal Management\u003c/a\u003e\n9. \u003ca href=\"#package-structure\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003ePackage Structure\u003c/a\u003e\n10. \u003ca href=\"#manifest-format\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eManifest Format\u003c/a\u003e\n11. \u003ca href=\"#template-syntax\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eTemplate Syntax\u003c/a\u003e (includes SEO rules, image handling, forms, inline editing)\n12. \u003ca href=\"#deployment--build-status\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eDeployment \u0026 Build Status\u003c/a\u003e\n13. \u003ca href=\"#validation\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eValidation\u003c/a\u003e\n14. \u003ca href=\"#common-mistakes--how-to-fix-them\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eCommon Mistakes \u0026 How to Fix Them\u003c/a\u003e\n15. \u003ca href=\"#pre-deployment-checklist\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003ePre-Deployment Checklist\u003c/a\u003e\n15. \u003ca href=\"#error-handling--exit-codes\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eError Handling \u0026 Exit Codes\u003c/a\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eEnd-to-End Workflow\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThis is the complete sequence to go from nothing to a live website.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# 1. Authenticate (one-time β€” credentials persist at ~/.fastmode/credentials.json)\nfastmode login\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e2. Create a project (gets a free hosted URL instantly)\u003c/h2\u003e\nfastmode projects create \"Acme Corp\"\nfastmode use \"Acme Corp\"\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e3. Define content structure (write schema.json, then sync it)\u003c/h2\u003e\nfastmode schema sync -f schema.json\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e4. Add content\u003c/h2\u003e\nfastmode items create posts -n \"Welcome\" -d '{\"title\": \"Welcome to Acme\", \"body\": \"\u003cp\u003eWe build great things.\u003c/p\u003e\"}'\nfastmode items create team -n \"Jane Doe\" -d '{\"role\": \"Founder\", \"bio\": \"\u003cp\u003eVisionary leader.\u003c/p\u003e\"}'\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e5. Build HTML templates with {{tokens}}, package into a zip, validate, deploy\u003c/h2\u003e\nfastmode validate package site.zip\nfastmode deploy site.zip\n\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eDeploy waits for build to finish and reports success or failure with error details\u003c/h2\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e6. If the build failed, check what went wrong\u003c/h2\u003e\nfastmode status\n\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eFix the issue, then re-deploy\u003c/h2\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eCRITICAL: Before You Build Anything\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eSTOP. Before writing ANY HTML, templates, or manifest.json, complete these steps.\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eStep 1: Check for Existing Projects\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode projects\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThis lists all the user's existing FastMode projects.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eStep 2: Decide β€” Existing or New Project\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eIf projects exist:\u003c/strong\u003e Ask the user: \"Is this website for one of your existing projects, or should I create a new one?\" Let the user choose.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eIf NO projects exist:\u003c/strong\u003e This is a new user β€” ask: \"What would you like to name your new project?\"\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eStep 3a: For EXISTING Projects\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. User selects the project from the list\n2. Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode use \"Project Name\"\u003c/code\u003e to set it as default\n3. Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode schema show\u003c/code\u003e to get the current collections and fields\n4. \u003cstrong style=\"color:#e5e7eb\"\u003eUse this schema to build templates with the correct field names\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eStep 3b: For NEW Projects\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. Ask for the project name if you don't have it\n2. Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode projects create \"Project Name\"\u003c/code\u003e\n3. Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode use \"Project Name\"\u003c/code\u003e\n4. You'll create the schema later with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode schema sync\u003c/code\u003e\n5. Optionally generate sample content: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode generate-samples\u003c/code\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCheckpoint β€” Confirm Before Continuing\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Requirement | How to Get It |\n|-------------|---------------|\n| Project selected/created | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode projects\u003c/code\u003e / \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode projects create\u003c/code\u003e |\n| Default set | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode use \"Project Name\"\u003c/code\u003e |\n| Schema known (existing) | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode schema show\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eIf you don't have a project set, DO NOT PROCEED.\u003c/strong\u003e Go back to Step 1.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWHY THIS MATTERS:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eFor existing projects: The schema determines which fields to use in templates β€” get it wrong and the build fails\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eFor new projects: You need the project before you can deploy\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAlways: The user must confirm which project to use β€” never assume\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eWebsite Analysis (Do This Before Writing Code)\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eBefore writing any HTML or templates, analyze the site:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. \u003cstrong style=\"color:#e5e7eb\"\u003eMap ALL URLs\u003c/strong\u003e β€” document every page path (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/about\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/blog\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/blog/post-slug\u003c/code\u003e, etc.)\n2. \u003cstrong style=\"color:#e5e7eb\"\u003eCategorize each page\u003c/strong\u003e β€” Static (fixed content), List (shows multiple items), or Detail (single item from a collection)\n3. \u003cstrong style=\"color:#e5e7eb\"\u003eIdentify collections\u003c/strong\u003e β€” repeating content that should be CMS-managed (blog posts, team members, products, testimonials, etc.)\n4. \u003cstrong style=\"color:#e5e7eb\"\u003eDocument assets\u003c/strong\u003e β€” all CSS, JS, image, and font file locations\n5. \u003cstrong style=\"color:#e5e7eb\"\u003ePRESERVE original URLs\u003c/strong\u003e β€” if the site uses \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/resources\u003c/code\u003e for articles, keep \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/resources\u003c/code\u003e. Do NOT change it to \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/blog\u003c/code\u003e. Use the manifest's path configuration.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eCommand Reference\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eAuthentication\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode login # Open browser for OAuth device flow\nfastmode logout # Delete ~/.fastmode/credentials.json\nfastmode whoami # Show current user email and name\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003elogin\u003c/code\u003e uses OAuth 2.0 device authorization flow: opens a browser window where the user approves access on \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode.ai\u003c/code\u003e, then credentials are saved automatically. The browser is only needed for this one-time login step.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eOAuth scopes:\u003c/strong\u003e The token grants access to the user's FastMode projects only (project management, schema editing, content CRUD, deployments). No third-party service access is requested.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eCredentials persist at \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e~/.fastmode/credentials.json\u003c/code\u003e with restricted file permissions (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e0o600\u003c/code\u003e β€” owner read/write only). Treat this file as a sensitive secret.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eTokens auto-refresh. If a token expires, the next command will refresh it silently using the stored refresh token.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eIf credentials are missing or invalid, most commands will trigger the login flow automatically.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003elogout\u003c/code\u003e deletes \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e~/.fastmode/credentials.json\u003c/code\u003e and revokes the stored tokens.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eProjects\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode projects # List all projects (default action)\nfastmode projects list # Same as above\nfastmode projects create \"Name\" # Create a new project\nfastmode projects create \"Name\" --subdomain custom-sub # Custom subdomain\nfastmode projects create \"Name\" --force # Skip similar-name check\nfastmode use \u003cproject\u003e # Set default project for all commands\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eprojects create\u003c/code\u003e checks for existing projects with similar names. Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--force\u003c/code\u003e to skip.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eSubdomain auto-generated from name if not provided (lowercase, hyphens, max 30 chars).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003euse\u003c/code\u003e stores the default in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e~/.fastmode/config.json\u003c/code\u003e. Does NOT validate the project exists.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eSchema\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode schema show # Show all collections and fields\nfastmode schema show -p \"Project Name\" # Specify project\nfastmode schema sync -f schema.json # Create collections and fields from JSON file\nfastmode schema field-types # List all available field types (no auth needed)\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eschema show\u003c/code\u003e requires authentication and a project.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eschema sync\u003c/code\u003e reads a local JSON file and creates/updates the schema. Skips duplicates. Two-phase: creates collections first, then fields (handles relation dependencies).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eschema field-types\u003c/code\u003e works without authentication.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eContent Items\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode items list \u003ccollection\u003e # List all items\nfastmode items list posts --limit 10 --sort publishedAt --order desc\nfastmode items get \u003ccollection\u003e \u003cslug\u003e # Get single item\nfastmode items create \u003ccollection\u003e -n \"Name\" -d '{\"field\": \"value\"}'\nfastmode items create posts -n \"Title\" -f data.json # Data from file\nfastmode items create posts -n \"Draft Post\" -d '{}' --draft\nfastmode items update \u003ccollection\u003e \u003cslug\u003e -d '{\"field\": \"new value\"}'\nfastmode items update posts my-post -n \"New Title\"\nfastmode items update posts my-post --publish # Publish a draft\nfastmode items update posts my-post --unpublish # Revert to draft\nfastmode items delete \u003ccollection\u003e \u003cslug\u003e --confirm # REQUIRES --confirm\nfastmode items relations \u003ccollection\u003e # Show linkable items for relation fields\nfastmode items relations posts --field author # Options for specific field\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eSee the \u003ca href=\"#content-items\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eContent Items\u003c/a\u003e section below for detailed rules on data formats, relation fields, and drafts.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eClient Portal Management\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode clients list # List portal clients with access\nfastmode clients invite client@example.com # Invite with default permissions\nfastmode clients invite client@example.com -n \"Jane\" --permissions cms.read,cms.write\nfastmode clients invitations # List pending invitations\nfastmode clients update-permissions \u003caccessId\u003e --permissions cms.read,editor\nfastmode clients revoke \u003caccessId\u003e --confirm # REQUIRES --confirm\nfastmode clients cancel-invite \u003cinvitationId\u003e --confirm # REQUIRES --confirm\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eSee the \u003ca href=\"#client-portal-management\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eClient Portal Management\u003c/a\u003e section below for details on permissions, invite flow, and examples.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDeployment \u0026 Build Status\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode deploy site.zip # Deploy and wait for build to finish\nfastmode deploy site.zip --force # Skip GitHub sync check\nfastmode deploy site.zip --no-wait # Upload only, don't wait for build\nfastmode deploy site.zip --timeout 300000 # Custom timeout in ms (default: 120000)\nfastmode status # Check current build/deploy status\nfastmode deploys # List deployment history\nfastmode deploys --limit 5 # Limit number of results\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eSee \u003ca href=\"#deployment--build-status\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eDeployment \u0026 Build Status\u003c/a\u003e below for the full deploy lifecycle.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eValidation\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode validate manifest manifest.json\nfastmode validate template index.html -t custom_index\nfastmode validate template post.html -t custom_detail -c posts\nfastmode validate template post.html -t custom_detail -c posts -p \"My Project\"\nfastmode validate template about.html -t static_page\nfastmode validate package site.zip\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eTemplate types: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecustom_index\u003c/code\u003e (collection listing), \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecustom_detail\u003c/code\u003e (single item), \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003estatic_page\u003c/code\u003e (fixed page).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-c\u003c/code\u003e specifies the collection slug (required for \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecustom_index\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecustom_detail\u003c/code\u003e).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p\u003c/code\u003e validates tokens against the actual project schema (reports missing fields).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll validation commands exit with code 1 on errors β€” safe for CI/CD pipelines.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDocumentation \u0026 Examples\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode examples \u003ctype\u003e # Code examples for a specific pattern\nfastmode guide # Full website conversion guide\nfastmode guide templates # Template syntax guide\nfastmode guide common_mistakes # Common pitfalls to avoid\nfastmode generate-samples # Generate placeholder content for empty collections\nfastmode generate-samples -c posts team # Specific collections only\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAvailable example types: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest_basic\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest_custom_paths\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eblog_index_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eblog_post_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eteam_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edownloads_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eform_handling\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003easset_paths\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata_edit_keys\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eeach_loop\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003econditional_if\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003enested_fields\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efeatured_posts\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eparent_context\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eequality_comparison\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecomparison_helpers\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eyoutube_embed\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003enested_collection_loop\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eloop_variables\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecommon_mistakes\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAvailable guide sections: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efull\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efirst_steps\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eanalysis\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003estructure\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eseo\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etemplates\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etokens\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eforms\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eassets\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003echecklist\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecommon_mistakes\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eProject Resolution\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eEvery project-scoped command (schema, items, deploy, status, etc.) needs a project. Resolution order:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. \u003cstrong style=\"color:#e5e7eb\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p\u003c/code\u003e / \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--project\u003c/code\u003e flag\u003c/strong\u003e β€” explicit on the command: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p \"My Project\"\u003c/code\u003e or \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p abc123-uuid\u003c/code\u003e\n2. \u003cstrong style=\"color:#e5e7eb\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eFASTMODE_PROJECT\u003c/code\u003e environment variable\u003c/strong\u003e β€” set in shell: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eexport FASTMODE_PROJECT=\"My Project\"\u003c/code\u003e\n3. \u003cstrong style=\"color:#e5e7eb\"\u003eDefault project\u003c/strong\u003e β€” saved by \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode use \"My Project\"\u003c/code\u003e in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e~/.fastmode/config.json\u003c/code\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eIf none is set, the command prints an error and exits with code 1:\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003eError: No project specified.\nUse -p \u003cid-or-name\u003e, set FASTMODE_PROJECT env var, or run: fastmode use \u003cproject\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eProject identifiers can be:\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eUUID\u003c/strong\u003e β€” used directly (e.g. \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e550e8400-e29b-41d4-a716-446655440000\u003c/code\u003e)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProject name\u003c/strong\u003e β€” resolved via API (exact match first, then partial match, case-insensitive)\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eSchema \u0026 Field Types\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCreating a Schema\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eWrite a \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eschema.json\u003c/code\u003e file and sync it:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode schema sync -f schema.json\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eschema.json Format\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{\n \"collections\": [\n {\n \"slug\": \"posts\",\n \"name\": \"Blog Posts\",\n \"nameSingular\": \"Blog Post\",\n \"fields\": [\n { \"slug\": \"title\", \"name\": \"Title\", \"type\": \"text\", \"isRequired\": true },\n { \"slug\": \"excerpt\", \"name\": \"Excerpt\", \"type\": \"textarea\" },\n { \"slug\": \"body\", \"name\": \"Body\", \"type\": \"richText\" },\n { \"slug\": \"featured-image\", \"name\": \"Featured Image\", \"type\": \"image\" },\n { \"slug\": \"category\", \"name\": \"Category\", \"type\": \"select\", \"options\": \"News, Tutorial, Update\" },\n { \"slug\": \"tags\", \"name\": \"Tags\", \"type\": \"multiSelect\", \"options\": \"JavaScript, Python, DevOps, AI\" },\n { \"slug\": \"featured\", \"name\": \"Featured\", \"type\": \"boolean\" },\n { \"slug\": \"author\", \"name\": \"Author\", \"type\": \"relation\", \"referenceCollection\": \"team\" }\n ]\n },\n {\n \"slug\": \"team\",\n \"name\": \"Team Members\",\n \"nameSingular\": \"Team Member\",\n \"fields\": [\n { \"slug\": \"role\", \"name\": \"Role\", \"type\": \"text\" },\n { \"slug\": \"bio\", \"name\": \"Bio\", \"type\": \"richText\" },\n { \"slug\": \"photo\", \"name\": \"Photo\", \"type\": \"image\" },\n { \"slug\": \"email\", \"name\": \"Email\", \"type\": \"email\" }\n ]\n }\n ]\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eTo add fields to existing collections, use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efieldsToAdd\u003c/code\u003e:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{\n \"fieldsToAdd\": [\n {\n \"collectionSlug\": \"posts\",\n \"fields\": [\n { \"slug\": \"reading-time\", \"name\": \"Reading Time\", \"type\": \"number\" }\n ]\n }\n ]\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eYou can combine \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecollections\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efieldsToAdd\u003c/code\u003e in the same file. Duplicate collections and fields are automatically skipped.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eAvailable Field Types\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Type | Description | Template Usage | Notes |\n|------|-------------|----------------|-------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etext\u003c/code\u003e | Single-line text | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Titles, names, short strings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etextarea\u003c/code\u003e | Multi-line plain text | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Descriptions, excerpts |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003erichText\u003c/code\u003e | Formatted HTML content | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{field}}}\u003c/code\u003e | \u003cstrong style=\"color:#e5e7eb\"\u003eMUST use triple braces\u003c/strong\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003enumber\u003c/code\u003e | Numeric value | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Prices, counts, order |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eboolean\u003c/code\u003e | True/false toggle | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if field}}\u003c/code\u003e | Toggles, flags |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edate\u003c/code\u003e | Date only | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Birth dates, event dates |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edatetime\u003c/code\u003e | Date and time | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Timestamps |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eimage\u003c/code\u003e | Image file/URL | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Renders as URL |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efile\u003c/code\u003e | Downloadable file (max 10MB) | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Link as \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ca href=\"{{field}}\" download\u003e\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eurl\u003c/code\u003e | Web link | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | External URLs |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003evideoEmbed\u003c/code\u003e | YouTube/Vimeo/Wistia/Loom | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Embed URL |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eemail\u003c/code\u003e | Email with validation | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Validated email addresses |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eselect\u003c/code\u003e | Single dropdown | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Requires \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"options\": \"A, B, C\"\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emultiSelect\u003c/code\u003e | Multiple selections | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e | Requires \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"options\": \"A, B, C\"\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003erelation\u003c/code\u003e | Link to another collection | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field.name}}\u003c/code\u003e | Requires \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"referenceCollection\": \"slug\"\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eRelation Fields β€” CRITICAL\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eRelation fields link items between collections (e.g. a post has an author from the team collection). When creating or updating items with relation fields:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eYou MUST use the item's UUID\u003c/strong\u003e, not its name or slug\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items relations \u003ccollection\u003e\u003c/code\u003e to get the available IDs\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eExample: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items relations posts --field author\u003c/code\u003e shows team member IDs\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# First, find the author's item ID\nfastmode items relations posts --field author\n\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eOutput shows: ID: 550e8400-..., Name: Jane Doe, Slug: jane-doe\u003c/h2\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eThen use that ID when creating a post\u003c/h2\u003e\nfastmode items create posts -n \"My Post\" -d '{\"title\": \"My Post\", \"author\": \"550e8400-e29b-41d4-a716-446655440000\"}'\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWRONG:\u003c/strong\u003e \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"author\": \"Jane Doe\"\u003c/code\u003e β€” this will NOT work.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCORRECT:\u003c/strong\u003e \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"author\": \"550e8400-e29b-41d4-a716-446655440000\"\u003c/code\u003e β€” use the UUID.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eContent Items\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCreating Items\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode items create \u003ccollection\u003e -n \"Item Name\" -d '{\"field\": \"value\"}'\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Flag | Description |\n|------|-------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-n, --name \u003cname\u003e\u003c/code\u003e | \u003cstrong style=\"color:#e5e7eb\"\u003eRequired.\u003c/strong\u003e Item name/title. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-s, --slug \u003cslug\u003e\u003c/code\u003e | URL slug. Auto-generated from name if omitted. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d, --data \u003cjson\u003e\u003c/code\u003e | Field data as JSON string. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f, --file \u003cpath\u003e\u003c/code\u003e | Read field data from a JSON file (takes precedence over \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e). |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p, --project \u003cid\u003e\u003c/code\u003e | Project ID or name. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--draft\u003c/code\u003e | Create as unpublished draft. |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eData rules:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e value must be valid JSON. Keys are field slugs.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f\u003c/code\u003e reads from a JSON file. If both \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e are given, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f\u003c/code\u003e wins.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eIf neither \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e nor \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f\u003c/code\u003e is given, the item is created with just the name (no field data).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRich text fields accept raw HTML: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"body\": \"\u003ch2\u003eTitle\u003c/h2\u003e\u003cp\u003eContent here.\u003c/p\u003e\"\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRelation fields require UUIDs (see above).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eWithout \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--draft\u003c/code\u003e, items are published immediately (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublishedAt\u003c/code\u003e set to now).\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eUpdating Items\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode items update \u003ccollection\u003e \u003cslug\u003e -d '{\"field\": \"new value\"}'\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Flag | Description |\n|------|-------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-n, --name \u003cname\u003e\u003c/code\u003e | New name/title. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d, --data \u003cjson\u003e\u003c/code\u003e | Updated fields as JSON. Only provided fields change β€” others are preserved. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f, --file \u003cpath\u003e\u003c/code\u003e | Read updated data from a JSON file. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p, --project \u003cid\u003e\u003c/code\u003e | Project ID or name. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--publish\u003c/code\u003e | Set \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublishedAt\u003c/code\u003e to now (make item live). |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--unpublish\u003c/code\u003e | Set \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublishedAt\u003c/code\u003e to null (revert to draft). |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eUpdate is a partial merge.\u003c/strong\u003e Only the fields you provide in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e are changed. All other fields remain as they are.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDeleting Items\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode items delete \u003ccollection\u003e \u003cslug\u003e --confirm\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--confirm\u003c/code\u003e flag is \u003cstrong style=\"color:#e5e7eb\"\u003erequired\u003c/strong\u003e. Without it, the command refuses to run and exits with code 1. This is a safety measure β€” deletion is permanent and cannot be undone.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAlways ask the user for confirmation before deleting.\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDraft / Publish Mechanics\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Action | Command |\n|--------|---------|\n| Create as published (default) | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items create posts -n \"Title\" -d '{...}'\u003c/code\u003e |\n| Create as draft | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items create posts -n \"Title\" -d '{...}' --draft\u003c/code\u003e |\n| Publish a draft | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items update posts my-slug --publish\u003c/code\u003e |\n| Unpublish (revert to draft) | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items update posts my-slug --unpublish\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eDraft items have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublishedAt: null\u003c/code\u003e and are not visible on the live site.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003ePublished items have a \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublishedAt\u003c/code\u003e timestamp and appear on the live site.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eWithout \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--draft\u003c/code\u003e, new items are published immediately.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eClient Portal Management\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe client portal lets you give external clients (your customers, collaborators) limited access to manage content on your FastMode site. Clients get their own login, separate from your admin account, with configurable permissions.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eHow It Works\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. \u003cstrong style=\"color:#e5e7eb\"\u003eYou invite a client\u003c/strong\u003e by email β€” they receive a unique invite link\n2. \u003cstrong style=\"color:#e5e7eb\"\u003eClient clicks the link\u003c/strong\u003e β€” creates a password and gets portal access\n3. \u003cstrong style=\"color:#e5e7eb\"\u003eClient manages content\u003c/strong\u003e β€” based on the permissions you assigned\n4. \u003cstrong style=\"color:#e5e7eb\"\u003eYou control access\u003c/strong\u003e β€” update permissions or revoke access at any time\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe portal is \u003cstrong style=\"color:#e5e7eb\"\u003eauto-enabled\u003c/strong\u003e on the project when you send the first invitation. No manual setup needed.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eAvailable Permissions\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Permission | Description |\n|------------|-------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecms.read\u003c/code\u003e | View collection items |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecms.write\u003c/code\u003e | Create, edit, archive, and delete items |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eeditor\u003c/code\u003e | Access the visual editor |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eforms.read\u003c/code\u003e | View form submissions |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edns\u003c/code\u003e | Manage DNS settings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eapi\u003c/code\u003e | Access API and integrations |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003enotifications\u003c/code\u003e | Manage notification rules |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ebilling\u003c/code\u003e | View plans and manage billing |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eDefault permissions\u003c/strong\u003e (used when none specified): \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecms.read\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecms.write\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eeditor\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eforms.read\u003c/code\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eInviting Clients\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# Invite with default permissions\nfastmode clients invite client@example.com\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eInvite with a name\u003c/h2\u003e\nfastmode clients invite client@example.com -n \"Jane Smith\"\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eInvite with specific permissions\u003c/h2\u003e\nfastmode clients invite client@example.com -n \"Jane Smith\" --permissions cms.read,forms.read\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eInvite with all permissions\u003c/h2\u003e\nfastmode clients invite client@example.com --permissions cms.read,cms.write,editor,forms.read,dns,api,notifications,billing\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe command returns an \u003cstrong style=\"color:#e5e7eb\"\u003einvite URL\u003c/strong\u003e β€” share this with the client. The link expires in 7 days.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eImportant:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eEach email can only be invited once per project\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eIf a client already has access, the invite will fail\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eIf a pending invitation already exists for the email, the invite will fail\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eListing Clients and Invitations\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# See who has portal access\nfastmode clients list\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eSee pending (unaccepted) invitations\u003c/h2\u003e\nfastmode clients invitations\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eclients list\u003c/code\u003e shows the \u003cstrong style=\"color:#e5e7eb\"\u003eaccess ID\u003c/strong\u003e for each client β€” you need this ID to update permissions or revoke access.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eUpdating Permissions\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# First, get the access ID from the list\nfastmode clients list\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003eUpdate permissions (replaces ALL existing permissions)\u003c/h2\u003e\nfastmode clients update-permissions \u003caccessId\u003e --permissions cms.read,cms.write,editor\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003ePermissions are replaced entirely\u003c/strong\u003e β€” if a client had \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecms.read,cms.write,editor,forms.read\u003c/code\u003e and you set \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--permissions cms.read\u003c/code\u003e, they will ONLY have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecms.read\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eRevoking Access\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# Revoke a client's portal access (requires --confirm)\nfastmode clients revoke \u003caccessId\u003e --confirm\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--confirm\u003c/code\u003e flag is \u003cstrong style=\"color:#e5e7eb\"\u003erequired\u003c/strong\u003e. Without it, the command refuses to run.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAlways ask the user for confirmation before revoking access.\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eRevoking access is a soft delete β€” the client's account still exists but they cannot access this project's portal. Their active sessions are terminated immediately.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCanceling Invitations\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# Cancel a pending invitation (requires --confirm)\nfastmode clients cancel-invite \u003cinvitationId\u003e --confirm\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe invitation link will no longer work. Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode clients invitations\u003c/code\u003e to get the invitation ID.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eTypical Workflow\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# 1. Invite your client\nfastmode clients invite designer@agency.com -n \"Design Agency\" --permissions cms.read,cms.write,editor\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e2. Share the invite URL from the output with the client\u003c/h2\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e3. Later, check who has access\u003c/h2\u003e\nfastmode clients list\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e4. Restrict a client to read-only\u003c/h2\u003e\nfastmode clients update-permissions abc12345 --permissions cms.read\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e5. Remove a client who no longer needs access\u003c/h2\u003e\nfastmode clients revoke abc12345 --confirm\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003ePackage Structure\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe deployment package is a \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e.zip\u003c/code\u003e file with this exact structure:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003esite.zip\nβ”œβ”€β”€ manifest.json # REQUIRED β€” defines pages and CMS templates\nβ”œβ”€β”€ pages/ # Static HTML pages\nβ”‚ β”œβ”€β”€ index.html # Homepage (REQUIRED β€” must have path \"/\")\nβ”‚ β”œβ”€β”€ about.html\nβ”‚ └── contact.html\nβ”œβ”€β”€ templates/ # CMS-powered templates (if using collections)\nβ”‚ β”œβ”€β”€ posts_index.html # Blog listing page\nβ”‚ β”œβ”€β”€ posts_detail.html # Single blog post page\nβ”‚ └── team_index.html # Team listing page\n└── public/ # ALL static assets (CSS, JS, images, fonts)\n β”œβ”€β”€ css/\n β”‚ └── style.css\n β”œβ”€β”€ js/\n β”‚ └── main.js\n └── images/\n β”œβ”€β”€ logo.png\n └── favicon.ico\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eStrict Rules\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. \u003cstrong style=\"color:#e5e7eb\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest.json\u003c/code\u003e MUST be at the root of the zip.\u003c/strong\u003e\n2. \u003cstrong style=\"color:#e5e7eb\"\u003eStatic pages go in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epages/\u003c/code\u003e.\u003c/strong\u003e One HTML file per page.\n3. \u003cstrong style=\"color:#e5e7eb\"\u003eCMS templates go in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etemplates/\u003c/code\u003e.\u003c/strong\u003e Convention: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{collection}_index.html\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{collection}_detail.html\u003c/code\u003e.\n4. \u003cstrong style=\"color:#e5e7eb\"\u003eALL static assets go in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublic/\u003c/code\u003e.\u003c/strong\u003e CSS, JavaScript, images, fonts β€” everything.\n5. \u003cstrong style=\"color:#e5e7eb\"\u003eReference assets with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e prefix in HTML.\u003c/strong\u003e Example: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003clink href=\"/public/css/style.css\" rel=\"stylesheet\"\u003e\u003c/code\u003e.\n6. \u003cstrong style=\"color:#e5e7eb\"\u003eA homepage is required.\u003c/strong\u003e One page must have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"path\": \"/\"\u003c/code\u003e in the manifest.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCritical: Asset Paths\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWRONG β€” will 404:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003clink href=\"/assets/css/style.css\" rel=\"stylesheet\"\u003e\n\u003clink href=\"/css/style.css\" rel=\"stylesheet\"\u003e\n\u003clink href=\"../css/style.css\" rel=\"stylesheet\"\u003e\n\u003cscript src=\"js/main.js\"\u003e\u003c/script\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCORRECT:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003clink href=\"/public/css/style.css\" rel=\"stylesheet\"\u003e\n\u003cscript src=\"/public/js/main.js\"\u003e\u003c/script\u003e\n\u003cimg src=\"/public/images/logo.png\" alt=\"Logo\"\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThis also applies \u003cstrong style=\"color:#e5e7eb\"\u003einside CSS files\u003c/strong\u003e β€” background images AND fonts:\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e/* WRONG */\nbackground-image: url('../images/bg.jpg');\nbackground-image: url('images/bg.jpg');\nsrc: url('../fonts/custom.woff2');\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e/* CORRECT */\nbackground-image: url('/public/images/bg.jpg');\nsrc: url('/public/fonts/custom.woff2');\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAsset path conversion table:\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Original Path | Converted Path |\n|---------------|----------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecss/style.css\u003c/code\u003e | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/css/style.css\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e../css/style.css\u003c/code\u003e | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/css/style.css\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e./images/logo.png\u003c/code\u003e | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/images/logo.png\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/images/logo.png\u003c/code\u003e | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/images/logo.png\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e../fonts/custom.woff\u003c/code\u003e | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/fonts/custom.woff\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eExternal URLs (Google Fonts, CDNs, etc.) stay unchanged.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eManifest Format\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest.json\u003c/code\u003e file defines the site structure. It uses a FLAT format for CMS templates (not nested).\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eBasic Example (Static Only)\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{\n \"pages\": [\n { \"path\": \"/\", \"file\": \"pages/index.html\", \"title\": \"Home\" },\n { \"path\": \"/about\", \"file\": \"pages/about.html\", \"title\": \"About\" },\n { \"path\": \"/contact\", \"file\": \"pages/contact.html\", \"title\": \"Contact\" }\n ]\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eWith CMS Collections\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{\n \"pages\": [\n { \"path\": \"/\", \"file\": \"pages/index.html\", \"title\": \"Home\" },\n { \"path\": \"/about\", \"file\": \"pages/about.html\", \"title\": \"About\" }\n ],\n \"cmsTemplates\": {\n \"postsIndex\": \"templates/posts_index.html\",\n \"postsIndexPath\": \"/blog\",\n \"postsDetail\": \"templates/posts_detail.html\",\n \"postsDetailPath\": \"/blog\",\n \"teamIndex\": \"templates/team_index.html\",\n \"teamIndexPath\": \"/team\"\n }\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCMS Template Keys β€” FLAT Format\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eEach collection needs 2-4 keys in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecmsTemplates\u003c/code\u003e. The format is \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{collectionSlug}Index\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{collectionSlug}IndexPath\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{collectionSlug}Detail\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{collectionSlug}DetailPath\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Key | Required | Description |\n|-----|----------|-------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}Index\u003c/code\u003e | Yes | Path to the collection listing template file |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}IndexPath\u003c/code\u003e | Yes | URL path for the listing page (e.g. \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/blog\u003c/code\u003e) |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}Detail\u003c/code\u003e | No | Path to the single item template file |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}DetailPath\u003c/code\u003e | No | URL path prefix for item pages (e.g. \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/blog\u003c/code\u003e β†’ \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/blog/item-slug\u003c/code\u003e) |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eExample for a \"services\" collection:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\"cmsTemplates\": {\n \"servicesIndex\": \"templates/services_index.html\",\n \"servicesIndexPath\": \"/services\",\n \"servicesDetail\": \"templates/services_detail.html\",\n \"servicesDetailPath\": \"/services\"\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCommon Manifest Mistakes β€” AI Agents Frequently Get This Wrong\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAI agents frequently use a nested object format or \"collections\" key that FastMode does NOT support.\u003c/strong\u003e Read carefully.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWRONG β€” using \"collections\" key (MOST COMMON AI MISTAKE):\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{\n \"collections\": {\n \"posts\": {\n \"indexPath\": \"/blog\",\n \"indexFile\": \"collections/posts/index.html\",\n \"detailPath\": \"/blog/:slug\",\n \"detailFile\": \"collections/posts/detail.html\"\n }\n }\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWRONG β€” nested objects inside cmsTemplates:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\"cmsTemplates\": {\n \"posts\": {\n \"indexPath\": \"/blog\",\n \"detailPath\": \"/blog\"\n }\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWRONG β€” singular slug names:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\"postIndex\": \"...\" // Should be \"postsIndex\"\n\"postDetail\": \"...\" // Should be \"postsDetail\"\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCORRECT β€” flat keys using \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecmsTemplates\u003c/code\u003e, matching the collection slug exactly:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\"cmsTemplates\": {\n \"postsIndex\": \"templates/posts_index.html\",\n \"postsIndexPath\": \"/blog\",\n \"postsDetail\": \"templates/posts_detail.html\",\n \"postsDetailPath\": \"/blog\"\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eKey rules:\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecmsTemplates\u003c/code\u003e, \u003cstrong style=\"color:#e5e7eb\"\u003eNOT\u003c/strong\u003e \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecollections\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse \u003cstrong style=\"color:#e5e7eb\"\u003eFLAT\u003c/strong\u003e keys: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}Index\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}Detail\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}IndexPath\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{slug}DetailPath\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eDo \u003cstrong style=\"color:#e5e7eb\"\u003eNOT\u003c/strong\u003e nest objects inside collection names\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode validate manifest manifest.json\u003c/code\u003e to catch these errors before deploying\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eOptional: Head/Body Injection\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{\n \"pages\": [...],\n \"cmsTemplates\": {...},\n \"defaultHeadHtml\": \"\u003clink rel=\\\"stylesheet\\\" href=\\\"/public/css/global.css\\\"\u003e\",\n \"defaultBodyEndHtml\": \"\u003cscript src=\\\"/public/js/analytics.js\\\"\u003e\u003c/script\u003e\"\n}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eTemplate Syntax\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eFastMode templates use Handlebars-style tokens. There are three types of templates:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eStatic pages\u003c/strong\u003e (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epages/\u003c/code\u003e): Fixed HTML with optional \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-edit-key\u003c/code\u003e attributes for inline CMS editing and optional \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e loops for dynamic content.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eIndex templates\u003c/strong\u003e (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etemplates/\u003c/code\u003e): Collection listing pages. \u003cstrong style=\"color:#e5e7eb\"\u003eMUST\u003c/strong\u003e contain at least one \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each collectionSlug}}\u003c/code\u003e loop.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eDetail templates\u003c/strong\u003e (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etemplates/\u003c/code\u003e): Single item pages. \u003cstrong style=\"color:#e5e7eb\"\u003eMUST\u003c/strong\u003e contain CMS tokens like \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{name}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{body}}}\u003c/code\u003e, etc.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eSEO Tags β€” Do NOT Include\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eFastMode automatically manages all SEO meta tags. Including them in your HTML will cause duplicate tags (bad for SEO ranking). \u003cstrong style=\"color:#e5e7eb\"\u003eRemove ALL of these from your templates:\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Tag | Why to Remove |\n|-----|---------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ctitle\u003e...\u003c/title\u003e\u003c/code\u003e | Managed via CMS Settings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta name=\"description\"\u003e\u003c/code\u003e | Managed via CMS Settings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta name=\"keywords\"\u003e\u003c/code\u003e | Managed via CMS Settings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta property=\"og:*\"\u003e\u003c/code\u003e | Open Graph auto-generated |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta name=\"twitter:*\"\u003e\u003c/code\u003e | Twitter cards auto-generated |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003clink rel=\"icon\"\u003e\u003c/code\u003e | Favicon managed in settings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003clink rel=\"shortcut icon\"\u003e\u003c/code\u003e | Favicon managed in settings |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003clink rel=\"apple-touch-icon\"\u003e\u003c/code\u003e | Managed by FastMode |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta name=\"google-site-verification\"\u003e\u003c/code\u003e | Managed in settings |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCorrect \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003chead\u003e\u003c/code\u003e structure:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003chead\u003e\n \u003cmeta charset=\"UTF-8\"\u003e\n \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n \u003c!-- SEO managed by Fast Mode β€” do not add title, description, or OG tags --\u003e\n \u003clink rel=\"stylesheet\" href=\"/public/css/style.css\"\u003e\n \u003c!-- External fonts, scripts, etc. are fine --\u003e\n \u003clink href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;600\u0026display=swap\" rel=\"stylesheet\"\u003e\n\u003c/head\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eBuilt-in Fields (Every Item Has These)\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Token | Description | Example |\n|-------|-------------|---------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{name}}\u003c/code\u003e | Item name/title | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ch1\u003e{{name}}\u003c/h1\u003e\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{slug}}\u003c/code\u003e | URL slug | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ca href=\"/posts/{{slug}}\"\u003e\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{url}}\u003c/code\u003e | Full URL to detail page | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ca href=\"{{url}}\"\u003eRead more\u003c/a\u003e\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{publishedAt}}\u003c/code\u003e | Publish date | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ctime\u003e{{publishedAt}}\u003c/time\u003e\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{createdAt}}\u003c/code\u003e | Creation date | |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{updatedAt}}\u003c/code\u003e | Last modified date | |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eRegular Fields β€” Double Braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{field}}\u003c/code\u003e\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eUsed for text, number, date, image, url, email, select, boolean fields:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003ch1\u003e{{name}}\u003c/h1\u003e\n\u003cp\u003e{{excerpt}}\u003c/p\u003e\n\u003cimg src=\"{{featured-image}}\" alt=\"{{name}}\"\u003e\n\u003cspan\u003eCategory: {{category}}\u003c/span\u003e\n\u003ca href=\"{{website-url}}\"\u003eVisit\u003c/a\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eRich Text Fields β€” Triple Braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{field}}}\u003c/code\u003e\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCRITICAL:\u003c/strong\u003e Rich text fields contain HTML. You \u003cstrong style=\"color:#e5e7eb\"\u003eMUST\u003c/strong\u003e use triple braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{ }}}\u003c/code\u003e so the HTML renders correctly. Double braces will escape the HTML and display raw tags as text.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- CORRECT β€” HTML renders properly --\u003e\n\u003cdiv class=\"content\"\u003e{{{body}}}\u003c/div\u003e\n\u003cdiv class=\"bio\"\u003e{{{bio}}}\u003c/div\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- WRONG β€” HTML appears as escaped text like \u0026lt;p\u0026gt;Hello\u0026lt;/p\u0026gt; --\u003e\n\u003cdiv class=\"content\"\u003e{{body}}\u003c/div\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eLoops β€” \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each collection}}\u003c/code\u003e\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eUsed in index templates and static pages to iterate over collection items.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eBasic loop:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#each posts}}\n \u003carticle\u003e\n \u003ch2\u003e\u003ca href=\"{{url}}\"\u003e{{name}}\u003c/a\u003e\u003c/h2\u003e\n \u003cp\u003e{{excerpt}}\u003c/p\u003e\n \u003c/article\u003e\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eLoop modifiers:\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Modifier | Description | Example |\n|----------|-------------|---------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003elimit=N\u003c/code\u003e | Maximum items | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each posts limit=6}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003esort=\"field\"\u003c/code\u003e | Sort by field | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each posts sort=\"publishedAt\"}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eorder=\"asc\\|desc\"\u003c/code\u003e | Sort direction | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each posts sort=\"name\" order=\"asc\"}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efeatured=true\u003c/code\u003e | Only featured items | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each posts featured=true limit=3}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ewhere=\"field.slug:{{slug}}\"\u003c/code\u003e | Filter by relation | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each posts where=\"author.slug:{{slug}}\"}}\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCombined modifiers:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- Latest 3 featured posts, newest first --\u003e\n{{#each posts featured=true limit=3 sort=\"publishedAt\" order=\"desc\"}}\n \u003carticle\u003e{{name}}\u003c/article\u003e\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eLoop Variables\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAvailable only inside \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e blocks:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Variable | Description | Example |\n|----------|-------------|---------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{@index}}\u003c/code\u003e | Zero-based index (0, 1, 2...) | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eItem {{@index}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{@first}}\u003c/code\u003e | True for the first item | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if @first}}hero{{/if}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{@last}}\u003c/code\u003e | True for the last item | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#unless @last}},{{/unless}}\u003c/code\u003e |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{@length}}\u003c/code\u003e | Total number of items | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eShowing {{@length}} items\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eDo NOT use loop variables outside \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e blocks\u003c/strong\u003e β€” they will produce warnings and undefined values.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#each posts}}\n {{#if @first}}\n \u003cdiv class=\"hero\"\u003e\n \u003ch1\u003e{{name}}\u003c/h1\u003e\n \u003c/div\u003e\n {{else}}\n \u003cdiv class=\"card\"\u003e\n \u003ch3\u003e{{name}}\u003c/h3\u003e\n \u003c/div\u003e\n {{/if}}\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eConditionals β€” \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#unless}}\u003c/code\u003e\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- Show if field has a value --\u003e\n{{#if image}}\n \u003cimg src=\"{{image}}\" alt=\"{{name}}\"\u003e\n{{/if}}\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- Show if field has a value, with fallback --\u003e\n{{#if thumbnail}}\n \u003cimg src=\"{{thumbnail}}\" alt=\"\"\u003e\n{{else}}\n \u003cdiv class=\"placeholder\"\u003eNo image\u003c/div\u003e\n{{/if}}\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- Show if field is empty/missing --\u003e\n{{#unless posts}}\n \u003cp\u003eNo posts yet.\u003c/p\u003e\n{{/unless}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eEquality \u0026 Comparison Helpers\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- Equal --\u003e\n{{#if (eq status \"published\")}}\n \u003cspan class=\"badge\"\u003ePublished\u003c/span\u003e\n{{/if}}\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- Not equal β€” useful for \"Related Items\" excluding current item --\u003e\n{{#unless (eq slug ../slug)}}\n \u003ca href=\"{{url}}\"\u003e{{name}}\u003c/a\u003e\n{{/unless}}\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- Numeric comparisons --\u003e\n{{#if (lt @index 1)}} \u003c!-- Less than --\u003e\n{{#if (gt @index 0)}} \u003c!-- Greater than --\u003e\n{{#if (lte price 100)}} \u003c!-- Less than or equal --\u003e\n{{#if (gte stock 5)}} \u003c!-- Greater than or equal --\u003e\n{{#if (ne status \"draft\")}} \u003c!-- Not equal --\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eHero + grid layout pattern:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#each posts}}\n {{#if (lt @index 1)}}\n \u003cdiv class=\"hero\"\u003e\u003ch1\u003e{{name}}\u003c/h1\u003e\u003c/div\u003e\n {{else}}\n {{#if (lt @index 4)}}\n \u003cdiv class=\"featured\"\u003e\u003ch3\u003e{{name}}\u003c/h3\u003e\u003c/div\u003e\n {{else}}\n \u003cdiv class=\"list-item\"\u003e{{name}}\u003c/div\u003e\n {{/if}}\n {{/if}}\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eRelation Fields β€” Dot Notation\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAccess fields on related items using dot notation:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#each posts}}\n \u003carticle\u003e\n \u003ch2\u003e{{name}}\u003c/h2\u003e\n {{#if author}}\n \u003cspan class=\"author\"\u003eBy {{author.name}}\u003c/span\u003e\n {{#if author.photo}}\n \u003cimg src=\"{{author.photo}}\" alt=\"{{author.name}}\"\u003e\n {{/if}}\n {{/if}}\n \u003c/article\u003e\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAvailable: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{relation.name}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{relation.slug}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{relation.url}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{relation.anyField}}\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eParent Context β€” \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e../\u003c/code\u003e\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eInside a loop, access the parent scope (the current page's item) with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e../\u003c/code\u003e:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- On an author detail page, show only THIS author's posts --\u003e\n\u003ch1\u003e{{name}}\u003c/h1\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2\u003ePosts by {{name}}\u003c/h2\u003e\n{{#each posts}}\n {{#if (eq author.name ../name)}}\n \u003carticle\u003e\n \u003ch2\u003e\u003ca href=\"{{url}}\"\u003e{{name}}\u003c/a\u003e\u003c/h2\u003e\n \u003c/article\u003e\n {{/if}}\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eNested Loops with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e@root.\u003c/code\u003e\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eWhen nesting loops, use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e@root.\u003c/code\u003e to reference root-level collections:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#each categories}}\n \u003ch3\u003e{{name}}\u003c/h3\u003e\n {{#each @root.posts where=\"category.slug:{{slug}}\"}}\n \u003ca href=\"{{url}}\"\u003e{{name}}\u003c/a\u003e\n {{/each}}\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eInline Editing β€” \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-edit-key\u003c/code\u003e (CRITICAL for Static Pages)\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWithout \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-edit-key\u003c/code\u003e attributes, static pages have NO editable content in the CMS dashboard.\u003c/strong\u003e Every text element that should be editable MUST have one.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- Static pages β€” REQUIRED for editable content --\u003e\n\u003ch1 data-edit-key=\"home-hero-title\"\u003eWelcome to Our Site\u003c/h1\u003e\n\u003cp data-edit-key=\"home-hero-subtitle\"\u003eWe build amazing things.\u003c/p\u003e\n\u003cp data-edit-key=\"home-about-text\"\u003eOur story began in 2020...\u003c/p\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- Hierarchical naming for sections --\u003e\n\u003csection class=\"about\"\u003e\n \u003ch2 data-edit-key=\"about-section-title\"\u003eAbout Us\u003c/h2\u003e\n \u003cp data-edit-key=\"about-section-paragraph-1\"\u003eFirst paragraph...\u003c/p\u003e\n \u003cp data-edit-key=\"about-section-paragraph-2\"\u003eSecond paragraph...\u003c/p\u003e\n\u003c/section\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- CMS templates β€” optional, for hardcoded headers --\u003e\n\u003ch1 data-edit-key=\"blog-page-title\"\u003eOur Blog\u003c/h1\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eNaming convention: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{page}-{section}-{element}\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eExamples: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ehome-hero-title\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eabout-team-heading\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003econtact-form-intro\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eservices-cta-button\u003c/code\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eRules:\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eKeys must be unique across the \u003cstrong style=\"color:#e5e7eb\"\u003eentire site\u003c/strong\u003e (not just the page).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse lowercase with hyphens.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eFor different pages, prefix with the page name.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eStatic pages without edit keys will appear in the CMS but have nothing editable.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eVideo Embeds\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#if video}}\n \u003ciframe\n src=\"{{video}}\"\n allowfullscreen\n referrerpolicy=\"strict-origin-when-cross-origin\"\n title=\"Video\"\n \u003e\u003c/iframe\u003e\n{{/if}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThe \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ereferrerpolicy=\"strict-origin-when-cross-origin\"\u003c/code\u003e attribute is \u003cstrong style=\"color:#e5e7eb\"\u003erequired\u003c/strong\u003e for YouTube embeds β€” without it, videos may show Error 150/153.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eImages β€” Static vs CMS Content\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThere are two types of images and they are handled differently:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003e1. Static/UI images\u003c/strong\u003e β€” logos, icons, decorative backgrounds bundled with the site:\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- KEEP these as static /public/ paths --\u003e\n\u003cimg src=\"/public/images/logo.png\" alt=\"Company Logo\"\u003e\n\u003cimg src=\"/public/images/icons/arrow.svg\" alt=\"\"\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003e2. CMS content images\u003c/strong\u003e β€” post images, team photos, product images managed through the CMS:\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- USE CMS tokens β€” NEVER hardcode content image URLs --\u003e\n{{#if image}}\n \u003cimg src=\"{{image}}\" alt=\"{{name}}\"\u003e\n{{/if}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eRule of thumb:\u003c/strong\u003e If it's site branding/design β†’ keep static. If it's content that changes per item β†’ use CMS tokens.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAlways wrap CMS images in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if}}\u003c/code\u003e\u003c/strong\u003e β€” not every item may have an image:\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e{{#if image}}\n \u003cimg src=\"{{image}}\" alt=\"{{name}}\"\u003e\n{{else}}\n \u003cdiv class=\"placeholder-image\"\u003e\u003c/div\u003e\n{{/if}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCommon mistake β€” mixing static and CMS images:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003c!-- WRONG: hardcoded image inside a CMS loop --\u003e\n{{#each products}}\n \u003cimg src=\"/images/product-placeholder.jpg\" alt=\"Product\"\u003e \u003c!-- BAD --\u003e\n \u003ch2\u003e{{name}}\u003c/h2\u003e\n{{/each}}\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003c!-- CORRECT: all content comes from CMS --\u003e\n{{#each products}}\n {{#if image}}\n \u003cimg src=\"{{image}}\" alt=\"{{name}}\"\u003e\n {{/if}}\n \u003ch2\u003e{{name}}\u003c/h2\u003e\n{{/each}}\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eForms\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e\u003cform data-form-name=\"contact\" action=\"/_forms/contact\" method=\"POST\"\u003e\n \u003cinput type=\"text\" name=\"name\" placeholder=\"Your name\" required\u003e\n \u003cinput type=\"email\" name=\"email\" placeholder=\"Your email\" required\u003e\n \u003ctextarea name=\"message\" placeholder=\"Your message\" required\u003e\u003c/textarea\u003e\n \u003cbutton type=\"submit\"\u003eSend Message\u003c/button\u003e\n\u003c/form\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eRules:\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-form-name\u003c/code\u003e attribute is required.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eaction\u003c/code\u003e must point to \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/_forms/{formName}\u003c/code\u003e.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll inputs must have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ename\u003c/code\u003e attributes.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eA submit button is required.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eCRITICAL: Remove Original Form Handlers\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eIf the source site has JavaScript that handles form submissions, you \u003cstrong style=\"color:#e5e7eb\"\u003eMUST\u003c/strong\u003e remove or replace it. Original site JS often does \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ee.preventDefault()\u003c/code\u003e and shows a \"fake\" success toast β€” the data goes nowhere.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e// PROBLEM: This blocks real submissions!\nform.addEventListener('submit', (e) =\u003e {\n e.preventDefault();\n showToast('Message sent!'); // FAKE! Data not saved!\n});\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eOption A (simplest):\u003c/strong\u003e Remove the original JavaScript form handler entirely. The native \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cform action=\"/_forms/contact\" method=\"POST\"\u003e\u003c/code\u003e will submit correctly.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eOption B (keep JS UX):\u003c/strong\u003e Replace the handler with one that actually POSTs to FastMode:\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003eform.addEventListener('submit', async (e) =\u003e {\n e.preventDefault();\n const formName = form.dataset.formName;\n const response = await fetch('/_forms/' + formName, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(Object.fromEntries(new FormData(form)))\n });\n if (response.ok) {\n form.reset();\n alert('Message sent!'); // NOW it's real!\n }\n});\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eDeployment \u0026 Build Status\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eHow Deployment Works\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e1. \u003cstrong style=\"color:#e5e7eb\"\u003eUpload:\u003c/strong\u003e \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode deploy site.zip\u003c/code\u003e reads the zip, validates it, and uploads it to the server.\n2. \u003cstrong style=\"color:#e5e7eb\"\u003eBuild:\u003c/strong\u003e The server processes the package (renders templates, publishes pages). This happens asynchronously.\n3. \u003cstrong style=\"color:#e5e7eb\"\u003eWait:\u003c/strong\u003e By default, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edeploy\u003c/code\u003e polls for build status every 3 seconds until the build completes or times out (default 2 minutes).\n4. \u003cstrong style=\"color:#e5e7eb\"\u003eResult:\u003c/strong\u003e Success message with page count and version, or failure message with error details.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDeploy Flags\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Flag | Description |\n|------|-------------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--force\u003c/code\u003e | Skip the GitHub connection check. Use if the project has GitHub connected but you want to deploy via CLI anyway. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--no-wait\u003c/code\u003e | Upload only β€” don't wait for the build to finish. Useful for fire-and-forget. |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--timeout \u003cms\u003e\u003c/code\u003e | Custom build timeout in milliseconds. Default: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e120000\u003c/code\u003e (2 minutes). |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eChecking Build Status\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAfter every deploy or content change, check the build status:\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode status\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eIf the build failed, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003estatus\u003c/code\u003e shows:\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eThe error message\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eBuild logs\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eWhat went wrong\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAlways run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode status\u003c/code\u003e after deploying to verify the build succeeded.\u003c/strong\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eIf a build fails:\n1. Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode status\u003c/code\u003e to see the error\n2. Fix the issue (template errors, invalid tokens, missing files, etc.)\n3. Re-deploy with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode deploy site.zip\u003c/code\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDeploy History\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode deploys # Show last 10 deployments\nfastmode deploys --limit 5 # Show last 5\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eShows status, version, duration, source, and errors for each deployment.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eExit Codes\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edeploy\u003c/code\u003e: Exits 1 if the build fails (when waiting).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003estatus\u003c/code\u003e: Exits 1 if the latest deploy shows \"Failed\".\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eBoth: Exit 1 if no project is specified.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eValidation\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAlways validate before deploying. Validation catches errors that would cause build failures.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eValidation Workflow\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003e# 1. Validate the manifest\nfastmode validate manifest manifest.json\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e2. Validate each template\u003c/h2\u003e\nfastmode validate template pages/index.html -t static_page\nfastmode validate template templates/posts_index.html -t custom_index -c posts\nfastmode validate template templates/posts_detail.html -t custom_detail -c posts\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch2 style=\"color:#f3f4f6;margin:20px 0 10px;font-size:1.15em\"\u003e3. Validate the complete package\u003c/h2\u003e\nfastmode validate package site.zip\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eWhat Gets Checked\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eManifest validation:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eValid JSON syntax\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epages\u003c/code\u003e array exists and is not empty\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eHomepage (path \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/\u003c/code\u003e) exists\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll file paths are valid\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecmsTemplates\u003c/code\u003e format is correct (flat keys, not nested)\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eTemplate validation:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eBalanced tags: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e has matching \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{/each}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if}}\u003c/code\u003e has \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{/if}}\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eIndex templates have at least one \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e loop\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eDetail templates have CMS tokens\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRich text fields use triple braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{field}}}\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eLoop variables only used inside loops\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAsset paths use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e prefix\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eForms have required attributes\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eYouTube iframes have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ereferrerpolicy\u003c/code\u003e\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003ePackage validation:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003emanifest.json exists at root\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll referenced files exist in the zip\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAssets are in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublic/\u003c/code\u003e (not \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eassets/\u003c/code\u003e or root)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eTemplates are in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etemplates/\u003c/code\u003e (not \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecollections/\u003c/code\u003e)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll templates pass individual validation\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eValidation with Schema Check\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAdd \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p\u003c/code\u003e to validate tokens against the actual project schema:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode validate template templates/posts_detail.html -t custom_detail -c posts -p \"My Project\"\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eThis reports which tokens reference fields that don't exist in the schema yet, with instructions to create them via \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode schema sync\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eCommon Mistakes \u0026 How to Fix Them\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e1. Assets return 404\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e CSS, JS, or images don't load.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Files are in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/assets/\u003c/code\u003e instead of \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e, or paths don't include \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Move all static files to the \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublic/\u003c/code\u003e folder. Reference them as \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/css/style.css\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e2. Rich text shows as raw HTML\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Content displays \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cp\u003eHello\u003c/p\u003e\u003c/code\u003e as text instead of rendering it.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Using double braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{body}}\u003c/code\u003e on a rich text field.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Use triple braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{body}}}\u003c/code\u003e for all richText fields.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e3. Collection listing page is blank\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Index template shows no items.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Missing \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each collectionSlug}}\u003c/code\u003e loop.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Add a loop: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each posts}}...{{/each}}\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e4. All detail pages look the same\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Every item page shows identical content.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Detail template has no CMS tokens β€” just static HTML.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Use tokens like \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{name}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{body}}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{image}}\u003c/code\u003e in the detail template.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e5. Manifest uses wrong format\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Build fails with manifest errors.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Using nested objects or \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"collections\"\u003c/code\u003e instead of flat \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"cmsTemplates\"\u003c/code\u003e keys.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Use flat format: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"postsIndex\"\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"postsIndexPath\"\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"postsDetail\"\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"postsDetailPath\"\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e6. Relation field is empty after create\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Created an item with a relation field but it's null.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Used the item's name instead of its UUID.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items relations \u003ccollection\u003e --field \u003cfield\u003e\u003c/code\u003e to get the UUID, then use that.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e7. Forms don't submit\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Form appears to submit (shows toast/alert) but no data is received.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Original JavaScript calls \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epreventDefault()\u003c/code\u003e and shows a fake success message.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Remove any form JavaScript that blocks submission. Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-form-name\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eaction=\"/_forms/formName\"\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e8. Static pages can't be edited in CMS\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Pages appear in the CMS but have no editable content.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Missing \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-edit-key\u003c/code\u003e attributes on text elements.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Add \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-edit-key=\"unique-key\"\u003c/code\u003e to every text element that should be editable.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e9. Deploy blocked by GitHub\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edeploy\u003c/code\u003e refuses to upload, says GitHub is connected.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Project has GitHub auto-deploy enabled.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--force\u003c/code\u003e flag: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode deploy site.zip --force\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e10. Build fails after deploy\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Upload succeeds but build fails.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode status\u003c/code\u003e to see the error. Common causes: invalid tokens, missing template files, malformed manifest. Fix the issue and re-deploy.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e11. Template URLs don't match manifest\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Links in templates point to wrong paths.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Template hardcodes \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/posts/\u003c/code\u003e but manifest sets \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"postsIndexPath\": \"/blog\"\u003c/code\u003e.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Make sure hardcoded links in templates match the paths defined in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest.json\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e12. Loop variables undefined\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{@index}}\u003c/code\u003e or \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{@first}}\u003c/code\u003e shows nothing.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Used outside of a \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e block.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Only use loop variables inside \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}...{{/each}}\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e13. Duplicate SEO meta tags\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e SEO tags show up twice in the rendered HTML.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e HTML templates include \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ctitle\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta name=\"description\"\u003e\u003c/code\u003e, or Open Graph tags.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Remove all SEO tags from templates. FastMode manages them automatically via CMS Settings. See the \u003ca href=\"#seo-tags--do-not-include\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003eSEO Tags section\u003c/a\u003e above.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e14. CSS background images and fonts broken\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Background images or custom fonts don't load.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e CSS files use relative paths like \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eurl('../images/bg.jpg')\u003c/code\u003e or \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eurl('../fonts/custom.woff')\u003c/code\u003e.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Update all paths inside CSS files to use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e prefix: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eurl('/public/images/bg.jpg')\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eurl('/public/fonts/custom.woff2')\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003e15. Hardcoded example content instead of CMS tokens\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eProblem:\u003c/strong\u003e Index page shows static placeholder cards instead of real CMS data.\n\u003cstrong style=\"color:#e5e7eb\"\u003eCause:\u003c/strong\u003e Template has hardcoded HTML cards instead of \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e loops with CMS tokens.\n\u003cstrong style=\"color:#e5e7eb\"\u003eFix:\u003c/strong\u003e Replace hardcoded content blocks with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each collection}}...{{/each}}\u003c/code\u003e loops using CMS field tokens.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003ePre-Deployment Checklist\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eRun through this checklist before every deploy:\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eStructure:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003emanifest.json\u003c/code\u003e at package root\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Static pages in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epages/\u003c/code\u003e folder\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] CMS templates in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003etemplates/\u003c/code\u003e folder\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] ALL assets in \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003epublic/\u003c/code\u003e folder (not \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eassets/\u003c/code\u003e)\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eSEO (CRITICAL):\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] NO \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ctitle\u003e\u003c/code\u003e tags in HTML\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] NO \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta name=\"description\"\u003e\u003c/code\u003e tags\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] NO \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cmeta property=\"og:*\"\u003e\u003c/code\u003e tags\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] NO \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003clink rel=\"icon\"\u003e\u003c/code\u003e tags\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eManifest:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Homepage page with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\"path\": \"/\"\u003c/code\u003e exists\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] CMS templates use flat \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecmsTemplates\u003c/code\u003e keys (NOT nested, NOT \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ecollections\u003c/code\u003e)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Paths match original site URLs\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eTemplates:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Index templates have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e loops\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Detail templates have CMS tokens (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{name}}\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{body}}}\u003c/code\u003e, etc.)\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Rich text fields use triple braces \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{{field}}}\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] All \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#each}}\u003c/code\u003e have matching \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{/each}}\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] All \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if}}\u003c/code\u003e have matching \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{/if}}\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Static UI images use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e paths\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Content images use CMS tokens with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e{{#if}}\u003c/code\u003e wrappers\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eStatic Pages:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-edit-key\u003c/code\u003e on every editable text element\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Keys are unique across the entire site\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Forms have \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edata-form-name\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eaction=\"/_forms/{name}\"\u003c/code\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] Original form JavaScript handlers removed or replaced\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAssets:\u003c/strong\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] All HTML asset paths use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e prefix\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] CSS \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003ebackground-image\u003c/code\u003e and font \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eurl()\u003c/code\u003e paths use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e/public/\u003c/code\u003e prefix\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e[ ] External URLs (Google Fonts, CDNs) unchanged\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eValidation:\u003c/strong\u003e\n\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003efastmode validate manifest manifest.json\nfastmode validate template \u003ceach-template\u003e -t \u003ctype\u003e [-c \u003ccollection\u003e]\nfastmode validate package site.zip\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eError Handling \u0026 Exit Codes\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAll commands exit with code \u003cstrong style=\"color:#e5e7eb\"\u003e0\u003c/strong\u003e on success and code \u003cstrong style=\"color:#e5e7eb\"\u003e1\u003c/strong\u003e on failure.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eCommands that exit 1\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Scenario | Commands |\n|----------|----------|\n| No project specified | All project-scoped commands |\n| File not found | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eschema sync\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eitems create -f\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003evalidate *\u003c/code\u003e |\n| Invalid JSON | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eschema sync\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eitems create -d\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eitems update -d\u003c/code\u003e |\n| Validation errors | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003evalidate manifest\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003evalidate template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003evalidate package\u003c/code\u003e |\n| Build failed | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003edeploy\u003c/code\u003e (when waiting), \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003estatus\u003c/code\u003e |\n| Delete without \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--confirm\u003c/code\u003e | \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003eitems delete\u003c/code\u003e |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eError Messages\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003eError: No project specified.\nUse -p \u003cid-or-name\u003e, set FASTMODE_PROJECT env var, or run: fastmode use \u003cproject\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003eError: File not found: schema.json\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003eError: Invalid JSON in --data argument\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\"\u003eError: Deletion requires the --confirm flag. This action cannot be undone.\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eAuthentication Errors\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eMost commands auto-trigger \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode login\u003c/code\u003e if credentials are missing or expired. If authentication fails:\n1. Run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode login\u003c/code\u003e manually\n2. Complete the browser flow\n3. Retry the command\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eFile Locations\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e| Path | Purpose |\n|------|---------|\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e~/.fastmode/credentials.json\u003c/code\u003e | OAuth tokens (auto-created by \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003elogin\u003c/code\u003e) |\n| \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e~/.fastmode/config.json\u003c/code\u003e | Default project setting (created by \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003euse\u003c/code\u003e) |\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eBoth files have restricted permissions (0o600 β€” owner read/write only).\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003eNotes\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll project-scoped commands use your default project (set with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode use\u003c/code\u003e). Override with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p \u003cname-or-id\u003e\u003c/code\u003e.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eItem data (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e) must be valid JSON. For complex data, write a file and use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f data.json\u003c/code\u003e.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRich text fields accept HTML content (e.g. \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cp\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ch2\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cul\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ca\u003e\u003c/code\u003e). Always use triple braces in templates.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRelation fields require item IDs (UUIDs). Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items relations\u003c/code\u003e to find available IDs.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eThe \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--draft\u003c/code\u003e flag creates unpublished items. Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--publish\u003c/code\u003e/\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--unpublish\u003c/code\u003e to change status.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eEvery site gets free hosting, free SSL, and a \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e.fastmode.ai\u003c/code\u003e subdomain. Custom domains can be configured.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAfter deploying or making content changes, always run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode status\u003c/code\u003e to verify the build succeeded.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode examples \u003ctype\u003e\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode guide [section]\u003c/code\u003e for built-in documentation and code snippets.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch3 style=\"color:#e5e7eb;margin:18px 0 8px;font-size:1.05em\"\u003ePackage Provenance\u003c/h3\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003enpm package:\u003c/strong\u003e \u003ca href=\"https://www.npmjs.com/package/fastmode-cli\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003efastmode-cli\u003c/a\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eSource code:\u003c/strong\u003e \u003ca href=\"https://github.com/arihgoldstein/fastmode-mcp\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003egithub.com/arihgoldstein/fastmode-mcp\u003c/a\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eWebsite:\u003c/strong\u003e \u003ca href=\"https://fastmode.ai\" target=\"_blank\" rel=\"noopener\" style=\"color:#6366f1\"\u003efastmode.ai\u003c/a\u003e\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eAuthor:\u003c/strong\u003e Arih Goldstein\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003cstrong style=\"color:#e5e7eb\"\u003eLicense:\u003c/strong\u003e MIT\u003c/li\u003e\n\u003c/p\u003e"])</script><script>self.__next_f.push([1,"20:[\"$\",\"div\",null,{\"className\":\"skill-page\",\"children\":[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"SoftwareApplication\\\",\\\"name\\\":\\\"FastMode CMS - Host, Deploy, Manage Websites for Free\\\",\\\"description\\\":\\\"Build, deploy, and host websites for free with full CMS. Create a live website from scratch, deploy it to the cloud with free hosting, free SSL, and custom d...\\\",\\\"url\\\":\\\"https://bytesagain.com/skill/fastmode\\\",\\\"applicationCategory\\\":\\\"clawhub\\\",\\\"operatingSystem\\\":\\\"Any\\\",\\\"offers\\\":{\\\"@type\\\":\\\"Offer\\\",\\\"price\\\":\\\"0\\\",\\\"priceCurrency\\\":\\\"USD\\\"},\\\"publisher\\\":{\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"BytesAgain\\\",\\\"url\\\":\\\"https://bytesagain.com\\\"}}\"}}],[\"$\",\"div\",null,{\"className\":\"breadcrumb\",\"children\":[[\"$\",\"a\",null,{\"href\":\"/\",\"children\":\"BytesAgain\"}],\" β€Ί \",[\"$\",\"a\",null,{\"href\":\"/skills\",\"children\":\"Skills\"}],\" β€Ί \",\"FastMode CMS - Host, Deploy, Manage Websites for Free\"]}],[\"$\",\"div\",null,{\"className\":\"two-col\",\"children\":[[\"$\",\"div\",null,{\"className\":\"two-col-main\",\"children\":[[\"$\",\"div\",null,{\"className\":\"skill-card\",\"children\":[[\"$\",\"div\",null,{\"className\":\"skill-header\",\"children\":[[\"$\",\"div\",null,{\"className\":\"skill-badges\",\"children\":[[\"$\",\"span\",null,{\"className\":\"badge\",\"style\":{\"color\":\"#818cf8\",\"background\":\"#818cf822\",\"borderColor\":\"#818cf844\"},\"children\":[\"πŸ¦€\",\" \",\"ClawHub\"]}],false]}],[\"$\",\"div\",null,{\"className\":\"skill-top-actions\",\"children\":[\"$\",\"$L22\",null,{\"slug\":\"fastmode\"}]}]]}],[\"$\",\"h1\",null,{\"className\":\"skill-title\",\"children\":\"FastMode CMS - Host, Deploy, Manage Websites for Free\"}],[\"$\",\"p\",null,{\"className\":\"skill-owner\",\"children\":[\"by \",[\"$\",\"span\",null,{\"children\":[\"@\",\"arihgoldstein\"]}]]}],[\"$\",\"p\",null,{\"className\":\"skill-desc\",\"children\":\"Build, deploy, and host websites for free with full CMS. Create a live website from scratch, deploy it to the cloud with free hosting, free SSL, and custom d...\"}],[\"$\",\"div\",null,{\"className\":\"skill-meta\",\"children\":[[\"$\",\"div\",null,{\"className\":\"meta-item\",\"children\":[[\"$\",\"span\",null,{\"className\":\"meta-label\",\"children\":\"Version\"}],[\"$\",\"span\",null,{\"className\":\"meta-value\",\"children\":[\"v\",\"1.5.3\"]}]]}],[\"$\",\"div\",null,{\"className\":\"meta-item\",\"children\":[[\"$\",\"span\",null,{\"className\":\"meta-label\",\"children\":\"Downloads\"}],[\"$\",\"span\",null,{\"className\":\"meta-value\",\"children\":\"1,403\"}]]}],false,[\"$\",\"div\",null,{\"className\":\"meta-item\",\"children\":[[\"$\",\"span\",null,{\"className\":\"meta-label\",\"children\":\"Stars\"}],[\"$\",\"span\",null,{\"className\":\"meta-value\",\"children\":[\"⭐ \",\"2\"]}]]}],false,[\"$\",\"div\",null,{\"className\":\"meta-item\",\"style\":{\"flexDirection\":\"row\",\"gap\":6,\"alignItems\":\"center\"},\"children\":[[\"$\",\"a\",\"devops\",{\"href\":\"/?q=devops\",\"className\":\"tag\",\"children\":[\"#\",\"devops\"]}],[\"$\",\"a\",\"legal\",{\"href\":\"/?q=legal\",\"className\":\"tag\",\"children\":[\"#\",\"legal\"]}],[\"$\",\"a\",\"gaming\",{\"href\":\"/?q=gaming\",\"className\":\"tag\",\"children\":[\"#\",\"gaming\"]}],[\"$\",\"a\",\"productivity\",{\"href\":\"/?q=productivity\",\"className\":\"tag\",\"children\":[\"#\",\"productivity\"]}]]}]]}],[\"$\",\"div\",null,{\"style\":{\"marginTop\":6},\"children\":[\"$\",\"a\",null,{\"href\":\"https://clawhub.ai/arihgoldstein/fastmode\",\"target\":\"_blank\",\"rel\":\"noopener\",\"className\":\"btn-secondary\",\"style\":{\"padding\":\"6px 12px\",\"fontSize\":\".82em\",\"borderRadius\":8,\"background\":\"transparent\",\"border\":\"1px solid var(--border-card)\",\"color\":\"var(--text-muted2)\",\"textDecoration\":\"none\",\"whiteSpace\":\"nowrap\"},\"children\":[\"View on \",\"ClawHub\",\" β†’\"]}]}]]}],[\"$\",\"div\",null,{\"className\":\"install-box\",\"children\":[[\"$\",\"div\",null,{\"className\":\"install-header\",\"children\":[[\"$\",\"div\",null,{\"className\":\"install-dots\",\"children\":[[\"$\",\"div\",null,{\"className\":\"dot\",\"style\":{\"background\":\"#ef4444\"}}],[\"$\",\"div\",null,{\"className\":\"dot\",\"style\":{\"background\":\"#eab308\"}}],[\"$\",\"div\",null,{\"className\":\"dot\",\"style\":{\"background\":\"#22c55e\"}}]]}],[\"$\",\"span\",null,{\"className\":\"install-label\",\"children\":\"TERMINAL\"}]]}],[\"$\",\"div\",null,{\"className\":\"install-body\",\"style\":{\"flexWrap\":\"wrap\"},\"children\":[[\"$\",\"code\",null,{\"className\":\"install-cmd\",\"children\":\"clawhub install fastmode\"}],[\"$\",\"button\",null,{\"className\":\"copy-btn\",\"data-cmd\":\"clawhub install fastmode\",\"style\":{\"fontWeight\":700},\"children\":\"Copy\"}]]}]]}],[\"$\",\"section\",null,{\"className\":\"skill-card\",\"style\":{\"marginBottom\":20},\"children\":[[\"$\",\"h2\",null,{\"style\":{\"color\":\"#f8fafc\",\"fontSize\":\"1.2em\",\"fontWeight\":800,\"margin\":\"0 0 16px\",\"display\":\"flex\",\"alignItems\":\"center\",\"gap\":8},\"children\":\"πŸ“– About This Skill\"}],[\"$\",\"div\",null,{\"style\":{\"fontSize\":\".92em\",\"color\":\"#94a3b8\",\"lineHeight\":1.75},\"dangerouslySetInnerHTML\":{\"__html\":\"$23\"}}]]}],null,null,null,\"$L24\",\"$L25\",\"$L26\",null,false,false]}],\"$L27\"]}]]}]\n"])</script><script>self.__next_f.push([1,"21:[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n document.querySelectorAll('.copy-btn, .script-copy-btn').forEach(btn =\u003e {\\n btn.addEventListener('click', () =\u003e {\\n const cmd = btn.getAttribute('data-cmd');\\n if (!cmd) return;\\n navigator.clipboard.writeText(cmd).then(() =\u003e {\\n const orig = btn.textContent;\\n btn.textContent = 'Copied!';\\n setTimeout(() =\u003e btn.textContent = orig, 1500);\\n }).catch(() =\u003e {});\\n });\\n });\\n \"}}]\n"])</script><script>self.__next_f.push([1,"2a:I[71521,[\"/_next/static/chunks/0ph_0rx9ah5dc.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/0i_x3w546rsb3.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/06ig5gym-0n-u.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\",\"/_next/static/chunks/12w5ognupk9fb.js?dpl=dpl_9zPFH6pojPkqyspdDNz28GzCc6KQ\"],\"default\"]\n28:Tb73,"])</script><script>self.__next_f.push([1,"\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll project-scoped commands use your default project (set with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode use\u003c/code\u003e). Override with \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-p \u003cname-or-id\u003e\u003c/code\u003e.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eItem data (\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-d\u003c/code\u003e) must be valid JSON. For complex data, write a file and use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e-f data.json\u003c/code\u003e.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRich text fields accept HTML content (e.g. \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cp\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ch2\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003cul\u003e\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e\u003ca\u003e\u003c/code\u003e). Always use triple braces in templates.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eRelation fields require item IDs (UUIDs). Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode items relations\u003c/code\u003e to find available IDs.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eThe \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--draft\u003c/code\u003e flag creates unpublished items. Use \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--publish\u003c/code\u003e/\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e--unpublish\u003c/code\u003e to change status.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eEvery site gets free hosting, free SSL, and a \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003e.fastmode.ai\u003c/code\u003e subdomain. Custom domains can be configured.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAfter deploying or making content changes, always run \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode status\u003c/code\u003e to verify the build succeeded.\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eUse \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode examples \u003ctype\u003e\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\"\u003efastmode guide [section]\u003c/code\u003e for built-in documentation and code snippets.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e"])</script><script>self.__next_f.push([1,"24:[\"$\",\"section\",null,{\"className\":\"skill-card\",\"style\":{\"marginBottom\":20},\"children\":[[\"$\",\"h2\",null,{\"style\":{\"color\":\"#f8fafc\",\"fontSize\":\"1.2em\",\"fontWeight\":800,\"margin\":\"0 0 16px\",\"display\":\"flex\",\"alignItems\":\"center\",\"gap\":8},\"children\":\"πŸ“‹ Tips \u0026 Best Practices\"}],[\"$\",\"div\",null,{\"style\":{\"fontSize\":\".92em\",\"color\":\"#94a3b8\",\"lineHeight\":1.75},\"dangerouslySetInnerHTML\":{\"__html\":\"$28\"}}]]}]\n25:[\"$\",\"section\",null,{\"className\":\"skill-card\",\"style\":{\"marginBottom\":20},\"children\":[[\"$\",\"h2\",null,{\"style\":{\"color\":\"#f8fafc\",\"fontSize\":\"1.2em\",\"fontWeight\":800,\"margin\":\"0 0 16px\",\"display\":\"flex\",\"alignItems\":\"center\",\"gap\":8},\"children\":\"πŸ“¦ Core Types\"}],[\"$\",\"div\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\"}}]]}]\n29:T2889,"])</script><script>self.__next_f.push([1,"\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003efastmode validate manifest manifest.json\nfastmode validate template index.html -t custom_index\nfastmode validate template post.html -t custom_detail -c posts\nfastmode validate template post.html -t custom_detail -c posts -p \"My Project\"\nfastmode validate template about.html -t static_page\nfastmode validate package site.zip\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eTemplate types: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecustom_index\u003c/code\u003e (collection listing), \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecustom_detail\u003c/code\u003e (single item), \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003estatic_page\u003c/code\u003e (fixed page).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003e-c\u003c/code\u003e specifies the collection slug (required for \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecustom_index\u003c/code\u003e and \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecustom_detail\u003c/code\u003e).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003e\u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003e-p\u003c/code\u003e validates tokens against the actual project schema (reports missing fields).\u003c/li\u003e\n\u003cli style=\"color:#94a3b8;margin:3px 0\"\u003eAll validation commands exit with code 1 on errors β€” safe for CI/CD pipelines.\u003c/li\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003ch4 style=\"color:#d1d5db;margin:14px 0 6px;font-size:.95em\"\u003eDocumentation \u0026 Examples\u003c/h4\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003cpre style=\"background:#0a0a1c;border:1px solid #1e1e3f;border-radius:6px;padding:10px 12px;overflow-x:auto;font-size:.9em;margin:8px 0\"\u003e\u003ccode style=\"color:#a5f3fc;background:none;padding:0;font-size:1em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003efastmode examples \u003ctype\u003e # Code examples for a specific pattern\nfastmode guide # Full website conversion guide\nfastmode guide templates # Template syntax guide\nfastmode guide common_mistakes # Common pitfalls to avoid\nfastmode generate-samples # Generate placeholder content for empty collections\nfastmode generate-samples -c posts team # Specific collections only\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAvailable example types: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003emanifest_basic\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003emanifest_custom_paths\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eblog_index_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eblog_post_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eteam_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003edownloads_template\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eform_handling\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003easset_paths\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003edata_edit_keys\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eeach_loop\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003econditional_if\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003enested_fields\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003efeatured_posts\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eparent_context\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eequality_comparison\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecomparison_helpers\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eyoutube_embed\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003enested_collection_loop\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eloop_variables\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecommon_mistakes\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003eAvailable guide sections: \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003efull\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003efirst_steps\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eanalysis\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003estructure\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eseo\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003emanifest\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003etemplates\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003etokens\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eforms\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003eassets\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003echecklist\u003c/code\u003e, \u003ccode style=\"background:#0d0d1e;color:#a5f3fc;padding:1px 5px;border-radius:3px;font-size:.88em\" style=\"background:#0a0a1c;color:#fbbf24;padding:1px 5px;border-radius:3px;font-size:.85em\"\u003ecommon_mistakes\u003c/code\u003e.\u003c/p\u003e\u003cp style=\"margin:8px 0\"\u003e\u003chr style=\"border:none;border-top:1px solid #1e1e3f;margin:12px 0\"\u003e\u003c/p\u003e"])</script><script>self.__next_f.push([1,"26:[\"$\",\"section\",null,{\"className\":\"skill-card\",\"style\":{\"marginBottom\":20},\"children\":[[\"$\",\"h2\",null,{\"style\":{\"color\":\"#f8fafc\",\"fontSize\":\"1.2em\",\"fontWeight\":800,\"margin\":\"0 0 16px\",\"display\":\"flex\",\"alignItems\":\"center\",\"gap\":8},\"children\":\"πŸ”’ Constraints\"}],[\"$\",\"div\",null,{\"style\":{\"fontSize\":\".92em\",\"color\":\"#94a3b8\",\"lineHeight\":1.75},\"dangerouslySetInnerHTML\":{\"__html\":\"$29\"}}]]}]\n27:[\"$\",\"div\",null,{\"className\":\"two-col-side\",\"children\":[\"$\",\"$L2a\",null,{\"category\":\"clawhub\",\"currentSlug\":\"fastmode\",\"name\":\"FastMode CMS - Host, Deploy, Manage Websites for Free\",\"tags\":[\"devops\",\"legal\",\"gaming\",\"productivity\"]}]}]\n"])</script></body></html>