devkit Tiếng Việt

The desktop apps

devkit has two desktop apps: devkit.app, a menu-bar app for macOS 14 or later, and devkit-gtk, a GTK 4 tray app for Linux. They look and work the same. Both are a face on the CLI: every button runs a devkit … --json command, and one devkit watch --json keeps the window live. Whatever you do in a terminal shows up in the app within a couple of seconds, and the other way round.

On macOS devkit is an icon in the menu bar (a box, filled while any site runs) with no Dock icon. Clicking it opens a panel:

  1. Header: "devkit", a summary such as 3 sites running, and a button that opens the manager window.
  2. One card per stack: its name, 4 of 5 up, and a dot per service (hover for its state and role).
  3. Running: every running site and lane with its URL (click to open) and a stop button; then a link such as 2 stopped sites → to the manager.
  4. Start all (every stopped, visible site and lane, one after the other) and Stop all (lanes first, then sites).
  5. AI agents connected, when an agent runs devkit mcp, with the time of its last call. It opens the MCP section.
  6. Open devkit…, Run doctor (the full report), Quit devkit.

On Linux the same content is a tray menu (a StatusNotifierItem). Each stack is a submenu of its services; each running site is a submenu with Open, Copy URL and Stop. A left click on the icon opens the manager window. KDE Plasma, Xfce, Cinnamon, MATE, LXQt and Budgie show the tray; GNOME needs the AppIndicator extension. Without a tray, or with --no-tray, the app shows the panel as a small window instead and quits when its last window closes.

The manager window

A sidebar with seven sections, in this order: Sites, Lanes, Stacks, PHP, Templates, Settings, MCP.

  • Search (Search sites) appears in Sites and Lanes and matches name, branch or URL, ignoring case and accents.
  • The status bar at the bottom shows how many sites there are and how many run, Engine default: artisan · ports 8100–8999, and on the right the connected MCP agents (a link to the MCP section).
  • Notices: the result of an action (a quick action's output, an error with devkit's hint) appears as a banner at the top of the section, closed with Dismiss.
  • One change at a time per site: while devkit works on a site (starting, a checkout, a clone, a restore) its row shows a spinner and the entries that would change it wait. Its open, view and log entries still work.

Sites

At the top, a strip per stack with its service dots and Inbox ↗ when it has a mail catcher. Then the sites: Parked (one group per parked directory, with Clone from git… on its right) and Linked. The header has Link folder… and Park directory…, both with a folder picker.

ColumnWhat it shows
Sitethe name (click for the site detail); lanes are indented under their site with lane 1, lane 2…
Branchthe git branch, an orange dot for uncommitted changes, and ahead/behind or no upstream under it
Engineartisan or caddy
PHPa picker for the site's version (a lane shows its site's, inherited)
URLwhere it is served
Databasethe database name
DoctorOK, 2 warnings or 1 failure from devkit doctor <site>, run at launch and when a site appears
Actionsstart or stop, open in the browser, the red trash (delete; for a lane: remove) and …

The … button, or a right-click on the row, opens the site's menu: a panel with the site's name and what it runs, then these groups.

GroupSiteLane
OpenOpen in browser ⌘O, Open in editor ⌘E, Open terminal here ⌘T, Copy URL ⌘Cthe same
ToolsNew lane…, Edit .env template…, View logs, Modules, Run doctorView logs, Modules, Run doctor
Quick actionsClear log, Clear cache, Publish core assets and the site's own, each with its command as a hintthe same
WebChange engine…, Xdebug…Xdebug…
DatabaseSnapshot database, Restore snapshot…Snapshot database, Reset database from <site>…
RemoveHide from devkit (keeps files), Delete site… (deletes code)Remove lane… (drops its database)

The shortcuts work while the panel is open (on Linux Ctrl+O/E/T/C). On macOS the right-click menu has the same entries without shortcuts; on Linux a right-click opens the same panel.

The site detail

