3.8 KiB
3.8 KiB
packages/cli/
Main CLI tool for OpenPets agent configuration and pet management.
Responsibility
Primary user-facing CLI for the OpenPets ecosystem. Provides commands for: installing pets from gallery, configuring projects for Claude/OpenCode/Cursor agents, running MCP server wrapper, executing Claude hooks, and direct pet interaction (status, react, say).
Design/Patterns
Command Router: main() dispatches to subcommands based on process.argv[2]:
install <pet-id>- Install pet via running appconfigure- Interactive project setup for Claude, OpenCode, or Cursorstatus- Check OpenPets desktop app connectivity and print JSON statuspets- List installed pets with flags (default, broken)react <reaction>- Send reaction to desktop appsay <message> [--reaction <reaction>]- Display message on petmcp- Spawn MCP server (delegates to@open-pets/mcp)hook- Execute Claude hook from stdin
Configuration Flow (configureProject):
- Resolve project directory (symlink/escape checks)
- Route to agent-specific handler (claude/opencode/cursor)
- For Claude: Assert availability, list pets, build MCP config, write hooks
- For OpenCode: Prepare and write OpenCode config via
@open-pets/opencode - For Cursor: Configure MCP in
.cursor/mcp.json, optional rules in.cursor/rules/openpets.mdc
Cursor Configuration:
--with-rules- Install MCP + project rules--rules-only- Install only.cursor/rules/openpets.mdc--remove-rules- Remove managed rules file- Status classification:
not_installed,installed,needs_update,conflict,error - Atomic writes with backup creation
Safety Checks:
- Project path validation (no symlinks, must be directory)
.claude/.cursor/.opencodedirectory safety (no symlinks, path containment)- Settings file atomic writes (temp + rename pattern)
- Shell argument quoting for command injection prevention
Pet Resolution (resolveConfiguredPet):
- Validates explicit
--petargument - Otherwise: fetches installed pets, interactive TTY prompt
- Validates selected pet is not broken
Flow
openpets configure --agent claude --pet <id> --cwd <dir>
↓
resolveProjectDir() → assertSafeProjectHookPath()
↓
assertClaudeAvailable() (spawnSync "claude --version")
↓
resolveConfiguredPet() → listPets() → pickPet() (interactive)
↓
prepareProjectLocalHooks() → Build hook command with marker
↓
runClaudeMcpAddJson() → spawnSync "claude mcp add-json ..."
↓
writePreparedHooks() → Atomic write to .claude/settings.local.json
openpets configure --agent cursor --with-rules
↓
readCursorMcpConfig() → classifyCursorMcpStatus()
↓
readCursorOpenPetsRules() → classifyCursorRulesStatus()
↓
planCursorMcpInstall/Replace() → executeCursorMcpWrite()
↓
planCursorRulesInstall/Replace() → executeCursorRulesWrite()
openpets status
↓
createOpenPetsClient().status() → Print JSON result
Integration Points
Dependencies:
@open-pets/client- Pet listing, installation, status, react, say@open-pets/claude- Hook management, MCP config@open-pets/mcp- MCP server spawning@open-pets/opencode- OpenCode project setup@open-pets/cursor- Cursor project setup (MCP + rules)
External Commands:
claude- Claude Code CLI for MCP configurationnpx- For published package execution
Exports:
cliPackageNameconstantconfigureProject(),resolveConfiguredPet()- Programmatic APIparseConfigureArgs(),parseInstallArgs(),parseReactArgs(),parseSayArgs()- Argument parsingcreateVersionPinnedCliCommand(),createLocalDevCliCommand()- Command buildersinstallProjectLocalHooks(),prepareProjectLocalHooks()- Hook installationrunClaudeMcpAddJson(),createClaudeMcpAddJsonArgs()- MCP integration