Use si coder
Zero-human full-stack deployment skill bundle for AI agents — GitHub + Dokploy + Convex (self-hosted & Cloud) + Vercel + Hostinger DNS, via modular /sc-* slash commands.
npx -y skills add rahmanef63/si-coder-agent --skill use-si-coderAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Legacy one-shot full-stack auto-deploy monolith. Runs scripts/deploy.js to create a GitHub repo, push local code via SSH, set up a Dokploy project, configure self-hosted Convex (Docker Compose) + Next.js, wire Hostinger DNS, and trigger + poll the deployment — zero human steps. Superseded by the modular /sc-* skills (/sc-all) but kept fully functional.
SKILL.md
12.3 KB, as published. Nobody here has run it
SI Coder Auto Deploy (legacy /use-si-coder)
This skill automates the entire lifecycle of creating a GitHub repository and deploying full-stack apps to a Dokploy server via the single monolithic scripts/deploy.js. It is the original one-shot pipeline; the modular /sc-* skills (/sc-all, /sc-dokploy, /sc-convex, …) now cover the same ground in surgical pieces, but this monolith remains supported.
CORE MANDATES FOR THE AI (LEARNED LESSONS)
To guarantee Zero Human Involvement (the user just wants to receive the final working URL):
- Self-Hosted Convex by Default: NEVER use Clerk unless explicitly asked. ALWAYS use
@convex-dev/auth. ALWAYS include adocker-compose.ymlfor self-hosting Convex alongside the frontend. - Build Safety: Do NOT run
npx convex codegeninside theDockerfile. You MUST generate the types locally (npx convex dev --once) and commit theconvex/_generatedfolder to Git before deploying. - No Prompts / Dependency Hell: Always use
npm install --yes --legacy-peer-deps. If a scaffolded template is too complex (bloated), wipe it and start fresh withnpx create-next-appto avoid endless TypeScript errors. - Exact Cloning: If asked to clone a website, you MUST replicate its actual layout and structure, not just build a generic admin dashboard. Fetch the website to understand its structure.
- Dokploy Idempotency: The deployment script handles existing apps, composes, and domains safely. Do NOT delete or recreate existing domains if Dokploy rejects them (it means they are already configured).
- Convex Admin Key Sync: When generating or rotating a self-hosted Convex admin key, immediately update the Dokploy Compose environment and the repo's local env file so they stay in sync. Use the project's actual env name for that template or app, and do not invent a second secret name.
- Clerk MCP for Clerk Apps: If a target project already uses Clerk, preserve it, do not swap it to
@convex-dev/auth, and use Clerk MCP (clerkathttps://mcp.clerk.com/mcp) for SDK snippets and integration patterns.
Pre-requisites
- Dokploy Credentials: Environment variables
DOKPLOY_API_URLandDOKPLOY_API_KEY(usually stored in~/.bashrc). - GitHub Credentials: A GitHub Personal Access Token (PAT) with repository creation permissions, stored in the
GITHUB_TOKENenvironment variable. - Hostinger Credentials:
HOSTINGER_API_TOKEN(optional but recommended for DNS automation). The script reads this directly from the environment. - SSH Keys: The machine must have SSH access to GitHub (
[email protected]) configured for pushing code.
See the repo's .env.example for the full setup checklist.
Workflow
When the user asks to deploy a project:
- Verify Credentials: Check for
DOKPLOY_API_URL,DOKPLOY_API_KEY, andGITHUB_TOKEN(andHOSTINGER_API_TOKENif DNS automation is wanted). - Docker Compose: Ensure the project has a
docker-compose.ymlthat defines the frontend, backend (Convex DB), etc. (Or at least a Dockerfile for simple apps). - Execute Deployment Script: Run the Node.js deployment script from inside the project directory.
flowchart TD
Start["scripts/deploy.js<br/>(cwd = your app)"] --> GH["GitHub: create private repo<br/>+ push via SSH"]
GH --> Guard{".env leak guard<br/>git check-ignore"}
Guard -->|secret unignored| Abort["ABORT before push"]
Guard -->|clean| Compose{"docker-compose.yml?"}
Compose -->|yes| CVX["Convex compose template (backend + dashboard)<br/>api-/site-/dash- DNS + domains<br/>+ INSTANCE_SECRET"]
CVX --> Key["generate admin key<br/>(health-poll) → Dokploy env"]
Key --> TLS["wait for valid TLS"]
TLS --> Schema["npx convex deploy<br/>(env-only, no argv)"]
Compose -->|no| Dockerfile{"Dockerfile?"}
Schema --> Dockerfile
Dockerfile -->|yes| App["Dokploy application (Next.js frontend)<br/>GitHub provider, PAT-less"]
App --> DNS["Hostinger A record<br/>main domain"]
DNS --> Poll["trigger deploy + poll status"]
Poll --> Done["live URL ✅"]
Features
- Zero-Human Intervention: The script creates repos, pushes code, creates projects, and triggers deployments automatically.
- Hostinger DNS Automation: If
HOSTINGER_API_TOKENis present in the environment, the script automatically addsArecords for your main domain and Convex backend subdomains (api-,dash-,site-) pointing to your Dokploy server. - Self-Hosted Convex DB: Automatically deploys a production-ready Convex self-hosted DB using the Dokploy
convexcompose template.
Invocation
Secrets are NEVER passed on the command line.
DOKPLOY_API_URL,DOKPLOY_API_KEY,GITHUB_TOKEN(and optionalHOSTINGER_API_TOKEN) are read only from the environment — never from argv — so they cannot leak viaps aux//proc/<pid>/cmdline. Export them in~/.bashrc(or run/sc-onboarding). Only the non-secret project/app/domain values are written on the command line, via flags.
scripts/deploy.js lives at the repo root (it imports ../lib/*), so run it from a clone of si-coder-agent. Point it at your project directory with cd first (it operates on the current working directory's git repo).
# 1. Secrets stay in env (exported once in ~/.bashrc):
# export DOKPLOY_API_URL=... DOKPLOY_API_KEY=... GITHUB_TOKEN=...
# (optional) export HOSTINGER_API_TOKEN=...
# 2. cd into the app you want to deploy:
cd ~/projects/<app_name>
# 3. Run the monolith from your si-coder-agent checkout — only NON-secret flags on argv:
node ~/path/to/si-coder-agent/scripts/deploy.js \
--project "<PROJECT_NAME>" --app "<APP_NAME>" --domain "<DOMAIN>"
The only command-line values you write by hand are <PROJECT_NAME>, <APP_NAME>, and <DOMAIN> — no secret occupies an argv slot. Two opt-in behaviors are gated behind environment variables (both unset by default): SC_ALLOW_FORCE_PUSH=1 appends --force to the git push (deploy.js ~541/615), and SC_ALLOW_REMOTE_REWRITE=1 permits rewriting a pre-existing local origin remote that points elsewhere (deploy.js ~578). Leave both unset unless you specifically need them.
Flags (all non-secret):
node scripts/deploy.js --project <PROJECT_NAME> --app <APP_NAME> [--domain <DOMAIN>]
# bare positionals also accepted (still no secrets): <PROJECT_NAME> <APP_NAME> [DOMAIN]
Example
cd ~/projects/my-saas-app
node ~/path/to/si-coder-agent/scripts/deploy.js \
--project "my-project" --app "my-saas-app" --domain "myapp.example.com"
How the script works
The script will:
- Contact the GitHub API using
GITHUB_TOKENto create a new private repository namedAPP_NAME(skips if it already exists). - Initialize local Git, commit files (including
convex/_generated), andgit pushto GitHub via SSH ([email protected]:<owner>/<app>.git). - Fetch Dokploy projects to find or create
PROJECT_NAME. - Auto-detect
docker-compose.yml/Dockerfile. If a compose file exists, it deploys the Dokployconvexcompose template (the Convex backend + dashboard — not the frontend) and sets theapi-/site-/dash-DNS + backend domains before deploying the Convex schema. If aDockerfileexists, it creates/updates a standard Dokploy Application — this is the path by which the Next.js frontend deploys separately (its main-domain DNS is set here). - Bind the Dokploy application to its source without ever embedding a PAT in the git URL: it first looks for a configured Dokploy GitHub provider (
/github.githubProviders) and usesapplication.saveGithubProvider+sourceType: "github". If no provider exists, it falls back to a PAT-less public git URL (https://github.com/<owner>/<repo>.git,sourceType: "git") and warns that private repos then need an SSH deploy key / GitHub App configured in Dokploy. A PAT is never persisted intocustomGitUrl. - Create the
DOMAIN(and theapi-/site-/dash-backend domains for the compose path) in Dokploy, silently skipping any that already exist, then prune stale /*.traefik.medomains. - Sync the compose env (without rotating existing Convex secrets), auto-generate the Convex admin key from the running backend container, push the Convex schema via
npx convex deploy, then trigger the application deployment and poll untildone/error.
Secret-leak guards (before git add .)
Before the script ever stages your project, it runs two guards. The first, ensureGitignoreSafety, runs before git init and inspects the repo root:
- Ensures
.gitignoreexists and covers.env,.env.*(re-including.env.example),node_modules,.next,.DS_Store. - Asks git itself (
git check-ignore) whether each discovered.env*file is actually ignored, so it honors negations, nested.gitignorefiles, and your global excludes — not a hand-rolled matcher. A trailing!.env/!.env.*re-include (which git's last-match-wins precedence would use to un-ignore your secrets) causes a hard abort. - Hard-aborts on any unignored
.env/.env.<suffix>file at the project root (other than.env.example). - For other common secret files at the repo root (
id_rsa,*.pem,*.p12,*.key,serviceAccount*.json, …) it warns but does not abort — naming conventions vary, so you decide. If sensitive, add them to.gitignorebefore deploying.
The second guard, scanNestedDotenvLeaks, runs after git init (so git check-ignore is authoritative) and walks the whole tree — because git add . stages every directory, not just the root (it skips .git/ and node_modules/):
- HARD-ABORTS on any unignored nested
.env/.env.*(e.g.apps/web/.env,convex/.env.local) — the same dotenv rule as the root guard, but tree-wide. - WARNS (does not abort) on nested non-dotenv secrets (
id_rsa,*.pem,*.key,serviceAccount*.json, …) thatgit add .would otherwise stage. Add them to.gitignoreif sensitive.
Admin Key Sync Rule
If the deployment includes a self-hosted Convex backend, always generate or rotate the admin key from the running backend container, then update both places before finishing the task:
- Dokploy Compose service environment for the Convex backend
- Local repo env file used for debugging and dashboard access
Never leave the backend container, Dokploy env, and local env file on different admin key values. If the dashboard rejects the key, assume the key belongs to a different backend instance and regenerate it from the active backend container.
Convex Self-Hosted Authentication (@convex-dev/auth)
Full @convex-dev/auth setup — generating JWT_PRIVATE_KEY + JWKS, the required backend env-var table, the PBKDF2 password-hashing override (Scrypt/bcrypt time out on the Dokploy proxy), the ConvexClientProvider "route auth:* via HTTP" pattern, the NEXT_PUBLIC_CONVEX_URL build-time Dockerfile gotcha, and "Connection lost while action was in flight" diagnosis — is owned by /sc-convex. Use its scripts/set-auth-env.js --generate (automated admin REST /api/update_environment_variables) instead of hand-rolling keys or a raw curl.
Caveat (progressive disclosure): scripts/deploy.js sets INSTANCE_SECRET, INSTANCE_NAME, CONVEX_CLOUD_ORIGIN, CONVEX_SITE_ORIGIN, and the Convex admin key on the compose env, but it does NOT auto-set JWT_PRIVATE_KEY / JWKS. A project using @convex-dev/auth will crash on signIn ("Connection lost while action was in flight") until you set those two on the backend via /sc-convex.
Auth file layout (kept here because /sc-convex doesn't spell it out):
convex/
├── auth.ts # convexAuth({ providers: [Password({...})] }) → exports auth, signIn, signOut, store, isAuthenticated
├── auth.config.ts # { providers: [{ domain: process.env.CONVEX_SITE_URL }] }
├── http.ts # httpRouter + auth.addHttpRoutes(http)
└── schema.ts # defineSchema({ ...authTables, ...featureTables })