Click a site's name. At the top: a breadcrumb, the status, the URL and the branch bar: a branch picker (local branches, remote ones without a local copy, New branch…), the sync state (up to date with origin/main · clean), Fetch, Pull (blue Pull ↓3 when behind), Push (blue Push ↑2 when ahead) and Include submodules (on). Picking a branch does not check it out at once: a box says what will happen (the site restarts, submodules move or stay) and waits for Check out.

Below: the quick actions as one group of buttons, Open in editor, New lane… (a lane: Remove lane…) and Start site / Stop site. Then cards for the Engine (with its port), PHP (a picker; a lane shows 8.3 · follows core-development), Database, Xdebug (opens the Xdebug sheet) and Mail inbox when the stack has one.

Switching PHP from this card shows a banner: Switching to PHP 8.2, then Switched to PHP 8.2, saying that serve and the PHP processes keep the old version until the site restarts, that lanes follow the site, and any doctor problem with the new version. Restart now restarts the site and its running lanes; Undo puts the old version back. (The picker in the Sites table and in the Settings tab switch without a banner.)

Then five tabs:

Processes
The serve row (php artisan serve --port=8100, or caddy route → php-fpm) with its pid, Restart, Stop / Start and Logs; then every process with its command and port, its status (running, stopped, exited with its last lines on hover), the Autostart switch (with site), start, stop, restart and Logs. The selected log is shown below, refreshed every two seconds, with Open in logs….
Modules and Extensions
The submodules of modules/ and extensions/. Across the top: a Branch field, Create if missing, Checkout in all modules, Fetch, Pull all, Push all (enabled when something is ahead) and, on Extensions, Add extension…. Each row: a branch picker (the module's branch, the branch .gitmodules tracks, the site's branch, New branch…), a blue dot when it is not on the tracked branch, Tracks, Changes (clean or 3 changed), Ahead / behind, Pull, Push and Terminal. A row with uncommitted work refuses a checkout: Commit or stash first.
Database
The database (forked from core_development for a lane), Snapshot database…, for a lane Reset from <site>…, and the snapshots (name, created, size) with Restore… and Drop….
Settings
Engine (Change engine…), PHP, Xdebug (Xdebug…), Database, the folder with Reveal, and the branch.

The sheets

Every change that needs a decision opens a sheet. Return presses the main button and Esc cancels, except while devkit is working. Red, destructive buttons have no Return shortcut.

SheetWhat it asksDefaults
New lane from <site>Lane name; Branch: Create feat/<name> from a base branch, or Use an existing branch; Database: Fork with data, Schema only or Empty database; Start the lane when it is readyCreate from the current branch, Fork with data, start on
Clone into <directory>Repository URL, Folder name, Branch, Clone into (with several parked directories), the steps under After cloningevery step on except Start the site when ready
Delete <site>?what devkit says would go (folder, lanes, Caddy route), Drop database, Move the folder to the Trash instead of deleting it permanently, and the site's name typed to confirm. With work that exists only on this machine: Delete anyway and lose this workTrash on, drop database off
Remove lane <lane>?what lane rm --dry-run reports, Keep the database, Also delete the local branch; with unsaved work Remove anyway and discard this workboth off
Hide <site> from devkit?nothing: it says the site and its lanes stop and nothing on disk changes
Snapshot <database>Name (empty: the current time); shows the existing snapshots
Restore <database>which snapshot, Snapshot the current database first; What happens lists the three stepssafety snapshot on
Reset <lane>'s database?Schema and data or Schema only, Snapshot the lane database before resettingschema and data, snapshot on
Drop snapshot <name>?a confirmation: a dropped snapshot cannot be brought back
Xdebug · <site>the mode (off, debug, coverage, profile); for debug how to start a session (trigger, client host, port 9003, path mapping); which sites a container change affectsdebug when off
Web server engine · <site>artisan or caddy, What changes (URL, PHP, DB_HOST, REDIS_HOST, port) and Requirements (PHP installed, a free port; or Caddy and PHP services, the same-path mount, a certificate)the other engine
.env template · <site>Template / Rendered .env, Show passwords and secrets, Variables · click to insert, Save, Save and restart sitesecrets hidden
Add to extensions · <site>Repository URL, Folder name, Branchthe repository's default branch
Logs · <site>a tab per source, Filter lines, Follow, Copy visible lines, Reveal in Finderlast 200 lines, following
Doctor · <site>every check with its status and hint, Copy report, Run again

