init-env
Skill18 starsChanged 58 days agoMITView on GitHub
First-time setup orchestrator for the AI Workflow ai-workflow repo. Mirrors SETUP.md as an agent-driven flow (project linking, env vars across Jira / VCS / Agent / Slack / Neon, production deploy, post-deploy registrations for the Jira webhook and the Slack /ai-workflow slash command, and smoke checks). Use when starting fresh on this repo for the first time, such as "init project", "first-time setup", "bootstrap this repo", "onboard me", "set up env from scratch".
- Reads credentials
- Installs packages
In this repository13 other files it gives its agents.
- AGENTS.mdAGENTS.md
- packages/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- packages/CLAUDE.mdCLAUDE.md
- artur-releaseSkill
- gate-ladderSkill
- init-agentSkill
- init-jiraSkill
- init-neonSkill
- init-slackSkill
- init-vcsSkill
- new-integrationSkill
- ai-workflow-reviewSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
14 rules. About 0 are common, 7 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 28
If the user replies with anything other than a clear go-signal, do not advance: answer them, fix what they flagged, then re-ask.
- Very specific: line 30
Run every command from apps/worker unless a step says otherwise, so .vercel/project.json below means apps/worker/.vercel/project.json.
- Very specific: line 56
Run these in order. Halt with a clear message on any failure.
- Very specific: line 69
If any version is below the floor, HALT with the exact mismatch and the install command from SETUP.md §1 (npm i -g pnpm, npm i -g …
- Very specific: line 89
Link present: read its orgId / projectId.
- Distinctive: line 206
Run from the directory linked in Step 1:
- Distinctive: line 241
Do not auto-retry. Build errors usually need human intervention.
- Distinctive: line 256
If the user opts to defer webhook registration (custom domain coming, admin permission missing, etc.), record it as a TODO for the final …
- Very specific: line 267
GitLab: add the project hook at https://<project>.vercel.app/webhooks/gitlab with the settings in GITLAB-SETUP.md.
- Distinctive: line 269
If deferred, record it as a TODO for the final summary.
- Very specific: line 279
Read .vercel/project.json for the project name and construct:
- Distinctive: line 303
If the user can't register the slash command now (admin permission missing, custom domain pending, etc.), record it as a TODO for the final …
- Very specific: line 336
If the unauth call returns 200, CRON_SECRET is missing in Production.
- Distinctive: line 364
Wait for the user's response.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Initialize Project Environment (Cold Start)
Cold-start orchestrator. Coordinates project linking, paste-template-driven env population across 5 domains, a single production deploy, post-deploy registrations (Jira webhook + Slack slash command), and a smoke handoff. Self-contained: does not invoke other plugins.
Canonical reference: SETUP.md at the repo root is the human-readable end-to-end guide. This skill is the agent-driven orchestration of that same flow. When the two diverge, SETUP.md wins; update this skill.
What this skill does NOT do
- Partial re-runs. This is a cold start only. To rotate one integration later, invoke that subskill standalone (e.g.
init-jira,init-vcs). - Local-only setup. Vercel-only deployment track.
.env.localis a mirror produced byvercel env pull, never the source of truth. - Auto-write secrets. The user pastes values into the Vercel dashboard; this skill never sees them. The skill emits
.env-format paste-templates and runbooks.
Execution rules: read first
Step-by-step. One step per turn. Stop and wait at every irreversible boundary. Don't bulk through. Don't preview the next step's questions.
For each step:
- Announce the step in one sentence.
- Run the step's logic (subskill invocation, command, or paste-template).
- Pause at irreversible boundaries: every step that ends in → Stop. Ask. Trivial steps (printing a checklist, advancing past a confirmation) chain.
- End-of-turn: at every hard pause, ask "Ready for the next step: <name>?" and wait for a yes/next/go signal.
If the user replies with anything other than a clear go-signal, do not advance: answer them, fix what they flagged, then re-ask.
Run every command from apps/worker unless a step says otherwise, so .vercel/project.json below means apps/worker/.vercel/project.json. Linking there pins the project's Root Directory to apps/worker, so Vercel builds the worker and its cron rather than the repo root (SETUP.md section 3).
Sequence
0. Pre-flight → tool versions, vercel whoami, existing-link check, team scope
1. vercel link → only if not already linked
2. init-jira (phase 1) → credentials + columns + JIRA_WEBHOOK_SECRET
3. init-vcs → branch on github | gitlab
4. init-agent → branch on claude | codex
5. init-slack → bot token, channel, signing secret
6. init-neon → Marketplace install runbook
7. Inline: CRON_SECRET + dashboard auth → auto-generate, paste-template
8. vercel env pull + validate → .env.local + apps/worker/src/infra/runtime-env.ts
9. vercel --prod → single production deploy
10. init-jira (phase 2) → webhook registration with deploy URL
10b. VCS webhook → GitHub App webhook URL or GitLab project hook (SETUP.md section 8)
11. Slack slash command → /ai-workflow registration with deploy URL
12. Smoke checks → /health + /cron/poll auth + manual ticket
13. Final summaryStep 0: Pre-flight
Run these in order. Halt with a clear message on any failure; never invoke vercel login from this skill.
0a. Toolchain
Required (per SETUP.md §1):
node --version # v20+
pnpm --version # v10+
vercel --version # latest; older CLIs may miss flags this skill expects
git --version # 2.40+If any version is below the floor, HALT with the exact mismatch and the install command from SETUP.md §1 (npm i -g pnpm, npm i -g vercel@latest, etc.). Don't try to upgrade for the user.
Also assume the user has run pnpm install after cloning. If node_modules/ is missing, halt and direct them to run it.
0b. Authentication
vercel whoami- Fails: HALT. Tell the user: "Vercel CLI not authenticated. Run
vercel login, then re-invokeinit-env." - OK: record the current scope (team or personal) for step 0d.
0c. Existing link
test -f .vercel/project.json && cat .vercel/project.json- No link: continue to step 0d.
- Link present: read its
orgId/projectId. Print: "Existing link found: scope=<X> project=<Y>. Use this link or relink?"- Use: skip step 1 entirely; carry this link forward.
- Relink: HALT. Tell the user: "Remove
.vercel/project.json(rm .vercel/project.json) and re-invokeinit-env."
0d. Team-scope confirmation
Compare the existing link's scope (if any) with vercel whoami output. If they differ, surface the mismatch explicitly. Otherwise:
Print: "Will link to team scope: <current-team>. Correct?"
- No: HALT. Tell the user: "Run
vercel switch <team-name>to change scope, then re-invokeinit-env." - Yes: continue.
→ Stop. Ask: "Pre-flight passed. Ready for Step 1: vercel link?"
Step 1: vercel link
Skip if step 0c found a usable existing link.
vercel linkThe CLI is interactive: let the user complete it. On success, .vercel/project.json is written.
Failure handling:
- Permission denied: HALT. "Account lacks access to project <X>. Ask an owner to grant access, or pick a different project."
- Project not found and user declined to create: HALT. "Re-invoke
init-envand accept Vercel's offer to create the project." - Network: HALT. "Vercel API unreachable. Check connection and re-invoke."
→ Stop. Ask: "Linked. Ready for Step 2: Jira credentials and webhook secret?"
Step 2: Invoke init-jira (phase 1)
Invoke the init-jira subskill via the Skill tool. It detects state and runs phase 1 because JIRA_BASE_URL is not yet set in Vercel:
- Asks for
JIRA_BASE_URL,JIRA_API_TOKEN, andJIRA_PROJECT_KEY. Board status names are configured on the Settings page. - Pre-generates
JIRA_WEBHOOK_SECRETviaopenssl rand -hex 32. - Emits a single
.env-format paste-template. - Walks the user through pasting into the Vercel dashboard (Project Settings → Environment Variables).
- Returns when phase 1 is complete, without testing the values: the Jira card on the Integrations page checks them after the deploy.
→ Stop. Ask: "Jira phase 1 done. Ready for Step 3: VCS provider?"
Step 3: Invoke init-vcs
Invoke init-vcs. It asks github, gitlab or both and emits a paste-template per chosen provider. No variable picks the provider: each repository record names the one that serves it.
→ Stop. Ask: "VCS configured. Ready for Step 4: agent runtime?"
Step 4: Invoke init-agent
Invoke init-agent. It identifies which providers the deployment's harness profiles use and emits only the credentials those providers require. Codex defaults to an API key; OAuth is a documented alternative in the runbook.
→ Stop. Ask: "Agent runtime configured. Ready for Step 5: Slack?"
Step 5: Invoke init-slack
Invoke init-slack. It walks the user through creating the Slack app (or finding an existing bot token), the bot's chat:write scope, and the channel ID format.
→ Stop. Ask: "Slack configured. Ready for Step 6: Neon Postgres?"
Step 6: Invoke init-neon
Invoke init-neon. It walks the user through the Vercel Marketplace install of Neon Postgres with branch-per-environment enabled so Vercel auto-injects DATABASE_URL for each environment, which apps/worker/src/infra/runtime-env.ts requires.
→ Stop. Ask: "Neon installed. Ready for Step 7: cron secret?"
Step 7: CRON_SECRET and dashboard auth (inline)
Generate locally and emit a one-line paste-template:
openssl rand -hex 32Tell the user: "Paste this into Vercel → Project Settings → Environment Variables for all three environments (Production, Preview, Development):"
CRON_SECRET=<the generated value>Without CRON_SECRET, the cron endpoint at /cron/poll accepts unauthenticated callers (apps/worker/src/services/triggers/polling/cron-authorization.ts allows every caller when the secret is unset). Vercel's auto-injected Authorization: Bearer $CRON_SECRET only protects the endpoint when the env var is set.
Then collect the dashboard login variables. The worker refuses to boot without them (apps/worker/src/infra/runtime-env.ts), so the Step 9 deploy fails if any is missing:
BETTER_AUTH_SECRET=<openssl rand -base64 32>
BETTER_AUTH_URL=https://<project>.vercel.app
DASHBOARD_ORIGIN=<the dashboard deployment's origin>
DASHBOARD_AUTH_EMAIL=<the admin's email>
DASHBOARD_AUTH_PASSWORD=<8+ characters>See SETUP.md section 5 for what each one does.
→ Stop. Ask: "CRON_SECRET and dashboard auth set. Ready for Step 8: pull and validate?"
Step 8: vercel env pull and validate
Run from the directory linked in Step 1:
vercel env pull .env.local
pnpm --dir <repo root>/apps/worker exec tsx --env-file="$PWD/.env.local" \
-e "import('./src/infra/runtime-env.ts').then(() => console.log('env ok'))"The validator (apps/worker/src/infra/runtime-env.ts, @t3-oss/env-core) checks the core variables only:
- Missing boot-required keys (
DATABASE_URL,BETTER_AUTH_*,DASHBOARD_ORIGIN,DASHBOARD_AUTH_*). - Format violations (URLs, the 64-hex encryption keys).
- Cross-field violations (
COMMIT_AUTHOR/COMMIT_EMAIL, the fourSSO_*,RESEND_*).
It does not check Jira, GitHub, GitLab, Slack or agent credentials: those are integration connection values, and a missing one shows as Failing on that integration's card on the Integrations page after the deploy. Check the cards after Step 9.
On failure: the validator prints Invalid environment variables: followed by the specific keys. Direct the user to fix them in the Vercel dashboard, then re-run this step.
→ Stop. Ask: "Validator passed. Ready for Step 9: production deploy?"
Step 9: vercel --prod
vercel --prodThis is the first production deploy. It will:
- Build the project against the env vars now in Vercel.
- Assign the stable production URL
<project>.vercel.app. - Print the deploy URL on success.
On failure: the orchestrator pauses (does not abort). Print the deploy error verbatim, and offer:
- "Fix the issue (commonly a missing env var the validator can't detect, or a build error) and reply
redeployto re-runvercel --prod."
Do not auto-retry. Build errors usually need human intervention.
→ Stop. Ask: "Deployed. Ready for Step 10: register the Jira webhook?"
Step 10: Invoke init-jira (phase 2)
Invoke init-jira again. State detection now sees:
JIRA_*env vars present in Vercel..vercel/project.jsonexists with project name.- A successful production deploy (this step's outcome).
Phase 2 derives the webhook URL from .vercel/project.json (https://<project>.vercel.app/webhooks/jira) and walks the user through Jira's webhook admin UI. It uses the JIRA_WEBHOOK_SECRET already pasted in phase 1: no redeploy needed because the handler reads the secret at request time.
If the user opts to defer webhook registration (custom domain coming, admin permission missing, etc.), record it as a TODO for the final summary and continue.
→ Stop. Ask: "Webhook registered (or deferred). Ready for Step 10b: VCS webhook?"
Step 10b: Register the VCS webhook
Walk the user through SETUP.md section 8:
- GitHub: set the App's webhook URL to
https://<project>.vercel.app/webhooks/githubif a placeholder was used, and confirm the App subscribes to all five events in GITHUB-APP-SETUP.md section 5. The GitHub card's App webhook health check on the Integrations page names any missing event. - GitLab: add the project hook at
https://<project>.vercel.app/webhooks/gitlabwith the settings in GITLAB-SETUP.md. GitLab has no health check for its event selection, so read the list there.
If deferred, record it as a TODO for the final summary.
→ Stop. Ask: "VCS webhook registered (or deferred). Ready for Step 11: Slack slash command?"
Step 11: Slack slash command
Register the /ai-workflow slash command against the deployed URL. This is the Slack analogue of Step 10: both webhook and slash command need a live deploy URL, hence both run post-deploy.
Read .vercel/project.json for the project name and construct:
https://<project>.vercel.app/webhooks/slackWalk the user through the runbook (full version: init-slack/references/slash-commands.md). The TL;DR:
- Open the Slack app's config page (https://api.slack.com/apps → your AI Workflow app).
- Slash Commands → Create New Command.
- Fill:
- Command:
/ai-workflow - Request URL: the slash URL from above
- Short description:
Inspect and control AI workflow runs - Usage hint:
list | status <KEY> | cancel <KEY>
- Command:
- Save and reinstall the app to the workspace if Slack prompts.
- Confirm
SLACK_SIGNING_SECRETis set in Vercel (collected in Step 5). The shared webhook route (apps/worker/src/routes/webhooks/[id].post.ts) hands the request tointegrations/slack/slash-command.ts, which rejects a bad signature with 401; with no signing secret every request is refused with 503.
Verify in Slack:
/ai-workflow listIf the user can't register the slash command now (admin permission missing, custom domain pending, etc.), record it as a TODO for the final summary and continue.
→ Stop. Ask: "Slash command registered (or deferred). Ready for Step 12: smoke checks?"
Step 12: Smoke checks
Three checks, in order. Don't skip the first two: they catch deploy/env issues without needing a live ticket round-trip.
12a. Health endpoint
curl https://<project>.vercel.app/health
# expect: 200 with "status":"ok"; commit, env and timestamp identify the deploymentFailure modes:
- Non-200: build is broken or env-var validation crashed at startup. Run
vercel logs --prodto inspect; the user must fix and redeploy. - 200 but wrong body: a middleware or routing regression. Surface the response and stop.
12b. Cron auth
# unauth: must reject
curl -i https://<project>.vercel.app/cron/poll
# expect: HTTP/1.1 401
# authed: must succeed
curl -i -H "Authorization: Bearer $CRON_SECRET" https://<project>.vercel.app/cron/poll
# expect: HTTP/1.1 200If the unauth call returns 200, CRON_SECRET is missing in Production. Ask the user to set it (Step 7's value) and redeploy.
The user can paste $CRON_SECRET directly from their local shell if they ran vercel env pull in Step 8 and source .env.local first.
12c. End-to-end ticket
Print:
Last check. Drop a test ticket in Jira to verify the bot end-to-end.
1. Open ${JIRA_BASE_URL}/jira/your-projects
2. Create a small issue:
- Title: "Hello from AI Workflow"
- Description: include an "Acceptance Criteria" block, e.g.
## Acceptance Criteria
- The repo has a HELLO.md file
3. Drag the ticket from the Backlog column to the AI column.
Within ~5s (with webhook) or up to 15 minutes (cron fallback), expect:
- A bot comment on the ticket
- A branch `ai-workflow/<ticket-key>` and a PR opened in your VCS
- A Slack message in your channel
- The ticket transitions to "AI Review"
Reply when you've seen the PR (or "stuck on X" if a step is missing).Wait for the user's response. If they report a failure, capture which milestone was missing and route to the matching row in SETUP.md §13, Troubleshooting. Include the result in the final summary.
→ Stop. Ask: "Smoke passed?"
Step 13: Final summary
Print the summary template below, populated with the values gathered during the flow. Use the actual project name from .vercel/project.json and the user-reported smoke result.
Cold start complete.
Linked Vercel project: <team>/<project>
Production URL: https://<project>.vercel.app
Jira webhook URL: https://<project>.vercel.app/webhooks/jira
Slack request URL: https://<project>.vercel.app/webhooks/slack
Configured:
Jira <project_key> webhook <registered | deferred>
VCS <github|gitlab|both> webhook <registered | deferred>
Agent <claude|codex|both> credentials set (model comes from each block's Harness Profile)
Slack channel <id> bot @<bot_name>, slash <registered | deferred>
Neon DATABASE_URL per env via Marketplace
Cron CRON_SECRET set poll every 15 minutes
Skipped (see SETUP.md for the full how-to):
- Arthur AI tracing: SETUP.md §12. Set GENAI_ENGINE_API_KEY and
GENAI_ENGINE_TRACE_ENDPOINT to enable per-run tracing and the
prompt-injection check.
- GitLab alongside or instead of GitHub: SETUP.md §12. Provide
GITLAB_TOKEN and GITLAB_WEBHOOK_SECRET (+ GITLAB_HOST for self-hosted),
or connect GitLab on the Integrations page, register the project webhook
(SETUP.md section 8), then import its repositories on the Repositories page.
- CI / GitHub Actions: SETUP.md §11. The `e2e` GitHub environment
needs the prod env vars plus E2E_BASE_URL, E2E_GITHUB_APP_ID,
E2E_GITHUB_APP_PRIVATE_KEY (base64 PEM), E2E_GITHUB_INSTALLATION_ID,
E2E_GITHUB_OWNER, E2E_GITHUB_REPO, and VERCEL_AUTOMATION_BYPASS_SECRET
as secrets.
- Custom domain: point a domain at the Vercel project for a stable
webhook URL (then update the Jira webhook, the VCS webhook and the Slack
request URLs).
- VERCEL_TOKEN local PAT: local dev only; Vercel uses OIDC in prod.
Smoke checks:
/health <pass | fail>
/cron/poll <pass | fail>
end-to-end <user-reported pass | fail with diagnostic>
Maintenance:
Rotate one integration later by invoking that subskill standalone:
init-jira | init-vcs | init-agent | init-slack | init-neon
Inspect the deployment:
vercel logs --prod
https://vercel.com/<team>/<project>/observability
Troubleshooting matrix: SETUP.md §13.
No git changes were made. .env.local and .vercel/project.json are gitignored.→ Done. Do not auto-commit, auto-push, or open a PR. The user owns git.
Don'ts
- Don't invoke
vercel login. It's an interactive, browser-launching flow the orchestrator can't observe. If pre-flight detects no auth, halt and tell the user. - Don't print or log secret values. Reference them by name only. Pre-generated secrets (
JIRA_WEBHOOK_SECRET,CRON_SECRET) appear once in the paste-template the user copies; never repeat them in summaries or logs. - Don't auto-retry failed deploys. Pause, surface the error, let the user fix and reply
redeploy. - Don't bulk through subskill invocations. Each subskill is its own step; pause for the user's confirmation between them.
- Don't auto-
vercel linkto a team without confirming. Linking writes.vercel/project.jsonand binds future deploys. - Don't write
.env..env.local(fromvercel env pull) is the only local file, and.env.exampleis the committed reference. - Don't invent variables. Core variables live in
apps/worker/src/infra/runtime-env.ts, integration variables in eachintegrations/<id>/manifest.ts. If you need a new key, propose adding it there first.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

