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:
| Flag | Description |
|---|---|
--json | Output in structured JSON format, suitable for scripts or AI tools |
--text | Plain text output without colors, suitable for piping |
--version / -v / -V | Display the CLI version number |
--help | Display help information |
When neither
--jsonnor--textis 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
| Argument | Description |
|---|---|
name | Project name, optional. If omitted, interactive input is used |
Options
| Option | Short | Description |
|---|---|---|
--yes | -y | Skip 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
nameandtitleautomatically — no title prompt in non-interactive mode - Generated directory:
yc117_web(YC code lowercased, suffixed with_web) swift.config.jsonrecordsproject.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.nameis taken frombasename(cwd)
Arbitrary plain names are rejected (e.g.
sw create my-project,sw create 123abcreturnINVALID_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):
| Question | Default | Effect |
|---|---|---|
| Theme mode | light | light 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-state | Only asked when toggle is chosen: tri-state (can return to auto) / two-state (light/dark only, cannot return to auto once toggled) |
| Enable i18n | No | Integrates @nuxtjs/i18n |
| Pick locales | zh-CN | Only asked when i18n is on; multi-select |
| Enable PWA | No | Service Worker + manifest |
| Enable WebSocket | No | Registers the global $ws client |
| Enable Tailwind CSS v4 | No | Installs deps + wires Vite plugin |
| Enable dev mock data? | Yes | Enables 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? | Yes | Installs 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.jsonreset to "new project" state:namesubstituted,versionreset to 0.0.0,private: true, publishConfig / release fields removed, pnpm 11 guard added (preinstall)README.mdheading substituted with the project title.npmrcauto-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_BASEetc.; project constants ship innuxt.config.tswith the code).mcp.json/.codex/config.toml/.cursor/mcp.json(so Claude Code / Codex / Cursor and other AI tools can discover and invokeswcommands)@swift-web/frameworkinpackage.jsonis 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
| Argument | Description |
|---|---|
key | Config 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 aNOT_PROJECTerror.
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
| Argument | Description |
|---|---|
key | Config path (required), supports dot-separated nested paths |
value | New 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 key | Files synced |
|---|---|
project.name | package.json (name field) |
project.title | README.md (heading); nuxt.config.ts picks the value up automatically by importing swift.config.json — no file-level rewrite |
project.description | No 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.mode | theme 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.pwa | PWA 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.tailwind | Tailwind 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:
| Field | In one line |
|---|---|
request.timeout / request.uploadTimeout / request.headers / request.transport | Timeouts / 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.aiBotPolicy | Allow / disallow AI crawlers; paid sites switch to disallow |
obfuscate | Production JS obfuscation; turn off for temporary debugging |
suppressConsole | Suppress console output in production; turn off while troubleshooting |
styles (reset / responsive / modal / toast) | Base style layer injection; rarely touched |
seo.sitemap.exclude | Extra 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 shrinkingguardedPathsexposes previously protected pages — in interactive modesw config setasks for a second confirmation; non-interactive modes (--json/--text/ MCP) proceed, but the JSON response carries an extrawarningfield. Additionally, explicitly settingguardedPathsreplaces the framework default guard list entirely (which includes/mine); the CLI attaches an override notice (optionalnoticefield in the JSON response).For array / nested-object fields (
seo.sitemap.exclude/guardedPaths/providersetc.) 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.errorHandleris not prompted in thesw createwizard and defaults to off. To enable it, just runsw config set framework.errorHandler true—nuxt.config.tspicks the value up automatically by importingswift.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
updatedFilescan contain (consumers beware — cli#45 / audit Y-9):
Value Meaning Array of real relative paths Files 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.jsonwas written
For dangerous
authchanges (disabling the guard / shrinkingguardedPaths) in non-interactive mode, the command proceeds and the JSON response carries an extra optionalwarningfield (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
| Option | Description |
|---|---|
--text | Plain-text output (default is interactive coloured) |
--json | Structured 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.jsonin VCS and you wantnuxt.config.tsto follow - You hand-edited
swift.config.jsonand 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
| Argument | Description |
|---|---|
type | File type: page / component / store / api |
name | File name (without extension) |
Options
| Option | Short | Description |
|---|---|---|
--force | -f | Overwrite 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
importstatements, 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/oauth2are fine;2fa/3d-viewerare not) — the name becomes theapi.<name>key (generate-apiregisters 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/frameworkversion - 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
| Option | Description |
|---|---|
--check | Check only, writes not a single byte. Exits 1 when a newer version exists, 0 when up to date, 2 when the lookup fails |
--yes / -y | Skip confirmation. Without it, non-interactive runs are refused |
Exit codes
| Code | Meaning |
|---|---|
0 | Success, or --check found no difference (already up to date) |
1 | Difference found, or the operation did not run: --check found a newer version / non-interactive run refused for want of --yes / the upgrade failed |
2 | Tool or environment error: not a swift-web project / version lookup failed (network, private registry) |
⚠️ When the network is down,
--checkexits 2 rather than 1 — otherwise callers read "cannot tell" as "a newer version exists" and upgrade anyway.
How It Works
- Reads the currently installed
@swift-web/frameworkversion from the project'spackage.json - Queries the private registry for the latest published version
- Compares version numbers and, after interactive confirmation, rewrites the framework range in package.json (keeping
^/~), then runspnpm install --lockfile-onlyfollowed bypnpm install --frozen-lockfile(only framework-related entries are re-resolved, so unrelated dependencies are not upgraded; cli 0.23.2+ / cli#62);--checkstops after step 3 and only reports, while a non-interactive run without--yesis refused with exit1
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 yieldsstatus: "outdated"plussuccess: truebut exit code1(same convention asgit diff --exit-code:successmeans the query itself succeeded, the exit code signals "there is a difference").set -escripts 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
| Argument | Description |
|---|---|
script | Name 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):
| Tool | Capability | Just say |
|---|---|---|
sw_version | Current cli version | "which sw version is this?" |
sw_create | Create a new project | "create a new project called yc123_web" |
sw_config_getsw_config_setsw_config_sync | Read / write / sync swift.config.json | "which framework capabilities are on?" / "turn on PWA" |
sw_add_pagesw_add_componentsw_add_storesw_add_api | Scaffold the four file types | "create an order-detail page" / "add a cart store" |
sw_info | Project info | "which framework version does this project use?" |
sw_upgrade | Upgrade @swift-web/framework | "is there a new framework release? upgrade it" |
sw_framework_docs | Rich docs for the five framework API layers + framework config | "what props does SwImage have?" |
sw_project_apis | List 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_rule | Look 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_run | List / 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 theframework-api.jsonshipped with the installed version, so there is no version drift.
sw_project_apisre-reads and parsesapp/api/modules/*.ts(thepnpm generate-apioutput) 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, withmodulefor per-module endpoint details (method / path / param fields with comments), or withkeywordto 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 Code | Description |
|---|---|
NOT_PROJECT | The current directory is not a Swift Web project (missing swift.config.json) |
INVALID_NAME | sw create received a name that is neither . nor a valid YC<digits>-WEB-<title> |
MISSING_NAME | No project name provided in any non-interactive mode (--yes / --json / --text / non-TTY) |
DIR_NOT_EMPTY | sw create target directory is not empty (errors out in non-interactive / --yes mode; add --force to empty it first, keeping .git) |
TYPE_LOCKED | sw config set project.type rejected (this CLI is hard-locked to web) |
FETCH_FAILED | sw create failed to fetch the starter from verdaccio via npm pack @swift-web/starter |
FILE_EXISTS | Target file already exists (sw add takes --force) |
INVALID_TYPE | Invalid type argument for sw add (allowed: page / component / store / api) |
INVALID_NAME | Invalid 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_FOUND | The specified config path does not exist for sw config get |
CONFIG_PARSE_FAILED | swift.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_FAILED | sw config set failed to sync-update a project file (project files rolled back; swift.config.json was written first and is not restored) |
SYNC_FAILED | sw config sync failed (an applier threw an error) |
AUTH_INVALID_SHAPE | sw config set rejected an invalid auth field shape (e.g. guardedPaths is not a string array) |
INVALID_VALUE_SHAPE | sw config set rejected a non-boolean value for a boolean field (e.g. framework.pwa only accepts true/false) |
FETCH_FAILED | sw upgrade could not connect to the private registry |
UPGRADE_FAILED | sw 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_SCRIPTS | sw run found no package.json in the current directory, or its scripts field is empty |
SCRIPT_FAILED | sw run <script> exited with a non-zero status, was killed by a signal, or timed out (>5 min) |
SCRIPT_SPAWN_FAILED | sw run <script> process failed to start (e.g. Windows .cmd spawn without shell, spawn ENOENT) |
CONFIRMATION_REQUIRED | sw upgrade refused to run in a non-interactive environment (--text / --json / non-TTY / MCP) without --yes; exits 1 |
ERROR | Generic 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"
}
Related links
- Quick start — getting started with
sw createplus an overview of project scripts - Module Options — quick reference for the
swiftConfigfields thatsw configedits - 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