Skip to content

Commit 71feaa2

Browse files
committed
Add README, hudl command, lint-warnings script; update convention-sync, pr-address, lint-commit, im, typescript-standards
1 parent e087fc4 commit 71feaa2

File tree

11 files changed

+1201
-54
lines changed

11 files changed

+1201
-54
lines changed

.cursor/README.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
Complete agent-assisted development workflow for Edge repositories — slash commands with companion scripts, coding standards, review standards, and the author skill.
2+
3+
## Installation
4+
5+
**1. Set the required env var** in your `~/.zshrc`:
6+
```bash
7+
export GIT_BRANCH_PREFIX=yourname # e.g. jon, paul, sam — used for branch naming and PR discovery
8+
```
9+
10+
**2. Install files into `~/.cursor/`:**
11+
```bash
12+
curl -sL https://github.com/EdgeApp/edge-conventions/archive/refs/heads/jon/agents.tar.gz | \
13+
tar -xz --strip-components=2 -C ~/.cursor 'edge-conventions-jon-agents/.cursor' && \
14+
chmod +x ~/.cursor/commands/*.sh && \
15+
echo "✓ Installed into ~/.cursor/"
16+
```
17+
18+
**3. Verify prerequisites:**
19+
- `gh` CLI — `gh auth login`
20+
- `jq``brew install jq`
21+
- `ASANA_TOKEN` env var (Asana scripts only)
22+
23+
---
24+
25+
## Table of Contents
26+
27+
- [Architecture](#architecture)
28+
- [Commands](#commands-slash-commands)
29+
- [Companion Scripts](#companion-scripts)
30+
- [Shared Module](#shared-module-edge-repojs)
31+
- [Rules](#rules-mdc-files)
32+
- [Skills](#skills)
33+
- [Design Principles](#design-principles)
34+
35+
---
36+
37+
## Architecture
38+
39+
```
40+
.cursor/
41+
├── commands/ # Slash commands (.md) + companion scripts (.sh, .js)
42+
├── rules/ # Coding standards (.mdc) — loaded on-demand
43+
└── skills/ # Agent-triggered capabilities
44+
└── author/SKILL.md
45+
```
46+
47+
**Separation of concerns:**
48+
- **Commands** (`.md`) — Define agent workflows: steps, rules, edge cases. Invoked explicitly via `/command`.
49+
- **Companion scripts** (`.sh`, `.js`) — Handle deterministic operations: API calls, git ops, JSON processing. Commands call scripts; scripts never call commands.
50+
- **Rules** (`.mdc`) — Persistent coding standards loaded on-demand by file type or command step. Two classes: **editing standards** (loaded when writing code) and **review standards** (loaded during PR review).
51+
- **Skills** (`.md`) — Specialized agent capabilities triggered by context, not explicit invocation.
52+
53+
All GitHub API operations use **`gh` CLI** (`gh api`, `gh api graphql`, `gh pr`). No raw `curl` + `$GITHUB_TOKEN`.
54+
55+
**User-specific configuration** is driven by the `GIT_BRANCH_PREFIX` env var — set once in `.zshrc`, used by scripts for branch naming (`$GIT_BRANCH_PREFIX/feature-name`) and PR discovery. No hardcoded usernames.
56+
57+
---
58+
59+
## Commands (Slash Commands)
60+
61+
### Core Development
62+
63+
| Command | Description |
64+
|---------|-------------|
65+
| [`/im`](.cursor/commands/im.md) | Implement an Asana task or ad-hoc feature/fix with clean, structured commits |
66+
| [`/pr-create`](.cursor/commands/pr-create.md) | End-to-end: resolve Asana task → implement → create PR with linking |
67+
| [`/changelog`](.cursor/commands/changelog.md) | Update CHANGELOG.md following existing patterns |
68+
| [`/dep-pr`](.cursor/commands/dep-pr.md) | Create a dependent Asana task in another repo and run the full PR workflow |
69+
70+
### Code Review
71+
72+
| Command | Description |
73+
|---------|-------------|
74+
| [`/pr-review`](.cursor/commands/pr-review.md) | Review a PR against both coding and review standards |
75+
| [`/pr-address`](.cursor/commands/pr-address.md) | Address PR feedback with fixup commits, resolving each comment after replying |
76+
| [`/task-review`](.cursor/commands/task-review.md) | Fetch + analyze Asana task context (shared by `/im` and `/pr-create`) |
77+
78+
### Landing & Publishing
79+
80+
| Command | Description |
81+
|---------|-------------|
82+
| [`/pr-land`](.cursor/commands/pr-land.md) | Full landing pipeline: discover → comment check → rebase → merge → publish → Asana update |
83+
84+
### Analysis
85+
86+
| Command | Description |
87+
|---------|-------------|
88+
| [`/chat-audit`](.cursor/commands/chat-audit.md) | Analyze a Cursor chat export to identify inefficiencies and rule violations against the invoked command |
89+
90+
### Utility
91+
92+
| Command | Description |
93+
|---------|-------------|
94+
| [`/q`](.cursor/commands/q.md) | Answer questions before taking action |
95+
| [`/author`](.cursor/commands/author.md) | Create or edit commands and skills via the author skill |
96+
97+
---
98+
99+
## Companion Scripts
100+
101+
### PR Operations
102+
103+
| Script | What it does | API |
104+
|--------|-------------|-----|
105+
| [`pr-create.sh`](.cursor/commands/pr-create.sh) | Create PR for current branch with auto-generated title/body | `gh pr create` |
106+
| [`pr-address.sh`](.cursor/commands/pr-address.sh) | Fetch unresolved feedback, post replies, resolve threads, mark addressed | `gh api` REST + GraphQL |
107+
| [`github-pr-review.sh`](.cursor/commands/github-pr-review.sh) | Fetch PR context (metadata + patches) and submit reviews | `gh pr view` + `gh api` REST |
108+
| [`github-pr-activity.sh`](.cursor/commands/github-pr-activity.sh) | List PRs by activity (recent reviews, comments, CI status) | `gh api graphql` |
109+
110+
### PR Status Dashboard
111+
112+
| Script | What it does | API |
113+
|--------|-------------|-----|
114+
| [`pr-status-gql.sh`](.cursor/commands/pr-status-gql.sh) | PR status with review state, CI checks, new comments (primary) | `gh api graphql` |
115+
| [`pr-status.sh`](.cursor/commands/pr-status.sh) | Same as above, REST fallback when `gh` unavailable | `https` + `$GITHUB_TOKEN` |
116+
| [`pr-watch.sh`](.cursor/commands/pr-watch.sh) | TUI wrapper — auto-refresh dashboard with rate limit awareness | Delegates to above |
117+
118+
### PR Landing Pipeline (`/pr-land`)
119+
120+
These scripts run sequentially. Each handles one phase of the landing workflow:
121+
122+
| Script | Phase | What it does | API |
123+
|--------|-------|-------------|-----|
124+
| [`pr-land-discover.sh`](.cursor/commands/pr-land-discover.sh) | 1: Discovery | Find all `$GIT_BRANCH_PREFIX/*` PRs with approval status | Single `gh api graphql` query |
125+
| [`pr-land-comments.sh`](.cursor/commands/pr-land-comments.sh) | 2: Comment check | Detect unaddressed feedback (inline threads, review bodies, top-level comments) | `gh api graphql` per PR |
126+
| [`pr-land-prepare.sh`](.cursor/commands/pr-land-prepare.sh) | 3: Prepare | Autosquash → rebase → conflict detection → verification | Git only |
127+
| [`verify-repo.sh`](.cursor/commands/verify-repo.sh) | 3b: Verify | CHANGELOG validation + `prepare`/`tsc`/`lint`/`test` (with `--base` and `--require-changelog` options) | Git + yarn |
128+
| [`pr-land-merge.sh`](.cursor/commands/pr-land-merge.sh) | 5: Merge | Sequential merge with auto-rebase, mandatory verification | `gh api` REST |
129+
| [`pr-land-publish.sh`](.cursor/commands/pr-land-publish.sh) | 6: Publish | Version bump, changelog update, commit + tag (no push) | Git + npm |
130+
131+
**Conflict handling is fully scripted:**
132+
- Code conflicts → skip PR, continue with remaining
133+
- CHANGELOG-only (including staging) → agent resolves semantically, re-runs
134+
135+
### Chat Analysis
136+
137+
| Script | What it does |
138+
|--------|-------------|
139+
| [`cursor-chat-extract.js`](.cursor/commands/cursor-chat-extract.js) | Parse Cursor chat export JSON into compact structured summary (messages, tool calls, stats) |
140+
141+
### Asana Integration
142+
143+
| Script | What it does | API |
144+
|--------|-------------|-----|
145+
| [`asana-get-context.sh`](.cursor/commands/asana-get-context.sh) | Fetch task details, attachments, subtasks, custom fields | Asana REST |
146+
| [`asana-attach-pr.sh`](.cursor/commands/asana-attach-pr.sh) | Attach a GitHub PR URL to an Asana task | Asana REST |
147+
| [`asana-create-dep-task.sh`](.cursor/commands/asana-create-dep-task.sh) | Create dependent task in another repo's project | Asana REST |
148+
| [`asana-whoami.sh`](.cursor/commands/asana-whoami.sh) | Get current Asana user info | Asana REST |
149+
| [`asana-verification-needed.sh`](.cursor/commands/asana-verification-needed.sh) | Update task status "Publish Needed" → "Verification Needed" | Asana REST (no GitHub) |
150+
151+
### Build & Deps
152+
153+
| Script | What it does |
154+
|--------|-------------|
155+
| [`lint-commit.sh`](.cursor/commands/lint-commit.sh) | ESLint `--fix` before commit, auto-runs `update-eslint-warnings` when available |
156+
| [`upgrade-dep.sh`](.cursor/commands/upgrade-dep.sh) | Upgrade a dependency in the GUI repo |
157+
158+
---
159+
160+
## Shared Module: `edge-repo.js`
161+
162+
[`edge-repo.js`](.cursor/commands/edge-repo.js) eliminates duplication across the `pr-land-*` scripts. Exports:
163+
164+
| Function | Purpose |
165+
|----------|---------|
166+
| `getRepoDir(repo)` | Resolve local checkout path (`~/git/`, `~/projects/`, `~/code/`) |
167+
| `getUpstreamBranch(repo)` | `origin/develop` for GUI, `origin/master` for everything else |
168+
| `runGit(args, cwd, opts)` | Safe `spawnSync` wrapper with `GIT_EDITOR=true` |
169+
| `parseConflictFiles(output)` | Extract conflicting file paths from rebase output |
170+
| `isChangelogOnly(files)` | Check if all conflicts are in CHANGELOG.md |
171+
| `runVerification(repoDir, baseRef, opts)` | Run the full verify script with scoped lint (supports `{requireChangelog: true}`) |
172+
| `ghApi(endpoint, opts)` | `gh api` wrapper with method, body, paginate, jq support |
173+
| `ghGraphql(query, vars)` | `gh api graphql` wrapper with typed variable injection |
174+
175+
---
176+
177+
## Rules (`.mdc` files)
178+
179+
| Rule | Activation | Purpose |
180+
|------|-----------|---------|
181+
| [`typescript-standards.mdc`](.cursor/rules/typescript-standards.mdc) | Loaded before editing `.ts`/`.tsx` files | TypeScript + React coding standards for **editing** (includes `simple-selectors` rule, descriptive variable names, biggystring arithmetic) |
182+
| [`review-standards.mdc`](.cursor/rules/review-standards.mdc) | Loaded by `/pr-review` command | ~50 review-specific diagnostic rules extracted from PR history |
183+
| [`load-standards-by-filetype.mdc`](.cursor/rules/load-standards-by-filetype.mdc) | Always applied | Auto-loads language-specific standards before editing |
184+
| [`fix-workflow-first.mdc`](.cursor/rules/fix-workflow-first.mdc) | Always applied | Fix command/skill definitions before patching downstream symptoms |
185+
| [`answer-questions-first.mdc`](.cursor/rules/answer-questions-first.mdc) | Always applied | Detect `?` in user messages → answer before acting |
186+
| [`no-format-lint.mdc`](.cursor/rules/no-format-lint.mdc) | Always applied | Don't manually fix formatting — auto-format on agent finish handles it |
187+
| [`eslint-warnings.mdc`](.cursor/rules/eslint-warnings.mdc) | `.ts`/`.tsx` files | ESLint warning handling patterns |
188+
189+
**Editing vs. review separation**: `typescript-standards` contains rules for writing code (prefer `useHandler`, use `InteractionManager`, descriptive variable names, biggystring for numeric calculations). `review-standards` contains diagnostic patterns for catching bugs during review (null `tokenId` fallback, stack trace preservation, module-level cache bugs, etc.). Both are loaded together during `/pr-review`; only `typescript-standards` is loaded during editing.
190+
191+
---
192+
193+
## Skills
194+
195+
| Skill | Purpose |
196+
|-------|---------|
197+
| [`author/SKILL.md`](.cursor/skills/author/SKILL.md) | Meta-skill for creating/maintaining commands and skills. Enforces XML format, `scripts-over-reasoning`, `gh-cli-over-curl`, `minimize-context`, companion script naming conventions, and `small-model-conventions` for commands targeting faster models. |
198+
199+
---
200+
201+
## Design Principles
202+
203+
1. **Scripts over reasoning** — Deterministic operations (API calls, git, JSON) go in companion scripts, not inline in commands.
204+
2. **`gh` CLI over `curl`** — All GitHub API calls use `gh api` / `gh api graphql`. Handles auth, pagination, API versioning automatically.
205+
3. **GraphQL over REST** — Fetch only required fields in a single request where possible. Fall back to REST only when GraphQL doesn't expose the needed data (e.g., file patches).
206+
4. **DRY shared modules** — Common utilities extracted into `edge-repo.js` rather than duplicated across scripts.
207+
5. **XML format** — Commands use XML structure (`<goal>`, `<rules>`, `<step>`) for reliable LLM instruction-following.
208+
6. **Standards-first** — Load coding standards before writing or reviewing any code.
209+
7. **Fix workflow first** — When behavior is wrong, fix the command/skill definition, not the downstream symptom.
210+
8. **No hardcoded usernames** — All user-specific values come from `GIT_BRANCH_PREFIX` env var, set once in `.zshrc`.
211+
9. **Minimize context** — Script output must be compact and structured. Never return raw API responses. Every token costs context.
212+
10. **Small-model conventions** — Commands that run on faster/cheaper models use verbatim bash, file-over-args, inline guardrails, and explicit parallel instructions for reliability.
213+
11. **Knowledge base over crawling** — Maintain curated knowledge files (e.g., `eslint-warnings.mdc`) instead of having the agent crawl/grep for information repeatedly. Pre-indexed knowledge reduces tool calls and context consumption.
214+
12. **Continuous improvement** — Workflows feed back into their own knowledge. PR review feedback updates `review-standards.mdc`, addressed warnings update `eslint-warnings.mdc`, and chat audits surface rule gaps. Each cycle reduces repetitive context gathering by the agent and repetitive review by humans.
Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,46 @@
1-
<goal>Sync cursor files between `~/.cursor/` and the `edge-conventions` repo, commit, push, and optionally update the PR description.</goal>
1+
<goal>Sync cursor files between `~/.cursor/` and the `edge-conventions` repo, commit, push, and update PR description from README.</goal>
22

33
<rules>
44
<rule id="use-companion-script">Use `~/.cursor/commands/convention-sync.sh` for diffing and syncing. Do NOT manually diff or copy files.</rule>
55
<rule id="dry-run-first">Always run without `--stage` first to show the summary. Only stage/commit after user confirms.</rule>
66
<rule id="no-script-bypass">If the script fails, report the error and STOP.</rule>
7+
<rule id="readme-is-source">`.cursor/README.md` is the source of truth for documentation. The script mirrors it to the PR description automatically.</rule>
78
</rules>
89

9-
<step id="1" name="Detect changes">
10+
<step id="1" name="Detect changes and PR status">
1011
Determine the repo directory — default to the current working directory if it contains a `.cursor/` folder, otherwise use the `edge-conventions` checkout.
1112

12-
Run the script in dry-run mode (no flags):
13-
14-
```bash
15-
~/.cursor/commands/convention-sync.sh <repo-dir>
16-
```
13+
Run **in parallel**:
14+
1. Sync script in dry-run mode:
15+
```bash
16+
~/.cursor/commands/convention-sync.sh <repo-dir>
17+
```
18+
2. Check for open PR:
19+
```bash
20+
cd <repo-dir> && gh pr view --json number,url --jq '{number: .number, url: .url}' 2>/dev/null || echo '{}'
21+
```
1722

1823
Parse the JSON output. If `total` is 0, report "Everything is in sync" and stop.
1924
</step>
2025

2126
<step id="2" name="Present summary">
22-
Show the user a concise summary:
27+
Show the user a concise summary including PR update status:
2328

2429
```
2530
Sync summary (user → repo):
2631
New: file1, file2
2732
Modified: file3, file4
2833
Deleted: file5
2934
35+
PR #N: Will update description from README.md (or "No open PR")
36+
3037
Commit and push? [y/N]
3138
```
3239

3340
If the user provided a commit message in their prompt, skip the confirmation and proceed.
3441
</step>
3542

36-
<step id="3" name="Stage, commit, push">
43+
<step id="3" name="Stage, commit, push, update PR">
3744
Run the script with `--commit`:
3845

3946
```bash
@@ -45,24 +52,16 @@ Then push:
4552
```bash
4653
cd <repo-dir> && git push origin HEAD
4754
```
48-
</step>
49-
50-
<step id="4" name="Update PR description (if needed)">
51-
Only if new commands, scripts, or rules were added (check `new` array):
5255

53-
1. Detect the open PR for the current branch:
54-
```bash
55-
gh pr view --json number,url --jq '.number' 2>/dev/null
56-
```
57-
If no PR exists, skip this step.
56+
If an open PR exists, update the PR description from README:
5857

59-
2. Ask:
60-
> "New files added: file1, file2. Update PR #N description? [y/N]"
61-
62-
3. If confirmed, read the current PR body via `gh pr view --json body --jq '.body'`, add entries for new files in the appropriate tables, and update via `gh pr edit --body-file /tmp/pr-body.md`.
58+
```bash
59+
cd <repo-dir> && gh pr edit --body-file .cursor/README.md
60+
```
6361
</step>
6462

6563
<edge-cases>
6664
<case name="Reverse sync (repo → user)">If the user says "pull from repo" or "update my local", run with `--repo-to-user --stage` instead. No git operations needed.</case>
6765
<case name="Selective sync">If the user says to exclude specific files, note them but still run the full diff. The script syncs everything — manually skip files by not confirming, or remove them from staging with `git reset HEAD .cursor/<file>` before committing.</case>
66+
<case name="No README">If `.cursor/README.md` doesn't exist, skip PR description update and warn the user.</case>
6867
</edge-cases>

.cursor/commands/convention-sync.sh

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ new_json="[]"
4242
mod_json="[]"
4343
del_json="[]"
4444

45+
# Check README.md separately (single file, not a directory)
46+
if [[ -f "$USER_DIR/README.md" ]]; then
47+
if [[ ! -f "$REPO_CURSOR/README.md" ]]; then
48+
new_json=$(echo "$new_json" | jq '. + ["README.md"]')
49+
elif ! diff -q "$USER_DIR/README.md" "$REPO_CURSOR/README.md" >/dev/null 2>&1; then
50+
mod_json=$(echo "$mod_json" | jq '. + ["README.md"]')
51+
fi
52+
elif [[ -f "$REPO_CURSOR/README.md" ]]; then
53+
del_json=$(echo "$del_json" | jq '. + ["README.md"]')
54+
fi
55+
4556
for dir in $DIRS; do
4657
user_path="$USER_DIR/$dir"
4758
repo_path="$REPO_CURSOR/$dir"
@@ -80,8 +91,13 @@ if [[ "$DO_STAGE" == true && "$total" -gt 0 ]]; then
8091
if [[ "$DIRECTION" == "user-to-repo" ]]; then
8192
while IFS= read -r f; do
8293
[[ -z "$f" ]] && continue
83-
mkdir -p "$(dirname "$REPO_CURSOR/$f")"
84-
cp "$USER_DIR/$f" "$REPO_CURSOR/$f"
94+
# README.md is at .cursor/ root, others are in subdirs
95+
if [[ "$f" == "README.md" ]]; then
96+
cp "$USER_DIR/$f" "$REPO_CURSOR/$f"
97+
else
98+
mkdir -p "$(dirname "$REPO_CURSOR/$f")"
99+
cp "$USER_DIR/$f" "$REPO_CURSOR/$f"
100+
fi
85101
done <<< "$all_copy"
86102

87103
while IFS= read -r f; do
@@ -106,8 +122,12 @@ if [[ "$DO_STAGE" == true && "$total" -gt 0 ]]; then
106122
else
107123
while IFS= read -r f; do
108124
[[ -z "$f" ]] && continue
109-
mkdir -p "$(dirname "$USER_DIR/$f")"
110-
cp "$REPO_CURSOR/$f" "$USER_DIR/$f"
125+
if [[ "$f" == "README.md" ]]; then
126+
cp "$REPO_CURSOR/$f" "$USER_DIR/$f"
127+
else
128+
mkdir -p "$(dirname "$USER_DIR/$f")"
129+
cp "$REPO_CURSOR/$f" "$USER_DIR/$f"
130+
fi
111131
done <<< "$all_copy"
112132

113133
while IFS= read -r f; do

0 commit comments

Comments
 (0)