Skip to content

Onboard workspace và repo ​

Trang này gom lại các lệnh dùng khi đưa một máy mới vào workspace, hoặc khi sửa lại layout repo trên một workspace đã có. Với luồng đầy đủ từng bước, đọc Bắt đầu nhanh trước.

Khi nào dùng ​

Dùng các lệnh ở đây khi cài ZenifyKit trên một máy mới, khi team thêm repo và bạn cần kéo về đúng bộ, khi cần kiểm tra môi trường đang thiếu gì, hoặc khi một workspace cũ có repo nằm rải ở gốc và cần chuyển sang layout repos/<tên>.

Các bước ​

Trình tự onboard một máy mới

zenify up chạy an toàn nhiều lần: mỗi lần chạy lại nó chỉ sửa những gì lệch so với cấu hình chung của team, không ghi đè việc bạn đã tự chỉnh.

Lệnh ​

zenify up ​

Onboard máy vào workspace. Chạy trong terminal, lệnh mở wizard: chọn thư mục workspace, chọn repo bạn có quyền truy cập, rồi, với manifest không khai báo broker:, nhập các key toàn cục vào <workspace>/.zenify/.env. Khi manifest khai báo broker:, credential DB, E2E và PostHog đi qua broker và wizard không hỏi các key đó; xem Dùng credential broker.

