Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
02eb971
chore(.claude): polish skills, agents, CLAUDE.md for release/1.1
alfredorubin96 Jun 3, 2026
032a761
security(auth): gate SSO settings page + API by enterprise edition
alfredorubin96 Jun 4, 2026
30cecbf
test(auth): address CodeRabbit feedback on #934
alfredorubin96 Jun 4, 2026
ff8e0f9
fix(auth): mark FeatureGate + EnterpriseRequiredEmptyState props as r…
alfredorubin96 Jun 4, 2026
d573f6e
Merge pull request #934 from alfredo1996/security/issue-906-sso-gating
alfredo1996 Jun 4, 2026
f661f72
feat(import): unify NeoBoard + NeoDash flow with mapping UI + notes
alfredorubin96 Jun 4, 2026
40a7f8e
test(e2e): update import E2E specs for new post-success view + NeoDas…
alfredorubin96 Jun 4, 2026
e2a0b1b
fix(import): drop dashboard title from NeoDash placeholder name
alfredorubin96 Jun 4, 2026
d0c526f
Merge pull request #935 from alfredo1996/feat/issue-916-import-flow-r…
alfredo1996 Jun 4, 2026
b67e54d
fix(import): preserve NeoDash markdown + auto-generate parameter widgets
alfredorubin96 Jun 4, 2026
dc30bd8
fix(import): address CR + Sonar findings on #936
alfredorubin96 Jun 4, 2026
5984822
Merge pull request #936 from alfredo1996/fix/issue-915-neodash-conver…
alfredo1996 Jun 4, 2026
37befde
fix(plugins): graceful settings fallback via safeParseSettings + grap…
alfredorubin96 Jun 4, 2026
6d51192
test(plugins): smoke test safeParseSettings adoption across all 20 pl…
alfredorubin96 Jun 4, 2026
8b47192
Merge pull request #937 from alfredo1996/fix/issue-917-plugin-safe-pa…
alfredo1996 Jun 4, 2026
69349cc
fix(dashboard): suppress self-save 'updated by' banner on revisit
alfredorubin96 Jun 4, 2026
e4209b8
test(e2e): fix dashboard-states #904 test — Back goes to view mode, n…
alfredorubin96 Jun 4, 2026
68e4b95
Merge pull request #938 from alfredo1996/fix/issue-904-self-save-banner
alfredo1996 Jun 5, 2026
203c975
chore(devex): fail-fast HMAC, seed-from-host fix, dev DNS warning
alfredorubin96 Jun 5, 2026
07401ad
fix(test): type warn mock so app tsc accepts the assignment
alfredorubin96 Jun 5, 2026
9806797
fix(dev): redact URI in DNS warn, add tenant scope to diagnostic query
alfredorubin96 Jun 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .claude/agents/code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ Senior reviewer for NeoBoard. Check staged/unstaged changes against rules, then
1. Run `git diff` and `git diff --cached` to get all changes.
2. Read each changed file to understand full context.
3. Check against the rules below.
4. After code review, run `cd app && npm test` and `cd component && npm test` to verify tests pass.
4. After code review, run tests:
- `cd app && npm test` (unit)
- `cd component && npm test` (unit)
- **`cd app && npx playwright test`** (E2E — ALWAYS, per memory rule; not optional)
- Run `cd connection && npm test` if connection/ changed (needs Docker).
5. Check external review feedback:
- CodeRabbit: `gh pr view --comments | grep -A10 'coderabbitai'`
- SonarCloud: `gh pr checks` — verify quality gate passes
Expand Down
6 changes: 3 additions & 3 deletions .claude/agents/test-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ You are a test runner agent for the NeoBoard monorepo.
## Steps

1. Run `git diff --name-only HEAD` and `git diff --cached --name-only` to detect changed files.
2. Check that Docker is running.
2. Check Docker state: `docker ps --format '{{.Names}}: {{.Status}}'`. If E2E will run, first destroy all containers (memory rule: "Destroy Docker before E2E") then `docker compose up -d` and wait for healthchecks.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Scope Docker teardown to NeoBoard compose resources only.

