CLI Command Reference

sw is the Swift Web command-line tool, providing project creation, file generation, configuration management, and more.

Global Flags

The following flags apply to all commands and can be placed anywhere in the command:

FlagDescription
--jsonOutput in structured JSON format, suitable for scripts or AI tools
--textPlain text output without colors, suitable for piping
--version / -v / -VDisplay the CLI version number
--helpDisplay help information

When neither --json nor --text is passed and stdout is not a TTY (CI pipes / redirection), the CLI automatically falls back to text mode to avoid interactive prompts hanging.

Examples:

# JSON output (suitable for CI scripts)
sw create YC001-WEB-project-name --yes --json

# Plain text output (suitable for piping)
sw info --text | grep framework

sw create

Create a new Swift Web project from the Starter template.

Syntax

sw create [name] [options]

Arguments

ArgumentDescription
nameProject name, optional. If omitted, interactive input is used

Options

OptionShortDescription
--yes-ySkip all prompts, use defaults (title defaults to directory name)
--force—Empty a non-empty target directory before scaffolding (keeps .git). Without it: interactive mode asks for confirmation; non-interactive / --yes fails with DIR_NOT_EMPTY
--json—Output result in JSON format

Project Name Formats

sw create only accepts two formats (to keep repo naming consistent and traceable across all internal projects):

YC Format (mandatory for internal projects)

sw create YC117-WEB-Cinema-Management
  • Format: YC + digits (any length) + -WEB- + project title, case-insensitive
  • The CLI extracts name and title automatically — no title prompt in non-interactive mode
  • Generated directory: yc117_web (YC code lowercased, suffixed with _web)
  • swift.config.json records project.name: "yc117", project.type: "web", project.title: "Cinema-Management"

Current Directory (.)

mkdir my-project && cd my-project
sw create .
  • Initializes in the current directory, no subdirectory created
  • The CLI interactively asks for the project title and description
  • project.name is taken from basename(cwd)

Arbitrary plain names are rejected (e.g. sw create my-project, sw create 123abc return INVALID_NAME). This is a hard enforcement — every internal project must be identifiable from its YC code by looking at the repo name alone.

Interactive Configuration Wizard

In interactive mode, sw create asks the following after fetching the starter from verdaccio (Enter picks the default):

