-
Notifications
You must be signed in to change notification settings - Fork 8
chore: split composer-prompting skill into references/, add tsc --checkJs to CI #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,3 +36,6 @@ jobs: | |
|
|
||
| - name: Lint | ||
| run: npm run lint | ||
|
|
||
| - name: Typecheck | ||
| run: npm run typecheck | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
plugins/cursor/skills/composer-prompting/references/composer-antipatterns.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # Composer Prompt Anti-Patterns | ||
|
|
||
| Prompt shapes that reliably produce bad Composer runs, each with the fix. Adapted for Composer from `openai/codex-plugin-cc`'s prompt anti-patterns; the failure modes are the same, the fixes use the five-section anatomy. | ||
|
|
||
| ## Vague goal | ||
|
|
||
| Bad: | ||
|
|
||
| ```text | ||
| Improve the error handling in the API layer. | ||
| ``` | ||
|
|
||
| "Improve" has no end state — Composer will pick one for you, everywhere it can reach. Better: name the concrete outcome and the boundary. | ||
|
|
||
| ```text | ||
| # Goal | ||
| Wrap the three fetch calls in src/api/client.ts in try/catch and surface failures as ApiError with the upstream status code. Nothing outside client.ts. | ||
| ``` | ||
|
|
||
| ## Missing verify commands | ||
|
|
||
| Bad: a prompt that ends at acceptance criteria. Composer declares "done" on unverified work — the run reports success and the tests were never executed. Always end with **How to verify** listing exact commands (`npm test`, `task typecheck`). If you don't know the commands, that's a grounding failure — go read `package.json` first. | ||
|
|
||
| ## Kitchen-sink run | ||
|
|
||
| Bad: | ||
|
|
||
| ```text | ||
| Fix the failing login test, and while you're there update the README and clean up the unused imports. | ||
| ``` | ||
|
|
||
| Three unrelated jobs → one muddy diff you can't review or revert independently. One `/cursor:delegate` per coherent slice; queue the rest. | ||
|
|
||
| ## Prose instead of a file list | ||
|
|
||
| Bad: | ||
|
|
||
| ```text | ||
| You'll probably need to touch the router and maybe the middleware. | ||
| ``` | ||
|
|
||
| "Probably/maybe" reads as permission to wander. Either name the files (**Files to touch** section) or state explicitly that discovery is part of the task and bound it: "locate the middleware that sets the session cookie; modify only that file." | ||
|
|
||
| ## Re-explaining instead of re-scoping | ||
|
|
||
| When a run goes wrong, the instinct is to resume with a longer explanation of what you meant. If the prompt was structurally bad (vague goal, no verify, no file list), a longer version of it is still bad. Rewrite the prompt with the five sections and start `--fresh` — carrying a confused session forward compounds the confusion. | ||
|
|
||
| ## Asking Composer to make design decisions | ||
|
|
||
| Bad: | ||
|
|
||
| ```text | ||
| Add caching to the product endpoint — whatever approach you think is best. | ||
| ``` | ||
|
|
||
| Design decisions belong to the Claude thread (or the user), not the executor. Decide the approach first ("in-memory LRU, max 500 entries, 60 s TTL"), then delegate the implementation. If you can't specify the approach, the task isn't ready to delegate. |
30 changes: 30 additions & 0 deletions
30
plugins/cursor/skills/composer-prompting/references/model-selection.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Model Selection, Chunking, and Resume Routing | ||
|
|
||
| ## Chunk oversized plans before delegating | ||
|
|
||
| `cursor-agent --force` will YOLO through anything you hand it. That is the point — and also the risk. **Refuse to delegate a single monolithic blob of work.** Heuristics: | ||
|
|
||
| - More than **~5 discrete steps** → split into one `/cursor:delegate` call per step (or per coherent slice). | ||
| - More than **~10 files** or crossing **more than 2 architectural layers** → ask the main Claude to narrow the slice first. | ||
| - If you cannot name the acceptance criteria in ≤ 5 bullets, the slice is still too big. | ||
|
|
||
| Small slices give Composer a tight scope, make the diff reviewable, and make failures cheap to retry. | ||
|
|
||
| ## Pick a model | ||
|
|
||
| Default is `composer-2.5-fast` — Cursor's own current default and the fastest Composer variant. Escalate only when the task warrants it: | ||
|
|
||
| - `composer-2.5` (non-fast) — quality matters slightly more than latency, but the task is still well-scoped. | ||
| - `sonnet` (`claude-4.6-sonnet-medium`) — more than ~5 files touched, or moderate architecture changes. | ||
| - `opus` (`claude-opus-4-7-high`) — cross-cutting refactor, subtle correctness, or a prior `composer` run failed. | ||
| - `gpt` / `codex` (`gpt-5.3-codex`) — only when the user explicitly asks for it. | ||
|
|
||
| Unknown aliases are forwarded as-is, so `--model <whatever>` always works. Do not escalate without a reason — `composer-2.5-fast` is the default for speed and cost. | ||
|
|
||
| ## Resume or fresh | ||
|
|
||
| - **`--resume`** (default when not specified): continue the latest Cursor chat for this repo. Use it when **iterating on the same task** — "also cover the 429 path", "rename the helper you just added". Cheap, preserves Composer's mental model. | ||
| - **`--resume=<chat-id>`**: same, but target a specific prior chat — when `/cursor:status` or the user pointed you at one explicitly. | ||
| - **`--fresh`**: start a brand-new Cursor session. Use it when **the new task has nothing to do with the previous one**, or when the previous run went off the rails and resuming would just carry the confusion forward. | ||
|
|
||
| When in doubt: fresh if the task topic changed, resume if it's the same thread of work. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[SUGGESTION] Introducing the
objalias only insidewalkToolUses(whilepickTextabove still accessesitem.type/item.texton values narrowed similarly) is a slightly inconsistent style — future readers may wonder why one function needs the cast and the other doesn't.