Khi apply, lệnh clone repo còn thiếu, ghi các file cấu hình do kit sở hữu, cài kit vào gốc workspace (không vào cấp user): plugin znf@zenify-kit từ marketplace ~/.zenify/plugin-marketplace cài --scope local, hook znf và git-guard ghi vào .claude/settings.local.json của workspace, bốn MCP server zenify-grafana, zenify-posthog, zenify-zenie, zenify-plane đăng ký -s local. Vì vậy kit chỉ hoạt động khi session mở ở gốc workspace; ngoài workspace và trong thư mục con (repos/<repo>) kit không bật, nên hãy luôn mở session ở gốc. Lệnh cũng đánh dấu workspace là đã trust trong ~/.claude.json (projects["<workspace>"].hasTrustDialogAccepted = true, không đụng key khác), vì Claude chỉ chạy headersHelper của MCP local, nên zenify-grafana, zenify-posthog và zenify-zenie mới có header xác thực, khi workspace đã trust; máy chưa từng chạy claude (chưa có ~/.claude.json) thì bước này lỗi, zenify doctor báo ở mục claude-trust, và zenify down không gỡ cờ này. Kết thúc cài local, lệnh gỡ bản cài cấp user của kit bản cũ; việc gỡ là tất cả hoặc không gì, nên nếu một bước local lỗi (kể cả máy không có claude trên PATH) bản cấp user được giữ, hook znf, git-guard và hook Codex vừa ghi vào workspace được gỡ lại để không chạy hai lần, và zenify up thoát khác 0, rồi lần sau thử lại. Nếu chính bước gỡ bản cấp user dừng giữa chừng (ví dụ claude mcp remove lỗi), hook nào còn bản cấp user thì bản trong workspace của nó được gỡ lại, để mỗi hook chỉ chạy một lần. Các SessionStart sau cũng không ghi lại hook đó cho tới khi bản cấp user hết, và khi bước local lỗi thì zenify-plane chưa được đăng ký (hook plane-guard của nó nằm trong workspace). MCP -s user chỉ bị gỡ khi bản -s local cùng tên đã đăng ký và chính bản -s user là của kit; MCP bị bỏ qua đăng ký và server bạn tự cấu hình dưới cùng tên giữ bản -s user. Riêng zenify-plane: nếu chưa đăng ký được bản local (chưa có PLANE_API_KEY hoặc uv) mà máy còn zenify-plane cấp user của kit, up giữ nguyên toàn bộ bản cài cấp user (để plane-guard vẫn hỏi trước mỗi thao tác ghi Plane), in hướng dẫn rồi thoát khác 0. ~/.claude/skills/znf có file bạn đã sửa hoặc thêm thì được chuyển sang ~/.zenify/backup/skills-znf-<thời điểm> thay vì xoá. Hook, agent và link skill Codex ở ~/ chỉ bị gỡ khi workspace đã có bản thay. CLAUDE_CODE_SUBAGENT_MODEL và ZNF_REVIEWER bạn đã đặt ở cấp user được chép sang workspace thay cho giá trị mặc định. Skill và hook cá nhân trong ~/.claude giữ nguyên. Máy chưa chạy zenify up --apply bản này vẫn có kit ở cấp user: SessionStart không ghi gì vào workspace và in kit vẫn cài ở cấp user; chạy zenify up --apply để chuyển sang workspace. Đồng bộ plugin skill, chuẩn bị Playwright nếu workspace có repo frontend, cài extension gh-stack nếu thiếu (gh extension install github/gh-stack, lỗi chỉ cảnh báo), clone knowledge store và ghi con trỏ workspace vào ~/.zenify/workspace. Với Playwright, lệnh cài @playwright/cli@0.1.22 (ghim phiên bản) vào ~/.zenify/playwright/cli/pkg và Chromium revision 1247 qua đúng gói đó, nên trình duyệt chỉ tải lại khi kit nâng pin, tiến trình tải hiện ngay trên terminal; khi đúng bản Chromium đó đã cài xong, lệnh bỏ qua bước cài và in chromium <revision> already installed. znf:ui-verifier điều khiển trình duyệt qua zenify browser, mỗi verifier một phiên riêng nên chạy song song được. Lệnh gỡ Playwright MCP do kit từng đăng ký (ở mọi workspace, cả Claude và Codex khi codex có trên PATH), còn đăng ký bạn tự cấu hình thì giữ nguyên và lệnh in một dòng báo giữ; lệnh cũng bỏ các rule mcp__playwright__* kit từng thêm vào permissions.allow. Lệnh thêm vào permissions.allow của <workspace>/.claude/settings.local.json rule Bash(zenify browser *) mà znf:ui-verifier dùng, cùng Bash(zenify e2e *) và Bash(zenify visual *) và Bash(zenify ui-verify *), nên verify UI không hỏi quyền. Lệnh cũng thêm Bash(zenify db-read *), Bash(zenify redis-read *) và Bash(zenify data run *) vào permissions.allow, và zenify db-read *, zenify redis-read *, zenify data run * vào sandbox.excludedCommands, vì ba lệnh này gọi broker và lệnh con của data run nối thẳng tới DB. Lệnh con sau -- của data run vì vậy chạy không hỏi quyền và ngoài sandbox; git-guard vẫn xét lệnh con, còn ghi production vẫn cần role lead ở broker và dry-run trước. Riêng ghi production thì có hỏi: lệnh thêm Bash(zenify *data run*--prd*--write*) và Bash(zenify *data run*--write*--prd*) vào permissions.ask, nên mọi lệnh data run có cả --prd lẫn --write hiện prompt kể cả khi bật bypass (rule ask thắng rule allow). Lệnh cũng thêm Bash(ssh *) vào permissions.ask: lệnh chạy trên server nằm ngoài tầm git-guard và không hoàn tác được, nên mỗi lần ssh đều hỏi. zenify down gỡ các rule ask này cùng các mục kit khác. Lệnh cũng thêm vào permissions.allow cho stacked PR đúng các lệnh gh stack mà skill dùng: Bash(gh stack --help) và Bash(gh stack <lệnh> *) với init, add, checkout, rebase, push, submit, view; lệnh gh stack khác vẫn hỏi quyền. Lệnh cũng thêm zenify e2e login * và zenify browser * vào sandbox.excludedCommands, vì sandbox Bash chặn zenify e2e login ghi ~/.zenify và gọi app local, còn zenify browser chạy Chromium và ghi vào thư mục phiên; các lệnh zenify e2e khác vẫn chạy trong sandbox. Tương tự, gh stack <lệnh> * với bảy lệnh đó cũng được thêm vào sandbox.excludedCommands vì chúng đọc auth của gh và gọi GitHub, cả hai đều bị sandbox chặn; lệnh gh stack khác vẫn chạy trong sandbox, và git-guard vẫn chặn merge, gỡ, ghép stack và gh stack alias trước mọi rule quyền. Khi bạn không bật sandbox, mục này không có tác dụng. zenify down chỉ gỡ các mục kit đã thêm, mục bạn có từ trước vẫn còn; luật deny .zenify/.env của workspace đó do kit thêm bị gỡ khỏi ~/.claude/settings.json, luật deny bạn tự thêm và luật của workspace khác giữ nguyên. Mục kit mà bạn đã tự xoá khỏi permissions.allow hoặc sandbox.excludedCommands sẽ không bị thêm lại, kể cả mục bạn xoá ở ~/.claude/settings.json trước khi chuyển sang workspace. Lệnh cần gh đã đăng nhập với scope read:org và repo.

