Bootstrap jj (Jujutsu) workflow enforcement for this project
From project-setup-jjnpx claudepluginhub muloka/claude-plugins --plugin project-setup-jj/project-setupプロジェクトを分析し、スタック検出とユーザーインタビューを通じて .claude/rules/ ファイルを生成する
/project-setupGuides through standardized project initialization following team conventions
/project-setupAuto-discover project tooling and configure .claude/ settings
/project-setupBootstrap a new project from scratch: create repo, README, initial commit, then auto-chain into wflow:setup for templates, labels, and CLAUDE.md.
/project-setupAdds or updates the Conventions section (unified 6 subsections) in project/module CLAUDE.md. For existing projects, extracts conventions from source code; for new projects, collects them interactively. Use the --update option to modify an existing Conventions section (absorbs the former /convention-update).
Bootstrap jj (Jujutsu) workflow enforcement for the current project. This sets up a SessionStart hook, a PreToolUse guard hook, permissions, and CLAUDE.md instructions so that every Claude Code session in this project uses jj properly.
CRITICAL: This is a jj (Jujutsu) plugin. You MUST NOT use ANY raw git commands — not even for context discovery. Always use jj equivalents. The only exceptions are jj git subcommands and gh CLI.
jj root. If it fails, tell the user this command requires a jj repository and stop.~/.claude/plugins/cache/muloka-claude-plugins/project-setup-jj/<hash>/. The templates are in templates/ and scripts in scripts/ relative to the plugin root.jj root..claude/ and .claude/scripts/ directories exist in the project root:
mkdir -p "$(jj root)/.claude/scripts"
Copy jj-session-start.sh from the plugin's scripts/ directory to the project's .claude/scripts/:
cp <plugin-scripts-dir>/jj-session-start.sh "$(jj root)/.claude/scripts/"
chmod +x "$(jj root)/.claude/scripts/jj-session-start.sh"
.claude/settings.local.jsonRead the current .claude/settings.local.json (may not exist). Deep-merge the following configuration using jq, preserving all existing keys and deduplicating entries:
SessionStart hook:
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear|compact",
"hooks": [
{
"type": "command",
"command": "<project-root>/.claude/scripts/jj-session-start.sh",
"async": false
}
]
}
]
}
}
Permissions:
{
"permissions": {
"allow": [
"Bash(jj status*)", "Bash(jj diff*)", "Bash(jj log*)",
"Bash(jj new*)", "Bash(jj commit*)", "Bash(jj describe*)",
"Bash(jj bookmark*)", "Bash(jj git push*)", "Bash(jj git fetch*)",
"Bash(jj rebase*)", "Bash(jj squash*)", "Bash(jj edit*)",
"Bash(jj abandon*)", "Bash(jj undo*)", "Bash(jj op log*)",
"Bash(jj resolve*)", "Bash(jj root*)", "Bash(jj file*)",
"Bash(jj split*)", "Bash(jj config*)", "Bash(jj git remote*)",
"Bash(gh *)"
],
"deny": ["Bash(git *)"]
}
}
Replace <project-root> with the actual absolute path from jj root.
Merge strategy: Use jq to deep-merge. For array fields (allow, deny, hook arrays), concatenate and deduplicate. For object fields, merge recursively. Preserve any existing settings not related to jj.
Copy require-jj-new.sh from the plugin's scripts/ directory to the project's .claude/scripts/:
cp <plugin-scripts-dir>/require-jj-new.sh "$(jj root)/.claude/scripts/"
chmod +x "$(jj root)/.claude/scripts/require-jj-new.sh"
Then merge a PreToolUse hook entry into .claude/settings.local.json (using the same deep-merge strategy as Step 3):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "<project-root>/.claude/scripts/require-jj-new.sh"
}
]
}
]
}
}
Replace <project-root> with the actual absolute path from jj root.
Copy workspace scripts from the plugin's scripts/ directory to the project's .claude/scripts/:
cp <plugin-scripts-dir>/jj-workspace-create.sh "$(jj root)/.claude/scripts/"
cp <plugin-scripts-dir>/jj-workspace-remove.sh "$(jj root)/.claude/scripts/"
chmod +x "$(jj root)/.claude/scripts/jj-workspace-create.sh"
chmod +x "$(jj root)/.claude/scripts/jj-workspace-remove.sh"
Then merge WorktreeCreate and WorktreeRemove hook entries into .claude/settings.local.json (using the same deep-merge strategy as Steps 3 and 4):
{
"hooks": {
"WorktreeCreate": [
{
"hooks": [
{
"type": "command",
"command": "<project-root>/.claude/scripts/jj-workspace-create.sh"
}
]
}
],
"WorktreeRemove": [
{
"hooks": [
{
"type": "command",
"command": "<project-root>/.claude/scripts/jj-workspace-remove.sh"
}
]
}
]
}
}
Replace <project-root> with the actual absolute path from jj root.
Read the CLAUDE.md template from the plugin's templates/CLAUDE.md.template. The template includes a content hash in its start marker (<!-- jj-project-setup:start hash:<hex> -->) for version tracking. It uses an ## VCS heading (h2) so it fits naturally into any existing CLAUDE.md heading hierarchy.
Then handle four cases:
<!-- jj-project-setup:start hash:<hex> --> marker: Extract the hash from the installed marker and compare it to the hash in the template. If they match, the section is up to date — skip (report "CLAUDE.md already up to date"). If they differ, replace the section between the start and <!-- jj-project-setup:end --> markers (inclusive) with the template content.<!-- jj-project-setup:start --> (no hash — legacy): Replace the section between markers with the template content (upgrades to the hashed format).The CLAUDE.md file is at the project root (from jj root).
Show a summary of what was set up:
.claude/scripts/jj-session-start.sh.claude/scripts/require-jj-new.sh.claude/scripts/jj-workspace-create.sh.claude/scripts/jj-workspace-remove.sh.claude/settings.local.json (SessionStart + PreToolUse + WorktreeCreate + WorktreeRemove hooks + permissions)Remind the user to:
.claude/scripts/ to their ignore patterns if they don't want to track these in version control