Skip to content

Slim corgea-scan and point it at --help - #7

Merged
leenk7991 merged 2 commits into
feat/mcp-and-rules-skillsfrom
feat/corgea-scan-pointer
Aug 17, 2026
Merged

Slim corgea-scan and point it at --help#7
leenk7991 merged 2 commits into
feat/mcp-and-rules-skillsfrom
feat/corgea-scan-pointer

Conversation

@leenk7991

@leenk7991 leenk7991 commented Aug 10, 2026

Copy link
Copy Markdown
Member

Stacked on #6. No longer waits on a CLI release — see below.

Summary

The CLI copy of this skill is 394 lines, this one was 210, and they disagreed. Two copies with separate review and separate release cadence always drift.

Rather than sync them, shrink the overlap. This file keeps what makes it useful the moment it loads — install, auth, and the handful of core commands — and stops duplicating the parts that change per release.

  • Cuts the body from 210 lines to 106
  • The flag matrix, scan types, export formats, upload matrix, CI gating detail, pre-commit hook and troubleshooting go
  • corgea --help and corgea <command> --help are named authoritative wherever they disagree with this file; the long tail points at docs.corgea.app
  • Opens with corgea --version, and tells the agent to report an outdated CLI with the upgrade for how it was installed rather than upgrading unprompted, since CI and self-hosted installs are often pinned

What's left is stable across releases, so there is little surface left to drift. The cli-skills sync flow stays enabled as a backstop and will usually find nothing.

Changed since the first version of this PR. It originally pointed at corgea skill show, a new command that would have compiled the skill into the binary. That was dropped in Corgea/cli#152 after review: --help is already pinned to the installed version by clap and costs nothing. The practical effect is that this PR no longer needs to wait for a release — every released CLI already answers --help.

Widens the frontmatter description rather than narrowing it. The body shrank, but this is the entry point for the whole CLI, so the trigger text has to cover the pip/npm install gate, dependency inventory and SBOMs, and advisory lookups as well as scanning.

Keeps the name corgea-scan. npx skills add corgea/skills --skill corgea-scan is already published in the docs and the README; renaming breaks it for no benefit.

Test plan

  • node scripts/validate.mjs passes
  • Frontmatter description is 589 chars, within the 1024 limit
  • README row updated to match the widened scope
  • No reference to corgea skill show remains anywhere in the repo

@leenk7991
leenk7991 requested a review from juangaitanv August 10, 2026 15:15
@leenk7991 leenk7991 changed the title Point corgea-scan at the skill the CLI carries Slim corgea-scan and point it at --help Aug 11, 2026
@leenk7991
leenk7991 force-pushed the feat/mcp-and-rules-skills branch from 0c65991 to 78b6fd0 Compare August 11, 2026 14:19
@leenk7991
leenk7991 force-pushed the feat/corgea-scan-pointer branch from fb753df to 9c71bf8 Compare August 11, 2026 14:19
@leenk7991
leenk7991 force-pushed the feat/mcp-and-rules-skills branch from 78b6fd0 to 5cf9d45 Compare August 12, 2026 20:13
@leenk7991
leenk7991 force-pushed the feat/corgea-scan-pointer branch from 9c71bf8 to 5156fe2 Compare August 12, 2026 20:13
@leenk7991
leenk7991 force-pushed the feat/mcp-and-rules-skills branch from 5cf9d45 to cf2499c Compare August 13, 2026 15:46
leenk7991 and others added 2 commits August 13, 2026 18:50
The CLI now compiles its own skill into the binary and prints it with
`corgea skill show`, so the depth belongs there, pinned to the version
actually installed. Keeping a second copy here guarantees the two drift.

Cuts the body roughly in half: install, auth, and the commands worth
having loaded immediately stay, and the flag matrix, export formats,
upload matrix and troubleshooting go. The skill defers to `corgea skill
show` for the rest, and to `corgea --help` where that command does not
exist yet.

