devkit Tiếng Việt

CLI reference

Every devkit command, from devkit <command> --help of version v1.0.0. Wherever a command takes <site> or <site|lane>, a lane is written <site>--<lane>. Flags that are on by default are turned off with --flag=false.

Global flags

FlagMeaning
--jsonprint exactly one JSON object on stdout (see JSON output)
--progressreport the steps of lane new, site clone and site setup on stderr: … <step>, or one {"progress":"…"} line each with --json
-h, --helphelp for any command
-v, --versionthe version

devkit completion bash|zsh|fish|powershell prints a shell completion script.

Stacks

CommandFlagsWhat it does
stack add <compose-folder>add a Docker Compose folder
stack liststacks with their discovered services, roles, ports and state
stack up <stack> [service…]docker compose up -d for the stack or some services
stack restart <stack> [service…]restart the stack or some services
stack down <stack> [service…]the whole stack: docker compose down (volumes kept); services: docker compose stop
stack logs <stack> <service>--tail N (200)recent container logs

Sites

CommandFlagsWhat it does
park <dir>serve every Laravel folder (with artisan) inside dir
link <dir>--name n (default: folder name)add one Laravel folder as a site
site list--all (include hidden sites)parked and linked sites, their lanes, git branch and live state
site up <site>start the stack services it needs, create its database, render .env, serve it, start its autostart processes
site down <site>stop its processes, then the web server
site set <site>--engine artisan|caddy, --php X.Y ("": the default), --db name, --stack name, --copy-files a,b ("" clears), --submodule-groups name=path,… ("" restores modules,extensions)change the site's settings; an engine change stops it and its lanes first
site clone <git-url>--into dir, --name n, --branch b, --php X.Y, --no-submodules, --no-composer, --no-pnpm, --no-env, --startclone into a parked directory, then submodules, composer install, pnpm install, the .env template and database, and with --start site up
site setup <site>--no-submodules, --no-composer, --no-pnpm, --no-env, --startrun the setup steps of site clone (again) on an existing site
site hide <site>stop the site and its lanes and leave it out of lists; files, database and template stay
site unhide <site>list a hidden site again
site delete <site> --yes--trash, --drop-db, --force, --yesremove its lanes, stop it, delete its folder (or move it to the Trash), with --drop-db its databases and snapshots. Refuses DIRTY_WORKTREE unless --force
site actions <site>its quick actions
site action <site> <action>run one: clear-log, clear-cache, publish-core or the site's own
site action-set <site> <name>--command c (php is the site's PHP), --label ladd an action or override a default
site action-rm <site> <name>remove an action (a removed override restores the default)

Templates

CommandFlagsWhat it does
template get <site>print the template (seeded from .env when none is stored)
template set <site> --file <path>--filestore a template
template render <site|lane>--file pathprint the .env site up would write now, from the stored template or the file; writes nothing

Processes, exec and logs

CommandFlagsWhat it does
proc list <site>processes with live status, port and autostart
proc start <site> [proc…]start processes (default: the autostart ones)
proc stop <site> [proc…]stop processes (default: all running)
proc restart <site> [proc…]restart processes (default: all running)
proc logs <site> <proc>--lines N (200)the last lines of a process log
proc add <site> <name> --command <cmd>--command ({port} is replaced), --port, --autostartadd a custom process
proc set <site> <proc>--command, --port=bool, --autostart=boolchange a process
proc rm <site> <proc>remove a stopped process
proc reset <site>forget customisations and detect the defaults again
exec <site> -- <command…>--timeout d (10m), --xdebugrun a command in the site folder with the site's PHP first on PATH (caddy: php runs in the PHP container)
logs <site>--source laravel|serve|proc:<name>|container:<service> (laravel), --lines N (200)the last lines of a site log

Lanes

CommandFlagsWhat it does
lane new <site> <name>--branch b (feat/<name>), --base ref (the site's HEAD), --schema-only, --no-fork-db, --startcreate a lane: worktree, submodules on their branches, copy-on-write vendor and node_modules, forked database
lane list [site]lanes with branch, database, URL and live state
lane up <lane>render its .env and serve it (as site up)
lane down <lane>stop it (as site down)
lane rm <lane>--dry-run, --force, --keep-db, --delete-branchstop it, drop its database and snapshots, remove the worktree; refuses DIRTY_WORKTREE unless --force

Databases

CommandFlagsWhat it does
db snapshot <site|lane> [name]copy the database to <db>__snap_<name> (default name: the current time)
db snapshots <site|lane>list snapshots, newest first
db snapshot rm <site|lane> <name> --yes--yesdelete a snapshot
db restore <site|lane> <name> --yes--safety (default true), --yesreplace the database with a snapshot; the site's PHP is stopped and started again
db reset <lane> --yes--schema-only, --safety, --yesfork a lane's database again from its site's current one
db query <site|lane> <sql>one read-only SELECT/SHOW/DESCRIBE/EXPLAIN, at most 500 rows

Git and modules

CommandFlagsWhat it does
git status <site|lane>branch, ahead/behind its upstream, uncommitted changes, submodule summary
git checkout <site|lane> <branch>--create, --with-submodules (default true)check out a local branch, one from origin, or a new one; refuses DIRTY_WORKTREE; restarts a running site
git fetch <site|lane>--with-submodules (default true)git fetch --prune in the site (and its submodules)
git pull <site|lane>--with-submodules (default true)git pull --ff-only in the site and each clean submodule on a branch
git push <site|lane>--with-submodules (default true)push submodules that are ahead, then the site; sets the upstream on a first push
modules <site|lane>--fetch, --group g, --only a,beach submodule: branch, tracked branch, HEAD against the recorded commit, ahead/behind, dirty
modules checkout <site|lane> <branch>--create, --group, --onlycheck out a branch in every (or the selected) submodule; dirty ones are skipped (MODULE_DIRTY)
modules pull <site|lane>--group, --onlygit pull --ff-only in each clean submodule on a branch
modules push <site|lane>--group, --onlypush each submodule that is ahead, setting the upstream when missing
modules add <site|lane> <git-url>--group (extensions), --name n, --path p, --branch bgit submodule add into a group folder; staged, not committed

PHP and Xdebug

CommandFlagsWhat it does
php listPHP binaries found on the scan paths
php info <version>one binary: php.ini, extensions, Xdebug and the sites that run it
php check <version> <site|lane>composer check-platform-reqs for the site with that PHP; changes nothing
php containersthe stacks' PHP services (caddy) with their Xdebug mode and sites
php scan-pathswhere devkit looks for PHP (paths or globs with * and ~) and what each finds
php scan-paths add|rm|enable|disable <path>add (scanned at once), remove, scan again, keep without scanning
php scan-paths resetrestore this system's default scan paths
xdebug status <site|lane>the mode and whether Xdebug is installed
xdebug on <site|lane>--mode debug|coverage|profile (debug)turn it on; restarts the server and PHP processes (caddy: the PHP container, for every site on it)
xdebug off <site|lane>turn it off
xdebug container <stack> <php-service> --mode <mode>--mode off|debug|coverage|profileset a PHP container's mode (recreates it; every site on it is affected)

Settings, certificates, hosts

CommandFlagsWhat it does
settingsshow the settings
settings set--default-engine artisan|caddy, --default-php X.Y ("": the php on PATH), --domain-suffix s (localhost), --port-min N (8100), --port-max N (8999), --dry-runchange the defaults; --dry-run says what would change and which running sites would stop
trustmkcert -install unless mkcert's CA is already trusted (may ask for your password)
certsmkcert's CA and the certificates devkit issued; changes nothing
hostsdevkit's block in /etc/hosts against what it should be (only for a suffix other than localhost)
hosts syncrewrite devkit's block with sudo (one password prompt)

Status, doctor, watch, MCP

CommandFlagsWhat it does
statusstacks, sites and lanes (hidden ones too) with processes, connected agents and issues such as PORT_IN_USE, checked live, never written
doctor [site]check Docker, stacks, PHP and sites; one line per check with a hint
watch--interval d (2s)print what changes until Ctrl-C or until the process that started it exits; --json: one event per line
mcpthe MCP server on stdio, started by your agent
mcp config [agent]--write, --dir projecthow to add devkit to claude-code, codex, gemini, cursor, vscode, claude-desktop or other
mcp toolsthe tools with groups and descriptions (--json: input schemas)
mcp audit--limit N (100)the last calls agents made, newest first

What doctor checks

Machine: docker, each stack, php.binaries. Per site: site.php, site.composer (the platform check), site.ports, site.template, site.db (tables and size), site.submodules. When a site uses caddy: mkcert, caddy (the admin API), hosts (only for a domain suffix other than localhost), and per caddy site site.web (services and mounts) and site.cert. site.xdebug for caddy sites and sites with Xdebug on. Hidden sites are skipped unless you name one. Each line is ok, warn or fail; the last line counts them.

JSON output

With --json, stdout carries exactly one object. Human messages go to stderr.

{"ok":true,"data":{"site":"shop","url":"http://localhost:8100","port":8100,"php":"8.4.19"}}
{"ok":false,"error":{"code":"PHP_VERSION_MISSING","message":"PHP 8.1 not found on this machine","hint":"brew install php@8.1"}}

Bulk git and module commands report per repository: {"site", "results": [{"path", "status", "detail", "error"}], "done", "unchanged", "skipped", "failed"}, where status is done, unchanged, skipped or failed and path . is the site itself.

devkit watch --json prints one event per line, {"v":1,"seq":N,"time":"…","type":T,"change":C,"subject":S,"data":…}: first a snapshot (what status --json returns), then stack, service, site, process, mcp and issue events with change added, changed or removed, and error when a poll fails.

Exit codes

CodeWhen
0success
1any error; doctor when a check fails; git fetch|pull|push and modules checkout|pull|push when a repository was skipped or failed (in human mode)
the command's ownexec in human mode exits with the command's exit code
124exec stopped by --timeout (as timeout(1))

With --json the exit code follows the envelope: bulk commands and doctor exit 0 and report skips, failures and failed checks in data, and exec exits 0 and puts the command's code in data.exitCode (and timedOut when --timeout stopped it).

Error codes

CodeMeaning
NOT_FOUNDno such site, lane, stack, branch, file
INVALID_ARGUMENTa bad name, flag value or combination
CONFIRM_REQUIREDa destructive command without --yes (MCP: without confirm); the message says what it would do
DIRTY_WORKTREEuncommitted changes, unpushed commits or stashes would be lost; the message lists them
MODULE_DIRTYa submodule with uncommitted changes was skipped
GIT_FAILEDgit itself failed (the message carries its output)
PORT_IN_USEanother program holds the site's port
DOCKER_UNAVAILABLEdocker is not installed or its daemon is not running
STACK_SERVICE_DOWNa service the site needs is missing or not running
DB_UNREACHABLEthe database server does not answer
SNAPSHOT_NOT_FOUNDno snapshot by that name
PHP_VERSION_MISSINGthe PHP version is not installed (the hint has the install command)
XDEBUG_MISSINGXdebug is not installed for that PHP (the hint has the install command)
TEMPLATE_VAR_UNRESOLVEDa template variable is unknown or its service is missing
ENGINE_FAILEDthe web server did not start
PROC_FAILEDa process exited right after starting
ACTION_FAILEDa quick action exited non-zero (the message has its last lines)
SITE_NOT_MOUNTEDthe caddy or PHP container does not see the site at the same path
CADDY_UNREACHABLECaddy's admin API does not answer
INTERNALanything else

Environment variables

VariableUsed byMeaning
XDG_CONFIG_HOMECLIdevkit keeps its state in $XDG_CONFIG_HOME/devkit (default ~/.config/devkit). Point it at an empty folder to try things without touching your real setup
XDG_DATA_HOMECLI (Linux)the Trash for site delete --trash: $XDG_DATA_HOME/Trash (default ~/.local/share/Trash)
CODEX_HOMEmcp config codexwhere Codex's config.toml is (default ~/.codex)
CAROOTCLI, via mkcertmkcert's CA folder
PATHCLIwhere docker, git, composer, pnpm, mkcert and the default php are found
DEVKIT_BINappsthe devkit binary the app runs (as --devkit)
DEVKIT_CONFIG_HOMEappsrun devkit with XDG_CONFIG_HOME set to this (as --config-home)
DEVKIT_APP_LOGappsthe app's log file
DEVKIT_EDITORLinux appthe editor command for Open in editor; wins over Settings
TERMINALLinux appthe terminal for Open terminal here, Trust and hosts sync
DEVKIT_APP_THEMELinux applight or dark
DEVKIT_APP_CONFIGLinux appthe app's own settings file (default ~/.config/devkit-app/settings.json)
LANGUAGE, LC_ALL, LC_MESSAGES, LANGLinux appthe language when it is set to System

Inside a site, exec, processes and quick actions get your environment plus the site's PHP first on PATH; a process with a port also gets PORT. Template variables can read devkit's environment with {{env.NAME}}.