@stigmer/plugin-package 3.35.0 → 3.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/archive.d.ts.map +1 -1
- package/client/archive.js.map +1 -1
- package/client/builtin.d.ts.map +1 -1
- package/client/builtin.js.map +1 -1
- package/client/ignore/defaults.d.ts.map +1 -1
- package/client/ignore/defaults.js.map +1 -1
- package/client/ignore/match.d.ts.map +1 -1
- package/client/ignore/match.js.map +1 -1
- package/client/ignore/matcher.d.ts.map +1 -1
- package/client/ignore/matcher.js.map +1 -1
- package/client/ignore/pattern.d.ts.map +1 -1
- package/client/ignore/pattern.js.map +1 -1
- package/client/prepare.d.ts.map +1 -1
- package/client/prepare.js.map +1 -1
- package/client/presentation.d.ts.map +1 -1
- package/client/presentation.js.map +1 -1
- package/client/refs.d.ts.map +1 -1
- package/client/refs.js.map +1 -1
- package/client/release.d.ts.map +1 -1
- package/client/release.js.map +1 -1
- package/client/reroot.d.ts.map +1 -1
- package/client/reroot.js.map +1 -1
- package/client/select.d.ts.map +1 -1
- package/client/select.js.map +1 -1
- package/client/vocabulary.d.ts.map +1 -1
- package/client/vocabulary.js.map +1 -1
- package/client.d.ts.map +1 -1
- package/client.js.map +1 -1
- package/detect.d.ts.map +1 -1
- package/detect.js.map +1 -1
- package/dialects/claude.d.ts.map +1 -1
- package/dialects/claude.js.map +1 -1
- package/dialects/codex.d.ts.map +1 -1
- package/dialects/codex.js.map +1 -1
- package/dialects/cursor.d.ts.map +1 -1
- package/dialects/cursor.js.map +1 -1
- package/dialects/manifest.d.ts.map +1 -1
- package/dialects/manifest.js.map +1 -1
- package/dialects/open.d.ts.map +1 -1
- package/dialects/open.js.map +1 -1
- package/documents.d.ts.map +1 -1
- package/documents.js.map +1 -1
- package/files.d.ts.map +1 -1
- package/files.js.map +1 -1
- package/frontmatter.d.ts.map +1 -1
- package/frontmatter.js.map +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/marketplace/messages.d.ts.map +1 -1
- package/marketplace/messages.js.map +1 -1
- package/marketplace/outcome.d.ts.map +1 -1
- package/marketplace/outcome.js.map +1 -1
- package/marketplace/read-marketplace.d.ts.map +1 -1
- package/marketplace/read-marketplace.js.map +1 -1
- package/messages.d.ts.map +1 -1
- package/messages.js.map +1 -1
- package/normalise/ignored.d.ts.map +1 -1
- package/normalise/ignored.js.map +1 -1
- package/normalise/mcp-servers.d.ts.map +1 -1
- package/normalise/mcp-servers.js.map +1 -1
- package/normalise/overlay.d.ts.map +1 -1
- package/normalise/overlay.js.map +1 -1
- package/normalise/skills.d.ts.map +1 -1
- package/normalise/skills.js.map +1 -1
- package/normalise/sub-agents.d.ts.map +1 -1
- package/normalise/sub-agents.js.map +1 -1
- package/normalise/variables.d.ts.map +1 -1
- package/normalise/variables.js.map +1 -1
- package/outcome.d.ts.map +1 -1
- package/outcome.js.map +1 -1
- package/package.json +1 -1
- package/placeholders.d.ts.map +1 -1
- package/placeholders.js.map +1 -1
- package/presentation.d.ts.map +1 -1
- package/presentation.js.map +1 -1
- package/read-plugin-package.d.ts.map +1 -1
- package/read-plugin-package.js.map +1 -1
- package/testing.d.ts.map +1 -1
- package/testing.js.map +1 -1
- package/types.d.ts.map +1 -1
- package/types.js.map +1 -1
- package/src/__test-utils__/directory-files.ts +0 -29
- package/src/__test-utils__/read.ts +0 -55
- package/src/__tests__/adversarial.test.ts +0 -434
- package/src/__tests__/client-ignore.test.ts +0 -133
- package/src/__tests__/client-prepare.test.ts +0 -163
- package/src/__tests__/client-refs.test.ts +0 -101
- package/src/__tests__/client-select-archive.test.ts +0 -150
- package/src/__tests__/detect.test.ts +0 -144
- package/src/__tests__/files.test.ts +0 -119
- package/src/__tests__/fixtures/cursor-plugins/.cursor-plugin/marketplace.json +0 -412
- package/src/__tests__/fixtures/cursor-plugins/NOTICE +0 -27
- package/src/__tests__/fixtures/cursor-plugins/advisor/.cursor-plugin/plugin.json +0 -33
- package/src/__tests__/fixtures/cursor-plugins/advisor/CHANGELOG.md +0 -8
- package/src/__tests__/fixtures/cursor-plugins/advisor/LICENSE +0 -21
- package/src/__tests__/fixtures/cursor-plugins/advisor/README.md +0 -87
- package/src/__tests__/fixtures/cursor-plugins/advisor/agents/advisor-subagent.md +0 -48
- package/src/__tests__/fixtures/cursor-plugins/advisor/assets/avatar.png +0 -0
- package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/capture-response.sh +0 -20
- package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/hooks.json +0 -27
- package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/lib.sh +0 -61
- package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/mark-pending.sh +0 -27
- package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/record-consult.sh +0 -41
- package/src/__tests__/fixtures/cursor-plugins/advisor/hooks/stop-hook.sh +0 -48
- package/src/__tests__/fixtures/cursor-plugins/advisor/skills/advisor/SKILL.md +0 -123
- package/src/__tests__/fixtures/cursor-plugins/advisor/skills/advisor/references/briefing-template.md +0 -44
- package/src/__tests__/fixtures/cursor-plugins/github/.cursor-plugin/plugin.json +0 -45
- package/src/__tests__/fixtures/cursor-plugins/github/CHANGELOG.md +0 -9
- package/src/__tests__/fixtures/cursor-plugins/github/LICENSE +0 -21
- package/src/__tests__/fixtures/cursor-plugins/github/README.md +0 -64
- package/src/__tests__/fixtures/cursor-plugins/github/assets/logo.svg +0 -0
- package/src/__tests__/fixtures/cursor-plugins/github/mcp.json +0 -11
- package/src/__tests__/fixtures/cursor-plugins/playwright/.cursor-plugin/plugin.json +0 -35
- package/src/__tests__/fixtures/cursor-plugins/playwright/CHANGELOG.md +0 -8
- package/src/__tests__/fixtures/cursor-plugins/playwright/LICENSE +0 -21
- package/src/__tests__/fixtures/cursor-plugins/playwright/README.md +0 -46
- package/src/__tests__/fixtures/cursor-plugins/playwright/assets/logo.svg +0 -0
- package/src/__tests__/fixtures/cursor-plugins/playwright/mcp.json +0 -8
- package/src/__tests__/fixtures/cursor-plugins/salesforce/.cursor-plugin/plugin.json +0 -48
- package/src/__tests__/fixtures/cursor-plugins/salesforce/CHANGELOG.md +0 -10
- package/src/__tests__/fixtures/cursor-plugins/salesforce/LICENSE +0 -21
- package/src/__tests__/fixtures/cursor-plugins/salesforce/README.md +0 -95
- package/src/__tests__/fixtures/cursor-plugins/salesforce/assets/logo.svg +0 -0
- package/src/__tests__/fixtures/cursor-plugins/salesforce/mcp.json +0 -12
- package/src/__tests__/fixtures/cursor-plugins/thermos/.cursor-plugin/plugin.json +0 -32
- package/src/__tests__/fixtures/cursor-plugins/thermos/CHANGELOG.md +0 -8
- package/src/__tests__/fixtures/cursor-plugins/thermos/LICENSE +0 -21
- package/src/__tests__/fixtures/cursor-plugins/thermos/README.md +0 -70
- package/src/__tests__/fixtures/cursor-plugins/thermos/agents/thermo-nuclear-code-quality-review-subagent.md +0 -23
- package/src/__tests__/fixtures/cursor-plugins/thermos/agents/thermo-nuclear-review-subagent.md +0 -28
- package/src/__tests__/fixtures/cursor-plugins/thermos/assets/logo.png +0 -0
- package/src/__tests__/fixtures/cursor-plugins/thermos/skills/thermo-nuclear-code-quality-review/SKILL.md +0 -192
- package/src/__tests__/fixtures/cursor-plugins/thermos/skills/thermo-nuclear-review/SKILL.md +0 -51
- package/src/__tests__/fixtures/cursor-plugins/thermos/skills/thermos/SKILL.md +0 -21
- package/src/__tests__/fixtures/cursor-plugins/xero/.cursor-plugin/plugin.json +0 -53
- package/src/__tests__/fixtures/cursor-plugins/xero/CHANGELOG.md +0 -9
- package/src/__tests__/fixtures/cursor-plugins/xero/LICENSE +0 -21
- package/src/__tests__/fixtures/cursor-plugins/xero/README.md +0 -79
- package/src/__tests__/fixtures/cursor-plugins/xero/assets/logo.png +0 -0
- package/src/__tests__/fixtures/cursor-plugins/xero/mcp.json +0 -16
- package/src/__tests__/fixtures.test.ts +0 -198
- package/src/__tests__/marketplace.test.ts +0 -378
- package/src/__tests__/mcp-servers.test.ts +0 -120
- package/src/__tests__/overlay-and-ignored.test.ts +0 -65
- package/src/__tests__/presentation.test.ts +0 -186
- package/src/__tests__/skills.test.ts +0 -89
- package/src/__tests__/sub-agents.test.ts +0 -111
- package/src/__tests__/variables.test.ts +0 -94
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: thermo-nuclear-code-quality-review
|
|
3
|
-
description: Run an extremely strict maintainability review for abstraction quality, giant files, and spaghetti-condition growth. Use for a thermo-nuclear code quality review, thermonuclear review, deep code quality audit, or especially harsh maintainability review.
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Thermo-Nuclear Code Quality Review
|
|
8
|
-
|
|
9
|
-
Use this skill for an unusually strict review focused on implementation quality, maintainability, abstraction quality, and codebase health.
|
|
10
|
-
|
|
11
|
-
Above all, this skill should push the reviewer to be **ambitious** about code structure. Do not merely identify local cleanup opportunities. Actively search for "code judo" moves: restructurings that preserve behavior while making the implementation dramatically simpler, smaller, more direct, and more elegant.
|
|
12
|
-
|
|
13
|
-
## Core Prompt
|
|
14
|
-
|
|
15
|
-
Start from this baseline:
|
|
16
|
-
|
|
17
|
-
> Perform a deep code quality audit of the current branch's changes.
|
|
18
|
-
> Rethink how to structure / implement the changes to meaningfully improve code quality without impacting behavior.
|
|
19
|
-
> Work to improve abstractions, modularity, reduce Spaghetti code, improve succinctness and legibility.
|
|
20
|
-
> Be ambitious, if there is a clear path to improving the implementation that involves restructuring some of the codebase, go for it.
|
|
21
|
-
> Be extremely thorough and rigorous. Measure twice, cut once.
|
|
22
|
-
|
|
23
|
-
## Non-Negotiable Additional Standards
|
|
24
|
-
|
|
25
|
-
Apply the baseline prompt above, plus these explicit review rules:
|
|
26
|
-
|
|
27
|
-
0. **Be ambitious about structural simplification.**
|
|
28
|
-
- Do not stop at "this could be a bit cleaner."
|
|
29
|
-
- Look for opportunities to reframe the change so that whole branches, helpers, modes, conditionals, or layers disappear entirely.
|
|
30
|
-
- Prefer the solution that makes the code feel inevitable in hindsight.
|
|
31
|
-
- Assume there is often a "code judo" move available: a re-organization that uses the existing architecture more effectively and makes the change dramatically simpler and more elegant.
|
|
32
|
-
- If you see a path to delete complexity rather than rearrange it, push hard for that path.
|
|
33
|
-
|
|
34
|
-
1. **Do not let a PR push a file from under 1k lines to over 1k lines without a very strong reason.**
|
|
35
|
-
- Treat this as a strong code-quality smell by default.
|
|
36
|
-
- Prefer extracting helpers, subcomponents, modules, or local abstractions instead of letting a file sprawl past 1000 lines.
|
|
37
|
-
- If the diff crosses that threshold, explicitly ask whether the code should be decomposed first.
|
|
38
|
-
- Only waive this if there is a compelling structural reason and the resulting file is still clearly organized.
|
|
39
|
-
|
|
40
|
-
2. **Do not allow random spaghetti growth in existing code.**
|
|
41
|
-
- Be highly suspicious of new ad-hoc conditionals, scattered special cases, or one-off branches inserted into unrelated flows.
|
|
42
|
-
- If a change adds "weird if statements in random places", treat that as a design problem, not a stylistic nit.
|
|
43
|
-
- Prefer pushing the logic into a dedicated abstraction, helper, state machine, policy object, or separate module instead of tangling an existing path.
|
|
44
|
-
- Call out changes that make the surrounding code harder to reason about, even if they technically work.
|
|
45
|
-
|
|
46
|
-
3. **Bias toward cleaning the design, not just accepting working code.**
|
|
47
|
-
- If behavior can stay the same while the structure becomes meaningfully cleaner, push for the cleaner version.
|
|
48
|
-
- Do not rubber-stamp "it works" implementations that leave the codebase messier.
|
|
49
|
-
- Strongly prefer simplifications that remove moving pieces altogether over refactors that merely spread the same complexity around.
|
|
50
|
-
|
|
51
|
-
4. **Prefer direct, boring, maintainable code over hacky or magical code.**
|
|
52
|
-
- Treat brittle, ad-hoc, or "magic" behavior as a code-quality problem.
|
|
53
|
-
- Be skeptical of generic mechanisms that hide simple data-shape assumptions.
|
|
54
|
-
- Flag thin abstractions, identity wrappers, or pass-through helpers that add indirection without buying clarity.
|
|
55
|
-
|
|
56
|
-
5. **Push hard on type and boundary cleanliness when they affect maintainability.**
|
|
57
|
-
- Question unnecessary optionality, `unknown`, `any`, or cast-heavy code when a clearer type boundary could exist.
|
|
58
|
-
- Prefer explicit typed models or shared contracts over loosely-shaped ad-hoc objects.
|
|
59
|
-
- If a branch relies on silent fallback to paper over an unclear invariant, ask whether the boundary should be made explicit instead.
|
|
60
|
-
|
|
61
|
-
6. **Keep logic in the canonical layer and reuse existing helpers.**
|
|
62
|
-
- Call out feature logic leaking into shared paths or implementation details leaking through APIs.
|
|
63
|
-
- Prefer existing canonical utilities/helpers over bespoke one-offs.
|
|
64
|
-
- Push code toward the right package, service, or module instead of normalizing architectural drift.
|
|
65
|
-
|
|
66
|
-
7. **Treat unnecessary sequential orchestration and non-atomic updates as design smells when the cleaner structure is obvious.**
|
|
67
|
-
- If independent work is serialized for no good reason, ask whether the flow should run in parallel instead.
|
|
68
|
-
- If related updates can leave state half-applied, push for a more atomic structure.
|
|
69
|
-
- Do not over-index on micro-optimizations, but do flag avoidable orchestration complexity that makes the implementation more brittle.
|
|
70
|
-
|
|
71
|
-
## Primary Review Questions
|
|
72
|
-
|
|
73
|
-
For every meaningful change, ask:
|
|
74
|
-
|
|
75
|
-
- Is there a "code judo" move that would make this dramatically simpler?
|
|
76
|
-
- Can this change be reframed so fewer concepts, branches, or helper layers are needed?
|
|
77
|
-
- Does this improve or worsen the local architecture?
|
|
78
|
-
- Did the diff add branching complexity where a better abstraction should exist?
|
|
79
|
-
- Did a previously cohesive module become more coupled, more stateful, or harder to scan?
|
|
80
|
-
- Is this logic living in the right file and layer?
|
|
81
|
-
- Did this change enlarge a file or component past a healthy size boundary?
|
|
82
|
-
- Are there repeated conditionals that signal a missing model or missing helper?
|
|
83
|
-
- Is the implementation direct and legible, or does it rely on special cases and incidental control flow?
|
|
84
|
-
- Is this abstraction actually earning its keep, or is it just a wrapper?
|
|
85
|
-
- Did the diff introduce casts, optionality, or ad-hoc object shapes that obscure the real invariant?
|
|
86
|
-
- Is this logic living in the canonical layer, or did the diff leak details across a boundary?
|
|
87
|
-
- Is this orchestration more sequential or less atomic than it needs to be?
|
|
88
|
-
|
|
89
|
-
## What to Flag Aggressively
|
|
90
|
-
|
|
91
|
-
Escalate findings when you see:
|
|
92
|
-
|
|
93
|
-
- A complicated implementation where a cleaner reframing could delete whole categories of complexity.
|
|
94
|
-
- Refactors that move code around but fail to reduce the number of concepts a reader must hold in their head.
|
|
95
|
-
- A file crossing 1000 lines due to the PR, especially if the new code could be split out.
|
|
96
|
-
- New conditionals bolted onto unrelated code paths.
|
|
97
|
-
- One-off booleans, nullable modes, or flags that complicate existing control flow.
|
|
98
|
-
- Feature-specific logic leaking into general-purpose modules.
|
|
99
|
-
- Generic "magic" handling that hides simple structure and makes the code harder to reason about.
|
|
100
|
-
- Thin wrappers or identity abstractions that add indirection without simplifying anything.
|
|
101
|
-
- Unnecessary casts, `any`, `unknown`, or optional params that muddy the real contract.
|
|
102
|
-
- Copy-pasted logic instead of extracted helpers.
|
|
103
|
-
- Narrow edge-case handling implemented in the middle of an already busy function.
|
|
104
|
-
- Refactors that technically pass tests but make the code less modular or less readable.
|
|
105
|
-
- "Temporary" branching that is likely to become permanent debt.
|
|
106
|
-
- Bespoke helpers where the codebase already has a canonical utility for the job.
|
|
107
|
-
- Logic added in the wrong layer/package when it should live somewhere more central.
|
|
108
|
-
- Sequential async flow where obviously independent work could stay simpler and clearer with parallel execution.
|
|
109
|
-
- Partial-update logic that leaves state less atomic than necessary.
|
|
110
|
-
|
|
111
|
-
## Preferred Remedies
|
|
112
|
-
|
|
113
|
-
When you identify a code-quality problem, prefer suggestions like:
|
|
114
|
-
|
|
115
|
-
- Delete a whole layer of indirection rather than polishing it.
|
|
116
|
-
- Reframe the state model so conditionals disappear instead of getting centralized.
|
|
117
|
-
- Change the ownership boundary so the feature becomes a natural extension of an existing abstraction.
|
|
118
|
-
- Turn special-case logic into a simpler default flow with fewer exceptions.
|
|
119
|
-
- Extract a helper or pure function.
|
|
120
|
-
- Split a large file into smaller focused modules.
|
|
121
|
-
- Move feature-specific logic behind a dedicated abstraction.
|
|
122
|
-
- Replace condition chains with a typed model or explicit dispatcher.
|
|
123
|
-
- Separate orchestration from business logic.
|
|
124
|
-
- Collapse duplicate branches into a single clearer flow.
|
|
125
|
-
- Delete wrappers that do not meaningfully clarify the API.
|
|
126
|
-
- Reuse the existing canonical helper instead of introducing a near-duplicate.
|
|
127
|
-
- Make type boundaries more explicit so the control flow gets simpler.
|
|
128
|
-
- Move the logic to the package/module/layer that already owns the concept.
|
|
129
|
-
- Parallelize independent work when that also simplifies the orchestration.
|
|
130
|
-
- Restructure related updates into a more atomic flow when partial state would be harder to reason about.
|
|
131
|
-
|
|
132
|
-
Do not be satisfied with "maybe rename this" feedback when the real issue is structural.
|
|
133
|
-
Do not be satisfied with a merely cleaner version of the same messy idea if there is a plausible path to a much simpler idea.
|
|
134
|
-
|
|
135
|
-
## Review Tone
|
|
136
|
-
|
|
137
|
-
Be direct, serious, and demanding about quality.
|
|
138
|
-
Do not be rude, but do not soften major maintainability issues into mild suggestions.
|
|
139
|
-
If the code is making the codebase messier, say so clearly.
|
|
140
|
-
If the implementation missed an opportunity for a dramatic simplification, say that clearly too.
|
|
141
|
-
|
|
142
|
-
Good phrases:
|
|
143
|
-
|
|
144
|
-
- `this pushes the file past 1k lines. can we decompose this first?`
|
|
145
|
-
- `this adds another special-case branch into an already busy flow. can we move this behind its own abstraction?`
|
|
146
|
-
- `this works, but it makes the surrounding code more spaghetti. let's keep the behavior and restructure the implementation.`
|
|
147
|
-
- `this feels like feature logic leaking into a shared path. can we isolate it?`
|
|
148
|
-
- `this abstraction seems unnecessary. can we just keep the direct flow?`
|
|
149
|
-
- `why does this need a cast / optional here? can we make the boundary more explicit instead?`
|
|
150
|
-
- `this looks like a bespoke helper for something we already have elsewhere. can we reuse the canonical one?`
|
|
151
|
-
- `i think there's a code-judo move here that makes this much simpler. can we reframe this so these branches disappear?`
|
|
152
|
-
- `this refactor moves complexity around, but doesn't really delete it. is there a way to make the model itself simpler?`
|
|
153
|
-
|
|
154
|
-
## Output Expectations
|
|
155
|
-
|
|
156
|
-
Prioritize findings in this order:
|
|
157
|
-
|
|
158
|
-
1. Structural code-quality regressions
|
|
159
|
-
2. Missed opportunities for dramatic simplification / code-judo restructuring
|
|
160
|
-
3. Spaghetti / branching complexity increases
|
|
161
|
-
4. Boundary / abstraction / type-contract problems that make the code harder to reason about
|
|
162
|
-
5. File-size and decomposition concerns
|
|
163
|
-
6. Modularity and abstraction issues
|
|
164
|
-
7. Legibility and maintainability concerns
|
|
165
|
-
|
|
166
|
-
Do not flood the review with low-value nits if there are larger structural issues.
|
|
167
|
-
Prefer a smaller number of high-conviction comments over a long list of cosmetic notes.
|
|
168
|
-
|
|
169
|
-
## Approval Bar
|
|
170
|
-
|
|
171
|
-
Do not approve merely because behavior seems correct.
|
|
172
|
-
The bar for approval is:
|
|
173
|
-
|
|
174
|
-
- no clear structural regression
|
|
175
|
-
- no obvious missed opportunity to make the implementation dramatically simpler when such a path is visible
|
|
176
|
-
- no unjustified file-size explosion
|
|
177
|
-
- no obvious spaghetti-growth from special-case branching
|
|
178
|
-
- no obviously hacky or magical abstraction that makes the code harder to reason about
|
|
179
|
-
- no unnecessary wrapper/cast/optionality churn obscuring the real design
|
|
180
|
-
- no clear architecture-boundary leak or avoidable canonical-helper duplication
|
|
181
|
-
- no missed opportunity for an obvious decomposition that would materially improve maintainability
|
|
182
|
-
|
|
183
|
-
Treat these as presumptive blockers unless the author can justify them clearly:
|
|
184
|
-
|
|
185
|
-
- the PR preserves a lot of incidental complexity when there is a plausible code-judo move that would delete it
|
|
186
|
-
- the PR pushes a file from below 1000 lines to above 1000 lines
|
|
187
|
-
- the PR adds ad-hoc branching that makes an existing flow more tangled
|
|
188
|
-
- the PR solves a local problem by scattering feature checks across shared code
|
|
189
|
-
- the PR adds an unnecessary abstraction, wrapper, or cast-heavy contract that makes the design more indirect
|
|
190
|
-
- the PR duplicates an existing helper or puts logic in the wrong layer when there is a clear canonical home
|
|
191
|
-
|
|
192
|
-
If those conditions are not met, leave explicit, actionable feedback and push for a cleaner decomposition.
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: thermo-nuclear-review
|
|
3
|
-
description: Comprehensive security and correctness audit of a branch's changes. Use for thermo nuclear, thermonuclear, or deep review requests, or branch/PR diff audits focused on bugs, breaking changes, security issues, devex regressions, and feature-gate leaks.
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Thermo Nuclear Review
|
|
8
|
-
|
|
9
|
-
Use this skill for a comprehensive security and correctness audit of a checked-out branch.
|
|
10
|
-
|
|
11
|
-
## Prompt
|
|
12
|
-
|
|
13
|
-
You are a security expert performing a comprehensive review of a checked out branch. Audit this branch and its changes extremely thoroughly for bugs, changes that break existing features/functionality, and security vulnerabilities. Be EXTREMELY thorough, rigorous, careful, ambitious, and attentive. NOTHING can slip through.
|
|
14
|
-
|
|
15
|
-
# Scope
|
|
16
|
-
ONLY report issues related to code that is being ADDED or MODIFIED in this PR.
|
|
17
|
-
Focus on changes in the diff.
|
|
18
|
-
DO NOT report vulnerabilities in existing code that is not being changed.
|
|
19
|
-
|
|
20
|
-
# Guidelines
|
|
21
|
-
|
|
22
|
-
## Breaking Functionality Guidelines
|
|
23
|
-
This is a complex codebase, with many cross-package/module dependencies. Often simple code changes in one place have subtle interactions that break functionality elsewhere. You MUST be extremely thorough in tracing through possible side effects of the changes.
|
|
24
|
-
|
|
25
|
-
## Breaking Devex Guidelines
|
|
26
|
-
It can be easy to break developers' ability to run / build the code locally. You MUST catch changes that will impact users' developer experience. Some examples (not exhaustive):
|
|
27
|
-
- Modifying how secrets are read / where they are read from
|
|
28
|
-
- Updating environment variable names / adding environment variables
|
|
29
|
-
- Remapping ports / networking
|
|
30
|
-
- Adding scripts that must be run for certain functionality to continue working. Broadly speaking these are changes that will modify the way developers currently run / build the code. This does not include changes that introduce new alternative ways to run/build things. Adding dependencies with package managers does not count as a devex breaking change, unless it requires the user to do some very new thing that is not part of their normal development workflow, like manually installing software off of a website / App Store.
|
|
31
|
-
|
|
32
|
-
## Feature Leak Guidelines
|
|
33
|
-
The codebase might carefully gate features behind feature flags or internal-only checks. You MUST NOT allow any features that are meant to be behind a feature gate leak. These leaks are often subtle. Be VERY careful and thorough.
|
|
34
|
-
|
|
35
|
-
## Intended Breakage Guidelines
|
|
36
|
-
If you identify a high risk finding, but the intent of the branch is to introduce that finding – e.g. break some functionality, remove a feature flag, remove a safeguard – AND the scope of the change is well constrained, you SHOULD NOT waste the author's time by reporting the issue to them. However, if you believe it is likely that they are not aware of the full implications of their change, or you are worried that they are under-weighting the negative impacts (extreme example: a developer pushes a PR titled "Delete the database"), or you are worried that the change is actually malicious, you should still report the finding.
|
|
37
|
-
|
|
38
|
-
## Over-reporting Guidelines
|
|
39
|
-
If you report issues as High priority when they are not in fact high priority / meaningful issues, devs will lose trust in you and stop listening to you over time.
|
|
40
|
-
NEVER misreport the priority / importance of issues. Be extremely thorough in tracing issues end-to-end to gain complete, and total confidence before reporting.
|
|
41
|
-
|
|
42
|
-
# Final Response
|
|
43
|
-
IF you have medium-to-high priority / risk findings, and there is a PR for this branch, then check the PR/MR discussion using gh/glab cli to see if there are comments from BugBot or others present.
|
|
44
|
-
If so, take their findings into account. If they found issues you missed, evaluate them to determine if they are valid and include them in your report. If they found some of the same issues you did, see if there is anything from their findings that are worth incorporating into your response.
|
|
45
|
-
Flag issues found by BugBot or others in the PR/MR discussion that you include in your report.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# Critical Rules
|
|
49
|
-
- NEVER present issues with unfinished research. E.g. Never say something like, "The client has issue X, but if handled in the backend then this is ok." if you have access to the backend code and can check for yourself.
|
|
50
|
-
- You MUST wait to check the PR/MR discussion until AFTER you have performed your audit. This way you have fresh eyes while you review.
|
|
51
|
-
- Be EXTREMELY thorough, rigorous, careful, ambitious, and attentive. NOTHING can slip through.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: thermos
|
|
3
|
-
description: "Launch both thermo-nuclear review subagents in parallel, then synthesize their findings. Use for thermos, double thermo review, or combined bug/security and code-quality branch audits."
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Thermos
|
|
8
|
-
|
|
9
|
-
Run the two thermo review passes as async background subagents in parallel, then synthesize their results.
|
|
10
|
-
|
|
11
|
-
## Workflow
|
|
12
|
-
|
|
13
|
-
1. Determine the review scope from the user request, PR, current branch, or relevant changed files.
|
|
14
|
-
2. Gather the diff and any file/context excerpts needed for reviewers to evaluate the change without guessing.
|
|
15
|
-
3. Launch both subagents in the same message with `run_in_background: true`:
|
|
16
|
-
- `subagent_type: "thermo-nuclear-review-subagent"` for bugs, breakages, security, devex regressions, feature-flag leaks, and other branch-audit risks.
|
|
17
|
-
- `subagent_type: "thermo-nuclear-code-quality-review-subagent"` for maintainability, structure, file-size growth, spaghetti, abstractions, and codebase-health risks.
|
|
18
|
-
4. Pass each subagent the same scoped diff/file context and ask it to return prioritized findings with file references and evidence.
|
|
19
|
-
5. After both finish, synthesize the results with findings first, deduplicated across reviewers. Weight overlapping findings more heavily, resolve disagreements with your own judgment, and keep summaries brief.
|
|
20
|
-
|
|
21
|
-
If individual background summaries are already visible to the user, do not restate them wholesale. Surface the unified verdict, the highest-signal findings, and any remaining uncertainty.
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "xero",
|
|
3
|
-
"displayName": "Xero",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"minClientVersions": {
|
|
6
|
-
"cursor": "3.13.0"
|
|
7
|
-
},
|
|
8
|
-
"description": "Read and write invoices, contacts, reports, and payroll.",
|
|
9
|
-
"author": {
|
|
10
|
-
"name": "Cursor",
|
|
11
|
-
"email": "plugins@cursor.com"
|
|
12
|
-
},
|
|
13
|
-
"homepage": "https://github.com/XeroAPI/xero-mcp-server",
|
|
14
|
-
"repository": "https://github.com/cursor/plugins",
|
|
15
|
-
"license": "MIT",
|
|
16
|
-
"logo": "assets/logo.png",
|
|
17
|
-
"keywords": [
|
|
18
|
-
"xero",
|
|
19
|
-
"accounting",
|
|
20
|
-
"invoices",
|
|
21
|
-
"payroll",
|
|
22
|
-
"bookkeeping",
|
|
23
|
-
"finance",
|
|
24
|
-
"mcp"
|
|
25
|
-
],
|
|
26
|
-
"category": "integrations",
|
|
27
|
-
"tags": [
|
|
28
|
-
"xero",
|
|
29
|
-
"accounting",
|
|
30
|
-
"mcp",
|
|
31
|
-
"finance"
|
|
32
|
-
],
|
|
33
|
-
"variables": {
|
|
34
|
-
"type": "object",
|
|
35
|
-
"properties": {
|
|
36
|
-
"XERO_CLIENT_ID": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"title": "Xero client ID",
|
|
39
|
-
"description": "Client ID of the Custom Connection you created at developer.xero.com. A Custom Connection is bound to a single Xero organisation."
|
|
40
|
-
},
|
|
41
|
-
"XERO_CLIENT_SECRET": {
|
|
42
|
-
"type": "string",
|
|
43
|
-
"title": "Xero client secret",
|
|
44
|
-
"description": "Client secret generated alongside the Custom Connection's client ID at developer.xero.com."
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"required": [
|
|
48
|
-
"XERO_CLIENT_ID",
|
|
49
|
-
"XERO_CLIENT_SECRET"
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
"mcpServers": "./mcp.json"
|
|
53
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this plugin will be documented here.
|
|
4
|
-
|
|
5
|
-
## 1.0.0 — initial release
|
|
6
|
-
|
|
7
|
-
- Added the `xero` MCP server, running `@xeroapi/xero-mcp-server` locally over stdio.
|
|
8
|
-
- Auth uses a Xero Custom Connection client ID and secret supplied by the user.
|
|
9
|
-
- Logo: Xero's official mark, from the `XeroAPI` GitHub organization.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Cursor
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Xero
|
|
2
|
-
|
|
3
|
-
Cursor plugin that connects agents to [Xero](https://www.xero.com) through Xero's official [Model Context Protocol](https://modelcontextprotocol.io/) server, run locally by Cursor.
|
|
4
|
-
|
|
5
|
-
Read and write a Xero organisation's accounting and payroll data — invoices, contacts, chart of accounts, payments, quotes, journals, reports, and timesheets.
|
|
6
|
-
|
|
7
|
-
## Install
|
|
8
|
-
|
|
9
|
-
1. Open **Cursor Settings → Plugins**.
|
|
10
|
-
2. Search for **Xero**.
|
|
11
|
-
3. Click **Install**, then set the Xero client ID and client secret (below).
|
|
12
|
-
|
|
13
|
-
Or run `/add-plugin xero` in chat.
|
|
14
|
-
|
|
15
|
-
## MCP
|
|
16
|
-
|
|
17
|
-
```json
|
|
18
|
-
{
|
|
19
|
-
"mcpServers": {
|
|
20
|
-
"xero": {
|
|
21
|
-
"type": "stdio",
|
|
22
|
-
"command": "npx",
|
|
23
|
-
"args": [
|
|
24
|
-
"-y",
|
|
25
|
-
"@xeroapi/xero-mcp-server@latest"
|
|
26
|
-
],
|
|
27
|
-
"env": {
|
|
28
|
-
"XERO_CLIENT_ID": "${XERO_CLIENT_ID}",
|
|
29
|
-
"XERO_CLIENT_SECRET": "${XERO_CLIENT_SECRET}"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Xero does not publish a hosted MCP endpoint. Its official server runs locally over stdio and authenticates with a **Custom Connection** — Xero's machine-to-machine OAuth 2.0 flow — so the plugin takes a client ID and secret rather than prompting for browser sign-in.
|
|
37
|
-
|
|
38
|
-
## Before you connect
|
|
39
|
-
|
|
40
|
-
1. Sign in at [developer.xero.com](https://developer.xero.com) and create an app with the **Custom Connection** option.
|
|
41
|
-
2. Select the scopes up front. Connections created before 2026-04-29 use the bundled scope list; newer ones use the granular list. The server tries the bundled set first and falls back, so you usually do not need to set `XERO_SCOPES`.
|
|
42
|
-
3. Authorize the connection from the email Xero sends, and pick the organisation to connect.
|
|
43
|
-
4. Copy the **Client ID**, generate a **Client Secret**, and set both in **Dashboard → Plugins → Configure**.
|
|
44
|
-
|
|
45
|
-
A Custom Connection is bound to a single Xero organisation and is a paid add-on per organisation. Payroll tools require an NZ or UK organisation.
|
|
46
|
-
|
|
47
|
-
## What agents can do
|
|
48
|
-
|
|
49
|
-
| Category | Capabilities |
|
|
50
|
-
| --- | --- |
|
|
51
|
-
| Accounts & contacts | Chart of accounts, contacts, and contact groups |
|
|
52
|
-
| Sales & purchases | Invoices, quotes, credit notes, and payments |
|
|
53
|
-
| Banking | Bank transactions and manual journals |
|
|
54
|
-
| Items & tracking | Items and tracking categories |
|
|
55
|
-
| Reports | Profit and loss, balance sheet, trial balance, and aged receivables/payables |
|
|
56
|
-
| Payroll | Employees, leave, leave types, and timesheets (NZ and UK organisations) |
|
|
57
|
-
|
|
58
|
-
The server is the source of truth for tool names and schemas.
|
|
59
|
-
|
|
60
|
-
## Notes
|
|
61
|
-
|
|
62
|
-
- This is a local stdio server, so `npx` has to be available on the machine running Cursor. It downloads `@xeroapi/xero-mcp-server` on first run.
|
|
63
|
-
- Xero's own FAQ says the server works with any client supporting local stdio servers, and that its testing was done with Claude Desktop and Cursor.
|
|
64
|
-
- Tool calls run with the scopes granted to the Custom Connection, against the one organisation it is bound to. To work with several organisations, create a connection per organisation.
|
|
65
|
-
- To narrow the surface further, add a space-separated `XERO_SCOPES` value to the server's `env` — for example `accounting.invoices accounting.contacts accounting.settings`.
|
|
66
|
-
- `xero-mcp` by john-zhang-dev is a community package, and JAX is Xero's in-product assistant. Neither is this server.
|
|
67
|
-
|
|
68
|
-
## Docs
|
|
69
|
-
|
|
70
|
-
- Xero MCP server: https://github.com/XeroAPI/xero-mcp-server
|
|
71
|
-
- Xero AI and MCP: https://developer.xero.com/ai
|
|
72
|
-
- Custom Connections: https://developer.xero.com/documentation/guides/oauth2/custom-connections/
|
|
73
|
-
- npm package: https://www.npmjs.com/package/@xeroapi/xero-mcp-server
|
|
74
|
-
|
|
75
|
-
Logo is Xero's official mark, from the `XeroAPI` GitHub organization.
|
|
76
|
-
|
|
77
|
-
## License
|
|
78
|
-
|
|
79
|
-
MIT
|
|
File without changes
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mcpServers": {
|
|
3
|
-
"xero": {
|
|
4
|
-
"type": "stdio",
|
|
5
|
-
"command": "npx",
|
|
6
|
-
"args": [
|
|
7
|
-
"-y",
|
|
8
|
-
"@xeroapi/xero-mcp-server@latest"
|
|
9
|
-
],
|
|
10
|
-
"env": {
|
|
11
|
-
"XERO_CLIENT_ID": "${XERO_CLIENT_ID}",
|
|
12
|
-
"XERO_CLIENT_SECRET": "${XERO_CLIENT_SECRET}"
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The fixture suite: six real Cursor plugins, vendored from cursor/plugins
|
|
3
|
-
* at c1c0a32 (see fixtures/cursor-plugins/NOTICE), read exactly as a user's
|
|
4
|
-
* checkout would be. Every assertion names the field it pins; there are no
|
|
5
|
-
* snapshot files, so a change in what the reader produces is a change
|
|
6
|
-
* someone wrote down here.
|
|
7
|
-
*
|
|
8
|
-
* Between them the six cover: Cursor `variables` with `required` (github,
|
|
9
|
-
* xero, salesforce), a `${VAR}` inside a header (github), stdio `env` as
|
|
10
|
-
* `KEY: "${KEY}"` (xero), an entry with no `type` inferred to stdio
|
|
11
|
-
* (playwright), a `${VAR}` url plus the undocumented `auth` block
|
|
12
|
-
* (salesforce, the one refusal), two sub-agents and no server (thermos), a
|
|
13
|
-
* sub-agent with an unmappable model and a `readonly` field plus hooks that
|
|
14
|
-
* reference `${CURSOR_PLUGIN_ROOT}` and must never be read (advisor), skill
|
|
15
|
-
* frontmatter with vendor keys, `minClientVersions`, a `references/` file
|
|
16
|
-
* inside a skill, and image assets that are listed and never opened.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { fileURLToPath } from "node:url";
|
|
20
|
-
|
|
21
|
-
import { describe, expect, it } from "vitest";
|
|
22
|
-
|
|
23
|
-
import { readPluginPackage } from "../read-plugin-package.js";
|
|
24
|
-
import { directoryPluginFiles } from "../__test-utils__/directory-files.js";
|
|
25
|
-
import { accepted, findingOf, kindsOf, refused } from "../__test-utils__/read.js";
|
|
26
|
-
|
|
27
|
-
const FIXTURES = fileURLToPath(new URL("./fixtures/cursor-plugins/", import.meta.url));
|
|
28
|
-
|
|
29
|
-
function readFixture(name: string) {
|
|
30
|
-
return readPluginPackage(directoryPluginFiles(`${FIXTURES}${name}`));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe("thermos: skills and sub-agents, no server", () => {
|
|
34
|
-
const outcome = readFixture("thermos");
|
|
35
|
-
|
|
36
|
-
it("is accepted with no warnings", () => {
|
|
37
|
-
expect(kindsOf(outcome)).toEqual({ errors: [], warnings: [] });
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("carries the manifest identity", () => {
|
|
41
|
-
const plugin = accepted(outcome);
|
|
42
|
-
expect(plugin).toMatchObject({
|
|
43
|
-
name: "thermos",
|
|
44
|
-
version: "1.0.0",
|
|
45
|
-
license: "MIT",
|
|
46
|
-
dialect: "cursor",
|
|
47
|
-
manifestsFound: [".cursor-plugin/plugin.json"],
|
|
48
|
-
author: { name: "Cursor", email: "plugins@cursor.com" },
|
|
49
|
-
homepage: "https://github.com/cursor/plugins",
|
|
50
|
-
});
|
|
51
|
-
expect(plugin.keywords).toContain("thermo-nuclear");
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("reads the three skills with their descriptions and files", () => {
|
|
55
|
-
const plugin = accepted(outcome);
|
|
56
|
-
expect(plugin.skills.map((s) => s.name)).toEqual(["thermo-nuclear-code-quality-review", "thermo-nuclear-review", "thermos"]);
|
|
57
|
-
expect(plugin.skills[2]?.description).toMatch(/^Launch both thermo-nuclear review subagents/);
|
|
58
|
-
expect(plugin.skills[2]?.files).toEqual(["skills/thermos/SKILL.md"]);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("reads the two sub-agents with the file body as instructions and no model hint", () => {
|
|
62
|
-
const plugin = accepted(outcome);
|
|
63
|
-
expect(plugin.subAgents.map((a) => a.name)).toEqual(["thermo-nuclear-code-quality-review-subagent", "thermo-nuclear-review-subagent"]);
|
|
64
|
-
const review = plugin.subAgents[1];
|
|
65
|
-
expect(review?.description).toMatch(/^Thermo-nuclear branch audit/);
|
|
66
|
-
expect(review?.instructions.length).toBeGreaterThan(1000);
|
|
67
|
-
expect(review?.modelHint).toBeUndefined();
|
|
68
|
-
expect(review?.path).toBe("agents/thermo-nuclear-review-subagent.md");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("has no servers and no variables, and records only the logo", () => {
|
|
72
|
-
const plugin = accepted(outcome);
|
|
73
|
-
expect(plugin.mcpServers).toEqual([]);
|
|
74
|
-
expect(plugin.variables).toEqual([]);
|
|
75
|
-
expect(plugin.ignored).toEqual([
|
|
76
|
-
{ kind: "assets", path: "assets/" },
|
|
77
|
-
{ kind: "logo", path: ".cursor-plugin/plugin.json#logo" },
|
|
78
|
-
]);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe("github: an HTTP server with a token in a header", () => {
|
|
83
|
-
const outcome = readFixture("github");
|
|
84
|
-
|
|
85
|
-
it("is accepted with no warnings", () => {
|
|
86
|
-
expect(kindsOf(outcome)).toEqual({ errors: [], warnings: [] });
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("reads the server with the header reference on its env", () => {
|
|
90
|
-
expect(accepted(outcome).mcpServers).toEqual([
|
|
91
|
-
{
|
|
92
|
-
name: "github",
|
|
93
|
-
transport: "http",
|
|
94
|
-
url: "https://api.githubcopilot.com/mcp/",
|
|
95
|
-
headers: { Authorization: "Bearer ${GITHUB_PERSONAL_ACCESS_TOKEN}" },
|
|
96
|
-
env: ["GITHUB_PERSONAL_ACCESS_TOKEN"],
|
|
97
|
-
},
|
|
98
|
-
]);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("declares the required variable as a secret with the joined title and description", () => {
|
|
102
|
-
expect(accepted(outcome).variables).toEqual([
|
|
103
|
-
{
|
|
104
|
-
name: "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
105
|
-
description:
|
|
106
|
-
"GitHub personal access token: Fine-grained or classic PAT from https://github.com/settings/tokens with the repo scopes you want the agent to use.",
|
|
107
|
-
isSecret: true,
|
|
108
|
-
optional: false,
|
|
109
|
-
declaredBy: "cursor",
|
|
110
|
-
},
|
|
111
|
-
]);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("records minClientVersions and the logo as ignored", () => {
|
|
115
|
-
expect(accepted(outcome).ignored.map((c) => c.kind).sort()).toEqual(["assets", "logo", "min-client-versions"]);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe("xero: a stdio server passing two secrets by name", () => {
|
|
120
|
-
const outcome = readFixture("xero");
|
|
121
|
-
|
|
122
|
-
it("is accepted with no warnings", () => {
|
|
123
|
-
expect(kindsOf(outcome)).toEqual({ errors: [], warnings: [] });
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("reads the npx command with its args and both env references", () => {
|
|
127
|
-
expect(accepted(outcome).mcpServers).toEqual([
|
|
128
|
-
{
|
|
129
|
-
name: "xero",
|
|
130
|
-
transport: "stdio",
|
|
131
|
-
command: "npx",
|
|
132
|
-
args: ["-y", "@xeroapi/xero-mcp-server@latest"],
|
|
133
|
-
env: ["XERO_CLIENT_ID", "XERO_CLIENT_SECRET"],
|
|
134
|
-
},
|
|
135
|
-
]);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it("declares both variables as required secrets", () => {
|
|
139
|
-
expect(accepted(outcome).variables.map((v) => [v.name, v.isSecret, v.optional])).toEqual([
|
|
140
|
-
["XERO_CLIENT_ID", true, false],
|
|
141
|
-
["XERO_CLIENT_SECRET", true, false],
|
|
142
|
-
]);
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
describe("playwright: a server with no type and no variables", () => {
|
|
147
|
-
const outcome = readFixture("playwright");
|
|
148
|
-
|
|
149
|
-
it("is accepted with no warnings and infers stdio from command", () => {
|
|
150
|
-
expect(kindsOf(outcome)).toEqual({ errors: [], warnings: [] });
|
|
151
|
-
expect(accepted(outcome).mcpServers).toEqual([
|
|
152
|
-
{ name: "playwright", transport: "stdio", command: "npx", args: ["-y", "@playwright/mcp@latest"], env: [] },
|
|
153
|
-
]);
|
|
154
|
-
expect(accepted(outcome).variables).toEqual([]);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
describe("salesforce: a variable in the url is refused", () => {
|
|
159
|
-
const outcome = readFixture("salesforce");
|
|
160
|
-
|
|
161
|
-
it("is refused for the url alone, with the auth block warned", () => {
|
|
162
|
-
expect(kindsOf(outcome)).toEqual({ errors: ["mcp-server-url-variable"], warnings: ["mcp-server-auth-ignored"] });
|
|
163
|
-
expect(findingOf(refused(outcome), "mcp-server-url-variable").message).toBe(
|
|
164
|
-
"MCP server 'salesforce' in 'mcp.json' has a variable in its 'url'; Stigmer sends the URL as written, so write the URL out and put variables in 'headers'",
|
|
165
|
-
);
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
describe("advisor: a sub-agent with an unmappable model, and hooks that are never read", () => {
|
|
170
|
-
const outcome = readFixture("advisor");
|
|
171
|
-
|
|
172
|
-
it("is accepted with the model and the readonly field warned", () => {
|
|
173
|
-
expect(kindsOf(outcome)).toEqual({ errors: [], warnings: ["sub-agent-field-ignored", "sub-agent-model-unknown"] });
|
|
174
|
-
expect(findingOf(outcome.warnings, "sub-agent-model-unknown")).toMatchObject({ subject: "advisor-subagent", detail: "grok-4.6[effort=xhigh]" });
|
|
175
|
-
expect(findingOf(outcome.warnings, "sub-agent-field-ignored")).toMatchObject({ subject: "advisor-subagent", detail: "readonly" });
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it("keeps the raw model text in the hint", () => {
|
|
179
|
-
expect(accepted(outcome).subAgents[0]?.modelHint).toEqual({ raw: "grok-4.6[effort=xhigh]", alias: "unknown" });
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("reads the skill with its references file and vendor frontmatter keys", () => {
|
|
183
|
-
const skill = accepted(outcome).skills[0];
|
|
184
|
-
expect(skill?.name).toBe("advisor");
|
|
185
|
-
expect(skill?.files).toEqual(["skills/advisor/SKILL.md", "skills/advisor/references/briefing-template.md"]);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it("records hooks as ignored without reading the ${CURSOR_PLUGIN_ROOT} inside them", () => {
|
|
189
|
-
const plugin = accepted(outcome);
|
|
190
|
-
expect(plugin.ignored).toEqual([
|
|
191
|
-
{ kind: "assets", path: "assets/" },
|
|
192
|
-
{ kind: "hooks", path: "hooks/" },
|
|
193
|
-
{ kind: "logo", path: ".cursor-plugin/plugin.json#logo" },
|
|
194
|
-
{ kind: "hooks", path: ".cursor-plugin/plugin.json#hooks" },
|
|
195
|
-
]);
|
|
196
|
-
expect(plugin.mcpServers).toEqual([]);
|
|
197
|
-
});
|
|
198
|
-
});
|