incident-response
Turn a flagged npm supply-chain finding — or just a vague, non-technical description of one ("this package looks sketchy," "someone said we got hacked," "npm install did something weird") — into concrete remediation steps. Use whenever the user wants to know what to actually do about a suspicious/compromised/flagged package, however precisely or vaguely they describe it — not for the initial trust/vulnerability investigation itself (see package-trust-check/dependency-audit for that).
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-11
- Stars
- ★ 1.6k
- Forks
- 474
01 前言 Front Matter
- name
- incident-response
- description
- Turn a flagged npm supply-chain finding — or just a vague, non-technical description of one ("this package looks sketchy," "someone said we got hacked," "npm install did something weird") — into concrete remediation steps. Use whenever the user wants to know what to actually do about a suspicious/compromised/flagged package, however precisely or vaguely they describe it — not for the initial trust/vulnerability investigation itself (see package-trust-check/dependency-audit for that).
02 资源文件 1
- 参考文档references/test-prompts.md11.7 KB
03 SKILL.md 正文
NPMScan incident response
Use this skill once the user wants to know what to actually do about a
supply-chain concern, not just what was found — whether that concern is a
precise tool finding already in this conversation, or just a worried,
non-technical description of a symptom. Most users will not know terms like
"lifecycle script" or a rule id, and will not think to run an npmscan tool
themselves first — reformulating a vague description into the right call is
this skill's job, not something to push back on the user for. This is the
last step, not a replacement for package-trust-check (single-package trust
questions) or dependency-audit (multi-package audits): those skills
investigate and report; this one turns a concern — precise or vague — into
an actionable plan.
Connecting the npmscan tools
This skill calls the npmscan MCP server's tools (listed under "Tools used"
below). They only read public package data: no API key or account, nothing is
installed or changed on the user's machine, and the only server contacted is
https://npmscan.com/api/mcp.
- Claude Code, Codex, Gemini CLI, Kimi, Grok: the npmscan plugin connects the server for you.
- OpenClaw:
openclaw mcp add npmscan --url https://npmscan.com/api/mcp --transport streamable-http, thenopenclaw mcp doctor npmscan --probeto check it. - Any other MCP client: add a remote (streamable HTTP) server with that URL.
Some clients prefix tool names with the server name (for example
npmscan__get_package). If the tools aren't available at all, tell the user
how to connect them for their client instead of answering from memory.
Reading a vague or non-technical request
Do not require the user to already know a rule id, a playbook name, or
npmscan's own vocabulary. Translate what they actually said using their
intent, not their exact words. Common shapes and what they map to:
| What the user says (any rough equivalent) | What to do |
|---|---|
| Names a specific package and says it's "sketchy," "hacked," "compromised," or just "is this safe" | Run package-trust-check's investigation first (get_package, check_maintainer_changes, check_package_provenance, analyze_install_script as applicable) — you need real findings before a remediation plan means anything. Once findings exist, continue to step 2 below. |
| Names a package AND describes a specific symptom ("it downloads something during install," "the maintainer changed") | Run the one finding tool that actually checks that symptom (analyze_install_script for install-time behavior, check_maintainer_changes for ownership, check_package_provenance for publish/build mismatches) rather than the full trust-check sweep — faster, and still grounds the answer in a real finding. |
| Describes a symptom with NO package name — "what do we do about a postinstall that downloads a binary," "how do we respond to a typosquat," "what's the process for a maintainer takeover" | No finding tool has anything to check. Go straight to get_remediation_playbook({ id: "..." }) with your best-guess playbook id from the table below. A wrong guess is harmless — it comes back matched: false — so guess confidently rather than asking the user to be more specific first. |
| Totally generic, no package, no symptom — "we got a security alert, what do I do," "help, is this bad" | The one case worth a single clarifying question: ask what specifically happened or which package/alert, since there is nothing yet to ground a plan in. Don't guess a playbook id from nothing. |
Symptom → playbook id guesses for the no-package-name case:
- downloads/runs a binary, executable, or installer during install →
postinstall-binary - name looks like / is close to a well-known package, "typosquat," "fake version of X" →
suspected-typosquat - general "hacked," "compromised," "malicious code," "supply chain attack" with no more specific detail →
supply-chain-compromise - "we published something we didn't," "our npm token was stolen," "our package got hijacked," a worm spreading through packages we maintain (Shai-Hulud) — the user is the PUBLISHER, not a consumer →
compromised-publisher(token revocation, credential rotation, deprecating/unpublishing the bad versions, telling users). If both apply — they installed something malicious AND it then published from their account — present both playbooks. - runs shell commands,
exec, spawns a process during install →child-process-in-install - "calls out," "connects to a server," "phones home" during install →
unexpected-network-install - "new maintainer," "ownership changed," "ownership transfer," "ex-employee's account" →
maintainer-change-flagged - "provenance," "build doesn't match the repo," "install script wasn't in the source," "someone bypassed CI" →
provenance-mismatch
Steps
- Read the request per the table above. If a finding already exists in
this conversation (a prior
analyze_install_script,check_maintainer_changes, orcheck_package_provenanceresult), skip straight to step 2 with itsfindings[].rulevalue(s). - Call
get_remediation_playbook({ rules: [...] })with every distinctrulevalue from the finding(s) in one call — it batches and deduplicates, so don't call it once per rule. Useidinstead for a symptom-only request with no live finding (see the table above). - If the underlying finding's
riskTiercame backnone(or the findings array was empty), say plainly that no remediation is needed rather than still calling this tool to manufacture a plan — an incident-response playbook implies there's something to respond to. - For each
matched: trueresult, present that playbook'stitle,severity, andstepsdirectly in your answer — the steptextplus itswhy, in order — not a paraphrase and not just a link. Lead with the match's ownsituationNotewhen one exists (what this specific rule actually found) before the steps, so the response is grounded in the real finding rather than reading as generic boilerplate — this matters most when a batch has several different rules landing on the same playbook (see step 6). If you got here from anidguess rather than a real finding (nosituationNote), say so plainly ("this sounds like it might be X — here's that playbook; tell me more if it's actually something else") rather than presenting a guess as a confirmed diagnosis. Close with the playbook'spreventionTipswhen the user's question has any forward-looking angle ("how do we stop this happening again," a policy/CI question, or just naturally as part of a full incident report), and cite itsreferences(each labeledincidentorreading) so the user can verify the real-world grounding themselves — don't call anincidentreference a "reading" or vice versa, that distinction is deliberate. Include thenpmscanUrltoo so the user can also read it on the docs site. - For any
matched: falseresult, say so plainly using the tool's ownnote(e.g. "this finding is baseline/informational, not something with its own response plan") — don't silently drop it or invent generic advice in its place. If your ownidguess came back unmatched, try the next-closest guess from the table, or ask the one clarifying question from the "totally generic" row rather than giving up. - When a findings array maps to more than one distinct playbook (e.g. a
check_maintainer_changesresult with both a turnover finding and a repository-transfer finding pointing at the same playbook, or a mixed maintainer + provenance investigation pointing at two different ones), present each matched playbook once, not once per originating finding.
Do not
-
Do not write your own remediation steps once a finding tool has run — call
get_remediation_playbookand use its actualsteps/whytext, don't paraphrase or improvise around it. -
Do not refuse to help, or ask the user to look up a
rule/playbook id themselves, just because their request was vague — that is exactly the case the table above exists for. Only ask a clarifying question in the genuinely-nothing-to-go-on case. -
Do not treat
matched: falseas "this is safe" — it means no dedicated playbook exists for that specific rule, which is a different statement than "no risk here." Say what the tool'snoteactually says. -
Do not skip a finding tool and go straight to an
idguess when the user named a specific package — a guess is only for the no-package-name, symptom-only case. When a package is named, ground the answer in a real finding first. -
Do not present an
id-guessed playbook as if it were a confirmed diagnosis — say plainly that it's your best read of their description. -
Do not call
get_remediation_playbookonce per rule when a findings array has several — batch all the rule values into one call'srulesarray. -
Do not force a playbook onto a clean/
none-risk-tier result just because the user asked "what should I do" — say no action is needed. -
Do not embellish a playbook's
referencesbeyond what's returned — cite only thelabel/urlthe tool gave you, and preserve whether the tool marked itincident(a real, verified compromise) orreading(background material, not itself a breach) rather than upgrading areadingreference into a claimed incident. -
Do not answer a "we were the ones who got compromised" description with only the consumer-side
supply-chain-compromisesteps — pinning and auditing don't revoke a stolen token; usecompromised-publisher. -
Do not attempt to install, upgrade, or publish packages yourself; this skill only reads data through NPMScan's read-only MCP tools.
Tools used
get_remediation_playbook, plus whichever of analyze_install_script,
check_maintainer_changes, check_package_provenance is needed to produce
the finding this skill responds to — all provided by the npmscan MCP server bundled with this plugin
(.mcp.json). See references/test-prompts.md
for prompts to manually verify this skill after installing or editing it.
04 同仓库更多 Skills
migrate-to-e2e
Moves an existing Playwright, Cypress, Selenium, Appium, Detox, Maestro, or TesterArmy suite to e2e one slice at a time, with the old suite running beside the new one until each ported test is proven. Keeps a MIGRATION.md progress file so any later session resumes where the last stopped. Optionally plants a defect to show both suites catch it. Use for /migrate-to-e2e, "migrate our tests to e2e", "port these Maestro flows", "move our TesterArmy tests", or when a project has an e2e config and an older suite still running.
e2e
Writes, runs, and debugs end-to-end tests for web and mobile apps with e2e, the agentic test runner, which mixes agent.act goals with exact locator assertions on a Playwright browser or an iOS or Android device. Also drives a project's running app live over the e2e MCP server to look at a screen, check a UI change, take a screenshot or record a video, and try a locator; and runs bug bashes, parallel e2e explore runs with each bug proven by a repro test. Use when a project depends on e2e or has an e2e.config.ts, when asked for end-to-end, browser, mobile, or agentic UI tests, to check a change in the running app, to QA or bug bash an app or branch, or when an e2e run fails.
create-verification-skill
Generate a project-local verify-<app> skill on top of e2e, so any coding agent can launch the app, check it is worth driving, exercise a feature the way a user does, keep evidence, and bug bash it. Writes the skill, a feature map with one explore charter per feature, and proves it once. Use for /create-verification-skill, "make a verification skill for this repo", or when a project has no scripted way to prove UI behavior.
deja-search
deja-vu memory — search the user's past AI coding sessions with the deja CLI. Holds what they already settled and never wrote into the repo (naming rules, banned or already-tried tools, required checks before merge, preferred values, who owns what). Use before your first edit in a task, before you call a change done or ready to merge, before you recommend a tool, library, design or reviewer, before re-debugging an error that may already be solved, when they say 'didn't we fix this before', 'what did we decide about X' or 'I already have that', and before telling them something on this machine does not exist.
deja-reflect
End-of-session reflection and memory curation with deja-vu. Review what was decided, what commands broke and what repaired them, and record durable project rules or decisions with deja remember so the next session starts with them.
revid
Make, edit, export and post AI videos with Revid (revid.ai) through the Revid MCP server. Use whenever the user wants a short-form or long-form video made (from an idea, a script, a URL, an article, a PDF, a tweet, a product page, their own clips, or a song), wants to find what is going viral on TikTok, YouTube, Instagram or X before making something, wants to edit or re-export an existing Revid project, generate a standalone AI image or clip, make a series episode, or publish and schedule a finished video to connected social accounts. Covers setup (hosted MCP with OAuth, or an API key), the 36 tools, credits, polling and the rules for publishing. Routes to the more specific revid-* skills when one fits.