أوامر مخصصة
عرّف الأوامر المخصصة وتخطيطات مساحة العمل بإضافة ملف cmux.json إلى جذر مشروعك أو ~/.config/cmux/. تظهر الأوامر في لوحة الأوامر.
مواقع الملفات
يبحث cmux عن التكوين في مكانين:
- لكل مشروع:
./.cmux/cmux.json- يقع في دليل مشروعك، له الأولوية - محلي احتياطي:
./cmux.json- ما زال مدعومًا للمستودعات الحالية - عام:
~/.config/cmux/cmux.json- ينطبق على جميع المشاريع، يملأ الأوامر غير المعرفة محلياً
actions أو shortcut أو ui.surfaceTabBar.buttons.عدّل cmux.json، ثم اضغط Cmd+Shift+, أو شغّل cmux reload-config لتطبيق التغييرات.
المخطط
ما زالت commands تعرّف أوامر shell القابلة لإعادة الاستخدام وتخطيطات مساحات العمل. تضيف إصدارات nightly سجل actions. الإجراءات هي المعرفات العامة المشتركة بين شريط تبويبات السطح وCommand Palette واختصارات مستوى الإجراء.
{
"actions": {
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"subtitle": "Open Codex in a new terminal tab",
"command": "codex --dangerously-bypass-approvals-and-sandbox",
"target": "newTabInCurrentPane",
"shortcut": "cmd+t",
"icon": { "type": "image", "path": "./icons/codex.svg" }
},
"claude": {
"type": "command",
"title": "Claude Code",
"command": "claude --dangerously-skip-permissions",
"target": "newTabInCurrentPane",
"shortcut": "cmd+shift+c",
"icon": { "type": "image", "path": "./icons/claude.svg" }
},
"opencode": {
"type": "command",
"title": "OpenCode",
"command": "opencode",
"target": "newTabInCurrentPane",
"palette": false,
"icon": { "type": "emoji", "value": "🧪", "scale": 0.9 }
},
"web-dev": {
"type": "workspaceCommand",
"title": "Web Dev",
"commandName": "Web Dev"
}
},
"ui": {
"surfaceTabBar": {
"buttons": [
"cmux.newTerminal",
"cmux.newBrowser",
"cmux.splitRight",
"cmux.splitDown",
"claude"
]
}
},
"commands": [
{
"name": "Web Dev",
"keywords": ["dev", "start"],
"workspace": { ... }
}
]
}سجل إجراءات nightly
يربط actions معرفات ثابتة بسلوك قابل للتشغيل. استخدم المعرفات المدمجة cmux.newTerminal وcmux.newBrowser وcmux.splitRight وcmux.splitDown لتجاوز القيم الافتراضية. استخدم معرفاتك الخاصة لأدوات المشروع.
تكون palette بقيمة true افتراضيًا. اجعلها false لإخفاء الإجراء من Command Palette مع إبقائه متاحًا لشريط تبويبات السطح أو لاختصار. يستخدم shortcut صيغة اختصارات الإعدادات نفسها، مثل cmd+shift+c أو ["cmd+k", "cmd+c"].
يستبدل ui.surfaceTabBar.buttons قائمة الأزرار الافتراضية عند وجوده. اترك أي معرف مدمج خارج القائمة لإخفائه. تستخدم الأيقونات دائمًا شكل كائن: { "type": "symbol", "name": "play.circle" } أو { "type": "emoji", "value": "🧪", "scale": 0.9 } أو { "type": "image", "path": "./icons/codex.svg" }. مسارات الصور نسبية إلى ملف الإعداد. قيمة scale في emoji اختيارية وتكون 1 افتراضيًا. الصيغ SVG وPDF وPNG وJPEG وGIF وTIFF وBMP وHEIC وHEIF وWebP وAVIF وICO وICNS مدعومة.
يمكن أن يكون كل إدخال زر إما سلسلة معرف إجراء أو كائن زر. استخدم كائن زر عندما تريد الإجراء نفسه مع تسمية سطح أو أيقونة أو تلميح مختلف. يُستخدم عنوان الزر المحلول أيضًا كعنوان لمطالبة الثقة.
ضع أي أعلام موافقة أو أذونات مباشرة في سلسلة الأمر التي تريد تشغيلها فعلًا. هدف الإجراء الافتراضي هو newTabInCurrentPane، لذلك يكون النمط الشائع فتح تبويب طرفية جديد في اللوحة الحالية وبدء Codex أو Claude Code أو OpenCode هناك.
الإجراءات المخصصة ولوحة الأوامر
إدخال actions هو الشيء القابل لإعادة الاستخدام الذي يشغله cmux. استخدم الإجراءات عندما تريد إتاحة السلوك نفسه من لوحة الأوامر أو شريط تبويبات السطح أو الاختصارات أو قائمة زر الإضافة. أبقِ commands للأوامر الطرفية القابلة لإعادة الاستخدام وتخطيطات مساحات العمل. اضبط palette على false عندما يجب إخفاء الإجراء من لوحة الأوامر.
أنواع الإجراءات
"builtin": ينشئ اسما بديلا لإجراء cmux مدمج مثل cmux.newTerminal أو cmux.newBrowser أو cmux.splitRight أو cmux.splitDown."command": يشغّل نصا طرفيا. استخدم target لاختيار الطرفية الحالية أو تبويب جديد في اللوحة الحالية."agent": يشغّل وكيل برمجة مدعوما. يدعم اليوم codex و claude، مع وسائط اختيارية."workspaceCommand": يشغّل تعريف مساحة عمل مسمى من commands. استخدمه للتخطيطات متعددة اللوحات، ومجلدات العمل المخصصة، وأوامر البدء.
حقول الإجراء
title: عنوان صف لوحة الأوامر، وتسمية زر السطح، وعنوان عنصر القائمة، وعنوان طلب الثقة ما لم يستبدله إدخال آخر.subtitle/description: النص الثانوي في لوحة الأوامر. يقبل description كاسم بديل لـ subtitle.keywords: مصطلحات بحث إضافية للوحة الأوامر.palette: القيمة الافتراضية true للإجراءات المخصصة. اضبطها على false لإخفاء الإجراء من لوحة الأوامر مع إبقائه قابلا للاستدعاء من أماكن أخرى.shortcut: اختصار إجراء اختياري، باستخدام صيغة الضغطة الواحدة أو التسلسل نفسها مثل اختصارات الإعدادات.target: لإجراءات command و agent فقط. استخدم currentTerminal أو newTabInCurrentPane.confirm: اطلب التأكيد قبل تشغيل الإجراء.
سلوك لوحة الأوامر
تقرأ لوحة الأوامر سجل الإجراءات المحلول. تضاف معرّفات الإجراءات المخصصة كصفوف عندما لا تكون palette false. تضاف commands القديمة تلقائيا كصفوف مخصصة ما لم يكن إجراء بنفس المعرّف المولد موجودا بالفعل. تحتفظ الأوامر المدمجة بتسمياتها المعتادة في اللوحة، لكن تجاوز معرّف مدمج مثل cmux.newTerminal يغيّر السلوك خلف نقطة الدخول المشتركة.
إجراءات مخصصة لزر الإضافة
استخدم ui.newWorkspace.action لتجاوز ما يفعله زر الإضافة. استخدم ui.newWorkspace.contextMenu (أو الاسم البديل rightClick) لتعريف قائمة النقر بزر الفأرة الأيمن المرتبة. يمكن أن تكون عناصر القائمة معرفات إجراءات أو كائنات إجراءات أو { "type": "separator" }.
{
"actions": {
"worktree-agents": {
"type": "workspaceCommand",
"title": "Worktree Agents",
"commandName": "Worktree Agents",
"icon": { "type": "symbol", "name": "folder.badge.plus" }
}
},
"ui": {
"newWorkspace": {
"action": "worktree-agents",
"contextMenu": [
{ "action": "worktree-agents", "title": "Worktree Agents" },
{ "type": "separator" },
{ "action": "cmux.newTerminal", "title": "New Terminal" },
{ "action": "cmux.newBrowser", "title": "New Browser" }
]
}
},
"commands": [
{
"name": "Worktree Agents",
"description": "Create a fresh Git worktree and start Codex and Claude inside it",
"workspace": {
"name": "Worktree Agents",
"cwd": ".",
"layout": {
"direction": "horizontal",
"split": 0.38,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Worktree",
"command": "set -euo pipefail; state=\"${TMPDIR:-/tmp}/cmux-worktree-${CMUX_WORKSPACE_ID:-manual}.dir\"; rm -f \"$state\"; repo=$(git rev-parse --show-toplevel); mkdir -p \"$repo/../worktrees\"; slug=agents-$(date +%Y%m%d-%H%M%S); dir=\"$repo/../worktrees/$slug\"; git -C \"$repo\" worktree add -b \"$slug\" \"$dir\"; printf \"%s\\n\" \"$dir\" > \"$state\"; cd \"$dir\"; exec \"${SHELL:-/bin/zsh}\" -l",
"focus": true
}
]
}
},
{
"direction": "vertical",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Codex",
"command": "state=\"${TMPDIR:-/tmp}/cmux-worktree-${CMUX_WORKSPACE_ID:-manual}.dir\"; echo \"Waiting for worktree...\"; while [ ! -s \"$state\" ]; do sleep 0.2; done; dir=$(cat \"$state\"); cd \"$dir\"; exec codex --dangerously-bypass-approvals-and-sandbox"
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Claude",
"command": "state=\"${TMPDIR:-/tmp}/cmux-worktree-${CMUX_WORKSPACE_ID:-manual}.dir\"; echo \"Waiting for worktree...\"; while [ ! -s \"$state\" ]; do sleep 0.2; done; dir=$(cat \"$state\"); cd \"$dir\"; exec claude --dangerously-skip-permissions"
}
]
}
}
]
}
]
}
}
}
]
}يجعل هذا المثال النقر العادي على زر الإضافة يشغّل الإجراء worktree-agents. يستخدم أمر مساحة العمل من commands طرفية إعداد مرئية لإنشاء worktree في Git أولا. يبدأ Codex و Claude في الوقت نفسه، وينتظران ملف الحالة الخاص بمساحة العمل، ثم ينتقلان إلى المجلد المنشأ قبل exec.
أوامر بسيطة
الأمر البسيط ينفذ أمر shell في الطرفية المحددة حالياً:
{
"commands": [
{
"name": "Run Tests",
"keywords": ["test", "check"],
"command": "npm test",
"confirm": true
}
]
}الحقول
name: يظهر في لوحة الأوامر (مطلوب)description: وصف اختياريkeywords: مصطلحات بحث إضافية للوحة الأوامرcommand: أمر shell للتشغيل في الطرفية المحددةconfirm: عرض مربع حوار للتأكيد قبل التشغيل
تعمل الأوامر البسيطة في دليل العمل الحالي للطرفية المحددة. إذا كان أمرك يعتمد على مسارات نسبية للمشروع، أضف قبله cd "$(git rev-parse --show-toplevel)" && للتشغيل من جذر المستودع، أو cd /your/path && لأي دليل محدد.
أوامر مساحة العمل
يُنشئ أمر مساحة العمل مساحة عمل جديدة بتخطيط مخصص من الانقسامات والطرفيات وألواح المتصفح:
{
"commands": [
{
"name": "Dev Environment",
"keywords": ["dev", "fullstack"],
"workspace": {
"name": "Dev",
"cwd": ".",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Frontend",
"command": "npm run dev",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Backend",
"command": "cargo watch -x run",
"cwd": "./server",
"env": { "RUST_LOG": "debug" }
}
]
}
}
]
}
}
}
]
}حقول مساحة العمل
name: اسم علامة التبويب لمساحة العمل (الافتراضي: اسم الأمر)cwd: دليل العمل لمساحة العملcolor: لون علامة تبويب مساحة العملlayout: شجرة التخطيط التي تحدد الانقسامات والألواح
سلوك إعادة التشغيل
يتحكم فيما يحدث عندما توجد مساحة عمل بنفس الاسم:
"new": إنشاء مساحة عمل جديدة (الافتراضي)"ignore": التبديل إلى مساحة العمل الموجودة"recreate": الإغلاق وإعادة الإنشاء دون سؤال"confirm": السؤال قبل إعادة الإنشاء
شجرة التخطيط
تحدد شجرة التخطيط كيفية ترتيب الألواح باستخدام عقد الانقسام المتكررة:
عقدة الانقسام
تقسم المساحة إلى فرعين:
direction:"horizontal"أو"vertical"split: موضع الفاصل من 0.1 إلى 0.9 (الافتراضي 0.5)children: فرعان بالضبط (انقسام أو لوح)
عقدة اللوح
عقدة طرفية تحتوي على واحد أو أكثر من الأسطح (علامات التبويب داخل اللوح).
تعريف السطح
كل سطح في لوح يمكن أن يكون طرفية أو متصفحاً:
type:"terminal"أو"browser"name: عنوان علامة تبويب مخصصcommand: أمر shell للتشغيل التلقائي عند الإنشاء (للطرفية فقط)cwd: دليل العمل لهذا السطحenv: متغيرات البيئة كأزواج مفتاح-قيمةurl: رابط للفتح (للمتصفح فقط)focus: التركيز على هذا السطح بعد الإنشاء
تحليل دليل العمل
.أو محذوف: دليل عمل مساحة العمل./subdir: نسبي إلى دليل عمل مساحة العمل~/path: موسّع إلى الدليل الرئيسي- مسار مطلق: يُستخدم كما هو
مثال كامل
{
"actions": {
"web-dev": { "type": "workspaceCommand", "commandName": "Web Dev" },
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"command": "codex --dangerously-bypass-approvals-and-sandbox",
"target": "newTabInCurrentPane",
"shortcut": "cmd+t",
"icon": { "type": "image", "path": "./icons/codex.svg" }
},
"claude": {
"type": "command",
"title": "Claude Code",
"command": "claude --dangerously-skip-permissions",
"target": "newTabInCurrentPane",
"shortcut": "cmd+shift+c",
"icon": { "type": "image", "path": "./icons/claude.svg" }
},
"start-dev": {
"type": "command",
"command": "npm run dev",
"target": "newTabInCurrentPane",
"icon": { "type": "symbol", "name": "play.circle" }
}
},
"ui": {
"surfaceTabBar": {
"buttons": [
"cmux.newTerminal",
"cmux.newBrowser",
"cmux.splitRight",
"cmux.splitDown",
{
"action": "claude",
"title": "Claude Here"
},
"start-dev"
]
}
},
"commands": [
{
"name": "Web Dev",
"description": "Docs site with live preview",
"keywords": ["web", "docs", "next", "frontend"],
"workspace": {
"name": "Web Dev",
"cwd": "./web",
"color": "#3b82f6",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Next.js",
"command": "npm run dev",
"focus": true
}
]
}
},
{
"direction": "vertical",
"split": 0.6,
"children": [
{
"pane": {
"surfaces": [
{
"type": "browser",
"name": "Preview",
"url": "http://localhost:3777"
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Shell",
"env": { "NODE_ENV": "development" }
}
]
}
}
]
}
]
}
}
},
{
"name": "Debug Log",
"description": "Tail the debug event log from the running dev app",
"keywords": ["log", "debug", "tail", "events"],
"workspace": {
"name": "Debug Log",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Events",
"command": "tail -f /tmp/cmux-debug.log",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Shell"
}
]
}
}
]
}
}
},
{
"name": "Setup",
"description": "Initialize submodules and build dependencies",
"keywords": ["setup", "init", "install"],
"command": "./scripts/setup.sh",
"confirm": true
},
{
"name": "Reload",
"description": "Build and launch the debug app tagged to the current branch",
"keywords": ["reload", "build", "run", "launch"],
"command": "./scripts/reload.sh --tag $(git branch --show-current)"
},
{
"name": "Run Unit Tests",
"keywords": ["test", "unit"],
"command": "./scripts/test-unit.sh",
"confirm": true
}
]
}