[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-openai-provision-droplet":3,"mdc--y9wbin-key":33,"related-repo-openai-provision-droplet":2336,"related-org-openai-provision-droplet":2459},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":28,"sourceUrl":31,"mdContent":32},"provision-droplet","provision DigitalOcean droplets for remote development","Use when the user wants to spin up \u002F create \u002F launch \u002F provision a DigitalOcean droplet (or \"a remote dev box on DO\") and connect to it from Codex as a remote SSH workspace.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"openai","OpenAI","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fopenai.png",[12,16,19],{"name":13,"slug":14,"type":15},"Deployment","deployment","tag",{"name":17,"slug":18,"type":15},"Cloud","cloud",{"name":20,"slug":21,"type":15},"Infrastructure","infrastructure",3992,"https:\u002F\u002Fgithub.com\u002Fopenai\u002Fplugins","2026-06-30T19:00:57.102",null,465,[],{"repoUrl":23,"stars":22,"forks":26,"topics":29,"description":30},[],"OpenAI Plugins","https:\u002F\u002Fgithub.com\u002Fopenai\u002Fplugins\u002Ftree\u002FHEAD\u002Fplugins\u002Fdigitalocean\u002Fskills\u002Fprovision-droplet","---\nname: provision-droplet\ndescription: >\n  Use when the user wants to spin up \u002F create \u002F launch \u002F provision a\n  DigitalOcean droplet (or \"a remote dev box on DO\") and connect to it from\n  Codex as a remote SSH workspace.\n---\n\n# Provision a DigitalOcean droplet as a Codex remote workspace\n\nFollow these steps in order. Do not skip or reorder them.\n**Only the installed Codex DigitalOcean app tools and the bundled Python scripts\nmay be used. doctl, ad hoc integration configs, and any other DigitalOcean CLI\ntools are prohibited.**\n\n## Before you start\n\n- **Prerequisites:** a funded DigitalOcean account, the installed and\n  authenticated Codex **DigitalOcean** app, a local `ssh`\u002F`ssh-keygen`\n  (OpenSSH), Python 3, and the Codex desktop app.\n- **Cost:** the droplet bills **hourly from creation until you delete it**.\n  Sizes in step 5 show approximate monthly rates. Remind the user to delete it\n  when done (see *Cleanup* below).\n- **Time:** end-to-end takes ~10–15 minutes — roughly 7 minutes waiting for the\n  droplet to boot (steps 7-8) plus up to 7 minutes for cloud-init (step 9). This\n  is normal; do not abort.\n- **Locate the bundled scripts first (do this before Step 2).** The helper\n  scripts live in the `scripts\u002F` folder **next to this `SKILL.md`** (i.e.\n  `provision-droplet\u002Fscripts\u002F`). Your current working directory is **not** the\n  skill directory, so bare relative paths like `scripts\u002Fkeygen.py` will fail.\n  Resolve the absolute directory that contains this `SKILL.md` and call it\n  `\u003Cskill_dir>`. If you don't already know it, find it — the installed plugin may\n  nest it under a version folder (e.g. `...\u002F\u003Cversion>\u002Fprovision-droplet\u002F`), so\n  locate the directory that actually contains `scripts\u002Fkeygen.py`. Use\n  `\u003Cskill_dir>\u002Fscripts\u002F\u003Cname>.py` (an absolute path) in **every** command below.\n\n## Step 1 — Verify DigitalOcean app access\n\nThis plugin depends on the single Codex **DigitalOcean** app. Use it for all\nDigitalOcean operations; do not register or log in to separate plugin-owned app\nintegrations.\n\nThe **DigitalOcean** app provides both:\n- SSH key tools: `key-create`, `key-list`, `key-delete`.\n- Droplet tools: `droplet-create`, `droplet-get`, `droplet-delete`.\n\nConfirm that these tools are available before continuing. If the app's tools are\nmissing or unauthenticated, stop and tell the user to install or authenticate\nthe DigitalOcean app in Codex. Do not fall back to doctl, API tokens, or a local\nintegration config.\n\n## Step 2 — Generate SSH key pair\n\n```bash\npython3 \u003Cskill_dir>\u002Fscripts\u002Fkeygen.py\n```\n\nParse the JSON output and keep these values for the steps below:\n`prefix`, `name`, `key_name`, `key_path`, `pub_key`.\n\nHow these relate (all derived from one random `prefix` like `bright-hawk-a3f2`):\n- `name` = `codex-\u003Cprefix>` — the **droplet name** and the **local SSH alias**\n  (they are identical).\n- `key_name` = `codex-key-\u003Cprefix>` — the label for the key on DigitalOcean's\n  side only.\n- `key_path` — the local private key file.\n\n## Step 3 — Upload SSH public key\n\nCall the **DigitalOcean** app tool **`key-create`**:\n\n| Parameter | Value |\n|-----------|-------|\n| `Name` | `key_name` from step 2 |\n| `PublicKey` | `pub_key` from step 2 |\n\nExtract `ssh_key.id` from the response — this is `\u003Ckey_id>`.\n\nIf the call fails because a key with that name or fingerprint **already exists**\n(e.g. a previous run), do not create a duplicate: call the **DigitalOcean** app\ntool **`key-list`**, find the entry whose `name` matches `key_name` (or whose\nfingerprint matches the uploaded key), and use its `id` as `\u003Ckey_id>`.\n\n## Step 4 — Choose a region\n\nAsk the user, in chat:\n\n> Use the defaults — region **`nyc3`** (New York, US) and size\n> **`s-2vcpu-4gb`** (2 vCPU \u002F 4 GB, ~$24\u002Fmo) — or customize them?\n\nIf they choose the defaults, use `nyc3` as `\u003Cregion>` and `s-2vcpu-4gb` as\n`\u003Csize>`, then skip step 5 and continue to step 6.\n\nIf they want to customize the defaults, present this region list first and ask\nthem to reply with a slug:\n\n| Slug | Location |\n|------|----------|\n| `nyc3` *(default)* | New York, US |\n| `sfo3` | San Francisco, US |\n| `tor1` | Toronto, CA |\n| `lon1` | London, UK |\n| `fra1` | Frankfurt, DE |\n| `ams3` | Amsterdam, NL |\n| `sgp1` | Singapore, SG |\n| `blr1` | Bangalore, IN |\n| `syd1` | Sydney, AU |\n\nValidate their reply against this table. If it is not one of these slugs, ask\nagain — do not pass an unlisted value through. The chosen slug is `\u003Cregion>`.\n\n## Step 5 — Choose a droplet size\n\nSkip this step if `\u003Csize>` was already set to the default in step 4.\n\nOtherwise, present this size list and ask the user to reply with a slug. Every\nsize below is above the **1 vCPU \u002F 2 GB** floor required by the Codex Universal\nimage. Prices are approximate — confirm in the DigitalOcean dashboard.\n\n| Slug | vCPU | RAM | Tier | ~$\u002Fmo |\n|------|------|-----|------|-------|\n| `s-2vcpu-4gb` *(default)* | 2 | 4 GB | Shared basic | $24 |\n| `s-4vcpu-8gb` | 4 | 8 GB | Shared basic | $48 |\n| `s-8vcpu-16gb` | 8 | 16 GB | Shared basic | $96 |\n| `c-2` | 2 | 4 GB | Premium CPU-optimized | $42 |\n| `g-2vcpu-8gb` | 2 | 8 GB | Premium general-purpose | $63 |\n\nValidate their reply against this table. If it is not one of these slugs, ask\nagain — do not pass an unlisted value through. The chosen slug is `\u003Csize>`.\n\n## Step 6 — Create droplet\n\nCall the **DigitalOcean** app tool **`droplet-create`**:\n\n| Parameter | Value | Notes |\n|-----------|-------|-------|\n| `Name` | `name` from step 2 | |\n| `Region` | `\u003Cregion>` from step 4 | |\n| `Size` | `\u003Csize>` from step 5 | |\n| `ImageID` | `234061005` | DigitalOcean **Codex Universal** image |\n| `SSHKeys` | `[\"\u003Ckey_id>\"]` | |\n\nExtract `droplet.id` from the response — this is `\u003Cdroplet_id>`.\n\nIf `droplet-create` fails, show the user the error and handle it by cause — do\nnot blindly retry the same values:\n- **Size not available in this region** (premium tiers like `c-2` and\n  `g-2vcpu-8gb` are not in every region): go back to step 4 or 5 and pick a\n  different region\u002Fsize combination.\n- **Payment \u002F quota \u002F limit** errors: stop and tell the user to resolve it in\n  the DigitalOcean dashboard, then re-run.\n- **Invalid image or any other error:** stop and report it.\n\nThe uploaded SSH key from step 3 is harmless to leave, but if you abort here see\n*Cleanup* below.\n\n## Step 7 — Schedule delayed deployment check-in\n\nAfter `droplet-create` succeeds, inspect the response before polling. If the\ndroplet is not already `active` with a public IPv4 address in the create\nresponse, assume provisioning is still in progress.\n\nCreate a Codex **heartbeat** to resume this same thread in **5 minutes** for\nthe first status check. Use the Codex automation tool, not a shell sleep or\nlocal timer:\n\n| Field | Value |\n|-------|-------|\n| `mode` | `create` |\n| `kind` | `heartbeat` |\n| `destination` | `thread` |\n| `name` | `Check DigitalOcean droplet \u003Cname>` |\n| `rrule` | `FREQ=MINUTELY;INTERVAL=5` |\n| `status` | `ACTIVE` |\n| `prompt` | `Resume provisioning DigitalOcean droplet \u003Cname> (\u003Cdroplet_id>). Start at Step 8: check whether it is active and has a public IPv4 address, then continue the workflow. The droplet bills hourly until deleted.` |\n\nAfter creating the heartbeat, tell the user the droplet was created and Codex\nwill check back in about 5 minutes. **Stop the active turn here.** Do not start\n20-second polling until the heartbeat wakes the thread back up. This avoids\nbusy-waiting during the normal 5-7 minute deployment window.\n\nKeep the created heartbeat's automation id as `\u003Cheartbeat_id>` if the tool\nreturns one. When the heartbeat resumes the thread, use step 8 to decide\nwhether to keep checking or to delete\u002Fpause the heartbeat and continue.\n\nIf the create response already includes `status == \"active\"` and a public IPv4\naddress, skip the heartbeat and continue immediately to step 8.\n\n## Step 8 — Check whether the droplet is active\n\nCall the **DigitalOcean** app tool **`droplet-get`** once with\n`ID: \u003Cdroplet_id>`.\n\nIf the response has `status == \"active\"` **and** `networks.v4` contains an\nentry with `type == \"public\"`, extract `ip_address` from that entry — this is\n`\u003Cip>`. Delete or pause `\u003Cheartbeat_id>` if it still exists, then continue to\nstep 9.\n\nIf the droplet is still not active or does not yet have a public IPv4 address,\nschedule Codex to check this same thread again in **1 minute**, then **stop the\nactive turn here**. Keep checking back every minute until the droplet is ready;\ndo not give up merely because the DigitalOcean deployment is slow. Prefer\nupdating the existing `\u003Cheartbeat_id>` to a 1-minute interval; if that is not\npossible, create a replacement heartbeat and delete\u002Fpause the old one so there\nis only one active check-in.\n\nUse these values for the 1-minute follow-up heartbeat:\n\n| Field | Value |\n|-------|-------|\n| `mode` | `create` or `update`, depending on the available automation tool |\n| `kind` | `heartbeat` |\n| `destination` | `thread` |\n| `name` | `Check DigitalOcean droplet \u003Cname>` |\n| `rrule` | `FREQ=MINUTELY;INTERVAL=1` |\n| `status` | `ACTIVE` |\n| `prompt` | `Resume provisioning DigitalOcean droplet \u003Cname> (\u003Cdroplet_id>). Start at Step 8: check whether it is active and has a public IPv4 address, then continue the workflow. If it is still not ready, schedule another 1-minute heartbeat. The droplet bills hourly until deleted.` |\n\nKeep all status checks with the DigitalOcean app — do not use doctl or any other\ntool to check droplet status.\n\n## Step 9 — Configure local SSH\n\n```bash\npython3 \u003Cskill_dir>\u002Fscripts\u002Fconfigure_ssh.py \\\n  --alias codex-\u003Cprefix> \\\n  --ip \u003Cip> \\\n  --user root \\\n  --key-path \u003Ckey_path>\n```\n\n**⚠️ Do not interrupt this step.** It waits for cloud-init to finish (up to 7\nminutes) and prints a `⏳` status line every 5 seconds — that output means it is\nworking normally. **Do not run any other commands. Wait for the line\n`DROPLET READY`.** If the script exits with an error instead, report it and\noffer to delete the droplet (see *Cleanup*).\n\n## Final step: adding it to Codex\n\nAsk Codex to open the add-SSH-host flow by responding with a clickable Markdown\nlink. Replace `\u003Cssh-alias>` with `name` from step 2:\n\n`[Add \u003Cssh-alias> to Codex SSH](codex:\u002F\u002Fsettings\u002Fconnections\u002Fssh\u002Fadd?name=\u003Cssh-alias>)`\n\nThe SSH alias is the local host alias created by step 9. In this workflow, it is\nthe same value as the droplet name: `codex-\u003Cprefix>`.\n\nIf the link does not open the flow, or if the user wants to check it manually,\ntell them to open: **Codex App → Settings → Connections → Add SSH Host → pick\nthe alias → choose the remote folder.**\n\n## Cleanup (on failure or when done)\n\nThe droplet bills hourly until deleted. To tear down:\n\n1. **Delete the droplet** — **DigitalOcean** app tool **`droplet-delete`** with\n   `ID: \u003Cdroplet_id>`.\n2. **Delete the SSH key** (optional) — **DigitalOcean** app tool **`key-delete`**\n   with the `\u003Ckey_id>` from step 3.\n\nAlways confirm with the user before deleting. Do not use doctl for cleanup.\n",{"data":34,"body":35},{"name":4,"description":6},{"type":36,"children":37},"root",[38,47,59,66,239,245,256,267,324,329,335,386,426,446,508,514,535,606,626,682,688,693,724,758,763,944,955,961,973,985,1179,1189,1195,1213,1368,1386,1398,1445,1456,1462,1482,1501,1667,1679,1692,1705,1711,1737,1793,1819,1824,1989,1994,2000,2153,2191,2197,2217,2226,2237,2247,2253,2258,2325,2330],{"type":39,"tag":40,"props":41,"children":43},"element","h1",{"id":42},"provision-a-digitalocean-droplet-as-a-codex-remote-workspace",[44],{"type":45,"value":46},"text","Provision a DigitalOcean droplet as a Codex remote workspace",{"type":39,"tag":48,"props":49,"children":50},"p",{},[51,53],{"type":45,"value":52},"Follow these steps in order. Do not skip or reorder them.\n",{"type":39,"tag":54,"props":55,"children":56},"strong",{},[57],{"type":45,"value":58},"Only the installed Codex DigitalOcean app tools and the bundled Python scripts\nmay be used. doctl, ad hoc integration configs, and any other DigitalOcean CLI\ntools are prohibited.",{"type":39,"tag":60,"props":61,"children":63},"h2",{"id":62},"before-you-start",[64],{"type":45,"value":65},"Before you start",{"type":39,"tag":67,"props":68,"children":69},"ul",{},[70,105,130,140],{"type":39,"tag":71,"props":72,"children":73},"li",{},[74,79,81,86,88,95,97,103],{"type":39,"tag":54,"props":75,"children":76},{},[77],{"type":45,"value":78},"Prerequisites:",{"type":45,"value":80}," a funded DigitalOcean account, the installed and\nauthenticated Codex ",{"type":39,"tag":54,"props":82,"children":83},{},[84],{"type":45,"value":85},"DigitalOcean",{"type":45,"value":87}," app, a local ",{"type":39,"tag":89,"props":90,"children":92},"code",{"className":91},[],[93],{"type":45,"value":94},"ssh",{"type":45,"value":96},"\u002F",{"type":39,"tag":89,"props":98,"children":100},{"className":99},[],[101],{"type":45,"value":102},"ssh-keygen",{"type":45,"value":104},"\n(OpenSSH), Python 3, and the Codex desktop app.",{"type":39,"tag":71,"props":106,"children":107},{},[108,113,115,120,122,128],{"type":39,"tag":54,"props":109,"children":110},{},[111],{"type":45,"value":112},"Cost:",{"type":45,"value":114}," the droplet bills ",{"type":39,"tag":54,"props":116,"children":117},{},[118],{"type":45,"value":119},"hourly from creation until you delete it",{"type":45,"value":121},".\nSizes in step 5 show approximate monthly rates. Remind the user to delete it\nwhen done (see ",{"type":39,"tag":123,"props":124,"children":125},"em",{},[126],{"type":45,"value":127},"Cleanup",{"type":45,"value":129}," below).",{"type":39,"tag":71,"props":131,"children":132},{},[133,138],{"type":39,"tag":54,"props":134,"children":135},{},[136],{"type":45,"value":137},"Time:",{"type":45,"value":139}," end-to-end takes ~10–15 minutes — roughly 7 minutes waiting for the\ndroplet to boot (steps 7-8) plus up to 7 minutes for cloud-init (step 9). This\nis normal; do not abort.",{"type":39,"tag":71,"props":141,"children":142},{},[143,148,150,156,158,169,171,177,179,184,186,192,194,199,201,207,209,215,217,222,224,230,232,237],{"type":39,"tag":54,"props":144,"children":145},{},[146],{"type":45,"value":147},"Locate the bundled scripts first (do this before Step 2).",{"type":45,"value":149}," The helper\nscripts live in the ",{"type":39,"tag":89,"props":151,"children":153},{"className":152},[],[154],{"type":45,"value":155},"scripts\u002F",{"type":45,"value":157}," folder ",{"type":39,"tag":54,"props":159,"children":160},{},[161,163],{"type":45,"value":162},"next to this ",{"type":39,"tag":89,"props":164,"children":166},{"className":165},[],[167],{"type":45,"value":168},"SKILL.md",{"type":45,"value":170}," (i.e.\n",{"type":39,"tag":89,"props":172,"children":174},{"className":173},[],[175],{"type":45,"value":176},"provision-droplet\u002Fscripts\u002F",{"type":45,"value":178},"). Your current working directory is ",{"type":39,"tag":54,"props":180,"children":181},{},[182],{"type":45,"value":183},"not",{"type":45,"value":185}," the\nskill directory, so bare relative paths like ",{"type":39,"tag":89,"props":187,"children":189},{"className":188},[],[190],{"type":45,"value":191},"scripts\u002Fkeygen.py",{"type":45,"value":193}," will fail.\nResolve the absolute directory that contains this ",{"type":39,"tag":89,"props":195,"children":197},{"className":196},[],[198],{"type":45,"value":168},{"type":45,"value":200}," and call it\n",{"type":39,"tag":89,"props":202,"children":204},{"className":203},[],[205],{"type":45,"value":206},"\u003Cskill_dir>",{"type":45,"value":208},". If you don't already know it, find it — the installed plugin may\nnest it under a version folder (e.g. ",{"type":39,"tag":89,"props":210,"children":212},{"className":211},[],[213],{"type":45,"value":214},"...\u002F\u003Cversion>\u002Fprovision-droplet\u002F",{"type":45,"value":216},"), so\nlocate the directory that actually contains ",{"type":39,"tag":89,"props":218,"children":220},{"className":219},[],[221],{"type":45,"value":191},{"type":45,"value":223},". Use\n",{"type":39,"tag":89,"props":225,"children":227},{"className":226},[],[228],{"type":45,"value":229},"\u003Cskill_dir>\u002Fscripts\u002F\u003Cname>.py",{"type":45,"value":231}," (an absolute path) in ",{"type":39,"tag":54,"props":233,"children":234},{},[235],{"type":45,"value":236},"every",{"type":45,"value":238}," command below.",{"type":39,"tag":60,"props":240,"children":242},{"id":241},"step-1-verify-digitalocean-app-access",[243],{"type":45,"value":244},"Step 1 — Verify DigitalOcean app access",{"type":39,"tag":48,"props":246,"children":247},{},[248,250,254],{"type":45,"value":249},"This plugin depends on the single Codex ",{"type":39,"tag":54,"props":251,"children":252},{},[253],{"type":45,"value":85},{"type":45,"value":255}," app. Use it for all\nDigitalOcean operations; do not register or log in to separate plugin-owned app\nintegrations.",{"type":39,"tag":48,"props":257,"children":258},{},[259,261,265],{"type":45,"value":260},"The ",{"type":39,"tag":54,"props":262,"children":263},{},[264],{"type":45,"value":85},{"type":45,"value":266}," app provides both:",{"type":39,"tag":67,"props":268,"children":269},{},[270,298],{"type":39,"tag":71,"props":271,"children":272},{},[273,275,281,283,289,290,296],{"type":45,"value":274},"SSH key tools: ",{"type":39,"tag":89,"props":276,"children":278},{"className":277},[],[279],{"type":45,"value":280},"key-create",{"type":45,"value":282},", ",{"type":39,"tag":89,"props":284,"children":286},{"className":285},[],[287],{"type":45,"value":288},"key-list",{"type":45,"value":282},{"type":39,"tag":89,"props":291,"children":293},{"className":292},[],[294],{"type":45,"value":295},"key-delete",{"type":45,"value":297},".",{"type":39,"tag":71,"props":299,"children":300},{},[301,303,309,310,316,317,323],{"type":45,"value":302},"Droplet tools: ",{"type":39,"tag":89,"props":304,"children":306},{"className":305},[],[307],{"type":45,"value":308},"droplet-create",{"type":45,"value":282},{"type":39,"tag":89,"props":311,"children":313},{"className":312},[],[314],{"type":45,"value":315},"droplet-get",{"type":45,"value":282},{"type":39,"tag":89,"props":318,"children":320},{"className":319},[],[321],{"type":45,"value":322},"droplet-delete",{"type":45,"value":297},{"type":39,"tag":48,"props":325,"children":326},{},[327],{"type":45,"value":328},"Confirm that these tools are available before continuing. If the app's tools are\nmissing or unauthenticated, stop and tell the user to install or authenticate\nthe DigitalOcean app in Codex. Do not fall back to doctl, API tokens, or a local\nintegration config.",{"type":39,"tag":60,"props":330,"children":332},{"id":331},"step-2-generate-ssh-key-pair",[333],{"type":45,"value":334},"Step 2 — Generate SSH key pair",{"type":39,"tag":336,"props":337,"children":342},"pre",{"className":338,"code":339,"language":340,"meta":341,"style":341},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","python3 \u003Cskill_dir>\u002Fscripts\u002Fkeygen.py\n","bash","",[343],{"type":39,"tag":89,"props":344,"children":345},{"__ignoreMap":341},[346],{"type":39,"tag":347,"props":348,"children":351},"span",{"class":349,"line":350},"line",1,[352,358,364,370,376,381],{"type":39,"tag":347,"props":353,"children":355},{"style":354},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[356],{"type":45,"value":357},"python3",{"type":39,"tag":347,"props":359,"children":361},{"style":360},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[362],{"type":45,"value":363}," \u003C",{"type":39,"tag":347,"props":365,"children":367},{"style":366},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[368],{"type":45,"value":369},"skill_di",{"type":39,"tag":347,"props":371,"children":373},{"style":372},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[374],{"type":45,"value":375},"r",{"type":39,"tag":347,"props":377,"children":378},{"style":360},[379],{"type":45,"value":380},">",{"type":39,"tag":347,"props":382,"children":383},{"style":366},[384],{"type":45,"value":385},"\u002Fscripts\u002Fkeygen.py\n",{"type":39,"tag":48,"props":387,"children":388},{},[389,391,397,398,404,405,411,412,418,419,425],{"type":45,"value":390},"Parse the JSON output and keep these values for the steps below:\n",{"type":39,"tag":89,"props":392,"children":394},{"className":393},[],[395],{"type":45,"value":396},"prefix",{"type":45,"value":282},{"type":39,"tag":89,"props":399,"children":401},{"className":400},[],[402],{"type":45,"value":403},"name",{"type":45,"value":282},{"type":39,"tag":89,"props":406,"children":408},{"className":407},[],[409],{"type":45,"value":410},"key_name",{"type":45,"value":282},{"type":39,"tag":89,"props":413,"children":415},{"className":414},[],[416],{"type":45,"value":417},"key_path",{"type":45,"value":282},{"type":39,"tag":89,"props":420,"children":422},{"className":421},[],[423],{"type":45,"value":424},"pub_key",{"type":45,"value":297},{"type":39,"tag":48,"props":427,"children":428},{},[429,431,436,438,444],{"type":45,"value":430},"How these relate (all derived from one random ",{"type":39,"tag":89,"props":432,"children":434},{"className":433},[],[435],{"type":45,"value":396},{"type":45,"value":437}," like ",{"type":39,"tag":89,"props":439,"children":441},{"className":440},[],[442],{"type":45,"value":443},"bright-hawk-a3f2",{"type":45,"value":445},"):",{"type":39,"tag":67,"props":447,"children":448},{},[449,481,498],{"type":39,"tag":71,"props":450,"children":451},{},[452,457,459,465,467,472,474,479],{"type":39,"tag":89,"props":453,"children":455},{"className":454},[],[456],{"type":45,"value":403},{"type":45,"value":458}," = ",{"type":39,"tag":89,"props":460,"children":462},{"className":461},[],[463],{"type":45,"value":464},"codex-\u003Cprefix>",{"type":45,"value":466}," — the ",{"type":39,"tag":54,"props":468,"children":469},{},[470],{"type":45,"value":471},"droplet name",{"type":45,"value":473}," and the ",{"type":39,"tag":54,"props":475,"children":476},{},[477],{"type":45,"value":478},"local SSH alias",{"type":45,"value":480},"\n(they are identical).",{"type":39,"tag":71,"props":482,"children":483},{},[484,489,490,496],{"type":39,"tag":89,"props":485,"children":487},{"className":486},[],[488],{"type":45,"value":410},{"type":45,"value":458},{"type":39,"tag":89,"props":491,"children":493},{"className":492},[],[494],{"type":45,"value":495},"codex-key-\u003Cprefix>",{"type":45,"value":497}," — the label for the key on DigitalOcean's\nside only.",{"type":39,"tag":71,"props":499,"children":500},{},[501,506],{"type":39,"tag":89,"props":502,"children":504},{"className":503},[],[505],{"type":45,"value":417},{"type":45,"value":507}," — the local private key file.",{"type":39,"tag":60,"props":509,"children":511},{"id":510},"step-3-upload-ssh-public-key",[512],{"type":45,"value":513},"Step 3 — Upload SSH public key",{"type":39,"tag":48,"props":515,"children":516},{},[517,519,523,525,533],{"type":45,"value":518},"Call the ",{"type":39,"tag":54,"props":520,"children":521},{},[522],{"type":45,"value":85},{"type":45,"value":524}," app tool ",{"type":39,"tag":54,"props":526,"children":527},{},[528],{"type":39,"tag":89,"props":529,"children":531},{"className":530},[],[532],{"type":45,"value":280},{"type":45,"value":534},":",{"type":39,"tag":536,"props":537,"children":538},"table",{},[539,558],{"type":39,"tag":540,"props":541,"children":542},"thead",{},[543],{"type":39,"tag":544,"props":545,"children":546},"tr",{},[547,553],{"type":39,"tag":548,"props":549,"children":550},"th",{},[551],{"type":45,"value":552},"Parameter",{"type":39,"tag":548,"props":554,"children":555},{},[556],{"type":45,"value":557},"Value",{"type":39,"tag":559,"props":560,"children":561},"tbody",{},[562,585],{"type":39,"tag":544,"props":563,"children":564},{},[565,575],{"type":39,"tag":566,"props":567,"children":568},"td",{},[569],{"type":39,"tag":89,"props":570,"children":572},{"className":571},[],[573],{"type":45,"value":574},"Name",{"type":39,"tag":566,"props":576,"children":577},{},[578,583],{"type":39,"tag":89,"props":579,"children":581},{"className":580},[],[582],{"type":45,"value":410},{"type":45,"value":584}," from step 2",{"type":39,"tag":544,"props":586,"children":587},{},[588,597],{"type":39,"tag":566,"props":589,"children":590},{},[591],{"type":39,"tag":89,"props":592,"children":594},{"className":593},[],[595],{"type":45,"value":596},"PublicKey",{"type":39,"tag":566,"props":598,"children":599},{},[600,605],{"type":39,"tag":89,"props":601,"children":603},{"className":602},[],[604],{"type":45,"value":424},{"type":45,"value":584},{"type":39,"tag":48,"props":607,"children":608},{},[609,611,617,619,625],{"type":45,"value":610},"Extract ",{"type":39,"tag":89,"props":612,"children":614},{"className":613},[],[615],{"type":45,"value":616},"ssh_key.id",{"type":45,"value":618}," from the response — this is ",{"type":39,"tag":89,"props":620,"children":622},{"className":621},[],[623],{"type":45,"value":624},"\u003Ckey_id>",{"type":45,"value":297},{"type":39,"tag":48,"props":627,"children":628},{},[629,631,636,638,642,644,652,654,659,661,666,668,674,676,681],{"type":45,"value":630},"If the call fails because a key with that name or fingerprint ",{"type":39,"tag":54,"props":632,"children":633},{},[634],{"type":45,"value":635},"already exists",{"type":45,"value":637},"\n(e.g. a previous run), do not create a duplicate: call the ",{"type":39,"tag":54,"props":639,"children":640},{},[641],{"type":45,"value":85},{"type":45,"value":643}," app\ntool ",{"type":39,"tag":54,"props":645,"children":646},{},[647],{"type":39,"tag":89,"props":648,"children":650},{"className":649},[],[651],{"type":45,"value":288},{"type":45,"value":653},", find the entry whose ",{"type":39,"tag":89,"props":655,"children":657},{"className":656},[],[658],{"type":45,"value":403},{"type":45,"value":660}," matches ",{"type":39,"tag":89,"props":662,"children":664},{"className":663},[],[665],{"type":45,"value":410},{"type":45,"value":667}," (or whose\nfingerprint matches the uploaded key), and use its ",{"type":39,"tag":89,"props":669,"children":671},{"className":670},[],[672],{"type":45,"value":673},"id",{"type":45,"value":675}," as ",{"type":39,"tag":89,"props":677,"children":679},{"className":678},[],[680],{"type":45,"value":624},{"type":45,"value":297},{"type":39,"tag":60,"props":683,"children":685},{"id":684},"step-4-choose-a-region",[686],{"type":45,"value":687},"Step 4 — Choose a region",{"type":39,"tag":48,"props":689,"children":690},{},[691],{"type":45,"value":692},"Ask the user, in chat:",{"type":39,"tag":694,"props":695,"children":696},"blockquote",{},[697],{"type":39,"tag":48,"props":698,"children":699},{},[700,702,711,713,722],{"type":45,"value":701},"Use the defaults — region ",{"type":39,"tag":54,"props":703,"children":704},{},[705],{"type":39,"tag":89,"props":706,"children":708},{"className":707},[],[709],{"type":45,"value":710},"nyc3",{"type":45,"value":712}," (New York, US) and size\n",{"type":39,"tag":54,"props":714,"children":715},{},[716],{"type":39,"tag":89,"props":717,"children":719},{"className":718},[],[720],{"type":45,"value":721},"s-2vcpu-4gb",{"type":45,"value":723}," (2 vCPU \u002F 4 GB, ~$24\u002Fmo) — or customize them?",{"type":39,"tag":48,"props":725,"children":726},{},[727,729,734,735,741,743,748,750,756],{"type":45,"value":728},"If they choose the defaults, use ",{"type":39,"tag":89,"props":730,"children":732},{"className":731},[],[733],{"type":45,"value":710},{"type":45,"value":675},{"type":39,"tag":89,"props":736,"children":738},{"className":737},[],[739],{"type":45,"value":740},"\u003Cregion>",{"type":45,"value":742}," and ",{"type":39,"tag":89,"props":744,"children":746},{"className":745},[],[747],{"type":45,"value":721},{"type":45,"value":749}," as\n",{"type":39,"tag":89,"props":751,"children":753},{"className":752},[],[754],{"type":45,"value":755},"\u003Csize>",{"type":45,"value":757},", then skip step 5 and continue to step 6.",{"type":39,"tag":48,"props":759,"children":760},{},[761],{"type":45,"value":762},"If they want to customize the defaults, present this region list first and ask\nthem to reply with a slug:",{"type":39,"tag":536,"props":764,"children":765},{},[766,782],{"type":39,"tag":540,"props":767,"children":768},{},[769],{"type":39,"tag":544,"props":770,"children":771},{},[772,777],{"type":39,"tag":548,"props":773,"children":774},{},[775],{"type":45,"value":776},"Slug",{"type":39,"tag":548,"props":778,"children":779},{},[780],{"type":45,"value":781},"Location",{"type":39,"tag":559,"props":783,"children":784},{},[785,808,825,842,859,876,893,910,927],{"type":39,"tag":544,"props":786,"children":787},{},[788,803],{"type":39,"tag":566,"props":789,"children":790},{},[791,796,798],{"type":39,"tag":89,"props":792,"children":794},{"className":793},[],[795],{"type":45,"value":710},{"type":45,"value":797}," ",{"type":39,"tag":123,"props":799,"children":800},{},[801],{"type":45,"value":802},"(default)",{"type":39,"tag":566,"props":804,"children":805},{},[806],{"type":45,"value":807},"New York, US",{"type":39,"tag":544,"props":809,"children":810},{},[811,820],{"type":39,"tag":566,"props":812,"children":813},{},[814],{"type":39,"tag":89,"props":815,"children":817},{"className":816},[],[818],{"type":45,"value":819},"sfo3",{"type":39,"tag":566,"props":821,"children":822},{},[823],{"type":45,"value":824},"San Francisco, US",{"type":39,"tag":544,"props":826,"children":827},{},[828,837],{"type":39,"tag":566,"props":829,"children":830},{},[831],{"type":39,"tag":89,"props":832,"children":834},{"className":833},[],[835],{"type":45,"value":836},"tor1",{"type":39,"tag":566,"props":838,"children":839},{},[840],{"type":45,"value":841},"Toronto, CA",{"type":39,"tag":544,"props":843,"children":844},{},[845,854],{"type":39,"tag":566,"props":846,"children":847},{},[848],{"type":39,"tag":89,"props":849,"children":851},{"className":850},[],[852],{"type":45,"value":853},"lon1",{"type":39,"tag":566,"props":855,"children":856},{},[857],{"type":45,"value":858},"London, UK",{"type":39,"tag":544,"props":860,"children":861},{},[862,871],{"type":39,"tag":566,"props":863,"children":864},{},[865],{"type":39,"tag":89,"props":866,"children":868},{"className":867},[],[869],{"type":45,"value":870},"fra1",{"type":39,"tag":566,"props":872,"children":873},{},[874],{"type":45,"value":875},"Frankfurt, DE",{"type":39,"tag":544,"props":877,"children":878},{},[879,888],{"type":39,"tag":566,"props":880,"children":881},{},[882],{"type":39,"tag":89,"props":883,"children":885},{"className":884},[],[886],{"type":45,"value":887},"ams3",{"type":39,"tag":566,"props":889,"children":890},{},[891],{"type":45,"value":892},"Amsterdam, NL",{"type":39,"tag":544,"props":894,"children":895},{},[896,905],{"type":39,"tag":566,"props":897,"children":898},{},[899],{"type":39,"tag":89,"props":900,"children":902},{"className":901},[],[903],{"type":45,"value":904},"sgp1",{"type":39,"tag":566,"props":906,"children":907},{},[908],{"type":45,"value":909},"Singapore, SG",{"type":39,"tag":544,"props":911,"children":912},{},[913,922],{"type":39,"tag":566,"props":914,"children":915},{},[916],{"type":39,"tag":89,"props":917,"children":919},{"className":918},[],[920],{"type":45,"value":921},"blr1",{"type":39,"tag":566,"props":923,"children":924},{},[925],{"type":45,"value":926},"Bangalore, IN",{"type":39,"tag":544,"props":928,"children":929},{},[930,939],{"type":39,"tag":566,"props":931,"children":932},{},[933],{"type":39,"tag":89,"props":934,"children":936},{"className":935},[],[937],{"type":45,"value":938},"syd1",{"type":39,"tag":566,"props":940,"children":941},{},[942],{"type":45,"value":943},"Sydney, AU",{"type":39,"tag":48,"props":945,"children":946},{},[947,949,954],{"type":45,"value":948},"Validate their reply against this table. If it is not one of these slugs, ask\nagain — do not pass an unlisted value through. The chosen slug is ",{"type":39,"tag":89,"props":950,"children":952},{"className":951},[],[953],{"type":45,"value":740},{"type":45,"value":297},{"type":39,"tag":60,"props":956,"children":958},{"id":957},"step-5-choose-a-droplet-size",[959],{"type":45,"value":960},"Step 5 — Choose a droplet size",{"type":39,"tag":48,"props":962,"children":963},{},[964,966,971],{"type":45,"value":965},"Skip this step if ",{"type":39,"tag":89,"props":967,"children":969},{"className":968},[],[970],{"type":45,"value":755},{"type":45,"value":972}," was already set to the default in step 4.",{"type":39,"tag":48,"props":974,"children":975},{},[976,978,983],{"type":45,"value":977},"Otherwise, present this size list and ask the user to reply with a slug. Every\nsize below is above the ",{"type":39,"tag":54,"props":979,"children":980},{},[981],{"type":45,"value":982},"1 vCPU \u002F 2 GB",{"type":45,"value":984}," floor required by the Codex Universal\nimage. Prices are approximate — confirm in the DigitalOcean dashboard.",{"type":39,"tag":536,"props":986,"children":987},{},[988,1018],{"type":39,"tag":540,"props":989,"children":990},{},[991],{"type":39,"tag":544,"props":992,"children":993},{},[994,998,1003,1008,1013],{"type":39,"tag":548,"props":995,"children":996},{},[997],{"type":45,"value":776},{"type":39,"tag":548,"props":999,"children":1000},{},[1001],{"type":45,"value":1002},"vCPU",{"type":39,"tag":548,"props":1004,"children":1005},{},[1006],{"type":45,"value":1007},"RAM",{"type":39,"tag":548,"props":1009,"children":1010},{},[1011],{"type":45,"value":1012},"Tier",{"type":39,"tag":548,"props":1014,"children":1015},{},[1016],{"type":45,"value":1017},"~$\u002Fmo",{"type":39,"tag":559,"props":1019,"children":1020},{},[1021,1057,1088,1119,1149],{"type":39,"tag":544,"props":1022,"children":1023},{},[1024,1037,1042,1047,1052],{"type":39,"tag":566,"props":1025,"children":1026},{},[1027,1032,1033],{"type":39,"tag":89,"props":1028,"children":1030},{"className":1029},[],[1031],{"type":45,"value":721},{"type":45,"value":797},{"type":39,"tag":123,"props":1034,"children":1035},{},[1036],{"type":45,"value":802},{"type":39,"tag":566,"props":1038,"children":1039},{},[1040],{"type":45,"value":1041},"2",{"type":39,"tag":566,"props":1043,"children":1044},{},[1045],{"type":45,"value":1046},"4 GB",{"type":39,"tag":566,"props":1048,"children":1049},{},[1050],{"type":45,"value":1051},"Shared basic",{"type":39,"tag":566,"props":1053,"children":1054},{},[1055],{"type":45,"value":1056},"$24",{"type":39,"tag":544,"props":1058,"children":1059},{},[1060,1069,1074,1079,1083],{"type":39,"tag":566,"props":1061,"children":1062},{},[1063],{"type":39,"tag":89,"props":1064,"children":1066},{"className":1065},[],[1067],{"type":45,"value":1068},"s-4vcpu-8gb",{"type":39,"tag":566,"props":1070,"children":1071},{},[1072],{"type":45,"value":1073},"4",{"type":39,"tag":566,"props":1075,"children":1076},{},[1077],{"type":45,"value":1078},"8 GB",{"type":39,"tag":566,"props":1080,"children":1081},{},[1082],{"type":45,"value":1051},{"type":39,"tag":566,"props":1084,"children":1085},{},[1086],{"type":45,"value":1087},"$48",{"type":39,"tag":544,"props":1089,"children":1090},{},[1091,1100,1105,1110,1114],{"type":39,"tag":566,"props":1092,"children":1093},{},[1094],{"type":39,"tag":89,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":45,"value":1099},"s-8vcpu-16gb",{"type":39,"tag":566,"props":1101,"children":1102},{},[1103],{"type":45,"value":1104},"8",{"type":39,"tag":566,"props":1106,"children":1107},{},[1108],{"type":45,"value":1109},"16 GB",{"type":39,"tag":566,"props":1111,"children":1112},{},[1113],{"type":45,"value":1051},{"type":39,"tag":566,"props":1115,"children":1116},{},[1117],{"type":45,"value":1118},"$96",{"type":39,"tag":544,"props":1120,"children":1121},{},[1122,1131,1135,1139,1144],{"type":39,"tag":566,"props":1123,"children":1124},{},[1125],{"type":39,"tag":89,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":45,"value":1130},"c-2",{"type":39,"tag":566,"props":1132,"children":1133},{},[1134],{"type":45,"value":1041},{"type":39,"tag":566,"props":1136,"children":1137},{},[1138],{"type":45,"value":1046},{"type":39,"tag":566,"props":1140,"children":1141},{},[1142],{"type":45,"value":1143},"Premium CPU-optimized",{"type":39,"tag":566,"props":1145,"children":1146},{},[1147],{"type":45,"value":1148},"$42",{"type":39,"tag":544,"props":1150,"children":1151},{},[1152,1161,1165,1169,1174],{"type":39,"tag":566,"props":1153,"children":1154},{},[1155],{"type":39,"tag":89,"props":1156,"children":1158},{"className":1157},[],[1159],{"type":45,"value":1160},"g-2vcpu-8gb",{"type":39,"tag":566,"props":1162,"children":1163},{},[1164],{"type":45,"value":1041},{"type":39,"tag":566,"props":1166,"children":1167},{},[1168],{"type":45,"value":1078},{"type":39,"tag":566,"props":1170,"children":1171},{},[1172],{"type":45,"value":1173},"Premium general-purpose",{"type":39,"tag":566,"props":1175,"children":1176},{},[1177],{"type":45,"value":1178},"$63",{"type":39,"tag":48,"props":1180,"children":1181},{},[1182,1183,1188],{"type":45,"value":948},{"type":39,"tag":89,"props":1184,"children":1186},{"className":1185},[],[1187],{"type":45,"value":755},{"type":45,"value":297},{"type":39,"tag":60,"props":1190,"children":1192},{"id":1191},"step-6-create-droplet",[1193],{"type":45,"value":1194},"Step 6 — Create droplet",{"type":39,"tag":48,"props":1196,"children":1197},{},[1198,1199,1203,1204,1212],{"type":45,"value":518},{"type":39,"tag":54,"props":1200,"children":1201},{},[1202],{"type":45,"value":85},{"type":45,"value":524},{"type":39,"tag":54,"props":1205,"children":1206},{},[1207],{"type":39,"tag":89,"props":1208,"children":1210},{"className":1209},[],[1211],{"type":45,"value":308},{"type":45,"value":534},{"type":39,"tag":536,"props":1214,"children":1215},{},[1216,1235],{"type":39,"tag":540,"props":1217,"children":1218},{},[1219],{"type":39,"tag":544,"props":1220,"children":1221},{},[1222,1226,1230],{"type":39,"tag":548,"props":1223,"children":1224},{},[1225],{"type":45,"value":552},{"type":39,"tag":548,"props":1227,"children":1228},{},[1229],{"type":45,"value":557},{"type":39,"tag":548,"props":1231,"children":1232},{},[1233],{"type":45,"value":1234},"Notes",{"type":39,"tag":559,"props":1236,"children":1237},{},[1238,1261,1286,1311,1344],{"type":39,"tag":544,"props":1239,"children":1240},{},[1241,1249,1258],{"type":39,"tag":566,"props":1242,"children":1243},{},[1244],{"type":39,"tag":89,"props":1245,"children":1247},{"className":1246},[],[1248],{"type":45,"value":574},{"type":39,"tag":566,"props":1250,"children":1251},{},[1252,1257],{"type":39,"tag":89,"props":1253,"children":1255},{"className":1254},[],[1256],{"type":45,"value":403},{"type":45,"value":584},{"type":39,"tag":566,"props":1259,"children":1260},{},[],{"type":39,"tag":544,"props":1262,"children":1263},{},[1264,1273,1283],{"type":39,"tag":566,"props":1265,"children":1266},{},[1267],{"type":39,"tag":89,"props":1268,"children":1270},{"className":1269},[],[1271],{"type":45,"value":1272},"Region",{"type":39,"tag":566,"props":1274,"children":1275},{},[1276,1281],{"type":39,"tag":89,"props":1277,"children":1279},{"className":1278},[],[1280],{"type":45,"value":740},{"type":45,"value":1282}," from step 4",{"type":39,"tag":566,"props":1284,"children":1285},{},[],{"type":39,"tag":544,"props":1287,"children":1288},{},[1289,1298,1308],{"type":39,"tag":566,"props":1290,"children":1291},{},[1292],{"type":39,"tag":89,"props":1293,"children":1295},{"className":1294},[],[1296],{"type":45,"value":1297},"Size",{"type":39,"tag":566,"props":1299,"children":1300},{},[1301,1306],{"type":39,"tag":89,"props":1302,"children":1304},{"className":1303},[],[1305],{"type":45,"value":755},{"type":45,"value":1307}," from step 5",{"type":39,"tag":566,"props":1309,"children":1310},{},[],{"type":39,"tag":544,"props":1312,"children":1313},{},[1314,1323,1332],{"type":39,"tag":566,"props":1315,"children":1316},{},[1317],{"type":39,"tag":89,"props":1318,"children":1320},{"className":1319},[],[1321],{"type":45,"value":1322},"ImageID",{"type":39,"tag":566,"props":1324,"children":1325},{},[1326],{"type":39,"tag":89,"props":1327,"children":1329},{"className":1328},[],[1330],{"type":45,"value":1331},"234061005",{"type":39,"tag":566,"props":1333,"children":1334},{},[1335,1337,1342],{"type":45,"value":1336},"DigitalOcean ",{"type":39,"tag":54,"props":1338,"children":1339},{},[1340],{"type":45,"value":1341},"Codex Universal",{"type":45,"value":1343}," image",{"type":39,"tag":544,"props":1345,"children":1346},{},[1347,1356,1365],{"type":39,"tag":566,"props":1348,"children":1349},{},[1350],{"type":39,"tag":89,"props":1351,"children":1353},{"className":1352},[],[1354],{"type":45,"value":1355},"SSHKeys",{"type":39,"tag":566,"props":1357,"children":1358},{},[1359],{"type":39,"tag":89,"props":1360,"children":1362},{"className":1361},[],[1363],{"type":45,"value":1364},"[\"\u003Ckey_id>\"]",{"type":39,"tag":566,"props":1366,"children":1367},{},[],{"type":39,"tag":48,"props":1369,"children":1370},{},[1371,1372,1378,1379,1385],{"type":45,"value":610},{"type":39,"tag":89,"props":1373,"children":1375},{"className":1374},[],[1376],{"type":45,"value":1377},"droplet.id",{"type":45,"value":618},{"type":39,"tag":89,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":45,"value":1384},"\u003Cdroplet_id>",{"type":45,"value":297},{"type":39,"tag":48,"props":1387,"children":1388},{},[1389,1391,1396],{"type":45,"value":1390},"If ",{"type":39,"tag":89,"props":1392,"children":1394},{"className":1393},[],[1395],{"type":45,"value":308},{"type":45,"value":1397}," fails, show the user the error and handle it by cause — do\nnot blindly retry the same values:",{"type":39,"tag":67,"props":1399,"children":1400},{},[1401,1425,1435],{"type":39,"tag":71,"props":1402,"children":1403},{},[1404,1409,1411,1416,1418,1423],{"type":39,"tag":54,"props":1405,"children":1406},{},[1407],{"type":45,"value":1408},"Size not available in this region",{"type":45,"value":1410}," (premium tiers like ",{"type":39,"tag":89,"props":1412,"children":1414},{"className":1413},[],[1415],{"type":45,"value":1130},{"type":45,"value":1417}," and\n",{"type":39,"tag":89,"props":1419,"children":1421},{"className":1420},[],[1422],{"type":45,"value":1160},{"type":45,"value":1424}," are not in every region): go back to step 4 or 5 and pick a\ndifferent region\u002Fsize combination.",{"type":39,"tag":71,"props":1426,"children":1427},{},[1428,1433],{"type":39,"tag":54,"props":1429,"children":1430},{},[1431],{"type":45,"value":1432},"Payment \u002F quota \u002F limit",{"type":45,"value":1434}," errors: stop and tell the user to resolve it in\nthe DigitalOcean dashboard, then re-run.",{"type":39,"tag":71,"props":1436,"children":1437},{},[1438,1443],{"type":39,"tag":54,"props":1439,"children":1440},{},[1441],{"type":45,"value":1442},"Invalid image or any other error:",{"type":45,"value":1444}," stop and report it.",{"type":39,"tag":48,"props":1446,"children":1447},{},[1448,1450,1454],{"type":45,"value":1449},"The uploaded SSH key from step 3 is harmless to leave, but if you abort here see\n",{"type":39,"tag":123,"props":1451,"children":1452},{},[1453],{"type":45,"value":127},{"type":45,"value":1455}," below.",{"type":39,"tag":60,"props":1457,"children":1459},{"id":1458},"step-7-schedule-delayed-deployment-check-in",[1460],{"type":45,"value":1461},"Step 7 — Schedule delayed deployment check-in",{"type":39,"tag":48,"props":1463,"children":1464},{},[1465,1467,1472,1474,1480],{"type":45,"value":1466},"After ",{"type":39,"tag":89,"props":1468,"children":1470},{"className":1469},[],[1471],{"type":45,"value":308},{"type":45,"value":1473}," succeeds, inspect the response before polling. If the\ndroplet is not already ",{"type":39,"tag":89,"props":1475,"children":1477},{"className":1476},[],[1478],{"type":45,"value":1479},"active",{"type":45,"value":1481}," with a public IPv4 address in the create\nresponse, assume provisioning is still in progress.",{"type":39,"tag":48,"props":1483,"children":1484},{},[1485,1487,1492,1494,1499],{"type":45,"value":1486},"Create a Codex ",{"type":39,"tag":54,"props":1488,"children":1489},{},[1490],{"type":45,"value":1491},"heartbeat",{"type":45,"value":1493}," to resume this same thread in ",{"type":39,"tag":54,"props":1495,"children":1496},{},[1497],{"type":45,"value":1498},"5 minutes",{"type":45,"value":1500}," for\nthe first status check. Use the Codex automation tool, not a shell sleep or\nlocal timer:",{"type":39,"tag":536,"props":1502,"children":1503},{},[1504,1519],{"type":39,"tag":540,"props":1505,"children":1506},{},[1507],{"type":39,"tag":544,"props":1508,"children":1509},{},[1510,1515],{"type":39,"tag":548,"props":1511,"children":1512},{},[1513],{"type":45,"value":1514},"Field",{"type":39,"tag":548,"props":1516,"children":1517},{},[1518],{"type":45,"value":557},{"type":39,"tag":559,"props":1520,"children":1521},{},[1522,1543,1563,1584,1604,1625,1646],{"type":39,"tag":544,"props":1523,"children":1524},{},[1525,1534],{"type":39,"tag":566,"props":1526,"children":1527},{},[1528],{"type":39,"tag":89,"props":1529,"children":1531},{"className":1530},[],[1532],{"type":45,"value":1533},"mode",{"type":39,"tag":566,"props":1535,"children":1536},{},[1537],{"type":39,"tag":89,"props":1538,"children":1540},{"className":1539},[],[1541],{"type":45,"value":1542},"create",{"type":39,"tag":544,"props":1544,"children":1545},{},[1546,1555],{"type":39,"tag":566,"props":1547,"children":1548},{},[1549],{"type":39,"tag":89,"props":1550,"children":1552},{"className":1551},[],[1553],{"type":45,"value":1554},"kind",{"type":39,"tag":566,"props":1556,"children":1557},{},[1558],{"type":39,"tag":89,"props":1559,"children":1561},{"className":1560},[],[1562],{"type":45,"value":1491},{"type":39,"tag":544,"props":1564,"children":1565},{},[1566,1575],{"type":39,"tag":566,"props":1567,"children":1568},{},[1569],{"type":39,"tag":89,"props":1570,"children":1572},{"className":1571},[],[1573],{"type":45,"value":1574},"destination",{"type":39,"tag":566,"props":1576,"children":1577},{},[1578],{"type":39,"tag":89,"props":1579,"children":1581},{"className":1580},[],[1582],{"type":45,"value":1583},"thread",{"type":39,"tag":544,"props":1585,"children":1586},{},[1587,1595],{"type":39,"tag":566,"props":1588,"children":1589},{},[1590],{"type":39,"tag":89,"props":1591,"children":1593},{"className":1592},[],[1594],{"type":45,"value":403},{"type":39,"tag":566,"props":1596,"children":1597},{},[1598],{"type":39,"tag":89,"props":1599,"children":1601},{"className":1600},[],[1602],{"type":45,"value":1603},"Check DigitalOcean droplet \u003Cname>",{"type":39,"tag":544,"props":1605,"children":1606},{},[1607,1616],{"type":39,"tag":566,"props":1608,"children":1609},{},[1610],{"type":39,"tag":89,"props":1611,"children":1613},{"className":1612},[],[1614],{"type":45,"value":1615},"rrule",{"type":39,"tag":566,"props":1617,"children":1618},{},[1619],{"type":39,"tag":89,"props":1620,"children":1622},{"className":1621},[],[1623],{"type":45,"value":1624},"FREQ=MINUTELY;INTERVAL=5",{"type":39,"tag":544,"props":1626,"children":1627},{},[1628,1637],{"type":39,"tag":566,"props":1629,"children":1630},{},[1631],{"type":39,"tag":89,"props":1632,"children":1634},{"className":1633},[],[1635],{"type":45,"value":1636},"status",{"type":39,"tag":566,"props":1638,"children":1639},{},[1640],{"type":39,"tag":89,"props":1641,"children":1643},{"className":1642},[],[1644],{"type":45,"value":1645},"ACTIVE",{"type":39,"tag":544,"props":1647,"children":1648},{},[1649,1658],{"type":39,"tag":566,"props":1650,"children":1651},{},[1652],{"type":39,"tag":89,"props":1653,"children":1655},{"className":1654},[],[1656],{"type":45,"value":1657},"prompt",{"type":39,"tag":566,"props":1659,"children":1660},{},[1661],{"type":39,"tag":89,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":45,"value":1666},"Resume provisioning DigitalOcean droplet \u003Cname> (\u003Cdroplet_id>). Start at Step 8: check whether it is active and has a public IPv4 address, then continue the workflow. The droplet bills hourly until deleted.",{"type":39,"tag":48,"props":1668,"children":1669},{},[1670,1672,1677],{"type":45,"value":1671},"After creating the heartbeat, tell the user the droplet was created and Codex\nwill check back in about 5 minutes. ",{"type":39,"tag":54,"props":1673,"children":1674},{},[1675],{"type":45,"value":1676},"Stop the active turn here.",{"type":45,"value":1678}," Do not start\n20-second polling until the heartbeat wakes the thread back up. This avoids\nbusy-waiting during the normal 5-7 minute deployment window.",{"type":39,"tag":48,"props":1680,"children":1681},{},[1682,1684,1690],{"type":45,"value":1683},"Keep the created heartbeat's automation id as ",{"type":39,"tag":89,"props":1685,"children":1687},{"className":1686},[],[1688],{"type":45,"value":1689},"\u003Cheartbeat_id>",{"type":45,"value":1691}," if the tool\nreturns one. When the heartbeat resumes the thread, use step 8 to decide\nwhether to keep checking or to delete\u002Fpause the heartbeat and continue.",{"type":39,"tag":48,"props":1693,"children":1694},{},[1695,1697,1703],{"type":45,"value":1696},"If the create response already includes ",{"type":39,"tag":89,"props":1698,"children":1700},{"className":1699},[],[1701],{"type":45,"value":1702},"status == \"active\"",{"type":45,"value":1704}," and a public IPv4\naddress, skip the heartbeat and continue immediately to step 8.",{"type":39,"tag":60,"props":1706,"children":1708},{"id":1707},"step-8-check-whether-the-droplet-is-active",[1709],{"type":45,"value":1710},"Step 8 — Check whether the droplet is active",{"type":39,"tag":48,"props":1712,"children":1713},{},[1714,1715,1719,1720,1728,1730,1736],{"type":45,"value":518},{"type":39,"tag":54,"props":1716,"children":1717},{},[1718],{"type":45,"value":85},{"type":45,"value":524},{"type":39,"tag":54,"props":1721,"children":1722},{},[1723],{"type":39,"tag":89,"props":1724,"children":1726},{"className":1725},[],[1727],{"type":45,"value":315},{"type":45,"value":1729}," once with\n",{"type":39,"tag":89,"props":1731,"children":1733},{"className":1732},[],[1734],{"type":45,"value":1735},"ID: \u003Cdroplet_id>",{"type":45,"value":297},{"type":39,"tag":48,"props":1738,"children":1739},{},[1740,1742,1747,1748,1753,1754,1760,1762,1768,1770,1776,1778,1784,1786,1791],{"type":45,"value":1741},"If the response has ",{"type":39,"tag":89,"props":1743,"children":1745},{"className":1744},[],[1746],{"type":45,"value":1702},{"type":45,"value":797},{"type":39,"tag":54,"props":1749,"children":1750},{},[1751],{"type":45,"value":1752},"and",{"type":45,"value":797},{"type":39,"tag":89,"props":1755,"children":1757},{"className":1756},[],[1758],{"type":45,"value":1759},"networks.v4",{"type":45,"value":1761}," contains an\nentry with ",{"type":39,"tag":89,"props":1763,"children":1765},{"className":1764},[],[1766],{"type":45,"value":1767},"type == \"public\"",{"type":45,"value":1769},", extract ",{"type":39,"tag":89,"props":1771,"children":1773},{"className":1772},[],[1774],{"type":45,"value":1775},"ip_address",{"type":45,"value":1777}," from that entry — this is\n",{"type":39,"tag":89,"props":1779,"children":1781},{"className":1780},[],[1782],{"type":45,"value":1783},"\u003Cip>",{"type":45,"value":1785},". Delete or pause ",{"type":39,"tag":89,"props":1787,"children":1789},{"className":1788},[],[1790],{"type":45,"value":1689},{"type":45,"value":1792}," if it still exists, then continue to\nstep 9.",{"type":39,"tag":48,"props":1794,"children":1795},{},[1796,1798,1803,1805,1810,1812,1817],{"type":45,"value":1797},"If the droplet is still not active or does not yet have a public IPv4 address,\nschedule Codex to check this same thread again in ",{"type":39,"tag":54,"props":1799,"children":1800},{},[1801],{"type":45,"value":1802},"1 minute",{"type":45,"value":1804},", then ",{"type":39,"tag":54,"props":1806,"children":1807},{},[1808],{"type":45,"value":1809},"stop the\nactive turn here",{"type":45,"value":1811},". Keep checking back every minute until the droplet is ready;\ndo not give up merely because the DigitalOcean deployment is slow. Prefer\nupdating the existing ",{"type":39,"tag":89,"props":1813,"children":1815},{"className":1814},[],[1816],{"type":45,"value":1689},{"type":45,"value":1818}," to a 1-minute interval; if that is not\npossible, create a replacement heartbeat and delete\u002Fpause the old one so there\nis only one active check-in.",{"type":39,"tag":48,"props":1820,"children":1821},{},[1822],{"type":45,"value":1823},"Use these values for the 1-minute follow-up heartbeat:",{"type":39,"tag":536,"props":1825,"children":1826},{},[1827,1841],{"type":39,"tag":540,"props":1828,"children":1829},{},[1830],{"type":39,"tag":544,"props":1831,"children":1832},{},[1833,1837],{"type":39,"tag":548,"props":1834,"children":1835},{},[1836],{"type":45,"value":1514},{"type":39,"tag":548,"props":1838,"children":1839},{},[1840],{"type":45,"value":557},{"type":39,"tag":559,"props":1842,"children":1843},{},[1844,1873,1892,1911,1930,1950,1969],{"type":39,"tag":544,"props":1845,"children":1846},{},[1847,1855],{"type":39,"tag":566,"props":1848,"children":1849},{},[1850],{"type":39,"tag":89,"props":1851,"children":1853},{"className":1852},[],[1854],{"type":45,"value":1533},{"type":39,"tag":566,"props":1856,"children":1857},{},[1858,1863,1865,1871],{"type":39,"tag":89,"props":1859,"children":1861},{"className":1860},[],[1862],{"type":45,"value":1542},{"type":45,"value":1864}," or ",{"type":39,"tag":89,"props":1866,"children":1868},{"className":1867},[],[1869],{"type":45,"value":1870},"update",{"type":45,"value":1872},", depending on the available automation tool",{"type":39,"tag":544,"props":1874,"children":1875},{},[1876,1884],{"type":39,"tag":566,"props":1877,"children":1878},{},[1879],{"type":39,"tag":89,"props":1880,"children":1882},{"className":1881},[],[1883],{"type":45,"value":1554},{"type":39,"tag":566,"props":1885,"children":1886},{},[1887],{"type":39,"tag":89,"props":1888,"children":1890},{"className":1889},[],[1891],{"type":45,"value":1491},{"type":39,"tag":544,"props":1893,"children":1894},{},[1895,1903],{"type":39,"tag":566,"props":1896,"children":1897},{},[1898],{"type":39,"tag":89,"props":1899,"children":1901},{"className":1900},[],[1902],{"type":45,"value":1574},{"type":39,"tag":566,"props":1904,"children":1905},{},[1906],{"type":39,"tag":89,"props":1907,"children":1909},{"className":1908},[],[1910],{"type":45,"value":1583},{"type":39,"tag":544,"props":1912,"children":1913},{},[1914,1922],{"type":39,"tag":566,"props":1915,"children":1916},{},[1917],{"type":39,"tag":89,"props":1918,"children":1920},{"className":1919},[],[1921],{"type":45,"value":403},{"type":39,"tag":566,"props":1923,"children":1924},{},[1925],{"type":39,"tag":89,"props":1926,"children":1928},{"className":1927},[],[1929],{"type":45,"value":1603},{"type":39,"tag":544,"props":1931,"children":1932},{},[1933,1941],{"type":39,"tag":566,"props":1934,"children":1935},{},[1936],{"type":39,"tag":89,"props":1937,"children":1939},{"className":1938},[],[1940],{"type":45,"value":1615},{"type":39,"tag":566,"props":1942,"children":1943},{},[1944],{"type":39,"tag":89,"props":1945,"children":1947},{"className":1946},[],[1948],{"type":45,"value":1949},"FREQ=MINUTELY;INTERVAL=1",{"type":39,"tag":544,"props":1951,"children":1952},{},[1953,1961],{"type":39,"tag":566,"props":1954,"children":1955},{},[1956],{"type":39,"tag":89,"props":1957,"children":1959},{"className":1958},[],[1960],{"type":45,"value":1636},{"type":39,"tag":566,"props":1962,"children":1963},{},[1964],{"type":39,"tag":89,"props":1965,"children":1967},{"className":1966},[],[1968],{"type":45,"value":1645},{"type":39,"tag":544,"props":1970,"children":1971},{},[1972,1980],{"type":39,"tag":566,"props":1973,"children":1974},{},[1975],{"type":39,"tag":89,"props":1976,"children":1978},{"className":1977},[],[1979],{"type":45,"value":1657},{"type":39,"tag":566,"props":1981,"children":1982},{},[1983],{"type":39,"tag":89,"props":1984,"children":1986},{"className":1985},[],[1987],{"type":45,"value":1988},"Resume provisioning DigitalOcean droplet \u003Cname> (\u003Cdroplet_id>). Start at Step 8: check whether it is active and has a public IPv4 address, then continue the workflow. If it is still not ready, schedule another 1-minute heartbeat. The droplet bills hourly until deleted.",{"type":39,"tag":48,"props":1990,"children":1991},{},[1992],{"type":45,"value":1993},"Keep all status checks with the DigitalOcean app — do not use doctl or any other\ntool to check droplet status.",{"type":39,"tag":60,"props":1995,"children":1997},{"id":1996},"step-9-configure-local-ssh",[1998],{"type":45,"value":1999},"Step 9 — Configure local SSH",{"type":39,"tag":336,"props":2001,"children":2003},{"className":338,"code":2002,"language":340,"meta":341,"style":341},"python3 \u003Cskill_dir>\u002Fscripts\u002Fconfigure_ssh.py \\\n  --alias codex-\u003Cprefix> \\\n  --ip \u003Cip> \\\n  --user root \\\n  --key-path \u003Ckey_path>\n",[2004],{"type":39,"tag":89,"props":2005,"children":2006},{"__ignoreMap":341},[2007,2040,2077,2107,2125],{"type":39,"tag":347,"props":2008,"children":2009},{"class":349,"line":350},[2010,2014,2018,2022,2026,2030,2035],{"type":39,"tag":347,"props":2011,"children":2012},{"style":354},[2013],{"type":45,"value":357},{"type":39,"tag":347,"props":2015,"children":2016},{"style":360},[2017],{"type":45,"value":363},{"type":39,"tag":347,"props":2019,"children":2020},{"style":366},[2021],{"type":45,"value":369},{"type":39,"tag":347,"props":2023,"children":2024},{"style":372},[2025],{"type":45,"value":375},{"type":39,"tag":347,"props":2027,"children":2028},{"style":360},[2029],{"type":45,"value":380},{"type":39,"tag":347,"props":2031,"children":2032},{"style":366},[2033],{"type":45,"value":2034},"\u002Fscripts\u002Fconfigure_ssh.py",{"type":39,"tag":347,"props":2036,"children":2037},{"style":372},[2038],{"type":45,"value":2039}," \\\n",{"type":39,"tag":347,"props":2041,"children":2043},{"class":349,"line":2042},2,[2044,2049,2054,2059,2064,2069,2073],{"type":39,"tag":347,"props":2045,"children":2046},{"style":366},[2047],{"type":45,"value":2048},"  --alias",{"type":39,"tag":347,"props":2050,"children":2051},{"style":366},[2052],{"type":45,"value":2053}," codex-",{"type":39,"tag":347,"props":2055,"children":2056},{"style":360},[2057],{"type":45,"value":2058},"\u003C",{"type":39,"tag":347,"props":2060,"children":2061},{"style":366},[2062],{"type":45,"value":2063},"prefi",{"type":39,"tag":347,"props":2065,"children":2066},{"style":372},[2067],{"type":45,"value":2068},"x",{"type":39,"tag":347,"props":2070,"children":2071},{"style":360},[2072],{"type":45,"value":380},{"type":39,"tag":347,"props":2074,"children":2075},{"style":372},[2076],{"type":45,"value":2039},{"type":39,"tag":347,"props":2078,"children":2080},{"class":349,"line":2079},3,[2081,2086,2090,2095,2099,2103],{"type":39,"tag":347,"props":2082,"children":2083},{"style":366},[2084],{"type":45,"value":2085},"  --ip",{"type":39,"tag":347,"props":2087,"children":2088},{"style":360},[2089],{"type":45,"value":363},{"type":39,"tag":347,"props":2091,"children":2092},{"style":366},[2093],{"type":45,"value":2094},"i",{"type":39,"tag":347,"props":2096,"children":2097},{"style":372},[2098],{"type":45,"value":48},{"type":39,"tag":347,"props":2100,"children":2101},{"style":360},[2102],{"type":45,"value":380},{"type":39,"tag":347,"props":2104,"children":2105},{"style":372},[2106],{"type":45,"value":2039},{"type":39,"tag":347,"props":2108,"children":2110},{"class":349,"line":2109},4,[2111,2116,2121],{"type":39,"tag":347,"props":2112,"children":2113},{"style":366},[2114],{"type":45,"value":2115},"  --user",{"type":39,"tag":347,"props":2117,"children":2118},{"style":366},[2119],{"type":45,"value":2120}," root",{"type":39,"tag":347,"props":2122,"children":2123},{"style":372},[2124],{"type":45,"value":2039},{"type":39,"tag":347,"props":2126,"children":2128},{"class":349,"line":2127},5,[2129,2134,2138,2143,2148],{"type":39,"tag":347,"props":2130,"children":2131},{"style":366},[2132],{"type":45,"value":2133},"  --key-path",{"type":39,"tag":347,"props":2135,"children":2136},{"style":360},[2137],{"type":45,"value":363},{"type":39,"tag":347,"props":2139,"children":2140},{"style":366},[2141],{"type":45,"value":2142},"key_pat",{"type":39,"tag":347,"props":2144,"children":2145},{"style":372},[2146],{"type":45,"value":2147},"h",{"type":39,"tag":347,"props":2149,"children":2150},{"style":360},[2151],{"type":45,"value":2152},">\n",{"type":39,"tag":48,"props":2154,"children":2155},{},[2156,2161,2163,2169,2171,2183,2185,2189],{"type":39,"tag":54,"props":2157,"children":2158},{},[2159],{"type":45,"value":2160},"⚠️ Do not interrupt this step.",{"type":45,"value":2162}," It waits for cloud-init to finish (up to 7\nminutes) and prints a ",{"type":39,"tag":89,"props":2164,"children":2166},{"className":2165},[],[2167],{"type":45,"value":2168},"⏳",{"type":45,"value":2170}," status line every 5 seconds — that output means it is\nworking normally. ",{"type":39,"tag":54,"props":2172,"children":2173},{},[2174,2176,2182],{"type":45,"value":2175},"Do not run any other commands. Wait for the line\n",{"type":39,"tag":89,"props":2177,"children":2179},{"className":2178},[],[2180],{"type":45,"value":2181},"DROPLET READY",{"type":45,"value":297},{"type":45,"value":2184}," If the script exits with an error instead, report it and\noffer to delete the droplet (see ",{"type":39,"tag":123,"props":2186,"children":2187},{},[2188],{"type":45,"value":127},{"type":45,"value":2190},").",{"type":39,"tag":60,"props":2192,"children":2194},{"id":2193},"final-step-adding-it-to-codex",[2195],{"type":45,"value":2196},"Final step: adding it to Codex",{"type":39,"tag":48,"props":2198,"children":2199},{},[2200,2202,2208,2210,2215],{"type":45,"value":2201},"Ask Codex to open the add-SSH-host flow by responding with a clickable Markdown\nlink. Replace ",{"type":39,"tag":89,"props":2203,"children":2205},{"className":2204},[],[2206],{"type":45,"value":2207},"\u003Cssh-alias>",{"type":45,"value":2209}," with ",{"type":39,"tag":89,"props":2211,"children":2213},{"className":2212},[],[2214],{"type":45,"value":403},{"type":45,"value":2216}," from step 2:",{"type":39,"tag":48,"props":2218,"children":2219},{},[2220],{"type":39,"tag":89,"props":2221,"children":2223},{"className":2222},[],[2224],{"type":45,"value":2225},"[Add \u003Cssh-alias> to Codex SSH](codex:\u002F\u002Fsettings\u002Fconnections\u002Fssh\u002Fadd?name=\u003Cssh-alias>)",{"type":39,"tag":48,"props":2227,"children":2228},{},[2229,2231,2236],{"type":45,"value":2230},"The SSH alias is the local host alias created by step 9. In this workflow, it is\nthe same value as the droplet name: ",{"type":39,"tag":89,"props":2232,"children":2234},{"className":2233},[],[2235],{"type":45,"value":464},{"type":45,"value":297},{"type":39,"tag":48,"props":2238,"children":2239},{},[2240,2242],{"type":45,"value":2241},"If the link does not open the flow, or if the user wants to check it manually,\ntell them to open: ",{"type":39,"tag":54,"props":2243,"children":2244},{},[2245],{"type":45,"value":2246},"Codex App → Settings → Connections → Add SSH Host → pick\nthe alias → choose the remote folder.",{"type":39,"tag":60,"props":2248,"children":2250},{"id":2249},"cleanup-on-failure-or-when-done",[2251],{"type":45,"value":2252},"Cleanup (on failure or when done)",{"type":39,"tag":48,"props":2254,"children":2255},{},[2256],{"type":45,"value":2257},"The droplet bills hourly until deleted. To tear down:",{"type":39,"tag":2259,"props":2260,"children":2261},"ol",{},[2262,2293],{"type":39,"tag":71,"props":2263,"children":2264},{},[2265,2270,2272,2276,2277,2285,2287,2292],{"type":39,"tag":54,"props":2266,"children":2267},{},[2268],{"type":45,"value":2269},"Delete the droplet",{"type":45,"value":2271}," — ",{"type":39,"tag":54,"props":2273,"children":2274},{},[2275],{"type":45,"value":85},{"type":45,"value":524},{"type":39,"tag":54,"props":2278,"children":2279},{},[2280],{"type":39,"tag":89,"props":2281,"children":2283},{"className":2282},[],[2284],{"type":45,"value":322},{"type":45,"value":2286}," with\n",{"type":39,"tag":89,"props":2288,"children":2290},{"className":2289},[],[2291],{"type":45,"value":1735},{"type":45,"value":297},{"type":39,"tag":71,"props":2294,"children":2295},{},[2296,2301,2303,2307,2308,2316,2318,2323],{"type":39,"tag":54,"props":2297,"children":2298},{},[2299],{"type":45,"value":2300},"Delete the SSH key",{"type":45,"value":2302}," (optional) — ",{"type":39,"tag":54,"props":2304,"children":2305},{},[2306],{"type":45,"value":85},{"type":45,"value":524},{"type":39,"tag":54,"props":2309,"children":2310},{},[2311],{"type":39,"tag":89,"props":2312,"children":2314},{"className":2313},[],[2315],{"type":45,"value":295},{"type":45,"value":2317},"\nwith the ",{"type":39,"tag":89,"props":2319,"children":2321},{"className":2320},[],[2322],{"type":45,"value":624},{"type":45,"value":2324}," from step 3.",{"type":39,"tag":48,"props":2326,"children":2327},{},[2328],{"type":45,"value":2329},"Always confirm with the user before deleting. Do not use doctl for cleanup.",{"type":39,"tag":2331,"props":2332,"children":2333},"style",{},[2334],{"type":45,"value":2335},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2337,"total":2458},[2338,2356,2372,2384,2404,2426,2446],{"slug":2339,"name":2339,"fn":2340,"description":2341,"org":2342,"tags":2343,"stars":22,"repoUrl":23,"updatedAt":24},"accessibility-and-inclusive-visualization","make data visualizations accessible","Make data visualizations accessible and inclusive. Use when the user needs chart or diagram accessibility guidance, text alternatives for complex visuals, color and contrast review, keyboard support, reduced-motion behavior for animation or parallax, or an accessibility QA workflow for exported figures, UML-like diagrams, and dashboards.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2344,2347,2350,2353],{"name":2345,"slug":2346,"type":15},"Accessibility","accessibility",{"name":2348,"slug":2349,"type":15},"Charts","charts",{"name":2351,"slug":2352,"type":15},"Data Visualization","data-visualization",{"name":2354,"slug":2355,"type":15},"Design","design",{"slug":2357,"name":2357,"fn":2358,"description":2359,"org":2360,"tags":2361,"stars":22,"repoUrl":23,"updatedAt":2371},"agent-browser","automate browser interactions for agents","Browser automation CLI for AI agents. Use when the user needs to interact with websites, verify dev server output, test web apps, navigate pages, fill forms, click buttons, take screenshots, extract data, or automate any browser task. Also triggers when a dev server starts so you can verify it visually.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2362,2365,2368],{"name":2363,"slug":2364,"type":15},"Agents","agents",{"name":2366,"slug":2367,"type":15},"Browser Automation","browser-automation",{"name":2369,"slug":2370,"type":15},"Testing","testing","2026-04-06T18:41:03.44016",{"slug":2373,"name":2373,"fn":2374,"description":2375,"org":2376,"tags":2377,"stars":22,"repoUrl":23,"updatedAt":2383},"agent-browser-verify","verify dev server output with automated browser","Automated browser verification for dev servers. Triggers when a dev server starts to run a visual gut-check with agent-browser — verifies the page loads, checks for console errors, validates key UI elements, and reports pass\u002Ffail before continuing.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2378,2379,2382],{"name":2366,"slug":2367,"type":15},{"name":2380,"slug":2381,"type":15},"Local Development","local-development",{"name":2369,"slug":2370,"type":15},"2026-04-06T18:41:17.526867",{"slug":2385,"name":2385,"fn":2386,"description":2387,"org":2388,"tags":2389,"stars":22,"repoUrl":23,"updatedAt":2403},"agents-sdk","build AI agents on Cloudflare Workers","Build AI agents on Cloudflare Workers using the Agents SDK. Load when creating stateful agents, durable workflows, real-time WebSocket apps, scheduled tasks, MCP servers, or chat applications. Covers Agent class, state management, callable RPC, Workflows integration, and React hooks. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2390,2391,2394,2397,2400],{"name":2363,"slug":2364,"type":15},{"name":2392,"slug":2393,"type":15},"Cloudflare Workers","cloudflare-workers",{"name":2395,"slug":2396,"type":15},"SDK","sdk",{"name":2398,"slug":2399,"type":15},"Serverless","serverless",{"name":2401,"slug":2402,"type":15},"WebSockets","websockets","2026-04-06T18:39:51.717063",{"slug":2405,"name":2405,"fn":2406,"description":2407,"org":2408,"tags":2409,"stars":22,"repoUrl":23,"updatedAt":2425},"ai-elements","build chat UIs with AI Elements","AI Elements component library guidance — pre-built React components for AI interfaces built on shadcn\u002Fui. Use when building chat UIs, message displays, tool call rendering, streaming responses, reasoning panels, or any AI-native interface with the AI SDK.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2410,2413,2416,2419,2422],{"name":2411,"slug":2412,"type":15},"Frontend","frontend",{"name":2414,"slug":2415,"type":15},"React","react",{"name":2417,"slug":2418,"type":15},"shadcn\u002Fui","shadcn-ui",{"name":2420,"slug":2421,"type":15},"UI Components","ui-components",{"name":2423,"slug":2424,"type":15},"Vercel","vercel","2026-04-06T18:40:59.619419",{"slug":2427,"name":2427,"fn":2428,"description":2429,"org":2430,"tags":2431,"stars":22,"repoUrl":23,"updatedAt":2445},"ai-gateway","configure Vercel AI Gateway","Vercel AI Gateway expert guidance. Use when configuring model routing, provider failover, cost tracking, or managing multiple AI providers through a unified API.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2432,2435,2438,2441,2444],{"name":2433,"slug":2434,"type":15},"AI Infrastructure","ai-infrastructure",{"name":2436,"slug":2437,"type":15},"Cost Optimization","cost-optimization",{"name":2439,"slug":2440,"type":15},"LLM","llm",{"name":2442,"slug":2443,"type":15},"Performance","performance",{"name":2423,"slug":2424,"type":15},"2026-04-06T18:40:44.377464",{"slug":2447,"name":2447,"fn":2448,"description":2449,"org":2450,"tags":2451,"stars":22,"repoUrl":23,"updatedAt":2457},"ai-generation-persistence","implement persistence patterns for AI generations","AI generation persistence patterns — unique IDs, addressable URLs, database storage, and cost tracking for every LLM generation",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2452,2453,2456],{"name":2436,"slug":2437,"type":15},{"name":2454,"slug":2455,"type":15},"Database","database",{"name":2439,"slug":2440,"type":15},"2026-04-06T18:41:08.513425",600,{"items":2460,"total":2655},[2461,2482,2505,2522,2538,2553,2572,2584,2598,2612,2624,2639],{"slug":2462,"name":2462,"fn":2463,"description":2464,"org":2465,"tags":2466,"stars":2479,"repoUrl":2480,"updatedAt":2481},"prior-auth-packet-builder","build healthcare prior authorization packets","Build a concise prior authorization packet from local case files and payer policy docs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2467,2470,2473,2476],{"name":2468,"slug":2469,"type":15},"Documents","documents",{"name":2471,"slug":2472,"type":15},"Healthcare","healthcare",{"name":2474,"slug":2475,"type":15},"Insurance","insurance",{"name":2477,"slug":2478,"type":15},"Regulatory Compliance","regulatory-compliance",28169,"https:\u002F\u002Fgithub.com\u002Fopenai\u002Fopenai-agents-python","2026-04-16T05:11:39.180399",{"slug":2483,"name":2483,"fn":2484,"description":2485,"org":2486,"tags":2487,"stars":2502,"repoUrl":2503,"updatedAt":2504},"aspnet-core","build ASP.NET Core web applications","Build, review, refactor, or architect ASP.NET Core web applications using current official guidance for .NET web development. Use when working on Blazor Web Apps, Razor Pages, MVC, Minimal APIs, controller-based Web APIs, SignalR, gRPC, middleware, dependency injection, configuration, authentication, authorization, testing, performance, deployment, or ASP.NET Core upgrades.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2488,2491,2493,2496,2499],{"name":2489,"slug":2490,"type":15},".NET","dotnet",{"name":2492,"slug":2483,"type":15},"ASP.NET Core",{"name":2494,"slug":2495,"type":15},"Blazor","blazor",{"name":2497,"slug":2498,"type":15},"C#","csharp",{"name":2500,"slug":2501,"type":15},"Web Development","web-development",23787,"https:\u002F\u002Fgithub.com\u002Fopenai\u002Fskills","2026-04-12T05:07:02.819491",{"slug":2506,"name":2506,"fn":2507,"description":2508,"org":2509,"tags":2510,"stars":2502,"repoUrl":2503,"updatedAt":2521},"chatgpt-apps","build ChatGPT Apps SDK applications","Build, scaffold, refactor, and troubleshoot ChatGPT Apps SDK applications that combine an MCP server and widget UI. Use when Codex needs to design tools, register UI resources, wire the MCP Apps bridge or ChatGPT compatibility APIs, apply Apps SDK metadata or CSP or domain settings, or produce a docs-aligned project scaffold. Prefer a docs-first workflow by invoking the openai-docs skill or OpenAI developer docs MCP tools before generating code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2511,2514,2517,2520],{"name":2512,"slug":2513,"type":15},"Apps SDK","apps-sdk",{"name":2515,"slug":2516,"type":15},"ChatGPT","chatgpt",{"name":2518,"slug":2519,"type":15},"MCP","mcp",{"name":9,"slug":8,"type":15},"2026-04-12T05:07:05.468097",{"slug":2523,"name":2523,"fn":2524,"description":2525,"org":2526,"tags":2527,"stars":2502,"repoUrl":2503,"updatedAt":2537},"cli-creator","build CLIs from API docs","Build a composable CLI for Codex from API docs, an OpenAPI spec, existing curl examples, an SDK, a web app, an admin tool, or a local script. Use when the user wants Codex to create a command-line tool that can run from any repo, expose composable read\u002Fwrite commands, return stable JSON, manage auth, and pair with a companion skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2528,2531,2534],{"name":2529,"slug":2530,"type":15},"API Development","api-development",{"name":2532,"slug":2533,"type":15},"CLI","cli",{"name":2535,"slug":2536,"type":15},"Codex","codex","2026-04-12T05:07:04.132762",{"slug":2539,"name":2539,"fn":2540,"description":2541,"org":2542,"tags":2543,"stars":2502,"repoUrl":2503,"updatedAt":2552},"cloudflare-deploy","deploy projects to Cloudflare","Deploy applications and infrastructure to Cloudflare using Workers, Pages, and related platform services. Use when the user asks to deploy, host, publish, or set up a project on Cloudflare.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2544,2547,2550,2551],{"name":2545,"slug":2546,"type":15},"Cloudflare","cloudflare",{"name":2548,"slug":2549,"type":15},"Cloudflare Pages","cloudflare-pages",{"name":2392,"slug":2393,"type":15},{"name":13,"slug":14,"type":15},"2026-04-12T05:07:14.275118",{"slug":2554,"name":2554,"fn":2555,"description":2556,"org":2557,"tags":2558,"stars":2502,"repoUrl":2503,"updatedAt":2571},"define-goal","define and set measurable project goals","Help the user define a concrete, measurable goal before starting work, especially when they ask to use the goal tool, create a goal, set an objective, clarify success criteria, or turn a fuzzy intention into a quantitative outcome. Use this skill for goal creation and goal refinement only; it does not manage durable snapshots, decision logs, or long-running execution artifacts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2559,2562,2565,2568],{"name":2560,"slug":2561,"type":15},"Productivity","productivity",{"name":2563,"slug":2564,"type":15},"Project Management","project-management",{"name":2566,"slug":2567,"type":15},"Strategy","strategy",{"name":2569,"slug":2570,"type":15},"Task Management","task-management","2026-05-23T06:17:16.870838",{"slug":2573,"name":2573,"fn":2574,"description":2575,"org":2576,"tags":2577,"stars":2502,"repoUrl":2503,"updatedAt":2583},"figma","translate Figma designs into code","Use the Figma MCP server to fetch design context, screenshots, variables, and assets from Figma, and to translate Figma nodes into production code. Trigger when a task involves Figma URLs, node IDs, design-to-code implementation, or Figma MCP setup and troubleshooting.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2578,2579,2581,2582],{"name":2354,"slug":2355,"type":15},{"name":2580,"slug":2573,"type":15},"Figma",{"name":2411,"slug":2412,"type":15},{"name":2518,"slug":2519,"type":15},"2026-04-12T05:06:47.939943",{"slug":2585,"name":2585,"fn":2586,"description":2587,"org":2588,"tags":2589,"stars":2502,"repoUrl":2503,"updatedAt":2597},"figma-code-connect-components","connect Figma designs to code components","Connects Figma design components to code components using Code Connect mapping tools. Use when user says \"code connect\", \"connect this component to code\", \"map this component\", \"link component to code\", \"create code connect mapping\", or wants to establish mappings between Figma designs and code implementations. For canvas writes via `use_figma`, use `figma-use`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2590,2591,2594,2595,2596],{"name":2354,"slug":2355,"type":15},{"name":2592,"slug":2593,"type":15},"Design System","design-system",{"name":2580,"slug":2573,"type":15},{"name":2411,"slug":2412,"type":15},{"name":2420,"slug":2421,"type":15},"2026-05-10T05:59:52.971881",{"slug":2599,"name":2599,"fn":2600,"description":2601,"org":2602,"tags":2603,"stars":2502,"repoUrl":2503,"updatedAt":2611},"figma-create-design-system-rules","generate design system rules from Figma","Generates custom design system rules for the user's codebase. Use when user says \"create design system rules\", \"generate rules for my project\", \"set up design rules\", \"customize design system guidelines\", or wants to establish project-specific conventions for Figma-to-code workflows. Requires Figma MCP server connection.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2604,2605,2606,2609,2610],{"name":2354,"slug":2355,"type":15},{"name":2592,"slug":2593,"type":15},{"name":2607,"slug":2608,"type":15},"Documentation","documentation",{"name":2580,"slug":2573,"type":15},{"name":2411,"slug":2412,"type":15},"2026-05-16T06:07:47.821474",{"slug":2613,"name":2613,"fn":2614,"description":2615,"org":2616,"tags":2617,"stars":2502,"repoUrl":2503,"updatedAt":2623},"figma-implement-design","translate Figma designs into application code","Translates Figma designs into production-ready application code with 1:1 visual fidelity. Use when implementing UI code from Figma files, when user mentions \"implement design\", \"generate code\", \"implement component\", provides Figma URLs, or asks to build components matching Figma specs. For Figma canvas writes via `use_figma`, use `figma-use`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2618,2619,2620,2621,2622],{"name":2354,"slug":2355,"type":15},{"name":2580,"slug":2573,"type":15},{"name":2411,"slug":2412,"type":15},{"name":2420,"slug":2421,"type":15},{"name":2500,"slug":2501,"type":15},"2026-05-16T06:07:40.583615",{"slug":2625,"name":2625,"fn":2626,"description":2627,"org":2628,"tags":2629,"stars":2502,"repoUrl":2503,"updatedAt":2638},"hatch-pet","create animated pets for Codex","Create, repair, validate, visually QA, and package Codex-compatible animated pets and pet spritesheets from character art, generated images, company or prospect brand cues, or visual references. Use when a user wants a lightweight-worker Codex pet workflow, a non-pixel custom pet style, a prospect or company mascot pet, or a full 8x9 animated pet atlas with transparent unused cells, QA contact sheets, and pet.json packaging. This skill composes the installed $imagegen system skill for visual generation and uses bundled scripts for deterministic spritesheet assembly.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2630,2633,2634,2637],{"name":2631,"slug":2632,"type":15},"Animation","animation",{"name":2535,"slug":2536,"type":15},{"name":2635,"slug":2636,"type":15},"Creative","creative",{"name":2354,"slug":2355,"type":15},"2026-05-02T05:31:48.48485",{"slug":2640,"name":2640,"fn":2641,"description":2642,"org":2643,"tags":2644,"stars":2502,"repoUrl":2503,"updatedAt":2654},"imagegen","generate and edit raster images","Generate or edit raster images when the task benefits from AI-created bitmap visuals such as photos, illustrations, textures, sprites, mockups, or transparent-background cutouts. Use when Codex should create a brand-new image, transform an existing image, or derive visual variants from references, and the output should be a bitmap asset rather than repo-native code or vector. Do not use when the task is better handled by editing existing SVG\u002Fvector\u002Fcode-native assets, extending an established icon or logo system, or building the visual directly in HTML\u002FCSS\u002Fcanvas.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2645,2646,2647,2650,2653],{"name":2635,"slug":2636,"type":15},{"name":2354,"slug":2355,"type":15},{"name":2648,"slug":2649,"type":15},"Image Generation","image-generation",{"name":2651,"slug":2652,"type":15},"Images","images",{"name":9,"slug":8,"type":15},"2026-05-15T06:23:24.312127",675]