Repeating the same setup steps in every new project is boring, error-prone, and easy to avoid.

When I hit the same setup sequence more than a few times, I usually automate it away. This is how I changed my new repo flow so one command creates a project that can accept work from humans and remote AI agents.

I didn't want "make a directory" or "initialize a package"

I wanted a working repo with the operational pieces already in place:

  • Private GitHub remote created.
  • First commit pushed.
  • AI skills installed.
  • Remote AI agents connected to the repo.
  • Claude Code GitHub Actions workflow added.[1]
  • Secrets and variables wired for remote agents to work.
  • GitHub Actions permissions configured.

That is what my new command does.

# Create AI infused GitHub Repo
new my-next-thing

That was the point of my tweet. New repo setup should not be a checklist I perform from memory. It should be one repeatable command.

Repo templates & scaffold tools don't cut it

GitHub repo templates are fine, but they won't help me wire in everything I need.

Scaffolding tools like Yeoman are useful, but they stop short. They create the directory. Maybe they generate package.json. Maybe they install a framework template.

The code exists, but the repo still is not ready to use.

The friction is in the remote, permissions, secrets, workflow, repo-local AI context, and all the tiny decisions that are easy to postpone until they interrupt you later.

If I want GitHub issues, PR comments, or manual workflow dispatches to hand work to an agent, the repo needs more than code. It needs skills, rules, workflow triggers, secrets, permissions, and defaults.

So the script does not ask "how do I scaffold a package?"

It asks:

What has to be true before this repo can accept work from me, Cursor, GitHub Actions, and Claude Code?

What the command wires up

The command does roughly this:

%%{init: { "flowchart": { "wrappingWidth": 360 } }}%%
flowchart TD
  Start[Run command: new repo-name] --> Owner[Pick GitHub owner]
  Owner --> Local[Create directory, git init, package files]
  Local --> AgentWorkflow[Add Claude workflow and AI skills]
  AgentWorkflow --> Commit[Initial commit]
  Commit --> Remote[Create private GitHub repo and push]
  Remote --> Access[Set secrets, variables, and Actions permissions]
  Access --> Cursor[Open Cursor with project rules]

This is intentionally boring. The setup path should be deterministic enough that I can trust it when I am trying to get an idea out of my head quickly.

How it works

The real script lives in my dotfiles, but the outline is small:

function setup_claude_github_actions() {
  local workflow_dir=".github/workflows"
  local workflow_file="$workflow_dir/claude.yml"

  mkdir -p "$workflow_dir"

  cat > "$workflow_file" <<'YAML'
name: Claude Code

on:
  workflow_dispatch:
  issues:
    types: [opened, assigned]
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

jobs:
  claude:
    if: contains(github.event.comment.body || github.event.issue.body || '', '@claude')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      issues: write
      actions: write
    steps:
      - uses: actions/checkout@v4
      - name: Run Claude Code
        uses: your-ai-agent-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
YAML
}

function set_claude_github_secrets() {
  local repo="$1"

  # Pull these from your password manager, keychain, 1Password CLI,
  # environment, or any other local secure source.
  printf '%s' "$CLAUDE_CODE_OAUTH_TOKEN" |
    gh secret set CLAUDE_CODE_OAUTH_TOKEN -R "$repo"

  printf '%s' "$CLAUDE_CODE_NOTIFICATIONS_URL" |
    gh secret set CLAUDE_CODE_NOTIFICATIONS_URL -R "$repo"

  printf '%s' "$CLAUDE_CODE_NOTIFICATIONS_KEY" |
    gh secret set CLAUDE_CODE_NOTIFICATIONS_KEY -R "$repo"

  gh variable set CLAUDE_ACCOUNT -R "$repo" --body "$CLAUDE_ACCOUNT"
}

function configure_github_actions_permissions() {
  local repo="$1"

  gh api "repos/$repo/actions/permissions/workflow" 
    --method PUT 
    --field default_workflow_permissions=write 
    --field can_approve_pull_request_reviews=true 
    --silent
}