Widens the frontmatter description rather than narrowing it. The body
shrank, but this is now the entry point for the whole CLI, so the
trigger text has to cover the install gate, dependency inventory and
advisories as well as scanning.

Keeps the name: `npx skills add corgea/skills --skill corgea-scan` is
already published in the docs and the README.

Depends on a CLI release carrying `corgea skill show`; merging earlier
points users at a command their binary does not have.

Co-authored-by: Cursor <cursoragent@cursor.com>
The pointer targeted `corgea skill show`, which does not exist yet and is no
longer being added: `corgea --help` is already compiled into the binary by
clap, already pinned to the installed version, and costs nothing.

Same shape as before — this file stays the lean entry point and defers the
detail — but the target is a command every released CLI already answers, so
this no longer waits on a release to be useful. Adds the version-skew
guidance: report an outdated CLI rather than upgrading unprompted, and treat
a surprising result as a version difference before a bug, since a changed
default will not error the way a missing flag does.

The long-tail reference now points at docs.corgea.app rather than at a second
copy of it.

Co-authored-by: Cursor <cursoragent@cursor.com>
@leenk7991
leenk7991 force-pushed the feat/corgea-scan-pointer branch from 5156fe2 to bbf613f Compare August 13, 2026 15:51
@leenk7991
leenk7991 merged commit 9140b95 into feat/mcp-and-rules-skills Aug 17, 2026
3 checks passed
leenk7991 added a commit that referenced this pull request Aug 17, 2026
* Add corgea-mcp and sighthound-rules skills

Two capabilities the repo documented nowhere.

corgea-mcp covers the hosted MCP server: connecting, the CORGEA-TOKEN
header, and the ten read tools. Sourced from the published docs rather
than Corgea/mcp-server, which is private, has not been touched since
September, and still describes a local stdio server with three tools.
A skill written from it would document a product that no longer exists.

sighthound-rules covers rule authoring, which the sighthound skill
mentions in one line. The value is the parts a reader loses an hour to:
rules are RON and not YAML, --use-file-rules is required or edits are
ignored in favour of the rules compiled into the binary, and unknown
fields are dropped silently, so the unless: key in frontend_security.ron
is inert.

MCP is a separate plugin since it needs no CLI and authenticates
differently. Rules sit inside the sighthound plugin, being the same tool
and the same install.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Correct the taint example, field table and test loop

All five verified against the Sighthound source and, where runnable, against
the release binary.

The taint example was a bare rule tuple. Rule files deserialize into `Rules`,
whose list defaults to empty, so that shape parses cleanly and contributes
nothing — a search rule written this way exits 0 with `[]`. It is now wrapped,
and the trap is written up, including that `RULE_WRITING_GUIDE.md` shows a
bare tuple itself.

That example also filed `exec(` and `shell_exec(` under `cwe-89`, copying an
anomaly in `rules/php/taint.ron`. A rule spanning both sink classes has one
`cwe_id` to give them, so half its findings are misclassified. Split into a
SQL rule (`cwe-89`) and a command rule (`cwe-78`), each with matching
sanitizers; running both against a PHP fixture reports the two CWEs correctly.

The field table put severity's values on a row shared with `finding_type` and
`cwe_id`, which take Title Case phrases and lowercase `cwe-<number>`. Each now
has a row, with the `Medium` fallback severity and confidence take when unset.
`mode` is `#[serde(default = "default_search_mode")]`, so it was wrong to list
it as required.

The test loop called whatever `sighthound` is on `PATH`, right after building
the one that has your rules in it.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Take the token out of the config, split matching from metadata