QuestionDefaultEffect
Theme modelightlight fixed light / dark fixed dark / system follow OS / toggle user-switchable (renders the SwThemeSwitch switcher; useTheme() is registered in every mode, framework#191)
Switcher form (toggle only)tri-stateOnly asked when toggle is chosen: tri-state (can return to auto) / two-state (light/dark only, cannot return to auto once toggled)
Enable i18nNoIntegrates @nuxtjs/i18n
Pick localeszh-CNOnly asked when i18n is on; multi-select
Enable PWANoService Worker + manifest
Enable WebSocketNoRegisters the global $ws client
Enable Tailwind CSS v4NoInstalls deps + wires Vite plugin
Enable dev mock data?YesEnables the framework built-in /login/* + /system/info fake data and the starter business mock presets (see Dev-time request mocking); choosing No writes request.mock.enabled: false and removes the starter mock plugin app/plugins/dev-mock.ts (app/utils/dev-mock-data.ts and its unit test stay: they are fixtures for the starter component tests and have no effect unless registered)
Run pnpm install now?YesInstalls dependencies synchronously (1–2 minutes)

Answers are persisted to swift.config.json and propagated to package.json (dependency add/remove) / nuxt.config.ts / i18n/locales/ / tailwind.css (the Tailwind stylelint allowlist lives in the @swift-web/standards base — the cli no longer touches stylelint config). --yes mode skips every question and uses conservative defaults (tracker and dev mock enabled; i18n / PWA / WebSocket / Tailwind and other features off).

What Gets Generated

After sw create completes, the target directory contains:

  • A complete Nuxt 4 project structure (latest starter snapshot fetched from verdaccio via npm pack @swift-web/starter)
  • swift.config.json (project metadata, including the framework feature choices from the wizard)
  • package.json reset to "new project" state: name substituted, version reset to 0.0.0, private: true, publishConfig / release fields removed, pnpm 11 guard added (preinstall)
  • README.md heading substituted with the project title
  • .npmrc auto-generated (@swift-web → verdaccio routing + cross-platform archs; no authToken — packages install anonymously)
  • .env (auto-copied from .env.dev.example — only environment-specific values: NUXT_PUBLIC_SITE_URL / NUXT_PUBLIC_API_BASE etc.; project constants ship in nuxt.config.ts with the code)
  • .mcp.json / .codex/config.toml / .cursor/mcp.json (so Claude Code / Codex / Cursor and other AI tools can discover and invoke sw commands)
  • @swift-web/framework in package.json is pinned to the latest version from the private registry

Examples

# Interactive creation (default)
sw create

# YC name up-front — skips the first prompt
sw create YC001-WEB-User-Center

# Scaffold into an existing empty directory
sw create .

# Skip all prompts (CI-friendly)
sw create YC001-WEB-User-Center --yes

# CI environment, JSON output
sw create YC001-WEB-User-Center --yes --json

JSON output example:

{
  "success": true,
  "action": "create",
  "project": {
    "name": "yc001_web",
    "title": "User Center",
    "dir": "/Users/yourname/projects/yc001_web"
  },
  "nextSteps": [
    "cd yc001_web",
    "pnpm install",
    "# Edit .env and fill in NUXT_PUBLIC_SITE_URL and NUXT_PUBLIC_API_BASE",
    "# When wiring the backend, set the doc source in nuxt.config.ts › swiftConfig.apiDocs and API_DOCS_TOKEN in .env, then run: pnpm generate-api",
    "pnpm dev"
  ]
}

sw config get

View the swift.config.json configuration for the current project.

Syntax

sw config get [key]

Arguments

ArgumentDescription
keyConfig path, supports dot-separated nested paths. Omit to display the full config

Examples

# View the full config
sw config get

# View a top-level field
sw config get project

# Use dot paths to view nested fields
sw config get project.title
sw config get framework.theme
sw config get framework.i18n.defaultLocale
sw config get features.tailwind

Output example:

project.title: Cinema Management System
// --json output
{
  "success": true,
  "key": "project.title",
  "value": "Cinema Management System"
}

Without a key the whole config is returned under a different shape (no key / value, use config):

// sw config get --json
{
  "success": true,
  "config": { "project": { "title": "Cinema Management System" }, "framework": { } }
}

Note: This command must be run from the Swift Web project root (the directory containing swift.config.json), otherwise it returns a NOT_PROJECT error.


sw config set

Update a config entry in swift.config.json and automatically sync the relevant project files.

Syntax

sw config set <key> <value>

Arguments

ArgumentDescription
keyConfig path (required), supports dot-separated nested paths
valueNew value (required)

File Sync Rules

sw config set does more than modify swift.config.json — for specific keys, it also syncs the corresponding project files:

Config keyFiles synced
project.namepackage.json (name field)
project.titleREADME.md (heading); nuxt.config.ts picks the value up automatically by importing swift.config.json — no file-level rewrite
project.descriptionNo file-level update (nuxt.config.ts auto-syncs)
framework.i18n / framework.i18n.*nuxt.config.ts (i18n block) + i18n/locales/ (locale file scaffold)
framework.theme / framework.theme.modetheme applier (toggles the theme-dark marker blocks in skin CSS when mode ≠ light)
framework.tracker.*No file-level update (nuxt.config.ts auto-syncs; Tracking Foundation switch, on by default)
framework.pwaPWA applier (does not touch package.json — @vite-pwa/nuxt is carried by the framework; only icon / SW cleanup hints and legacy self-declaration detection)
features.tailwindTailwind applier (deps + nuxt.config.ts + tailwind.css + vite plugin)

If syncing a project file fails, the already-modified project files are rolled back; swift.config.json was written first and is not restored.

Manageable framework.* Fields

Besides the five wizard questions (theme / i18n / pwa / websocket / request.mock) and the defaults written at create time (tracker / errorHandler), FrameworkConfig has nine more optional field groups that are not asked in the sw create wizard (to keep creation lean) but can all be managed via sw config set framework.<path> <value> (and the MCP tool sw_config_set). These fields have no applier — once written to swift.config.json they take effect through the ...swiftConfig.framework spread in nuxt.config.ts; restart the dev server and they apply:

FieldIn one line
request.timeout / request.uploadTimeout / request.headers / request.transportTimeouts / global headers — defaults are usually fine; transport is the encrypted-payload encoding, default base64, switch to binary for raw-binary backends
systemInfo (enabled / endpoint / onError / ignorePaths / clientRefreshTtl)Backend system/info fetching; pure-frontend / mock projects can turn enabled off. clientRefreshTtl defaults to 300 seconds; 0 fetches on every full-page load.
seo.aiBotPolicyAllow / disallow AI crawlers; paid sites switch to disallow
obfuscateProduction JS obfuscation; turn off for temporary debugging
suppressConsoleSuppress console output in production; turn off while troubleshooting
styles (reset / responsive / modal / toast)Base style layer injection; rarely touched
seo.sitemap.excludeExtra sitemap exclusion paths (array)
image (provider / providers / originRules)External image CDN integration
auth (enabled / deviceLogin / guardedPaths / guestPaths)Login guard (dangerous changes trigger a safety confirmation, see below). deviceLogin defaults to true; false only disables the /login/device fallback, leaving real login and guards enabled.

⚠️ auth safety confirmation: disabling the guard (framework.auth.enabled → false) or shrinking guardedPaths exposes previously protected pages — in interactive mode sw config set asks for a second confirmation; non-interactive modes (--json / --text / MCP) proceed, but the JSON response carries an extra warning field. Additionally, explicitly setting guardedPaths replaces the framework default guard list entirely (which includes /mine); the CLI attaches an override notice (optional notice field in the JSON response).

For array / nested-object fields (seo.sitemap.exclude / guardedPaths / providers etc.) pass a JSON string as the value: sw config set framework.seo.sitemap.exclude '["/admin/**"]', or use MCP with natural language.

Examples

# Change the project title (also updates README.md)
sw config set project.title "New Project Title"

# Change the project description
sw config set project.description "A cinema membership management platform"

# Change the site code (package.json "name" becomes <name>_web, not the raw value)
sw config set project.name yc002

# Enable PWA
sw config set framework.pwa true

# Change the i18n default locale
sw config set framework.i18n.defaultLocale zh-TW

# Enable errorHandler (global error reporting)
sw config set framework.errorHandler true

framework.errorHandler is not prompted in the sw create wizard and defaults to off. To enable it, just run sw config set framework.errorHandler true — nuxt.config.ts picks the value up automatically by importing swift.config.json; no sync needed.

Output example:

✔ swift.config.json updated: project.title = New Project Title
  Synced file: README.md
// --json output
{
  "success": true,
  "action": "set",
  "key": "project.title",
  "value": "New Project Title",
  "updatedFiles": ["README.md"]
}

What updatedFiles can contain (consumers beware — cli#45 / audit Y-9):

ValueMeaning
Array of real relative pathsFiles this command rewrote directly (e.g. ["README.md"])
["<applier>"]A feature applier ran (pwa / tailwind / theme…). The changes happened inside the applier — this is not a file path, don't resolve it as one
["nuxt.config.ts", "i18n/locales/"]Fixed marker for the i18n applier (also a semantic marker, not an exact change list)
[]This key has no file side effects; only swift.config.json was written

For dangerous auth changes (disabling the guard / shrinking guardedPaths) in non-interactive mode, the command proceeds and the JSON response carries an extra optional warning field (the concrete safety message) — script / AI consumers should check and surface it.

Note: This command must be run from the Swift Web project root.


sw config sync

Re-runs every feature-flag applier to force-sync swift.config.json with nuxt.config.ts and other derived project files. Useful after manually editing swift.config.json to align all side effects in one shot.

Syntax

sw config sync [options]

Options

OptionDescription
--textPlain-text output (default is interactive coloured)
--jsonStructured JSON output (for scripts / AI consumers)

Behaviour

Reads swift.config.json and runs the four toggle appliers — i18n / PWA / Tailwind / theme (errorHandler / tracker have no applier — nuxt.config.ts picks them up automatically by importing swift.config.json), writes results back to nuxt.config.ts, and adds / removes layer files as needed (e.g. i18n locale stubs).

When to use it

  • A teammate updated swift.config.json in VCS and you want nuxt.config.ts to follow
  • You hand-edited swift.config.json and want one command to align everything
  • After upgrading framework, some applier rules changed; rerun once to refresh nuxt.config.ts

Examples

sw config sync           # interactive coloured output (default)
sw config sync --json    # for AI / script consumption

Note: This command must be run from the Swift Web project root.


sw add

Quickly generate new files (pages, components, stores, or API modules) in the current project.

Syntax

sw add <type> <name> [options]

Arguments

ArgumentDescription
typeFile type: page / component / store / api
nameFile name (without extension)

Options

OptionShortDescription
--force-fOverwrite existing files

Type Details

page — Page

sw add page product-detail

Generated file: app/pages/product-detail.vue. The template ships with a defineRouteRules rendering-strategy declaration plus a useSeo() SEO placeholder (aligned with framework's mandatory SEO — every page must declare its SEO meta).

<script setup lang="ts">
// Rendering strategy: default ISR cache 1h; adjust per page — private/auth pages use ssr:false, static pages prerender:true
// Quick guide: https://sw.djatm.cloud/guide/rendering-quick-guide
// Deep dive & pitfalls: https://sw.djatm.cloud/guide/rendering-strategies
defineRouteRules({ isr: 3600 })

// TDK length (display width: CJK = 2, ASCII = 1): keep title within 10-60 width;
// description must be a summary paragraph — 50-160 chars in English (too short
// triggers lint + dev warnings). For utility pages (login, redirect) pass
// robots: 'private' + silenceLengthWarnings: true instead.
useSeo({
  title: 'product-detail',
  description: 'TODO: replace with a 50-160 char summary of this page (the placeholder is too short and will trigger SEO warnings)',
})
</script>

<template>
  <div>
    <!-- product-detail page -->
  </div>
</template>

File names use kebab-case, corresponding to the route path (/product-detail).

component — Component

sw add component UserCard

Generated file: app/components/UserCard.vue

<script setup lang="ts"></script>

<template>
  <div>
    <!-- UserCard -->
  </div>
</template>

File names use PascalCase. Nuxt auto-imports them — no manual import needed.

store — Pinia Store

sw add store cart

Generated file: app/store/cart.ts

export const useCartStore = defineStore('cart', () => {
  // state
  const data = ref<unknown>(null)

  // actions

  return { data }
})

The store template does not include import statements, because Starter projects use Nuxt auto-imports — defineStore, ref, etc. do not need to be manually imported.

api — API Module

sw add api order

Generated file: app/api/manual/order.ts (the hand-written module directory; modules/ belongs to generate-api and is wiped on regeneration. The next generate-api run registers it as api.order)

⚠️ An api name must start with a letter (v2-order / oauth2 are fine; 2fa / 3d-viewer are not) — the name becomes the api.<name> key (generate-api registers manual modules by file name), and a leading digit is not a valid identifier. The CLI rejects it outright with a hint rather than emitting a broken file.

// Hand-written API module (app/api/manual/): generate-api never rewrites this directory and registers it as api.order on the next run
/** List */
export async function list(params?: Record<string, unknown>): Promise<unknown[]> {
  return request<unknown[]>('/order/list', { params })
}

/** Detail */
export async function detail(id: number | string): Promise<unknown> {
  return request<unknown>(`/order/detail/${id}`)
}

Examples

# Generate a page
sw add page about-us
sw add page products/index      # Generates app/pages/products/index.vue
sw add page products/[id]       # Generates a dynamic route page

# Generate a component
sw add component HeroSection
sw add component AdBanner

# Generate a store (multi-word names use kebab-case, function name auto-converts to PascalCase)
sw add store order-list         # → useOrderListStore
sw add store shopping-cart      # → useShoppingCartStore

# Generate an API module
sw add api product
sw add api user-auth

# Force overwrite an existing file
sw add component HeroSection --force

JSON output example:

{
  "success": true,
  "action": "add",
  "type": "component",
  "name": "HeroSection",
  "file": "app/components/HeroSection.vue"
}

Note: This command must be run from the Swift Web project root (the directory containing swift.config.json).


sw info

Display detailed information about the current Swift Web project.

Syntax

sw info

What It Shows

  • Project name (title, or package name if no title set), description
  • Currently installed @swift-web/framework version
  • Node.js version
  • Framework feature toggle states (theme, i18n, PWA, WebSocket, errorHandler)

Examples

sw info

Output example:

  Cinema Management System
  Cinema membership and ticketing platform

  framework:  ^x.y.z
  node:       v22.12.0
  theme:        toggle
  i18n:         on
  pwa:          off
  websocket:    off
  errorHandler: off

JSON output:

sw info --json
{
  "success": true,
  "info": {
    "project": {
      "name": "yc117",
      "type": "web",
      "title": "Cinema Management System",
      "description": "Cinema membership and ticketing platform"
    },
    "framework": {
      "version": "^x.y.z",
      "config": {
        "theme": { "mode": "toggle", "toggleStates": 3 },
        "i18n": { "enabled": true, "defaultLocale": "zh-CN", "locales": ["zh-CN", "zh-TW", "en"] },
        "pwa": false,
        "websocket": false,
        "errorHandler": false,
        "tracker": { "enabled": true, "autoPageView": true }
      }
    },
    "features": { "tailwind": false },
    "node": "v22.12.0"
  }
}

Note: This command must be run from the Swift Web project root.


sw upgrade

Check whether a new version of @swift-web/framework is available and, after interactive confirmation, run the upgrade automatically. Non-interactive modes (--text / --json / non-TTY / MCP) do not prompt and do not run — pass --yes explicitly, or the command exits 1 with CONFIRMATION_REQUIRED.

Syntax

sw upgrade            # upgrade after interactive confirmation
sw upgrade --check    # check only — writes nothing
sw upgrade --yes      # skip confirmation (required in non-interactive environments)

Options

OptionDescription
--checkCheck only, writes not a single byte. Exits 1 when a newer version exists, 0 when up to date, 2 when the lookup fails
--yes / -ySkip confirmation. Without it, non-interactive runs are refused

Exit codes

CodeMeaning
0Success, or --check found no difference (already up to date)
1Difference found, or the operation did not run: --check found a newer version / non-interactive run refused for want of --yes / the upgrade failed
2Tool or environment error: not a swift-web project / version lookup failed (network, private registry)

⚠️ When the network is down, --check exits 2 rather than 1 — otherwise callers read "cannot tell" as "a newer version exists" and upgrade anyway.

How It Works

  1. Reads the currently installed @swift-web/framework version from the project's package.json
  2. Queries the private registry for the latest published version
  3. Compares version numbers and, after interactive confirmation, rewrites the framework range in package.json (keeping ^ / ~), then runs pnpm install --lockfile-only followed by pnpm install --frozen-lockfile (only framework-related entries are re-resolved, so unrelated dependencies are not upgraded; cli 0.23.2+ / cli#62); --check stops after step 3 and only reports, while a non-interactive run without --yes is refused with exit 1

Examples

sw upgrade

When already up to date:

  Checking for the latest version…

  ✔ Already up to date: 0.x.y

When a new version is available:

  Checking for the latest version…

  Current version:  ^x.y.z
  Latest version:   x.y.z

  ◆  Upgrade to x.y.z? Yes

  …(rewrites the range, then runs pnpm install --lockfile-only and --frozen-lockfile)

  ✔ Upgraded to x.y.z

In interactive mode sw upgrade asks for confirmation, then rewrites the range and runs pnpm install --lockfile-only and pnpm install --frozen-lockfile automatically; --text / --json / non-TTY / MCP mode refuses to run without --yes (exits 1 with CONFIRMATION_REQUIRED); use --check if you only want to know whether a newer version exists.

JSON output (three shapes, distinguished by the status field):

⚠️ With --check, a newer version yields status: "outdated" plus success: true but exit code 1 (same convention as git diff --exit-code: success means the query itself succeeded, the exit code signals "there is a difference"). set -e scripts must tolerate this case explicitly.

// Already up to date
{
  "success": true,
  "action": "upgrade",
  "status": "up-to-date",
  "version": "x.y.z"
}
// A newer version is available (`--check` hit; `success: true`, exit code 1)
{
  "success": true,
  "action": "upgrade",
  "status": "outdated",
  "from": "x.y.z",
  "to": "x.y.z+1"
}
// Upgraded successfully
{
  "success": true,
  "action": "upgrade",
  "status": "upgraded",
  "from": "x.y.z",
  "to": "x.y.z+1"
}


sw run

Execute an npm script from the project's package.json. Without a script name it lists every available script with a one-line description — perfect for answering "what can this project actually run?".

Syntax

sw run [script]

Arguments

ArgumentDescription
scriptName of the script to run; omit to enter list mode

List Mode

sw run

Output (excerpt):

  Available scripts:

  dev            Start the Nuxt dev server (hot reload)
  build          Production build
  preview        Preview the production build
  lint           Run all lint checks (eslint + stylelint)
  type-check     TypeScript type check
  test           Run Vitest unit tests
  generate-api   Auto-generate API types and request functions from YAPI
  ...

  Usage:
    sw run <script>
    pnpm run <script>       (no CLI install required)

Where descriptions come from: the CLI's built-in standard-script description table (dev / build / lint, etc.) first; otherwise the first line of the JSDoc at the top of the .ts file the script invokes (convention: scriptName — one-line description).

Run Mode

sw run generate-api

Equivalent to pnpm run generate-api, with stdio inherited so colors and interactivity work as usual.

JSON output:

sw run generate-api --json
{
  "success": true,
  "script": "generate-api",
  "exitCode": 0,
  "output": "..."
}

On failure the response uses code: "SCRIPT_FAILED" and output contains the combined stdout + stderr. Timeout is capped at 5 minutes.

Without a script name (list mode) the JSON shape is different — this is what MCP sw_run gets when called with no argument:

// sw run --json
{
  "success": true,
  "scripts": [
    { "name": "dev", "command": "nuxt dev", "description": "Start the dev server" }
  ]
}

description falls back through: built-in known-script description → first JSDoc line of the script file → empty string.

This command works in any directory that has a package.json; it does not require a Swift Web project.


AI Toolchain (MCP)

The starter repo ships built-in MCP configs — Claude Code reads .mcp.json, Codex reads .codex/config.toml, and Cursor reads .cursor/mcp.json. All three launch sw --mcp. Codex loads project configuration after you trust the project in the client; confirm that the current session has connected to MCP before using its tools. Shared rules start at AGENTS.md; skill sources and their directory copies live in .claude/skills/ and .agents/skills/, respectively:

  • Inspect project info → sw info
  • Switch the i18n default locale → sw config set framework.i18n.defaultLocale zh-TW
  • Scaffold a new page → sw add page orders/[id]
  • Look up framework component / composable list → tool sw_framework_docs (live query, prevents the AI from referencing renamed components from memory)

Full MCP tools list (15):

ToolCapabilityJust say
sw_versionCurrent cli version"which sw version is this?"
sw_createCreate a new project"create a new project called yc123_web"
sw_config_get
sw_config_set
sw_config_sync
Read / write / sync swift.config.json"which framework capabilities are on?" / "turn on PWA"
sw_add_page
sw_add_component
sw_add_store
sw_add_api
Scaffold the four file types"create an order-detail page" / "add a cart store"
sw_infoProject info"which framework version does this project use?"
sw_upgradeUpgrade @swift-web/framework"is there a new framework release? upgrade it"
sw_framework_docsRich docs for the five framework API layers + framework config"what props does SwImage have?"
sw_project_apisList the project's backend APIs (parses the generated app/api layer)"which endpoints are related to likes?" "what APIs does the movie module have?"
sw_standards_ruleLook up a development-standard rule by id / keyword (sourced from the standards version installed in the project)"what is SI-002?" "which rules cover hover?"
sw_runList / run package.json scripts"what scripts can this project run?" / "sync the YAPI APIs"

The five layers of sw_framework_docs = components / composables / stores / utils / server utils, plus framework config (config) short-name lookup; the data source is the framework-api.json shipped with the installed version, so there is no version drift.

sw_project_apis re-reads and parses app/api/modules/*.ts (the pnpm generate-api output) from disk on every call — re-running generate-api is reflected immediately, no cache, no snapshot. Call it with no arguments for the module directory, with module for per-module endpoint details (method / path / param fields with comments), or with keyword to filter across modules by function name / path / description. AI assistants should check it before wiring page logic to decide which endpoint to call.

The fixed .mcp.json content (no customization needed):

{
  "mcpServers": {
    "swift-web-cli": {
      "command": "sw",
      "args": ["--mcp"]
    }
  }
}

The CLI does not provide an init-mcp-style command — the starter already ships .mcp.json, .codex/config.toml, and .cursor/mcp.json, so new projects work out of the box. If accidentally deleted, copy it back from the starter repo (Codex users: copy .codex/config.toml; Cursor users: copy .cursor/mcp.json).


Error Code Reference

When using the --json flag, error responses include the following error codes:

Error CodeDescription
NOT_PROJECTThe current directory is not a Swift Web project (missing swift.config.json)
INVALID_NAMEsw create received a name that is neither . nor a valid YC<digits>-WEB-<title>
MISSING_NAMENo project name provided in any non-interactive mode (--yes / --json / --text / non-TTY)
DIR_NOT_EMPTYsw create target directory is not empty (errors out in non-interactive / --yes mode; add --force to empty it first, keeping .git)
TYPE_LOCKEDsw config set project.type rejected (this CLI is hard-locked to web)
FETCH_FAILEDsw create failed to fetch the starter from verdaccio via npm pack @swift-web/starter
FILE_EXISTSTarget file already exists (sw add takes --force)
INVALID_TYPEInvalid type argument for sw add (allowed: page / component / store / api)
INVALID_NAMEInvalid name argument for sw add. page / component allow alphanumerics, -, _ and /-separated subdirectories (page additionally accepts Nuxt dynamic segments [id] / [...slug] / [[x]]); store / api do not support subdirectories (the name goes into an exported identifier). .., spaces and non-ASCII are rejected for all types
KEY_NOT_FOUNDThe specified config path does not exist for sw config get
CONFIG_PARSE_FAILEDswift.config.json exists but fails to parse (corrupted / manual edit broke the JSON); may be returned by config get/set/sync and info
FILE_UPDATE_FAILEDsw config set failed to sync-update a project file (project files rolled back; swift.config.json was written first and is not restored)
SYNC_FAILEDsw config sync failed (an applier threw an error)
AUTH_INVALID_SHAPEsw config set rejected an invalid auth field shape (e.g. guardedPaths is not a string array)
INVALID_VALUE_SHAPEsw config set rejected a non-boolean value for a boolean field (e.g. framework.pwa only accepts true/false)
FETCH_FAILEDsw upgrade could not connect to the private registry
UPGRADE_FAILEDsw upgrade failed (pnpm install errored or the range could not be rewritten; only after a successful fetch; package.json and pnpm-lock.yaml are restored)
NO_SCRIPTSsw run found no package.json in the current directory, or its scripts field is empty
SCRIPT_FAILEDsw run <script> exited with a non-zero status, was killed by a signal, or timed out (>5 min)
SCRIPT_SPAWN_FAILEDsw run <script> process failed to start (e.g. Windows .cmd spawn without shell, spawn ENOENT)
CONFIRMATION_REQUIREDsw upgrade refused to run in a non-interactive environment (--text / --json / non-TTY / MCP) without --yes; exits 1
ERRORGeneric fallback code (default code of error() in json mode, e.g. checkPnpm when pnpm is missing)

Error response format:

{
  "success": false,
  "error": "The current directory is not a swift-web project",
  "code": "NOT_PROJECT"
}
  • Quick start — getting started with sw create plus an overview of project scripts
  • Module Options — quick reference for the swiftConfig fields that sw config edits
  • Development standards — the naming / structure conventions that sw add-generated files follow
  • Dev request mock — the story behind sw create's "Enable dev mock data?" prompt