How the apps confirm

  1. They ask devkit first. A destructive sheet runs the command without --yes (or with --dry-run) and shows devkit's own answer: the uncommitted work, the database that will be dropped, the restore steps.
  2. They ask again right before acting. If the answer changed in between (someone committed, a snapshot appeared, an agent started the site), nothing is done and the sheet says This changed since you last looked with the new answer. Any "anyway" box is cleared.
  3. Only then do they pass --yes or --force.

The same applies to the default engine, the domain suffix and the port range in Settings, which go through --dry-run.

Lanes

Every lane under its site, with the same columns as Sites. New lane… at the top is a menu with one entry per site, and each site group has its own New lane….

Stacks

Add stack… picks a compose folder. Each stack is a card with Reveal, Start, Restart, Stop…, the mail Inbox ↗ and how many services are hidden by label, and a table of its services: Service, Role, Image, Ports, State and per service Restart, Stop… or Start, and Logs. Stop… warns that running sites that may use the stack's database or Redis stop working. Stopping a whole stack is docker compose down (containers removed, volumes kept); one service is docker compose stop.

PHP

Rescan and Add binary… at the top. Then:

  • Default PHP: php on PATH or one of the versions, set at once.
  • Host PHP: a card per binary (version, path, sites, Xdebug, extensions). The selected one's panel has Open php.ini, Copy path, Set as default, Xdebug or how to install it, Used by, Loaded extensions and composer check-platform-reqs for each site on it, plus Check another site.
  • In the same grid, a not installed card for a version a site needs, with the install command and Copy command. It is never run for you.
  • Scan locations: each path with an on/off box, where it comes from (Homebrew, System, phpenv, Added…) and a remove button; Add location; Reset to defaults….
  • Container PHP: the stacks' PHP-FPM services with version, image, state, the caddy sites on each and Xdebug (all sites); changing that opens a sheet naming the sites it affects.

Templates

One row per site: whether its template is stored or still seeded from .env (not stored), which lanes use it, whether it renders (every variable resolves), and Edit…, which opens the .env template sheet. Its Rendered .env tab is devkit template render --file of your draft, so you see the real result before saving.

Settings

  1. Default web server engine: artisan or caddy. Choosing one opens a sheet with the running sites that would stop.
  2. Port range: From, To, Apply…, and how many ports are in use.
  3. Domain suffix: caddy sites resolve as <site>.<suffix>; Apply….
  4. Certificates: whether mkcert's CA is trusted and how many site certificates were issued; Trust… and Check again.
  5. Hosts: whether devkit's block in /etc/hosts is current; Sync in Terminal… and Check again.
  6. PHP binaries: a summary with Manage in PHP → and Add path….
  7. Doctor: the full report for the machine and every site, Copy report, Run again.
  8. Hidden sites: each with Show again.
  9. This app: devkit binary, Editor, Open devkit at login and Language, described below.

Trust… and Sync in Terminal… never run inside the app, because they ask for your password. The app asks Run devkit trust in Terminal?, writes a small self-deleting script with the app's devkit, PATH and config folder, and opens it in a terminal. When it is done, go back and press Check again.

This app