Credential nằm ở <workspace>/.zenify/.env, không còn là placeholder trong khối env của settings; zenify up --apply dựng file thành khung có sẵn mọi key của manifest (key trống là KEY=), chia mục Staging, Tooling, Production, Custom; wizard chỉ hỏi các key toàn cục, bỏ nhóm production. Key không có trong manifest, ví dụ OPENROUTER_API_KEY, là key custom, thêm bằng zenify env set OPENROUTER_API_KEY --desc "key cá nhân". zenify up --apply chuyển key manifest còn nằm trong khối env của settings.local.json sang file mới và thêm luật deny Read(//<workspace>/.zenify/.env) (đường dẫn tuyệt đối) vào ~/.claude/settings.json. Chi tiết và quy tắc khi hai giá trị khác nhau: Credential dev với zenify env.

Khi một repo trong workspace cài package từ GitHub Packages (.npmrc trỏ tới npm.pkg.github.com và đọc token từ ${NPM_TOKEN}), zenify up thêm một dòng export NPM_TOKEN="${NPM_TOKEN:-$(gh auth token 2>/dev/null)}" # zenify-npm-token vào profile shell (~/.zshrc, hoặc ~/.bashrc/~/.profile với bash) để shell mới có NPM_TOKEN; NPM_TOKEN đã có sẵn trong môi trường thì được giữ nguyên. Sau đó chạy source <profile> hoặc mở terminal mới trước khi npm install. Token không được ghi ra đĩa hay in ra, nhưng đó là toàn bộ token của gh auth token (mọi scope gh đang giữ, không chỉ read:packages) và được export cho mọi shell mới. Nếu gh chưa có scope read:packages, zenify up chạy gh auth refresh -h github.com -s read:packages khi có TTY, còn với --non-interactive hoặc không có TTY thì in lệnh để bạn tự chạy. Profile đã tự đặt NPM_TOKEN thì giữ nguyên; shell khác zsh/bash thì lệnh in dòng trên để bạn tự thêm. zenify down không gỡ dòng # zenify-npm-token, hãy xoá tay nếu không cần nữa. Khi thiếu NPM_TOKEN, mục npm token (GitHub Packages) của zenify doctor báo hỏng, nên zenify doctor --exit-on-fail thất bại cho tới khi sửa xong. Muốn chạy lại riêng phần này, dùng zenify npm login: lệnh luôn chạy, kể cả khi không có repo nào cần GitHub Packages.

bash
zenify up
zenify up --non-interactive --dry-run --workspace ~/WorkingSpace/zenify
zenify up --non-interactive --apply --workspace ~/WorkingSpace/zenify
CờÝ nghĩa
--applyThực thi kế hoạch. Không kèm cờ này và không ở terminal, lệnh chỉ in kế hoạch
--dry-runChỉ in kế hoạch, không đổi gì. Mặc định khi chạy ngoài terminal
--non-interactiveKhông mở wizard kể cả khi đang ở terminal. Dùng trong script
--workspaceThư mục workspace

zenify down ​

Gỡ phần ZenifyKit đã cài vào máy và repo, giữ nguyên code, workspace và knowledge store. Đây là bước đảo của zenify up. Mặc định chỉ in preview, thêm --apply để thực thi. Lệnh gỡ plugin và marketplace local, MCP local, hook và các key kit sở hữu trong .claude/settings.local.json, file Codex trong workspace cùng mục trust, và mọi bản cài cấp user còn sót; file settings.local.json của workspace vẫn còn, và chạy lại không có hại. Lệnh không đụng vào repo đã clone hay knowledge store.

bash
zenify down
zenify down --apply

zenify doctor ​

Kiểm tra sức khỏe môi trường và báo từng mục đạt hay hỏng: phiên bản binary, đăng nhập git và quyền GitHub, danh tính commit của git (user.name, user.email), mục npm token (GitHub Packages) (chỉ áp dụng khi có repo cài từ GitHub Packages: báo gh thiếu scope read:packages, chưa đăng nhập, hoặc NPM_TOKEN chưa có; sửa bằng zenify doctor --fix hoặc zenify npm login; mục này chỉ xét account github.com đang active của gh và báo gh auth status timed out nếu gh auth status không trả lời sau 10 giây), credential trong .zenify/.env (secrets báo theo tên key toàn cục (trừ nhóm production) có giá trị hay trống, env-file báo quyền rộng hơn 0600 và key custom chưa có mô tả, settings-env báo theo tên key còn nằm trong settings), mục broker-creds (xin thử credential staging từ broker, báo tên biến nhận được; bỏ qua khi không có broker), tool bên ngoài (git, gh, mongosh, mysql), Playwright (mục playwright: @playwright/cli đã cài và Chromium đúng revision, chỉ đọc nên không mở trình duyệt; báo hỏng nếu MCP playwright do kit đăng ký vẫn còn, còn đăng ký bạn tự cấu hình không làm mục này hỏng), quyền zenify browser/zenify e2e/zenify visual/zenify ui-verify trong permissions.allow của workspace, znf-plugin (plugin bật ở workspace), git-guard và codex-hooks (đọc vị trí ở workspace), mục gh-stack (cần gh từ 2.90.0 và extension github/gh-stack; zenify doctor --fix cài extension nếu thiếu bằng gh extension install github/gh-stack), và Docker. Chạy ngay sau zenify up, và mỗi khi một skill báo thiếu tool hoặc thiếu secret. Lệnh chỉ đọc, chạy bao nhiêu lần cũng được.

bash
zenify doctor
zenify doctor --fix
CờÝ nghĩa
--fixTự sửa các mục an toàn rồi kiểm tra lại. Mục cần bạn tự làm vẫn in hướng dẫn
--exit-on-failTrả mã thoát khác 0 khi có mục hỏng, dùng trong script và CI
--jsonIn kết quả dạng JSON

zenify migrate ​

Gom các repo đang nằm rải ở gốc workspace vào thư mục con repos/<tên>, layout mà zenify up dùng. Chạy một lần khi workspace cũ chưa theo layout này.

bash
zenify migrate
zenify migrate --apply

Mặc định lệnh chỉ liệt kê từng repo với hành động Move, Refuse hoặc Skip kèm lý do. Với --apply, lệnh di chuyển repo, sửa lại liên kết worktree, trỏ lại symlink node_modules và cập nhật đường dẫn trong manifest workspace, rồi nhắc bạn khởi động lại dev server đang chạy. Repo còn thay đổi chưa commit hoặc có worktree đang mở bị đánh Refuse.

zenify update ​

Nâng cấp binary lên bản mới nhất bằng đúng kênh đã cài (Homebrew, Scoop, hoặc script cài đặt), hoặc chỉ kiểm tra có bản mới với --check. Đầu mỗi phiên, binary tự in dòng zenify: vX is available khi có bản mới; đặt ZENIFY_NO_UPDATE_CHECK=1 để tắt dòng nhắc này.

bash
zenify update --check
zenify update

Cấu hình worktree của một repo ​

Mỗi repo tham gia workspace khai báo một file .claude/worktree.json, ví dụ của zenify-kit:

json
{
  "abbrev": "kit",
  "baseRef": "origin/main",
  "worktreeDir": ".worktrees/",
  "copy": [".claude/settings.local.json"],
  "deps": "none",
  "portEnv": "PORT",
  "portRange": [3750, 3799]
}
TrườngÝ nghĩa
abbrevtên viết tắt của repo
baseRefbranch gốc mặc định cho zenify wt new --type feat/fix
hotfixBaseRefbase ref riêng cho --type hotfix, nếu khác baseRef
worktreeDirthư mục chứa các worktree, thường .worktrees/
copycác file được seed từ checkout chính vào worktree mới, ví dụ .claude/settings.local.json và CLAUDE.md. Nhờ seed .claude/settings.local.json, worktree dùng chung secret và bộ nhớ với checkout chính, xem Secret và settings.local.json
depscách seed dependency: symlink, clone, hoặc none cho repo không phải Node
installlệnh cài dependency khi deps cần cài riêng. Với clone, lệnh này được bỏ qua khi package-lock.json của worktree giống bản ở checkout chính và node_modules ở đó khớp lock, xem zenify wt new. Chế độ clone còn dùng một cache deps bật sẵn, khoá theo hash của package-lock.json cộng với dấu vân tay môi trường build (Node ABI/platform/arch), nên wt new lặp lại vẫn nhanh dù checkout chính đang ở branch nào; tắt bằng ZENIFY_DEPS_CACHE=off
portEnvtên biến môi trường worktree đọc port từ đó
portRangekhối port riêng của repo, không trùng repo khác trong workspace

Lưu ý về cache deps: cache khoá theo hash của package-lock.json cộng với Node ABI/platform/arch, nên khi đổi Node (ví dụ qua nvm) wt new tự dùng một slot khác — đây là cache miss tự động, không phải việc xoá tay, và không còn nguy cơ dùng lại native module build cho ABI cũ. Cây node_modules cài với ignore-scripts=true (deps chưa build) không được ghi vào cache. ZENIFY_DEPS_CACHE=off và --install chỉ bỏ qua việc đọc cache, không xoá slot cũ.

Chi tiết cách chọn baseRef, hotfixBaseRef và dải port cho repo mới: Base ref và port block.

Kết quả ​

.worktrees/ phải nằm trong .gitignore đã commit của mỗi repo, không nằm trong .git/info/exclude. Khai báo cục bộ không đi theo repo, nên đồng nghiệp clone lần đầu sẽ thấy checkout bị bẩn ngay khi chạy zenify wt new.

Lưu ý ​

  • zenify up chạy lại được bất cứ lúc nào, kể cả sau khi team thêm repo mới.
  • Repo không phải Node vẫn onboard bình thường, chỉ cần .claude/worktree.json khai "deps": "none" và một khối port riêng.

Xem thêm ​

zenify up, zenify doctor, zenify npm login, zenify migrate, zenify down, zenify update, Bắt đầu nhanh, Base ref và port block