The connect examples pasted the token straight into the file the token section
tells you never to put it in, and the Cursor one dressed it up as a variable:
it set `CORGEA_TOKEN` to a literal and referenced it as `${CORGEA_TOKEN}`,
which is not a syntax Cursor interpolates. Cursor resolves `${env:NAME}` in
`args`, `env`, `url` and `headers`, so the token now stays in the environment
and never reaches the file. Noted that Cursor reads its own environment, so a
GUI launch on macOS may not see a shell export until restarted, and that the
syntax belongs to the client rather than to MCP. Also called out
`.cursor/mcp.json` in the token section, since the project-local copy is the
one committed by accident.

`file_types` and `conditions` were filed under metadata, but both decide what
a rule matches — one picks the files it runs against, the other filters by AST
and context. Split the table in two, so the group to search when a rule fires
in the wrong place is the group that can cause it.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Give Claude Desktop its own config, separate the taint controls

"Same block as Cursor" was wrong: `${env:NAME}` is Cursor's syntax, and Claude
Desktop interpolates nothing. What resolves the placeholder there is mcp-remote,
which substitutes `${NAME}` in a header from its own `process.env`
(`src/lib/utils.ts`), so the value belongs in the `env` block. Cursor's spelling
does not fail loudly in that position — mcp-remote takes `env:CORGEA_TOKEN` as
the variable name, finds none, and sends the header empty — so the symptom is
written down next to the config that causes it. The token stays out of the
Cursor config, and the Claude Desktop file is a user-profile one, not a
repository one.

Both `--header` arguments also lost the space after the colon, which Cursor and
Claude Desktop on Windows mangle.

