一键导入
deploy
Deploy Julian to an exe.xyz VM (new instance or update existing)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Deploy Julian to an exe.xyz VM (new instance or update existing)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | deploy |
| description | Deploy Julian to an exe.xyz VM (new instance or update existing) |
| user-invocable | true |
| allowed-tools | ["Bash(ssh:*)","Bash(scp:*)","Bash(curl:*)","Bash(git:*)","Bash(gh:*)","Bash(mkdir:*)","Read","Write","Glob"] |
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_CLERK_PUBLISHABLE_KEY:
pk_(test|live)_*): Extract the value for later. Proceed./vibes:connect to set up Clerk + Connect end-to-endVITE_CLERK_PUBLISHABLE_KEY=pk_test_... to .envwith-email JWT template in Clerk Dashboard:
with-email|| '' fallbacks are required — Fireproof Studio rejects null names):
{
"params": {
"email": "{{user.primary_email_address}}",
"email_verified": "{{user.email_verified}}",
"external_id": "{{user.external_id}}",
"first": "{{user.first_name || ''}}",
"last": "{{user.last_name || ''}}",
"name": "{{user.full_name || ''}}",
"image_url": "{{user.image_url}}",
"public_meta": "{{user.public_metadata}}"
},
"role": "authenticated",
"userId": "{{user.id}}"
}
IMPORTANT: 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_CLERK_PUBLISHABLE_KEY from pre-flight (do NOT hardcode):
ssh -o StrictHostKeyChecking=accept-new <vmname>.exe.xyz "cat > /opt/julian/.env << 'ENVEOF'
VITE_CLERK_PUBLISHABLE_KEY=<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 Clerk JWT template. Create with-email in Clerk Dashboard → Configure → JWT Templates with the claims JSON from the Clerk Pre-flight section.