function new() {
  local name="$1"

  if [ -z "$name" ]; then
    echo "Usage: new <directory_name>"
    return 1
  fi

  local owner
  owner="$(pick_github_owner)"
  local repo="$owner/$name"

  mkdir "$name" && cd "$name"

  git init
  git branch -M master

  echo "# $name" > README.md
  cp ~/dotfiles/templates/.gitignore .gitignore
  cp ~/dotfiles/templates/.npmignore .npmignore

  setup_claude_github_actions

  npm init -y

  git add .
  git commit -m "Initial commit"

  gh repo create "$repo" --private --source=. --remote=origin
  git push -u origin master

  set_claude_github_secrets "$repo"
  configure_github_actions_permissions "$repo"

  cursor .
  npx get-rules
}

That is the skeleton. The real version has more convenience, but the idea is simple: repository creation should prepare the repo for work, not just create files.

Choose the GitHub owner first

Some repos belong under my personal account. Some belong under an organization. I do not want to remember the exact gh repo create spelling every time, and I do not want to accidentally create a repo in the wrong place.

So the script asks GitHub who I am, fetches my orgs, builds an ordered list, and lets me choose with fzf.[2]

The result is a repo_full_name like:

owner/repo-name

That value ties the rest of the workflow together: gh repo create, git remote, secret configuration, and Actions permission updates all need the same repo slug.

Commit the agent workflow early

The Claude Code workflow is copied into .github/workflows/claude.yml before the initial commit.

That matters because the first pushed state of the repo already knows how to respond to the places where I assign work:

  • Issue bodies that mention @claude.
  • Issue comments that mention @claude.
  • Pull request bodies.
  • Pull request review comments.
  • Manual workflow_dispatch runs.

The workflow is only the GitHub side of the setup. The repo still needs secrets, write permissions, and enough local context for the agent to do useful work. Miss one of those and the first handoff turns into infrastructure debugging.

Put secrets in the bootstrap

The script pulls required values from local secure storage and uses gh secret set / gh variable set to configure the repo. The template never contains secret values.

For this workflow, that means:

  • A Claude Code OAuth token for CI.
  • Notification credentials.
  • A repository variable identifying the active Claude account.

This makes the working path the default: no README step that says "go find the token and paste it somewhere."

Give Actions permission to write

GitHub Actions defaults are not always the permissions an agent workflow needs.

If the agent is expected to push commits, create PRs, update checks, comment on issues, or approve generated pull request flows, the repo has to allow that.

So after the remote exists and the first push succeeds, the script configures Actions workflow permissions through the GitHub API:

gh api repos/$repo_name/actions/permissions/workflow 
  --method PUT 
  --field default_workflow_permissions=write 
  --field can_approve_pull_request_reviews=true 
  --silent

An agent-ready repo is not ready if the agent can start but cannot write.

Install repo-local AI context

At the end, the script opens the project in Cursor and installs the local AI scaffolding:

npx get-rules

I mentioned this in the self-reply to the tweet because it is a handy scaffold for AI prompt, rule, and skill files. The files are not magic; they are context. They give editors and agents a local place to find project norms, commands, constraints, and expectations.

Why do this?

The repo matters because of the workflow it enables.[3]

This gives me a develop-from-anywhere flow.

So from any device with a browser I can:

  1. Open an issue.
  2. Tag @claude.
  3. Let GitHub Actions run Claude Code.
  4. Get a PR back.
  5. Iterate in PR review comments.

I can hand off work without a local checkout, a "proper" machine, or a round of git ceremony.

That is why the setup belongs in new: every repo starts with the same remote work path already attached.


Notes

Footnotes

  1. ^ Claude Code Action is Anthropic's GitHub Action for connecting Claude Code to GitHub issues, comments, and pull request workflows. In my setup, it is the remote-agent entry point. 

  2. ^ fzf is a command-line fuzzy finder. I use it here for the owner picker because it makes the personal-account-vs-org decision fast without hardcoding the choice. 

  3. ^ This is the workflow I was pointing at in the follow-up tweet: on-demand Claude from anywhere via GitHub issues, Actions, PRs, and review comments.