Repository navigation
feat(skills): custom skills from user folders, config paths and --skill-file (#79) - #91
Merged
Merged
Conversation
karthickmk2001
force-pushed
the
feat/79-custom-skills
branch
from
November 11, 2026 21:32
9c4a05a to
74fa7fe
Compare
…ll-file (#79) Load skills from ~/.secfoo/skills, [skills] paths, SECFOO_SKILLS_PATH and secfoo run --skill-file -- never from the scan target. Custom skills may reuse a built-in's output contract and findings lifecycle (output: sast) without ever closing the built-in scan's findings. Malformed or clashing user skills are skipped with a warning naming the files; built-ins still fail hard; user folders reload on mtime change. Adds secfoo skills list/new/validate/show, runs.skill_version/skill_source/skill_sha256 with a migration, a Custom skills sidebar group and picker badge, docs/SKILLS.md, examples/skills/ and a CI validation step. Closes #79 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
karthickmk2001
force-pushed
the
feat/79-custom-skills
branch
from
November 11, 2026 21:36
74fa7fe to
5c4ed74
Compare
CI's 80-column terminal wrapped long temp paths, splitting phrases like 'missing frontmatter' across lines. Run the CLI wide and compare whitespace-collapsed output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Leaderboard update
karthickmk2001 now has 31 points (rank #1, Bronze). 19 more to reach Silver. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #79
What does this change, and why?
Users can add a skill by dropping a Markdown file in a folder. It shows up in
secfoo run --skill,--help, the dashboard and assessments, with no code change and no rebuild. The guide is indocs/SKILLS.md, with two complete examples inexamples/skills/.Where skills load from (
skills/loader.py), all merged:$SECFOO_HOME/skills/*.md.[skills] pathsin config.SECFOO_SKILLS_PATH(os.pathsep-separated).secfoo run --skill-file ./x.md.Never from the target. None of these locations comes from the scan target. A test plants
.secfoo/skills/andskills/in a target,chdirs into it, and checks that neither is loaded and thatexecute_runsrefuses the skill id.File format: the built-ins' frontmatter, plus optional
outputandcategory, and#comment lines.output: generic(the default) uses the generic contract.output: <built-in id>reuses that skill's output contract and findings lifecycle.runner.pynow dispatches onskill.output_typeinstead of the skill id, sooutput: sastfindings land insast_findingsand the SAST dashboard.close_stale=False. Its report covers only what that review looked at, so it must never close findings the built-in scan recorded. A test covers this.Validation and failure handling:
idmust be lowercase kebab-case,versionan integer,outputgenericor a built-in id, and the body non-empty.secfoo servepicks up new or edited files. The sidebar global is now evaluated per render rather than once at import.CLI:
secfoo skills list | new <id> | validate [PATH...] | show <id> [--target], as specified.validateexits 1 on any problem, and CI now runssecfoo skills validate examples/skills.secfoo runaccepts--skill-file, and exits 2 if neither--skillnor--skill-fileis given.Traceability:
runs.skill_version,skill_source(builtin/user) andskill_sha256(hash of the definition file) are added toschema.sql, with an idempotent migration in_RUNS_MIGRATIONS. They're recorded on every run and shown in the run receipt on the run page.Dashboard:
category. It only appears when custom skills exist.Test isolation: a new autouse fixture in
tests/conftest.pypointsSECFOO_HOME, the config path andSECFOO_SKILLS_PATHat an empty folder, so a developer's own skills can't leak into tests.Not in this PR: pushing custom-skill runs to the enterprise portal with their output type. The portal ingest still dispatches by skill id. Happy to follow up.
Testing
pytest testspasses. 1052 passed locally. The only failures are the 4 existing Windows-only POSIX permission and symlink tests that fail onmaintoo; Linux CI is unaffected.ruff check .adds no new findings in changed files.tests/test_custom_skills.py(31 tests) for everything the issue's Done when lists:paths,SECFOO_SKILLS_PATHand--skill-filesecfoo skills listkeeps working.secfoo/skills/being ignoredoutput: sastlanding insast_findings, and a custom SAST run not closing built-in findingsskillscommands and the bundled examples validating🤖 Generated with Claude Code