devkit binary
Which devkit the app runs, from the next launch. Empty means the one inside the app, then the first on PATH. The --devkit launch option and DEVKIT_BIN win over it. devkit now shows which one is in use.
Editor
What Open in editor opens the site folder with. macOS: Default (system) (Visual Studio Code when installed, else Finder), an installed editor, or any app with Choose app…. Linux: a command, run with the folder as its argument (split as a shell would; ~ and $VAR are expanded in the program name); empty means code when it is on PATH, else the folder in your file manager. DEVKIT_EDITOR wins over it on Linux.
Open devkit at login
macOS adds a login item (System Settings may ask you to approve it under General → Login Items; the app offers Open Login Items). Linux writes ~/.config/autostart/vn.webpress.devkit.desktop.
Language
System, English or Tiếng Việt, used from the next launch; Relaunch now restarts the app. System follows your preferred languages on macOS and LANGUAGE, LC_ALL, LC_MESSAGES, LANG on Linux. On Linux the window's Menu button has the same choice. What devkit itself says (its messages, errors, hints and confirmations) stays in English, as the CLI writes it.

MCP

  • Connect an agent: one pill per agent (Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code · Copilot, Claude Desktop, Other (stdio)) with its terminal command or config file and Copy. For the agents configured per project (Claude Code, Gemini CLI, Cursor, VS Code) Write to project… picks a project folder and merges the entry into its config file, keeping a backup.
  • Connected: each running devkit mcp with its agent, pid, start time and number of calls.
  • Tools: every tool by group, with a confirm badge on the destructive ones.
  • Audit log: the latest calls (time, agent, tool, target, arguments, result), newest first, reloaded when an agent makes a call; Refresh and Reveal in Finder.

Details are in AI agents (MCP).

macOS and Linux differences

macOSLinux
Where it livesa menu-bar panela tray menu, or a panel window without a tray
Shortcuts in the … panel⌘O ⌘E ⌘T ⌘CCtrl+O/E/T/C
Trust and hosts syncopen in Terminal.appopen in $TERMINAL, else the first of x-terminal-emulator, gnome-terminal, ptyxis, kgx, konsole, xfce4-terminal, alacritty, kitty, xterm
Open terminal hereTerminal.appthe same terminal choice
Folder and terminal labelsReveal, Reveal in Finder, Sync in Terminal…, Run devkit trust in Terminal?Show in folder, Sync in a terminal…, Run devkit trust in a terminal?
Editor settingan app pickera command; DEVKIT_EDITOR wins
Open at logina login iteman XDG autostart file
Language settingSettings → This appSettings → This app, and the window's Menu
App settings stored inmacOS defaults (vn.webpress.devkit)~/.config/devkit-app/settings.json (DEVKIT_APP_CONFIG)
Light or darkfollows macOSfollows the desktop; DEVKIT_APP_THEME=light|dark forces one
PHP install commandsbrew install php@X.Yapt, dnf, pacman/AUR or Homebrew, after /etc/os-release
.local warningmDNSAvahi (mDNS)
App log~/Library/Logs/devkit/devkit-app.log~/.local/state/devkit/devkit-app.log

On Linux, quitting while devkit is still running a change waits for it to finish (Waiting to quit); quit again to interrupt it.

Launch options and the app log

Both apps read your login shell's PATH once at launch ($SHELL -ilc) and pass it to devkit, so docker, git, composer, pnpm and Homebrew's PHP are found as in your terminal. If the app cannot find a tool, check that it works in a new terminal window, then quit and reopen the app.

OptionVariableWhat it does
--devkit <path>DEVKIT_BINthe devkit binary to run
--config-home <dir>DEVKIT_CONFIG_HOMErun devkit with XDG_CONFIG_HOME=<dir>: a separate set of sites and settings, handy for trying things
--open-manageropen the manager window at launch
--no-tray (Linux)use the panel window instead of the tray
DEVKIT_APP_LOGwhere the app logs what it ran and what came back

On macOS pass options with open /Applications/devkit.app --args --open-manager and variables with open --env NAME=value. open devkit.app --args -AppleLanguages '(vi)' starts it in Vietnamese once. The app log records command lines and their answers, with credentials in URLs removed; it is the first thing to look at when a button does not do what you expect, and the thing to attach to a support request.