CodeVetter · Repo Unpack · Extension points
anthropics/claude-code
New product behaviour is supposed to arrive as a plugin (markdown command, agent, skill, or hooks.json command) registered in marketplace.json, or as another event subscription inside a mod's register. The engine nouns are extended by declaration merging on EngineInterface. Diff reserves a compile-time probe set for non-git VCS. security-guidance and hookify are the two user-file extension mechanisms. Organizations move sec-default by listing prependPlugins.
- Marketplace registration is the plugins array in .claude-plugin/marketplace.json. Each entry has name, description, source (a ./plugins/<dir> path), and category. plugins/README.md specifies the folder contract: .claude-plugin/plugin.json, optional commands/, agents/, skills/, hooks/, .mcp.json, and README.md.
- A function-hook plugin's entry is hooks/hooks.json modules: ["./register.ts"] and export function register(on). diff, telemetry, agents-md, and sec-default all follow that shape. New events are additional on('event.name', matcher, handler) calls. The matcher objects in this repo include {component}, {command}, {id}, {plugin}, {requestId}, {tool}, {fork}, and {instructionFiles}.
- Adding a noun on $ is a types contract: a .d.ts with no imports that exports the noun's types and uses declare module 'claude-code' { interface EngineInterface { ... } }. telemetry/plugin.json points types at ./types/index.d.ts. Callers include that folder via tsconfig; they must not copy the types.
- agents-md is configured without code changes: pluginConfigs['agents-md@builtin'].options.instructionFiles in user, --settings, or managed settings (not project .claude/settings.json). The four legal strings are listed on userConfig.options in plugin.json. An unknown hand-typed value is told once and read as the default.
- Organization seating of sec-default is the managed prependPlugins list. If that list is set, it replaces the whole prepend tier and the org must name sec-default@builtin to keep the default. Example from the README: ["acme-guard@acme-tools", "sec-default@builtin"].
- Non-git diff backends plug in by adding a BackendProbe to INSTALLED_BACKEND_PROBES before register runs. backendOf asks those probes in insertion order and only then Git.gitBackendOf. The set is empty as published; tests pass probes into backendOf directly instead of mutating the set.
- security-guidance user extension is two additive files, discovered user then project then project-local: claude-security-guidance.md (prompt text, cannot suppress built-in findings) and security-patterns.yaml or .json (regex/substring rules merged with SECURITY_PATTERNS). Built-in patterns cannot be disabled individually; ENABLE_PATTERN_RULES=0 disables all pattern checks. Managed-settings delivery of these files is not supported.
- hookify rules are markdown files matching .claude/hookify.*.local.md with YAML frontmatter (name, enabled, event, action warn|block, tool_matcher, pattern or conditions[{field, operator, pattern}]). The RuleEngine is the evaluator. Examples live in plugins/hookify/examples (dangerous-rm.local.md, sensitive-files-warning.local.md, require-tests-stop.local.md, console-log-warning.local.md).
- Slash commands are markdown files under commands/ with YAML frontmatter (description, argument-hint, allowed-tools). Agents are markdown under agents/. Skills are SKILL.md plus references. frontend-design is a skill with no command, meant to be auto-invoked. Output-style plugins are only a SessionStart shell hook (explanatory-output-style and learning-output-style).
- Classic command hooks, as opposed to function hooks, are JSON in hooks/hooks.json with keys SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, and Stop. Each hook has type command, a command string that may use ${CLAUDE_PLUGIN_ROOT}, optional timeout, matcher, if, asyncRewake, rewakeMessage. security-guidance, hookify, ralph-wiggum, and the two output-style plugins use this format. The four mods use the modules array format instead.
- Issue-bot behaviour is extended by editing the lifecycle table, not by scattering day counts. scripts/issue-lifecycle.ts is the single source imported by sweep.ts and lifecycle-comment.ts. Triage label policy is the prompt .claude/commands/triage-issue.md. New gh operations must go through scripts/gh.sh's allowlist (issue view, issue list, search issues, label list) or a new capped script listed in CLAUDE_CODE_SCRIPT_CAPS.
- Enterprise policy extension points documented as examples, not code registries: permissions.deny/ask, allowManagedPermissionRulesOnly, allowManagedHooksOnly, strictKnownMarketplaces, sandbox.network.allowedDomains, and MDM payloads for com.anthropic.claudecode (macOS) and HKLM\SOFTWARE\Policies\ClaudeCode\Settings (Windows).