`sanitizers` and `propagators` were described as one thing that narrows
reported flows. Sanitizers do that. Propagators do nothing at all here:
`src/models.rs` declares the field and no other file under `src/` reads it,
which is why no rule in the repo sets one. They now have separate rows, and the
inert field is filed with `unless:` under the trap it belongs to.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Slim corgea-scan and point it at --help (#7)

* Point corgea-scan at the skill the CLI carries

The CLI now compiles its own skill into the binary and prints it with
`corgea skill show`, so the depth belongs there, pinned to the version
actually installed. Keeping a second copy here guarantees the two drift.

Cuts the body roughly in half: install, auth, and the commands worth
having loaded immediately stay, and the flag matrix, export formats,
upload matrix and troubleshooting go. The skill defers to `corgea skill
show` for the rest, and to `corgea --help` where that command does not
exist yet.

Widens the frontmatter description rather than narrowing it. The body
shrank, but this is now the entry point for the whole CLI, so the
trigger text has to cover the install gate, dependency inventory and
advisories as well as scanning.

Keeps the name: `npx skills add corgea/skills --skill corgea-scan` is
already published in the docs and the README.

Depends on a CLI release carrying `corgea skill show`; merging earlier
points users at a command their binary does not have.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Point corgea-scan at --help rather than a new CLI command

The pointer targeted `corgea skill show`, which does not exist yet and is no
longer being added: `corgea --help` is already compiled into the binary by
clap, already pinned to the installed version, and costs nothing.

Same shape as before — this file stays the lean entry point and defers the
detail — but the target is a command every released CLI already answers, so
this no longer waits on a release to be useful. Adds the version-skew
guidance: report an outdated CLI rather than upgrading unprompted, and treat
a surprising result as a version difference before a bug, since a changed
default will not error the way a missing flag does.

The long-tail reference now points at docs.corgea.app rather than at a second
copy of it.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
leenk7991 added a commit that referenced this pull request Aug 17, 2026
* Validate manifests, skills and README on every PR

The repo had no CI. A plugin name that stops matching its directory, or
a skill absent from the README table, breaks installs for users rather
than failing anything at build time, so nothing caught it before merge.

Checks the marketplace and plugin manifests describe the same plugins,
that shared metadata has not diverged (plugin.json wins at runtime, so
divergence ships the wrong version silently), that every SKILL.md has
frontmatter whose name matches its directory, and that the README table
and its relative links match what is on disk.

Also drops the $schema line from marketplace.json. The URL 404s, so it
was an editor hint pointing at nothing.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Tighten the source check, stop failing valid YAML and links

Three holes from review.

`source` only had to start with `./` and end in the plugin name, so
`./vendor/corgea` passed while living outside the tree every other check
walks — a plugin could ship without anything here having looked at it. It
must now equal `./plugins/<name>`.

Quoted frontmatter was compared as raw text, so `name: "corgea-scan"` failed
the directory check on a name that is correct. Quoting is optional in YAML;
one layer of matching quotes is now stripped, with `''` and backslash escapes
undone. A quoted wrong name still fails.

README links were checked whole, so any `#fragment` or `?query` read as part
of the filename and never resolved. Both are addressing within the target,
not part of the path, and are now dropped before the existence check and
before comparing a table row to its skill directory.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Reject frontmatter the reader cannot represent, require the README

The reader keeps anything it does not understand as text and then validates
that text as though it were the value, so `description: [a, b` passed as a
description beginning with '['. It now reads a scalar, quoted or not, and
rejects the rest by name: flow collections, block scalars, anchors, quotes
that are never closed, and unquoted values holding ': ' or ' #', which mean a
nested mapping and a comment to a real parser. Duplicate keys are rejected too
rather than letting the last one win. A rejected key is not then reported a
second time as missing.

A missing README.md skipped the skills table and every relative link, so a
repo whose entry point had been deleted validated clean. Both it and the
marketplace manifest are now required, and their absence says so instead of
surfacing as a JSON parse error.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Scope the skills table, check every row, keep links in the repo

Skill rows were matched across the whole README, so the first other table to
carry links in its left column would be read as a list of skills and fail on
every row of it. Only the table under `## Skills` is read now, and a README
without that section says so once rather than once per skill.

Rows were matched by name and only the first of them was checked, so a second
row could name a real skill while linking at a different one. Every row is
checked against the skill it names now, and a name listed twice is rejected.

Relative links were resolved without regard for where they landed, so `../`
above the checkout passed as long as the path existed on the machine running
the validator — while being broken for anyone reading the README on GitHub.
Links must now stay inside the repository.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add corgea-mcp and sighthound-rules skills (#6)

* Add corgea-mcp and sighthound-rules skills

Two capabilities the repo documented nowhere.

corgea-mcp covers the hosted MCP server: connecting, the CORGEA-TOKEN
header, and the ten read tools. Sourced from the published docs rather
than Corgea/mcp-server, which is private, has not been touched since
September, and still describes a local stdio server with three tools.
A skill written from it would document a product that no longer exists.

sighthound-rules covers rule authoring, which the sighthound skill
mentions in one line. The value is the parts a reader loses an hour to:
rules are RON and not YAML, --use-file-rules is required or edits are
ignored in favour of the rules compiled into the binary, and unknown
fields are dropped silently, so the unless: key in frontend_security.ron
is inert.

MCP is a separate plugin since it needs no CLI and authenticates
differently. Rules sit inside the sighthound plugin, being the same tool
and the same install.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Correct the taint example, field table and test loop

All five verified against the Sighthound source and, where runnable, against
the release binary.

The taint example was a bare rule tuple. Rule files deserialize into `Rules`,
whose list defaults to empty, so that shape parses cleanly and contributes
nothing — a search rule written this way exits 0 with `[]`. It is now wrapped,
and the trap is written up, including that `RULE_WRITING_GUIDE.md` shows a
bare tuple itself.

That example also filed `exec(` and `shell_exec(` under `cwe-89`, copying an
anomaly in `rules/php/taint.ron`. A rule spanning both sink classes has one
`cwe_id` to give them, so half its findings are misclassified. Split into a
SQL rule (`cwe-89`) and a command rule (`cwe-78`), each with matching
sanitizers; running both against a PHP fixture reports the two CWEs correctly.

The field table put severity's values on a row shared with `finding_type` and
`cwe_id`, which take Title Case phrases and lowercase `cwe-<number>`. Each now
has a row, with the `Medium` fallback severity and confidence take when unset.
`mode` is `#[serde(default = "default_search_mode")]`, so it was wrong to list
it as required.

The test loop called whatever `sighthound` is on `PATH`, right after building
the one that has your rules in it.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Take the token out of the config, split matching from metadata

The connect examples pasted the token straight into the file the token section
tells you never to put it in, and the Cursor one dressed it up as a variable:
it set `CORGEA_TOKEN` to a literal and referenced it as `${CORGEA_TOKEN}`,
which is not a syntax Cursor interpolates. Cursor resolves `${env:NAME}` in
`args`, `env`, `url` and `headers`, so the token now stays in the environment
and never reaches the file. Noted that Cursor reads its own environment, so a
GUI launch on macOS may not see a shell export until restarted, and that the
syntax belongs to the client rather than to MCP. Also called out
`.cursor/mcp.json` in the token section, since the project-local copy is the
one committed by accident.

`file_types` and `conditions` were filed under metadata, but both decide what
a rule matches — one picks the files it runs against, the other filters by AST
and context. Split the table in two, so the group to search when a rule fires
in the wrong place is the group that can cause it.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Give Claude Desktop its own config, separate the taint controls

"Same block as Cursor" was wrong: `${env:NAME}` is Cursor's syntax, and Claude
Desktop interpolates nothing. What resolves the placeholder there is mcp-remote,
which substitutes `${NAME}` in a header from its own `process.env`
(`src/lib/utils.ts`), so the value belongs in the `env` block. Cursor's spelling
does not fail loudly in that position — mcp-remote takes `env:CORGEA_TOKEN` as
the variable name, finds none, and sends the header empty — so the symptom is
written down next to the config that causes it. The token stays out of the
Cursor config, and the Claude Desktop file is a user-profile one, not a
repository one.

Both `--header` arguments also lost the space after the colon, which Cursor and
Claude Desktop on Windows mangle.

`sanitizers` and `propagators` were described as one thing that narrows
reported flows. Sanitizers do that. Propagators do nothing at all here:
`src/models.rs` declares the field and no other file under `src/` reads it,
which is why no rule in the repo sets one. They now have separate rows, and the
inert field is filed with `unless:` under the trap it belongs to.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Slim corgea-scan and point it at --help (#7)

* Point corgea-scan at the skill the CLI carries

The CLI now compiles its own skill into the binary and prints it with
`corgea skill show`, so the depth belongs there, pinned to the version
actually installed. Keeping a second copy here guarantees the two drift.

Cuts the body roughly in half: install, auth, and the commands worth
having loaded immediately stay, and the flag matrix, export formats,
upload matrix and troubleshooting go. The skill defers to `corgea skill
show` for the rest, and to `corgea --help` where that command does not
exist yet.

Widens the frontmatter description rather than narrowing it. The body
shrank, but this is now the entry point for the whole CLI, so the
trigger text has to cover the install gate, dependency inventory and
advisories as well as scanning.

Keeps the name: `npx skills add corgea/skills --skill corgea-scan` is
already published in the docs and the README.

Depends on a CLI release carrying `corgea skill show`; merging earlier
points users at a command their binary does not have.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Point corgea-scan at --help rather than a new CLI command

The pointer targeted `corgea skill show`, which does not exist yet and is no
longer being added: `corgea --help` is already compiled into the binary by
clap, already pinned to the installed version, and costs nothing.

Same shape as before — this file stays the lean entry point and defers the
detail — but the target is a command every released CLI already answers, so
this no longer waits on a release to be useful. Adds the version-skew
guidance: report an outdated CLI rather than upgrading unprompted, and treat
a surprising result as a version difference before a bug, since a changed
default will not error the way a missing flag does.

The long-tail reference now points at docs.corgea.app rather than at a second
copy of it.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants