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:
That is what my new command does.
# Create AI infused GitHub Repo
new my-next-thingThat was the point of my tweet. New repo setup should not be a checklist I perform from memory. It should be one repeatable command.
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?
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.
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.
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-nameThat 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.
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:
@claude.@claude.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.
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:
This makes the working path the default: no README step that says "go find the token and paste it somewhere."
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
--silentAn agent-ready repo is not ready if the agent can start but cannot write.
At the end, the script opens the project in Cursor and installs the local AI scaffolding:
npx get-rulesI 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.
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:
@claude.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.