Line 12’s “destroy all containers” guidance is too broad and can kill unrelated local workloads. Limit teardown to this project’s compose stack/volumes (for example, docker compose down -v in the repo context) instead of global docker ps scope.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/agents/test-runner.md at line 12, Update the guidance that currently
says “Destroy Docker before E2E”: instead of instructing to kill all containers
globally, limit teardown to this repo’s compose stack by running a
docker-compose down with volume removal in the repository context or by
specifying the project name/project directory so only NeoBoard resources are
removed; replace the global "docker ps" / "destroy all containers" wording with
this scoped teardown instruction and keep the subsequent step to bring the
compose stack up and wait for healthchecks.

3. Determine which packages are affected:
- Files under `app/` → run `cd app && npm test` and `cd app && npx playwright test` (only if Docker is available)
- Files under `app/` → run `cd app && npm test` and **ALWAYS `cd app && npx playwright test`** (E2E is not optional; if Docker is unavailable, fail loudly — don't silently skip)
- Files under `component/` → run `cd component && npm test`
- Files under `connection/` → run `cd connection && npm test` (only if Docker is available)
- Files under `connection/` → run `cd connection && npm test` (requires Docker; fail loudly if absent)
4. If no changes detected, ask which package to test or run all.
5. Run the relevant test suites.

Expand Down
2 changes: 1 addition & 1 deletion .claude/agents/user-sim-creator.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ npx @playwright/cli resize 1280 720

## Your Session

Login as creator: `bob@example.com` / `password123`
Login as creator: `creator@neoboard.local` / `creator123` (seeded by `neoboard demo` once #921 ships; if absent, sign up via `/signup` then assign role=creator as admin in a setup step)

### Task 1: First Impressions

Expand Down
2 changes: 1 addition & 1 deletion .claude/agents/ux-crawler.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Test with these personas in order. Close and reopen the browser between personas

### Persona 2: Creator (standard user)

- Login: `bob@example.com` / `password123`
- Login: `creator@neoboard.local` / `creator123` (seeded by `neoboard demo`; if absent, sign up via `/signup` then assign role=creator as admin in a setup step)
- Tests: Dashboard CRUD, widget editing, query execution

### Persona 3: Unauthorized (no session)
Expand Down
7 changes: 7 additions & 0 deletions .claude/skills/code/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ Do NOT write implementation before the test. Do NOT skip this for "small" change
cd app && npx next lint --fix
npm run build
cd app && npm test
cd app && npx playwright test # ALWAYS run E2E — not optional
```

## Branching

- Default base: `dev`
- **Exception**: when a `release/X.Y` branch is active (see [memory](../../../.claude/projects/-Users-alfredorubin-Desktop-public/memory/project_release_1_1_active.md) or check `git branch -r | grep 'origin/release/'`), branch from and PR into the active release branch instead of `dev`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace machine-specific memory link with repo-stable guidance.

Line 51 links to a user-specific path (.claude/projects/-Users-...) that won’t resolve for other contributors. Use a repo-relative doc path or keep only the command-based check (git branch -r ...).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/code/SKILL.md at line 51, The sentence referencing a
machine-specific memory link for the "release/X.Y" exception is not portable;
remove the absolute path link and either replace it with a repo-relative
documentation path or drop the link entirely and keep only the command-based
check (`git branch -r | grep 'origin/release/'`), updating the line that
mentions the `release/X.Y` branch so it no longer points to
`.claude/projects/-Users-...` but to a stable repo doc or the command check.

- Verify base with: `git ls-remote --heads origin 'release/*' | head -1`

$ARGUMENTS = task description or issue number.
265 changes: 265 additions & 0 deletions .claude/skills/deploy/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
---
name: deploy
description: Production-deployment audit — fresh stand-up, secrets, backup/restore, migrations, observability. Capture gaps as GitHub issues; do NOT fix in place.
model: sonnet
user-invokable: true
allowed-tools: Read, Write, Bash(docker *), Bash(docker-compose *), Bash(npm *), Bash(npx *), Bash(curl *), Bash(gh *), Bash(git *), Bash(cat *), Bash(ls *), Bash(find *), Bash(grep *), Bash(head *), Bash(tail *), Bash(jq *), Bash(node *), Bash(openssl *), Bash(psql *), Bash(pg_dump *), Bash(pg_isready *), Bash(sleep *), Bash(echo *), Bash(mkdir *), Bash(cp *), Bash(mv *), Bash(rm *)
---

# Deploy — Production Readiness Audit

**Goal**: someone clones the repo, follows the docs, deploys to production, and doesn't lose data or get pwned.

**Operating principle**: this skill is a **read-and-record** audit. Don't fix in place. File every gap as a GitHub issue on `alfredo1996/neoboard` with concrete repro steps and proposed fix. Fixes happen in their own PRs per the [one-PR-per-issue rule](../../../.claude/projects/-Users-alfredorubin-Desktop-public/memory/feedback_pr_per_issue.md).

If $ARGUMENTS contains an umbrella issue number (e.g. `/deploy 895`), link every filed issue to that umbrella in the body and as a comment.

## Destructive-step approval gate (MANDATORY)

This skill includes operations that destroy or rewrite real state: container/volume teardown, DB restore drills, secret rotation, migration runs. **Before running ANY command tagged `⚠️ DESTRUCTIVE` below, you MUST**:

1. Stop and use `AskUserQuestion` to confirm with the user. Show them the exact command, what it will destroy, and what state it leaves the system in if you abort.
2. If the user declines, **skip the entire sub-section** that command belongs to and add a note to the final report ("Section X.Y not exercised — user declined destructive step.")
3. Never chain destructive steps without re-asking between them.

Read-only inspection (`docker ps`, `cat`, `grep`, `curl`, `gh issue create`) does NOT require approval — only the gated ⚠️ commands.

## Pre-conditions

- Clean Docker state (stop + rm all containers — memory rule "destroy Docker before E2E" applies; same here for a true cold start)
- A scratch directory outside the repo for backup/restore drills (e.g. `/tmp/neoboard-deploy-audit-<date>/`)
- Network access to the repo and to docker hub

## Phase 1 — Cold-start audit (~30 min)

Verify the prod compose stack actually starts from zero.

⚠️ **DESTRUCTIVE — requires approval gate before running**. This tears down every container and volume on the machine.

```bash
# Confirm with user FIRST. Then:
docker stop $(docker ps -aq) 2>/dev/null || true
docker rm $(docker ps -aq) 2>/dev/null || true
docker volume ls -q | xargs -r docker volume rm 2>/dev/null || true
```

Read-only inspection (always safe):

```bash
# Inspect the prod compose files (two exist: prod.yml + prod-full.yml)
ls docker/docker-compose.prod*.yml
cat docker/docker-compose.prod.yml
cat docker/docker-compose.prod-full.yml
```

**Capture as issues**:

- Required env vars that the compose file expects but `app/.env.example` doesn't list
- Services with no healthchecks
- Services missing resource limits (CPU/memory)
- Volumes without explicit backup paths documented
- Hard-coded `localhost` / dev-only values in a "prod" file
- Image tags pinned to `:latest` (should be specific version)

⚠️ **DESTRUCTIVE — requires approval gate before running**. This starts a real prod stack; subsequent steps depend on it.

```bash
# Confirm with user FIRST. Then:
# Try to stand up using ONLY the documented procedure (no shortcuts)
# Start from docs/src/content/docs/getting-started/ — whatever the docs say to do
# If docs are missing, that itself is a finding.

cd docker
docker compose -f docker-compose.prod.yml --env-file ../app/.env.local.audit up -d
sleep 30
docker compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml logs --tail 50 app # or whatever the app service is named
```

**Capture as issues**:

- Stack fails to start with a fresh `.env`
- App starts but immediately errors (DB connection, missing migrations, etc.)
- "ready" signal is silent (per [feedback_cli_ready_signal](../../../.claude/projects/-Users-alfredorubin-Desktop-public/memory/feedback_cli_ready_signal.md))
- Healthcheck endpoint doesn't return 200 within reasonable time
- Log noise (warnings, missing-env spam)

## Phase 2 — Deployment checklist walk-through (~20 min)

Walk every checkbox in `docs/src/content/docs/administration/deployment-checklist.mdx` against current code reality.

```bash
cat docs/src/content/docs/administration/deployment-checklist.mdx
```

For every checkbox, verify the **code actually requires what the docs say**:

- For each env var listed: is it actually read by the code? (`grep -rn "process.env.VAR_NAME" app/src`)
- For each "required" var: is it enforced at startup? (check `app/src/lib/env-config.ts`)
- For each "recommended" infra setting: does the code actually use it?

**Capture as issues**:

- Env vars listed in checklist but never referenced in code (stale doc)
- Env vars required by code but missing from checklist (incomplete doc)
- "Required" vars marked as optional in code's env-config (mismatch — see #907)
- Resource limits / network policies the docs prescribe but code never validates

## Phase 3 — Operational drills (~45 min)

The procedures in admin docs must actually work. Run them.

### 3a. Secret rotation

⚠️ **DESTRUCTIVE — requires approval gate**. Rotating `ENCRYPTION_KEY` against a live DB rewrites encrypted credentials. If the rotation procedure is broken, ALL stored connection credentials can become unrecoverable. Do this against a scratch DB created specifically for the drill, not anything you care about.

```bash
# Confirm with user FIRST, including which DB this targets. Then:
# Rotate ENCRYPTION_KEY following docs/src/content/docs/administration/*
# Verify: existing encrypted credentials decrypt with the old key, re-encrypt with new
# Verify: docs warn that mid-flight rotation requires a re-encryption step
```

**Capture as issues**:

- Docs don't have a rotation procedure for a given secret
- Procedure exists but fails when followed
- Rotation invalidates user-facing state silently (e.g. all API keys die without warning — see #907 acceptance criteria)

### 3b. Backup / restore

Read-only first:

```bash
cat docs/src/content/docs/administration/backup-restore.mdx
```

⚠️ **DESTRUCTIVE — requires approval gate**. `down -v` destroys the DB volume. If the drill is run against the wrong stack, real data is lost. Run only against the audit-scratch stack, never a live one.

```bash
# Confirm with user FIRST, showing which compose file and which volume. Then:
# Drill: take a backup, destroy the DB, restore, verify nothing lost
pg_dump -h localhost -U neoboard neoboard > /tmp/neoboard-deploy-audit/backup.sql
docker compose -f docker/docker-compose.prod.yml down -v # destroys DB volume
docker compose -f docker/docker-compose.prod.yml up -d postgres
sleep 10
psql -h localhost -U neoboard -d neoboard < /tmp/neoboard-deploy-audit/backup.sql
# Verify: bring app back up, log in, dashboards present, connections present
```

**Capture as issues**:

- Backup procedure missing a step (e.g. doesn't capture migration version table)
- Restore fails on a fresh DB (e.g. extension dependencies, FK ordering)
- Encrypted credential blob doesn't round-trip (lost ENCRYPTION_KEY ↔ new install)
- No documented retention/rotation strategy

### 3c. Migration upgrade path

Read-only first:

```bash
# Check forward-only enforcement
cat app/src/lib/db/migrate.ts | head -60
ls app/src/lib/db/migrations/
```

⚠️ **DESTRUCTIVE — requires approval gate**. Running migrations against a DB modifies schema. Use the audit-scratch DB, not anything you care about.

```bash
# Confirm with user FIRST. Then:
# Drill: start with an older migration set, run npm run db:migrate, verify advisory lock + idempotency
```

**Capture as issues**:

- Migration runner missing the advisory lock (memory rule: "Advisory lock prevents concurrent runs")
- `--skip-migrations` flag missing or undocumented
- No version-skip test path (can a v0.5 → v1.1 install succeed?)
- Rollback story undocumented (forward-only is fine, but operators need to know that)

## Phase 4 — Observability (~15 min)

Verify operators can actually monitor a deployed instance.

```bash
# Health endpoint
curl -s http://localhost:3000/api/health | jq
cat app/src/app/api/health/route.ts

# Logs — what does production output look like?
docker logs <app-container> --tail 100
# Is there structured JSON? Levels? Request IDs?

# Monitoring doc
cat docs/src/content/docs/administration/monitoring.mdx
```

**Capture as issues**:

- `/api/health` returns 200 even when DB is down (false healthy)
- Health response doesn't include version / migration status / connector status
- Logs are unstructured / lack request IDs
- monitoring.mdx references metrics/dashboards that don't exist
- No `/metrics` endpoint (Prometheus expectation)
- No example Grafana dashboard / Datadog template / etc.

## Phase 5 — TLS / reverse proxy / multi-tenancy (~15 min)

```bash
# What does the app expect from the reverse proxy?
grep -rn "X-Forwarded-Proto\|X-Forwarded-For\|trustProxy\|FORCE_HTTPS" app/src

# SaaS vs on-prem — memory rule: env vars only, never code branches
grep -rnE "process\.env\.(SAAS|ON_PREM|DEPLOYMENT_MODE)" app/src
```

**Capture as issues**:

- `FORCE_HTTPS` documented but not actually wired up
- No example reverse-proxy configs (nginx/Caddy/Traefik) in docs
- Code branches on deployment mode (violates memory rule)
- Tenant isolation not verifiable end-to-end (per Phase 7 of the polish plan — query safety)

## Phase 6 — Compile findings

Output a numbered list:

```
## Deployment audit findings (YYYY-MM-DD)

### Phase 1 — Cold start
- [ ] #NNN — <title>
...

### Phase 2 — Checklist
...

### Phase 3 — Drills
...

### Phase 4 — Observability
...

### Phase 5 — TLS/proxy/multi-tenancy
...
```
Comment on lines +228 to +246

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language identifier to the fenced block.

Line 228 starts a fenced code block without language, which trips markdown lint (MD040). Add ```markdown (or ```text) for the findings template block.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 228-228: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/deploy/SKILL.md around lines 228 - 246, The fenced code block
that begins with "## Deployment audit findings (YYYY-MM-DD)" is missing a
language identifier, triggering MD040; update the opening fence from ``` to
include a language tag such as ```markdown (or ```text) so the block becomes a
labeled fenced code block; locate the block in .claude/skills/deploy/SKILL.md
(look for the "Deployment audit findings (YYYY-MM-DD)" heading and the following
triple-backtick fence) and change only the opening fence to include the language
identifier.


File each as a GH issue using the [issue skill](../issue/skill.md):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix issue-skill link casing/path.

Line 248 links to ../issue/skill.md, but this repo uses SKILL.md naming. Update the link to the actual path to avoid dead navigation on case-sensitive systems.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/deploy/SKILL.md at line 248, Update the broken relative link
in .claude/skills/deploy/SKILL.md that currently points to "../issue/skill.md" —
change the target to the correct case-sensitive path "../issue/SKILL.md" so the
"issue skill" link resolves properly on case-sensitive filesystems; locate the
link text "issue skill" and replace the href string "../issue/skill.md" with
"../issue/SKILL.md".


- Labels: type + `pkg:app` + `area:devex` or `area:release` + (often) `documentation`
- Title prefix `[P0]` for ship blockers (stack won't start, data loss possible), `[P1]` for serious correctness gaps, `[P2]` for QoL / completeness
- Body must include exact repro from the audit + proposed fix shape
- Link to the umbrella issue passed in $ARGUMENTS if any

## Post-audit

- Print the count: "Audit complete: N issues filed across 5 phases. M P0, X P1, Y P2."
- Append a summary comment to the umbrella issue
- Do NOT proceed to fixes in this skill — fixes happen in their own PRs

## When NOT to use this skill

- Mid-development; not a code-correctness audit (use `code-reviewer` + `harden`)
- For a single feature deploy story (this is whole-system)
- When the prod compose is known broken (fix first, audit second)
21 changes: 16 additions & 5 deletions .claude/skills/github-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
---
name: github
name: github-workflow
description: GitHub conventions, labels, branching for NeoBoard.
model: haiku
---

# Branch: feat/, fix/, chore/, docs/, refactor/, security/
# Branches

# Commits: type(scope): description
- Prefixes: `feat/`, `fix/`, `chore/`, `docs/`, `refactor/`, `security/`
- Default base: `dev`. **Exception**: when a `release/X.Y` branch is active, branch from + PR to it instead.

# Scopes: app, component, connection, auth, encryption, migration, api, widget, chart
# Commits

# Labels: type (bug/enhancement/security/...) + package (pkg:app/pkg:component/pkg:connection) + area
`type(scope): description`

- Types: feat, fix, chore, docs, refactor, security, perf, test
- Scopes: app, component, connection, cli, auth, encryption, migration, api, widget, chart

# Labels (apply type + package + area)

- **Type**: bug, enhancement, security, documentation, performance, urgent, breaking-change, refactor, tech-debt, chore, question
- **Package**: pkg:app, pkg:component, pkg:connection, pkg:cli
- **Area**: area:auth, area:connectors, area:widgets, area:charts, area:query-exec, area:dashboard, area:api, area:a11y, area:params, area:table, area:design, area:devex, area:typography, area:motion, area:ci, area:release
- **Special**: enterprise, release-blocker, blocked, backlog, good first issue, claude, dependencies
8 changes: 4 additions & 4 deletions .claude/skills/issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Scopes: app, component, connection, auth, encryption, migration, api, widget, ch

Labels — always apply type + package + area:

- Type: bug, enhancement, security, documentation, performance, urgent
- Package: pkg:app, pkg:component, pkg:connection
- Area: area:auth, area:connectors, area:widgets, area:charts, area:query-exec, area:dashboard, area:api
- Special: enterprise, breaking-change, good-first-issue
- **Type**: bug, enhancement, security, documentation, performance, urgent, breaking-change, refactor, tech-debt, chore, question
- **Package**: pkg:app, pkg:component, pkg:connection, pkg:cli
- **Area**: area:auth, area:connectors, area:widgets, area:charts, area:query-exec, area:dashboard, area:api, area:a11y, area:params, area:table, area:design, area:devex, area:typography, area:motion, area:ci, area:release
- **Special**: enterprise, release-blocker, blocked, backlog, good first issue, claude, dependencies
9 changes: 8 additions & 1 deletion .claude/skills/next/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ If $ARGUMENTS is a number, use that issue instead of picking.

```bash
gh issue edit <number> --add-assignee @me
git checkout dev && git pull origin dev

# Detect the active base branch: release/X.Y if one exists, else dev
BASE=$(git ls-remote --heads origin 'release/*' 2>/dev/null | awk -F/ '{print $NF}' | sort -V | tail -1)
BASE="${BASE:-dev}"
git fetch origin "$BASE" && git checkout "$BASE" && git pull origin "$BASE"
git checkout -b <type>/<short-description>
Comment on lines +34 to 37

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

BASE detection drops the release/ prefix and breaks checkout.

Line 34 extracts only the last path token (1.2), so Line 36 may try to fetch/checkout a non-existent branch instead of release/1.2.

Suggested fix
-BASE=$(git ls-remote --heads origin 'release/*' 2>/dev/null | awk -F/ '{print $NF}' | sort -V | tail -1)
+BASE=$(git ls-remote --heads origin 'refs/heads/release/*' 2>/dev/null \
+  | sed -E 's#^.*refs/heads/##' \
+  | sort -V \
+  | tail -1)
 BASE="${BASE:-dev}"
 git fetch origin "$BASE" && git checkout "$BASE" && git pull origin "$BASE"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
BASE=$(git ls-remote --heads origin 'release/*' 2>/dev/null | awk -F/ '{print $NF}' | sort -V | tail -1)
BASE="${BASE:-dev}"
git fetch origin "$BASE" && git checkout "$BASE" && git pull origin "$BASE"
git checkout -b <type>/<short-description>
BASE=$(git ls-remote --heads origin 'refs/heads/release/*' 2>/dev/null \
| sed -E 's#^.*refs/heads/##' \
| sort -V \
| tail -1)
BASE="${BASE:-dev}"
git fetch origin "$BASE" && git checkout "$BASE" && git pull origin "$BASE"
git checkout -b <type>/<short-description>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/next/SKILL.md around lines 34 - 37, The BASE assignment
strips the release/ prefix (awk -F/ '{print $NF}') causing git fetch/checkout to
use a non-existent branch; update the extraction to preserve the full branch
name (e.g., replace awk -F/ '{print $NF}' with either sed 's#.*refs/heads/##' or
awk -F'/' '{print $(NF-1)"/"$NF}') so BASE becomes "release/1.2" and the
subsequent git fetch origin "$BASE" && git checkout "$BASE" && git pull origin
"$BASE" work correctly.

echo "Branched from: $BASE (target this base in your PR)"
```

Branch prefix from labels: bug → fix/, enhancement → feat/, security → security/, docs → docs/.

PR base = same `$BASE` detected above (release/X.Y when active, else dev).

## Step 3 — Run /drill

Before implementing, run `/drill <number>` to gather requirements, edge cases, and acceptance criteria. This is mandatory per CLAUDE.md.
Expand Down
Loading
Loading