npx claudepluginhub popmechanic/vibesos --plugin julianThis skill is limited to using the following tools:
Deploy Julian to an exe.xyz VM. Two paths: **provision** a new VM or **update** an existing one. The instance registry at `deploy/instances.json` tracks which VMs have been provisioned.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Deploy Julian to an exe.xyz VM. Two paths: provision a new VM or update an existing one. The instance registry at deploy/instances.json tracks which VMs have been provisioned.
Determine the target VM name:
$ARGUMENTS is provided, use it as the VM name (e.g., /julian:deploy screen-test)julian-<branch> (e.g., branch screen → julian-screen)PRODUCTION SAFETY: If the resolved VM name is exactly julian (the production instance), STOP and warn the user before proceeding. Only proceed after explicit confirmation.
Read deploy/instances.json. If the target VM name exists in the registry, run the Update path. Otherwise, run the Provision path.
If deploy/instances.json doesn't exist, create it as {}.
Full first-time setup. Run all steps in order.
git rev-parse --abbrev-ref HEADgit pull (stop on merge conflicts)git status --porcelain (warn but don't block)git pushhttps://<vmname>.exe.xyz/)Read the local .env file and check for VITE_OIDC_AUTHORITY:
/vibes:connect to set up Connect + Pocket ID end-to-endVITE_OIDC_AUTHORITY=https://studio.exe.xyz/auth and VITE_OIDC_CLIENT_ID=<id> to .envIMPORTANT: All SSH commands targeting the VM must include -o StrictHostKeyChecking=accept-new.
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 <vmname>.exe.xyz echo ok
If unreachable, create it:
ssh exe.dev new --name=<vmname>
ssh exe.dev share set-public <vmname>
Wait for boot (up to 90 seconds):
for i in $(seq 1 9); do
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5 <vmname>.exe.xyz echo ok && break
echo "Attempt $i failed, retrying in 10s..."
sleep 10
done
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "curl -fsSL https://bun.sh/install | bash && sudo apt-get update -qq && sudo apt-get install -y npm inotify-tools"
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "sudo mkdir -p /opt/julian && sudo chown exedev:exedev /opt/julian && mkdir -p /home/exedev/mailbox"
Generate an SSH key for push access:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "ssh-keygen -t ed25519 -f ~/.ssh/julian-deploy -N '' -C '<vmname>-deploy'"
Configure SSH to use it for GitHub:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "mkdir -p ~/.ssh && cat >> ~/.ssh/config << 'SSHEOF'
Host github.com
IdentityFile ~/.ssh/julian-deploy
StrictHostKeyChecking accept-new
SSHEOF"
Add the deploy key to GitHub with write access:
DEPLOY_KEY=$(ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cat ~/.ssh/julian-deploy.pub")
gh repo deploy-key add - --repo popmechanic/Julian --title "<vmname>-deploy" --allow-write <<< "$DEPLOY_KEY"
If the key title already exists, skip — it's fine.
Clone the repo and configure git identity:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "git clone git@github.com:popmechanic/Julian.git /opt/julian"
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && git config user.name 'Julian' && git config user.email 'julian@exe.xyz'"
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && /home/exedev/.bun/bin/bun install"
Use the VITE_OIDC_AUTHORITY and VITE_OIDC_CLIENT_ID from pre-flight (do NOT hardcode):
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cat > /opt/julian/.env << 'ENVEOF'
VITE_OIDC_AUTHORITY=<value from local .env>
VITE_OIDC_CLIENT_ID=<value from local .env>
ALLOWED_ORIGIN=https://<vmname>.exe.xyz
ENVEOF"
Enable Agent Teams (disabled by default) so Julian can spawn and manage agent teammates:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "mkdir -p /home/exedev/.claude && cat > /home/exedev/.claude/settings.json << 'SETTINGSEOF'
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
SETTINGSEOF"
scp deploy/julian.service <vmname>.exe.xyz:/tmp/
scp deploy/julian-screen.service <vmname>.exe.xyz:/tmp/
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "sudo cp /tmp/julian.service /etc/systemd/system/ && \
sudo cp /tmp/julian-screen.service /etc/systemd/system/ && \
sudo systemctl daemon-reload && \
sudo systemctl enable --now julian julian-screen"
Add the VM to deploy/instances.json:
{
"<vmname>": {
"url": "https://<vmname>.exe.xyz",
"provisioned": "<ISO 8601 timestamp>",
"branch": "<git branch used for first deploy>"
}
}
Read the existing file, merge the new entry, write it back. Commit and push the updated registry so other machines know about it:
git add deploy/instances.json
git commit -m "Register <vmname> instance"
git push
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "systemctl is-active julian julian-screen"
curl -sf https://<vmname>.exe.xyz/ | head -5
curl -sf https://<vmname>.exe.xyz/api/health
Report: URL, service status, and remind user that Anthropic credentials need one-time setup on new instances.
Fast path — just sync code and restart. This is the common case.
git pull (stop on merge conflicts)git status --porcelain (warn but don't block)git pushBefore deploying, assess the scope of changes. Get the server's current commit and diff it against what you're about to deploy:
SERVER_HEAD=$(ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && git rev-parse HEAD")
git diff --stat $SERVER_HEAD HEAD
git diff --name-only $SERVER_HEAD HEAD
Classify the deploy based on what changed:
Content only (soul/, memory/, catalog.xml, docs/):
Small code change (1-3 files changed in server/ or frontend, under ~100 lines total):
Large code change (4+ files changed, or 200+ lines, or structural changes to server.ts):
julian), suggest: "Want to deploy to a fresh test VM first? I can provision one with /julian:deploy test."Dependency change (package.json modified):
No changes (server is already on the same commit):
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && git pull"
If git pull fails because Julian has uncommitted changes:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && git stash && git pull && git stash pop"
If there are merge conflicts after stash pop, report them to the user.
Check if package.json changed in the pull:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && git diff HEAD~1 --name-only 2>/dev/null | grep -q package.json && echo changed || echo unchanged"
If changed (or if in doubt), run:
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cd /opt/julian && /home/exedev/.bun/bin/bun install"
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "sudo systemctl restart julian julian-screen"
curl -sf https://<vmname>.exe.xyz/api/health
Confirm the version field in the health response matches the current git hash. Report the URL and version.
ssh exe.dev list to verify VM exists. If it does, wait longer or check exe.dev status.ssh <vmname>.exe.xyz "/home/exedev/.bun/bin/bun --version".ssh <vmname>.exe.xyz "journalctl -u julian -n 20 --no-pager". Common causes: missing Bun, missing jose dependency.ssh <vmname>.exe.xyz "ssh -T git@github.com". Re-run Step P4 if needed.deploy/instances.json and re-run — it will take the Provision path./tokens/with-email: Missing OIDC JWT configuration. Check Pocket ID admin panel for proper token template setup.