ฟีเจอร์
การเริ่ม Claude Code
หน้านี้แปลด้วยเครื่องจากภาษาอังกฤษ ยินดีรับการแก้ไข แก้ไขหน้านี้บน GitHub
ccam work เริ่ม Claude Code ในชื่อบัญชี work และทุกอย่างหลังชื่อบัญชีจะส่งต่อให้ claude ตามเดิม ใช้ได้ทุกที่ที่คุณจะพิมพ์ claude: ในเทอร์มินัล ในสคริปต์ หรือเมื่อส่งอินพุตเข้ามาทางไปป์
การใช้งาน
ccam work # Claude Code as the account work
ccam 2 # the account with number 2 (see ccam list)
ccam work --resume # claude --resume, as work
ccam work -p "fix the tests" --output-format json
cat log.txt | ccam work -p "find the cause"
ccam -p "summarise" # no name: the default account
ccam use work # make work the default account
ccam run work --continue # same as ccam work --continue
ccam # the picker on a terminal, the list otherwise
ccam --dry-run work -p hi # print the command instead of running itระบุชื่อบัญชีหรือหมายเลขบัญชีจาก ccam list ccam ไม่อ่านอาร์กิวเมนต์ที่อยู่หลังชื่อบัญชี ดังนั้น ccam work --help จะแสดงความช่วยเหลือของ Claude Code จะใส่ -- หลังชื่อบัญชีหรือไม่ก็ได้ อินพุตมาตรฐาน รหัสออก (exit code) และสัญญาณ (signal) ทำงานเหมือนกับ claude
เมื่ออาร์กิวเมนต์แรกขึ้นต้นด้วย - และไม่ใช่แฟล็กของ ccam เอง ccam จะเริ่มบัญชีเริ่มต้นพร้อมอาร์กิวเมนต์ทั้งหมด บัญชีเริ่มต้นคือบัญชีที่ตั้งไว้ด้วย ccam use หรือบัญชีที่มีหมายเลขต่ำสุดหากคุณยังไม่ได้ตั้ง
ตัวเลือกบัญชี
ccam ที่ไม่มีอาร์กิวเมนต์จะเปิดตัวเลือกบัญชี (picker) เมื่ออินพุตและเอาต์พุตมาตรฐานเป็นเทอร์มินัล และจะพิมพ์ ccam list ในกรณีอื่น ตัวเลือกบัญชีแสดงหมายเลข อีเมล การใช้งาน 5 ชั่วโมง เวลาที่ใช้ล่าสุด และรายการที่ใช้ร่วมกันของแต่ละบัญชี ตัวเลขการใช้งานจะปรากฏขึ้นเมื่อแต่ละบัญชีได้รับคำตอบ
| ปุ่ม | สิ่งที่ทำ |
|---|---|
Enter |
เริ่ม Claude Code ในชื่อบัญชีที่เลือก |
1 ถึง 9 |
เริ่มบัญชีที่มีหมายเลขนั้น |
Up/Down, k/j |
เลื่อนตัวเลือก |
a |
ปิดตัวเลือกบัญชีแล้วเปิดตัวช่วยตั้งค่าของ ccam add |
s |
แก้ไขรายการที่ใช้ร่วมกันของบัญชีที่เลือก (Space หรือ x สลับ, Enter นำไปใช้, Esc ย้อนกลับ) |
d |
ตั้งบัญชีที่เลือกเป็นบัญชีเริ่มต้น |
r |
ดึงการใช้งานอีกครั้งโดยไม่ใช้แคชระยะสั้น |
q, Esc, Ctrl+C |
ออก |
ตัวเลือกบัญชีจะปิดตัวเองก่อนทำงาน เทอร์มินัลจึงกลับสู่สภาพเดิมก่อนที่ Claude Code จะเริ่ม หลังจากกด d หรือเปลี่ยนการใช้ร่วมกัน ตัวเลือกบัญชีจะเปิดขึ้นอีกครั้ง การเปลี่ยนการใช้ร่วมกันจะแสดงแผนและถามก่อน เหมือนกับที่ ccam share ทำ
ตัวเลือก
| ตัวเลือก | สิ่งที่ทำ | ค่าเริ่มต้น |
|---|---|---|
--dry-run |
พิมพ์ตัวแปรสภาพแวดล้อมและคำสั่งที่ ccam จะรัน แล้วออก | ปิด |
-v, --version |
พิมพ์ ccam <version> (เฉพาะเมื่อเป็นอาร์กิวเมนต์แรก) |
|
-h, --help |
ความช่วยเหลือของ ccam ในรูป ccam --help หรือ ccam run --help |
กฎของอาร์กิวเมนต์:
- ccam อ่านแฟล็กของตัวเองเฉพาะที่อยู่ก่อนชื่อบัญชี หลังชื่อบัญชี ทุกอาร์กิวเมนต์เป็นของ Claude Code รวมถึง
--dry-runและ--help --dry-runใช้ได้ในรูปccam --dry-run work,ccam run --dry-run workและccam --dry-run(บัญชีเริ่มต้น) ตัวเลือกนี้ได้รับการรองรับ ไม่ถูกปฏิเสธccam run <name|number> [claude args]คือรูปแบบเต็มของccam <name>ส่วนccam runที่ไม่มีชื่อบัญชีจะใช้บัญชีเริ่มต้น- ชื่อบัญชีต้องไม่ซ้ำกับชื่อคำสั่งของ ccam เช่น
add,list,runหรือusageดังนั้นccam <word>จึงไม่กำกวม
การทดลองรัน (dry run) จะพิมพ์หนึ่งบรรทัดที่คุณนำไปวางในเชลล์ได้:
$ ccam --dry-run work -p "fix the tests"
CLAUDE_CONFIG_DIR=/home/me/.local/share/ccam/profiles/work /home/me/.local/bin/claude --mcp-config=/home/me/.local/share/ccam/groups/default/mcp.json -p 'fix the tests'วิธีการทำงาน
การเริ่มทุกครั้งผ่านขั้นตอนเดียวกัน ตั้งแต่บรรทัดคำสั่งไปจนถึง exec:
แต่ละกล่องจะสว่างขึ้นเมื่อขั้นตอนนั้นทำงาน และบรรทัดด้านล่างคือตัวแปรสภาพแวดล้อมและอาร์กิวเมนต์ที่ Claude Code ใช้เริ่มทำงาน
cmd/ccam/main.goเรียกapp.Mainหาก ccam ถูกเริ่มด้วยชื่ออื่น แสดงว่าเป็นคำสั่งลัด และจะไปที่ตัวเริ่มโปรแกรมโดยตรงapp.parseตรวจos.Argsก่อนที่ cobra จะเข้ามาเกี่ยวข้อง มีเพียงccamเดี่ยว ๆ (ตัวเลือกบัญชี) ชื่อคำสั่งของ ccam (config.Reserved)-h/--helpและ-v/--versionที่ไปยังcli.Executeนอกนั้นถือเป็นการเริ่ม Claude Codelauncher.Launchอ่าน~/.config/ccam/config.tomlซึ่งเป็นไฟล์เดียวที่พาร์สlauncher.Prepareหาบัญชีจากชื่อหรือหมายเลข ตัด--ตัวแรกที่นำหน้าออกหนึ่งตัว และหาไฟล์ปฏิบัติการclaudeด้วยResolveClaudeผลการค้นหาใน PATH จะถูกแคชไว้ใน~/.local/state/ccam/claude-pathพร้อมเวลาแก้ไขของไฟล์ ccam จึงไม่ต้องค้นหาในPATHทุกครั้งที่เริ่ม หากไฟล์เปลี่ยนหรือหายไปจะค้นหาใหม่ พาธclaude_binในconfig.tomlจะถูกใช้ตามที่ระบุ ccam จะปฏิเสธclaudeที่เป็นตัว ccam เอง (เปรียบเทียบด้วย inode) เพราะจะทำให้วนซ้ำไม่สิ้นสุดcheckLinksเปรียบเทียบโฟลเดอร์บัญชี~/.local/share/ccam/profiles/<name>/กับการตั้งค่าการใช้ร่วมกันด้วยshare.Checkซึ่งเรียกเพียงlstatและreadlinkหนึ่งหรือสอง system call ต่อรายการ ลิงก์ที่หายไปจะถูกสร้างทันที สิ่งใดที่อาจทำให้ข้อมูลสูญหายจะหยุดการเริ่มapplyMCPเพิ่มเซิร์ฟเวอร์ MCP ที่ใช้ร่วมกัน (ดูด้านล่าง)session.Registerบันทึกเซสชัน ccam เขียนไฟล์เครื่องหมายที่ตั้งชื่อตาม PID ซึ่งเก็บเวลาเริ่มของโปรเซส ไว้ที่$XDG_RUNTIME_DIR/ccam/profile-<name>/<pid>(หรือ~/.local/state/ccam/locks/หากไม่มีXDG_RUNTIME_DIR) สำหรับบัญชีที่ใช้ประวัติการสนทนาร่วมกันhistoryCheckจะค้นหาเซสชันที่กำลังทำงานในhistory-<group>-<hash>ก่อน โดย hash คำนวณจากโฟลเดอร์ปัจจุบัน แล้วลงทะเบียนไว้ที่นั่นด้วยexecคง PID ไว้ เครื่องหมายจึงระบุถึงโปรเซสของ Claude Code เอง ที่ใช้เครื่องหมายแทนการถือล็อก เพราะโปรเซสที่ Claude Code เริ่มจะสืบทอดล็อกไปและถือไว้ต่อหลังจากเซสชันจบแล้วPlan.Execตั้งชื่อหน้าต่างเทอร์มินัลเป็นclaude · <name>(เมื่อ standard error เป็นเทอร์มินัล) เขียนเวลาที่เริ่มลงใน~/.local/state/ccam/last-used/<name>โดยไม่เรียกfsyncแล้วเรียกsyscall.Exec
Claude Code ทำงานโดยตั้ง CLAUDE_CONFIG_DIR เป็นโฟลเดอร์ของบัญชี และ CCAM_PROFILE เป็นชื่อบัญชี ccam จะลบค่าของตัวแปรเหล่านี้ที่สืบทอดมา สำหรับโฟลเดอร์ ~/.claude ที่ลงทะเบียนด้วย ccam import บน macOS ccam จะตั้ง CLAUDE_SECURESTORAGE_CONFIG_DIR เป็นค่าว่างด้วย เพื่อให้บัญชีนั้นและ claude แบบปกติใช้การเข้าสู่ระบบเดียวกันในพวงกุญแจ (Keychain)
ทำไมจึงใช้ exec
syscall.Exec แทนที่โปรเซสของ ccam ด้วย claude ccam จึงไม่ค้างอยู่ในหน่วยความจำ การกดแป้น สัญญาณ และรหัสออกเป็นของ Claude Code เอง และอาร์กิวเมนต์ยังคงเป็นอาร์เรย์ ไม่เคยเป็นสตริงของเชลล์ งานหลังจบเซสชัน เช่น การตรวจพบเซิร์ฟเวอร์ที่เพิ่มด้วย claude mcp add จะเกิดขึ้นในการเริ่มครั้งถัดไป: ccam เปรียบเทียบเวลาแก้ไขของ .claude.json กับ ~/.local/state/ccam/mcp/<name>/seen และพาร์สไฟล์เฉพาะเมื่อไฟล์เปลี่ยนไป
บรรทัดคำสั่งถูกส่งต่ออย่างไร
สามบรรทัดคำสั่ง สามเส้นทางผ่าน internal/app:
คำสั่งลัดจับคู่จาก argv[0] ส่วน ccam <name> จับคู่จากอาร์กิวเมนต์แรก และทั้งสองจบที่ syscall.Exec มีเพียงคำสั่งของ ccam เช่น ccam usage เท่านั้นที่ไปถึง cobra
เซิร์ฟเวอร์ MCP ที่ใช้ร่วมกัน
ด้วยกลยุทธ์ flag ซึ่งเป็นค่าเริ่มต้น ccam ส่งเซิร์ฟเวอร์ MCP ของกลุ่มให้ Claude Code เป็นอาร์กิวเมนต์ โดยวางไว้ก่อนอาร์กิวเมนต์ของคุณ:
mcp.FlagArgs คืนอาร์กิวเมนต์เฉพาะเมื่อ mcp.json ของกลุ่มมีอยู่ และ Plan.InsertArgs วางอาร์กิวเมนต์ไว้ต่อจาก claude ทันที --mcp-config หรือ --strict-mcp-config ของคุณเองจึงยังมีผลซ้อนทับอยู่ด้านบน อาร์กิวเมนต์นี้เป็นอาร์กิวเมนต์เดียว --mcp-config=<path> เพราะ --mcp-config ของ Claude Code รับได้หลายค่า หากเขียนเป็นสองอาร์กิวเมนต์ ก็จะอ่านพรอมต์ที่ตามมาเป็นไฟล์การตั้งค่าไปด้วย
เมื่อตั้ง mcp_strategy = "sync" ใน config.toml ccam จะเขียนเซิร์ฟเวอร์ลงใน .claude.json ของบัญชีแทน และจะข้ามขั้นตอนนี้หากบัญชีกำลังทำงานอยู่แล้ว
Remote Control
ccam work rc (หรือ ccam work remote-control) เริ่ม Remote Control ของ Claude Code ในฐานะ work ส่วน claude remote-control ปฏิเสธ --mcp-config ที่อยู่ก่อนคำกริยา (verb) ของมัน และไม่รับเลยหลังคำกริยา อีกทั้งเซสชันของมันอ่านเซิร์ฟเวอร์ MCP จาก .claude.json ของบัญชีเท่านั้น ดังนั้นกลยุทธ์ flag จึงทำงานต่างออกไปในกรณีนี้:
remoteControlถือว่าอาร์กิวเมนต์แรกหลังชื่อบัญชีที่ไม่ขึ้นต้นด้วย-คือคำกริยาของ Claude Code เมื่อเป็นremote-controlหรือrcแล้วmcp.FlagArgsจะไม่เพิ่มอะไรเลยmcp.Syncedเปรียบเทียบเวลาแก้ไขของmcp.jsonของกลุ่มกับsync-stampของบัญชี หาก.claude.jsonมีเซิร์ฟเวอร์ปัจจุบันของกลุ่มอยู่แล้ว หรือกลุ่มไม่มีเซิร์ฟเวอร์เลย Remote Control จะเริ่มโดยไม่ถามมิฉะนั้น ccam จะระบุชื่อเซิร์ฟเวอร์ที่เซสชันจะไม่ได้รับ แล้วถามว่า:
ccam: Remote Control sessions only get MCP servers stored in account work's .claude.json, not the shared MCP servers (ctx, fs). Copy them into .claude.json (a backup is kept)? [y/N]เมื่อตอบ
yแล้วmcp.Syncจะคัดลอกเซิร์ฟเวอร์เหล่านั้นแบบเดียวกับกลยุทธ์sync: ภายใต้ล็อกของ Claude Code หลังจากสำรองไฟล์ และคงเซิร์ฟเวอร์ของบัญชีเองไว้ เมื่อตอบNหรือเมื่อไม่มีเทอร์มินัล Remote Control จะเริ่มโดยไม่มีเซิร์ฟเวอร์เหล่านั้น และ ccam จะแนะนำmcp_strategy = "sync"ซึ่งคัดลอกให้ก่อนการเริ่มทุกครั้ง
ccam จะถามทุกครั้งที่เริ่ม Remote Control จนกว่าจะคัดลอกเซิร์ฟเวอร์แล้ว และหลังจากคัดลอกแล้วจะถามอีกเฉพาะเมื่อ mcp.json ของกลุ่มเปลี่ยนอีกครั้ง สำเนาใน .claude.json มีผลเหนือกว่า --mcp-config ในการเริ่มตามปกติครั้งต่อ ๆ ไป ดังนั้น ccam mcp add, remove และ import จึงอัปเดตสำเนาที่บัญชีอื่นถืออยู่ด้วย (เซิร์ฟเวอร์ MCP ที่ใช้ร่วมกัน)
งบเวลา 10 ms
ccam ใช้เวลาเพิ่มไม่เกิน 10 ms (p95) ก่อนที่ Claude Code จะเริ่ม เส้นทางการเริ่มไม่เคยสร้างโครงสร้างคำสั่งของ cobra ไม่เริ่ม Bubble Tea และไม่เปิดการเชื่อมต่อเครือข่าย และ TestPackageInitIsCheap จะล้มเหลวหากฟังก์ชัน init() ของแพ็กเกจใช้เวลารวมเกิน 5 ms scripts/perf-check.sh วัด ccam --dry-run work, ccam work และคำสั่งลัดด้วย hyperfine และล้มเหลวเมื่อเกิน 10 ms ส่วน BenchmarkLaunchPath ใน internal/launcher รันขั้นตอนต่าง ๆ ซ้ำในลูป หากต้องการดูเวลาของแต่ละขั้นตอน ให้ตั้ง CCAM_TRACE=1:
$ CCAM_TRACE=1 ccam --dry-run work >/dev/null
ccam trace: start 2.830ms (total 2.830ms)
ccam trace: load config 0.397ms (total 3.227ms)
ccam trace: prepare 0.112ms (total 3.339ms)
ccam trace: check links 0.238ms (total 3.578ms)
ccam trace: prelaunch 0.083ms (total 3.661ms)ความปลอดภัยและกรณีพิเศษ
- ชื่อหรือหมายเลขที่ไม่รู้จักจะหยุดด้วย
no account "<name>"และแนะนำccam listหากยังไม่มีบัญชีเลย ccam จะขอให้คุณเพิ่มบัญชีด้วยccam add <name> - หากพาธที่ใช้ร่วมกันกลายเป็นไฟล์ธรรมดาหรือชี้ไปผิดที่ ccam จะหยุดด้วย
stopped because of share link problems:แสดงรายการปัญหา และขอให้คุณรันccam doctor --fixccam ไม่ย้ายข้อมูลในเส้นทางการเริ่ม - หากมี Claude Code อีกตัวที่ใช้ประวัติการสนทนาร่วมกับบัญชีนี้ (กลุ่มเดียวกัน) ทำงานอยู่ในโฟลเดอร์เดียวกัน ccam จะเตือนว่าประวัติอาจปนกันและถาม
Run anyway? [y/N]หากไม่มีเทอร์มินัลจะแสดงคำเตือนแล้วทำงานต่อ --dry-runข้ามการซิงก์ MCP การแจ้งเซิร์ฟเวอร์ใหม่ การตรวจประวัติ เครื่องหมายเซสชัน ชื่อหน้าต่าง และเวลาที่ใช้ล่าสุด และไม่เรียก exec แต่ยังคงตรวจลิงก์ที่ใช้ร่วมกัน และสร้างลิงก์ที่หายไปเหมือนการเริ่มปกติccam work rcขณะที่workกำลังทำงานอยู่แล้ว จะไม่แตะ.claude.jsonแจ้งให้ทราบ และเริ่ม Remote Control โดยไม่มีเซิร์ฟเวอร์ของกลุ่ม ให้รันอีกครั้งหลังจากเซสชันจบเพื่อคัดลอก เมื่อใช้--dry-runจะพิมพ์ข้อความแต่ไม่ถามและไม่คัดลอก- เมื่อใช้
mcp_strategy = "sync"การซิงก์ที่ล้มเหลวจะพิมพ์ccam: MCP sync failed (launching anyway): …และ Claude Code จะเริ่มด้วยเซิร์ฟเวอร์ที่มีอยู่เดิม