From dev-core
Connect project to GitHub Project V2 board — discover or create board, labels, branch protection, workspace registration. Triggers: "github setup" | "setup github project" | "connect github board" | "setup project board".
npx claudepluginhub roxabi/roxabi-plugins --plugin dev-coreThis skill is limited to using the following tools:
Let:
Configures GitHub repository via gh CLI with main branch protection rules, issue/PR templates, standard labels, .gitignore, and metadata. For new or existing professional projects.
Initializes and configures projects: detects tech stacks, scaffolds new apps, creates task files, sets branch strategies, handles git submodules, exports to other AI platforms.
Manages GitHub Projects v2 via gh CLI: create/edit/list projects, add issues/PRs as items, manage fields, link repos, automate workflows.
Share bugs, ideas, or general feedback.
Let:
I_TS := ${CLAUDE_PLUGIN_ROOT}/skills/init/init.ts
F := --force flag present in $ARGUMENTS
PID := selected project ID (PVT_...)
disc := JSON result of bun $I_TS discover
ω := owner/repo (from disc)
δ := .claude/dev-core.yml
D(label, result) := Display: {label} {result}
D✅(label) := D(label, "✅ Created")
D⏭(label) := D(label, "⏭ Skipped")
Connect to GitHub: Project V2 board, field IDs, labels, branch protection, Vercel, issue migration, workspace registration. Standalone or called by /init.
Run: bun $I_TS discover. Parse → extract owner, repo, projects, fields, labels, workflows, protection, vercel, env.
bun $I_TS create-project --owner <owner> --repo <repo> [--type technical|company]. Parse PID + field IDs.¬PID → field IDs stay empty. PID ∃ ∧ fields missing → run create-project.
After selection: re-run bun $I_TS discover to refresh field IDs. Status/Size/Priority still missing → run bun $I_TS create-project --owner <owner> --repo <repo> [--type technical|company] (handles pre-existing Status gracefully).
| Flag | Values | Default | Description |
|---|---|---|---|
--type | technical | company | technical | Sets project type in workspace.json. |
PID ∃ → run: bun $I_TS list-workflows --project-id <PVT_...>. Parse JSON, display table:
GitHub Project Workflows
┌─────────────────────────────────────────┬──────────┐
│ Workflow │ Status │
├─────────────────────────────────────────┼──────────┤
│ Auto-add to project │ ❌ off │
│ Auto-add sub-issues to project │ ❌ off │
│ Auto-archive items │ ❌ off │
│ ... │ │
└─────────────────────────────────────────┴──────────┘
∃ disabled → display:
ℹ️ GitHub doesn't expose an API to toggle built-in project workflows.
Enable them manually in the project settings:
https://github.com/orgs/<owner>/projects/<number>/workflows
(replace `orgs` with `users` for personal accounts)
labels.missing ≠ ∅ → Ask: Create all | Type only | Area only | Skip.
Run: bun $I_TS labels --repo <owner/repo> --scope <all|type|area>
Ask: Set up branch protection | Skip.
yes → bun $I_TS protect-branches --repo <owner/repo>
Applies: branch protection (required ci, strict up-to-date) on main + staging; PR_Main ruleset if missing (squash/rebase/merge, ¬deletion/force-push, thread resolution — merge commits needed for staging→main). Display per-branch ✅/❌ + Ruleset status.
vercel ≠ null in disc → Ask: Set up Vercel | Skip.
yes → Ask for VERCEL_TOKEN (free text — Vercel Settings → Tokens).
issues.orphaned > 0 in disc → Ask: Add N open issues to board | Skip.
yes → bun $I_TS migrate-issues --owner <owner> --repo <repo> --project-number <N>. Parse → D("Issues", "Added {added}/{total} to board").
Display summary table:
dev-core Configuration
======================
GitHub:
GITHUB_REPO = owner/repo
GH_PROJECT_ID = PVT_kwHO...
STATUS_FIELD_ID = PVTSSF_...
SIZE_FIELD_ID = PVTSSF_...
PRIORITY_FIELD_ID = PVTSSF_...
Labels: 11 labels (created / skipped)
Branch protection: main, staging (created / skipped)
Ask: Confirm | Edit a value | Abort. Edit → ask which, accept new, re-display, re-confirm.
# dev-core plugin configuration
# 3-tier fallback: this file → process.env → gh CLI (github_repo only)
github_repo: <owner/repo>
gh_project_id: <PVT_...>
status_field_id: <PVTSSF_...>
size_field_id: <PVTSSF_...>
priority_field_id: <PVTSSF_...>
status_options_json: '<json>'
size_options_json: '<json>'
priority_options_json: '<json>'
Ensure δ ∈ .gitignore.
Run: bun $I_TS scaffold --github-repo <owner/repo> --project-id <PVT_...> --status-field-id <PVTSSF_...> --size-field-id <PVTSSF_...> --priority-field-id <PVTSSF_...> --status-options-json '<json>' --size-options-json '<json>' --priority-options-json '<json>' [--vercel-token <token>] [--vercel-project-id <id>] [--vercel-team-id <id>] [--force]
Also writes .env/.env.example for backward compat. δ takes precedence at runtime via loadDevCoreConfig(). Installs roxabi shim at ~/.local/bin/roxabi (or ~/bin/roxabi) — self-healing, survives plugin updates. Run roxabi dashboard to launch.
Register in shared workspace config (enables multi-project dashboard).
Check:
bun -e "
import { readWorkspace } from '${CLAUDE_PLUGIN_ROOT}/skills/shared/adapters/workspace-helpers.ts'
const ws = readWorkspace()
console.log(ws.projects.some(p => p.repo === process.env.GITHUB_REPO) ? 'registered' : 'not-registered')
"
registered → D("workspace.json", "✅ Already registered"), skip.
¬registered → Ask: Add to workspace | Skip
Add:
bun -e "
import { getWorkspacePath, readWorkspace, writeWorkspace } from '${CLAUDE_PLUGIN_ROOT}/skills/shared/adapters/workspace-helpers.ts'
const ws = readWorkspace()
const entry = {
repo: process.env.GITHUB_REPO ?? '',
projectId: process.env.GH_PROJECT_ID ?? '',
label: (process.env.GITHUB_REPO ?? '').split('/')[1] ?? '',
}
if (process.env.VERCEL_PROJECT_ID) entry.vercelProjectId = process.env.VERCEL_PROJECT_ID
if (process.env.VERCEL_TEAM_ID) entry.vercelTeamId = process.env.VERCEL_TEAM_ID
ws.projects.push(entry)
writeWorkspace(ws)
console.log('written:' + getWorkspacePath())
"
D("workspace.json", "✅ Registered <GITHUB_REPO> at ").
Skip → D⏭("workspace.json").
Scan filesystem for repos with dev-core configured but ∉ workspace.json.
Find candidates:
find "$HOME" -maxdepth 6 \( -path "*/.claude/dev-core.yml" -o -name ".env" \) 2>/dev/null \
| sort -u
∀ found: extract config:
grep -E "^(github_repo|gh_project_id):" <path>/.claude/dev-core.yml 2>/dev/null
grep -E "^(GITHUB_REPO|GH_PROJECT_ID|VERCEL_PROJECT_ID|VERCEL_TEAM_ID)=" <path>/.env 2>/dev/null
Filter: current project + already-registered. ∄ candidates → skip silently.
∃ candidates → display list, Ask: Add all | Select | Skip.
Add → ∀ chosen: derive label from repo name, append to workspace.json (Vercel IDs only if ∃). D("workspace.json", "✅ Added N projects (repo-a, repo-b, ...)").
Skip → D⏭("Bulk discovery").
GitHub Setup Complete
=====================
dev-core.yml ✅ Written (.claude/dev-core.yml)
.env ✅ Written (N variables, legacy fallback)
.env.example ✅ Written
Project board ✅ Created / Detected / ⏭ Skipped
Issue migration ✅ N issues added to board / ⏭ Skipped
Labels ✅ N labels created / ⏭ Skipped
Project workflows ✅ Displayed / ⏭ Skipped
Branch protection ✅ Created / ⏭ Skipped
Ruleset PR_Main ✅ Created / ✅ Already exists / ⏭ Skipped
roxabi shim ✅ Installed (~/.local/bin/roxabi)
PATH ✅ ~/.local/bin added to .bashrc/.zshrc (or ⏭ already present)
artifacts/ ✅ Created
.gitignore ✅ .env added
workspace.json ✅ Registered <repo> / ⏭ Skipped
bulk discovery ✅ Added N projects / ⏭ Skipped / ⏭ No others found
Next: run /ci-setup to configure GitHub Actions and pre-commit hooks.
.env values without F or explicit confirmation.env — ensure both are in .gitignore.env.example — use empty placeholder values$ARGUMENTS