agentleFS
BlazityBlazity/ai-workflow/.claude/skills/init-env/SKILL.md

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

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
  1. Distinctive:

    If the user replies with anything other than a clear go-signal, do not advance: answer them, fix what they flagged, then re-ask.

    line 28
  2. Very specific:

    Run every command from apps/worker unless a step says otherwise, so .vercel/project.json below means apps/worker/.vercel/project.json.

    line 30
  3. Very specific:

    Run these in order. Halt with a clear message on any failure.

    line 56
  4. Very specific:

    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 …

    line 69
  5. Very specific:

    Link present: read its orgId / projectId.

    line 89
  6. Distinctive:

    Run from the directory linked in Step 1:

    line 206
  7. Distinctive:

    Do not auto-retry. Build errors usually need human intervention.

    line 241
  8. Distinctive:

    If the user opts to defer webhook registration (custom domain coming, admin permission missing, etc.), record it as a TODO for the final …

    line 256
  9. Very specific:

    GitLab: add the project hook at https://<project>.vercel.app/webhooks/gitlab with the settings in GITLAB-SETUP.md.

    line 267
  10. Distinctive:

    If deferred, record it as a TODO for the final summary.

    line 269
  11. Very specific:

    Read .vercel/project.json for the project name and construct:

    line 279
  12. Distinctive:

    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 …

    line 303
  13. Very specific:

    If the unauth call returns 200, CRON_SECRET is missing in Production.

    line 336
  14. Distinctive:

    Wait for the user's response.

    line 364

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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.local is a mirror produced by vercel 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:

  1. Announce the step in one sentence.
  2. Run the step's logic (subskill invocation, command, or paste-template).
  3. Pause at irreversible boundaries: every step that ends in → Stop. Ask. Trivial steps (printing a checklist, advancing past a confirmation) chain.
  4. 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 summary

Step 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-invoke init-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-invoke init-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-invoke init-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 link

The 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-env and 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, and JIRA_PROJECT_KEY. Board status names are configured on the Settings page.
  • Pre-generates JIRA_WEBHOOK_SECRET via openssl 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 32

Tell 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 four SSO_*, 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 --prod

This 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 redeploy to re-run vercel --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.json exists 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/github if 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/gitlab with 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/slack

Walk the user through the runbook (full version: init-slack/references/slash-commands.md). The TL;DR:

  1. Open the Slack app's config page (https://api.slack.com/apps → your AI Workflow app).
  2. Slash Commands → Create New Command.
  3. 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>
  4. Save and reinstall the app to the workspace if Slack prompts.
  5. Confirm SLACK_SIGNING_SECRET is set in Vercel (collected in Step 5). The shared webhook route (apps/worker/src/routes/webhooks/[id].post.ts) hands the request to integrations/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 list

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 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 deployment

Failure modes:

  • Non-200: build is broken or env-var validation crashed at startup. Run vercel logs --prod to 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 200

If 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 link to a team without confirming. Linking writes .vercel/project.json and binds future deploys.
  • Don't write .env. .env.local (from vercel env pull) is the only local file, and .env.example is the committed reference.
  • Don't invent variables. Core variables live in apps/worker/src/infra/runtime-env.ts, integration variables in each integrations/<id>/manifest.ts. If you need a new key, propose adding it there first.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.