mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-06-16 22:33:35 +00:00
Compare commits
6 Commits
fix-2099-t
...
bump-2-0-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17b532f92e | ||
|
|
3d368d2972 | ||
|
|
84011d43b1 | ||
|
|
2a822c0787 | ||
|
|
a40c9f1e83 | ||
|
|
c7a3e2ffa0 |
@@ -2170,7 +2170,7 @@
|
||||
{
|
||||
"name": "security-guidance",
|
||||
"description": "Security review for Claude-generated code. Pattern-based warnings on edits, LLM-powered diff review on Stop, and an agentic commit reviewer that catches injection, XSS, SSRF, hardcoded secrets, and 25+ other vulnerability classes.",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"author": {
|
||||
"name": "Anthropic",
|
||||
"email": "support@anthropic.com"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "security-guidance",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"description": "Security review for Claude-generated code. Pattern-based warnings on edits, LLM-powered diff review on Stop, and an agentic commit reviewer that catches injection, XSS, SSRF, hardcoded secrets, and 25+ other vulnerability classes.",
|
||||
"author": {
|
||||
"name": "David Dworken",
|
||||
|
||||
@@ -355,9 +355,9 @@ def _list_untracked(cwd):
|
||||
the holdouts."""
|
||||
try:
|
||||
repo = _git_toplevel(cwd) or cwd
|
||||
# core.quotePath=false comes from GIT_CMD globally (see gitutil.py).
|
||||
r = subprocess.run(
|
||||
[*GIT_CMD, "-c", "core.quotePath=false", "ls-files",
|
||||
"--others", "--exclude-standard", "-z"],
|
||||
[*GIT_CMD, "ls-files", "--others", "--exclude-standard", "-z"],
|
||||
cwd=repo, capture_output=True, timeout=15,
|
||||
)
|
||||
if r.returncode != 0:
|
||||
|
||||
@@ -26,6 +26,17 @@ GIT_CMD = [
|
||||
"git",
|
||||
"-c", "core.fsmonitor=false",
|
||||
"-c", "core.hooksPath=/dev/null",
|
||||
# core.quotePath=false: emit raw UTF-8 in path-emitting commands instead
|
||||
# of C-quoting non-ASCII bytes (default `"\\303\\201vila/..."` vs
|
||||
# `Ávila/...`). Downstream parsers — both ours (parse_diff_into_files,
|
||||
# extract_file_paths_from_diff) and Python stdlib (os.path.isabs,
|
||||
# os.path.join) — expect raw paths and silently drop / mishandle the
|
||||
# quoted form. Adding the flag globally to GIT_CMD covers every
|
||||
# subprocess.run site that uses the splat — diff feeders, rev-parse
|
||||
# path queries (--show-toplevel, --git-dir, --git-common-dir),
|
||||
# reflog %gs subjects, ls-files, status, etc. — without per-site
|
||||
# flag duplication. See #2082, #2099.
|
||||
"-c", "core.quotePath=false",
|
||||
]
|
||||
|
||||
|
||||
@@ -222,15 +233,12 @@ def _git_diff_range(repo_root, base, head="HEAD"):
|
||||
them reviewed — otherwise unreviewed commits get permanently silenced.
|
||||
"""
|
||||
try:
|
||||
# core.quotePath=false makes git emit raw UTF-8 in `diff --git a/... b/...`
|
||||
# headers instead of C-quoting non-ASCII path bytes (`"a/\303\201vila/..."`
|
||||
# vs `a/Ávila/...`). The downstream `re.match(r'^a/(.+?) b/(.+)$', ...)`
|
||||
# in parse_diff_into_files / extract_file_paths_from_diff matches the
|
||||
# raw form only — quoted headers slip past and the entire file is
|
||||
# silently dropped from review. See #2082 (sibling of #2056 / #2075).
|
||||
# GIT_CMD globally passes core.quotePath=false (see definition) so
|
||||
# non-ASCII paths in `diff --git a/... b/...` headers come through as
|
||||
# raw UTF-8, not C-quoted. Required by the downstream
|
||||
# parse_diff_into_files / extract_file_paths_from_diff regex.
|
||||
r = subprocess.run(
|
||||
[*GIT_CMD, "-c", "core.quotePath=false",
|
||||
"diff", "-p", "--no-color", "--no-ext-diff", base, head],
|
||||
[*GIT_CMD, "diff", "-p", "--no-color", "--no-ext-diff", base, head],
|
||||
cwd=repo_root, capture_output=True, timeout=30,
|
||||
)
|
||||
if r.returncode != 0:
|
||||
@@ -355,8 +363,9 @@ def _git_name_only(cwd, base, include_untracked=False):
|
||||
# result.stdout=None, and propagate AttributeError out of the helper.
|
||||
# Same fix shape as diffstate._list_untracked. See #2056.
|
||||
def _run(env):
|
||||
# core.quotePath=false comes from GIT_CMD globally (see definition).
|
||||
result = subprocess.run(
|
||||
[*GIT_CMD, "-c", "core.quotePath=false", "diff", "--name-only", "-z", base],
|
||||
[*GIT_CMD, "diff", "--name-only", "-z", base],
|
||||
cwd=cwd, capture_output=True, timeout=30,
|
||||
env=env,
|
||||
)
|
||||
@@ -393,9 +402,9 @@ def _git_status_porcelain(cwd):
|
||||
# sibling helpers — a non-ASCII path in the worktree would otherwise
|
||||
# crash the cp1252 reader thread on Windows. See #2056.
|
||||
try:
|
||||
# core.quotePath=false comes from GIT_CMD globally (see definition).
|
||||
r = subprocess.run(
|
||||
[*GIT_CMD, "-c", "core.quotePath=false", "status",
|
||||
"--porcelain=v1", "-uall", "-z"],
|
||||
[*GIT_CMD, "status", "--porcelain=v1", "-uall", "-z"],
|
||||
cwd=cwd, capture_output=True, timeout=30,
|
||||
)
|
||||
if r.returncode != 0:
|
||||
@@ -471,11 +480,8 @@ def get_git_diff(cwd, baseline_sha, full_context=False, paths=None, untracked_pa
|
||||
# change exists to fix.
|
||||
return ""
|
||||
|
||||
# core.quotePath=false: emit raw UTF-8 in `diff --git a/... b/...` headers
|
||||
# so non-ASCII paths aren't C-quoted past the downstream parse_diff_into_files
|
||||
# regex. See #2082 (sibling of #2056 / #2075).
|
||||
cmd = [*GIT_CMD, "-c", "core.quotePath=false",
|
||||
"diff", "--no-color", "--no-ext-diff", baseline_sha] + (["--unified=99999"] if full_context else []) + pathspec
|
||||
# core.quotePath=false comes from GIT_CMD globally (see definition).
|
||||
cmd = [*GIT_CMD, "diff", "--no-color", "--no-ext-diff", baseline_sha] + (["--unified=99999"] if full_context else []) + pathspec
|
||||
try:
|
||||
with _temp_index(cwd, untracked_paths) as env:
|
||||
# env is None when no index could be found (bare repo / not a
|
||||
|
||||
@@ -479,10 +479,21 @@ def _call_claude(prompt, output_schema, thinking_budget=10000, max_tokens=16000,
|
||||
"max_tokens": max_tokens,
|
||||
"system": CLAUDE_CODE_SYSTEM_PROMPT,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"output_format": {
|
||||
"type": "json_schema",
|
||||
"schema": output_schema
|
||||
}
|
||||
# API moved the structured-output schema from top-level `output_format`
|
||||
# to `output_config.format` per
|
||||
# https://platform.claude.com/docs/en/build-with-claude/structured-outputs.
|
||||
# The old form "continues to work for a transition period" for some
|
||||
# auth modes (API key + non-streaming), but is rejected with
|
||||
# `invalid_request_error: output_format: This field is deprecated.
|
||||
# Use 'output_config.format' instead.` for others (OAuth Bearer +
|
||||
# newer CLI versions hit it consistently — reporter saw 462 errors
|
||||
# in one day). See #2098.
|
||||
"output_config": {
|
||||
"format": {
|
||||
"type": "json_schema",
|
||||
"schema": output_schema,
|
||||
},
|
||||
},
|
||||
}
|
||||
if thinking_budget > 0:
|
||||
# Models trained on adaptive thinking (4.6+) reject the budget_tokens
|
||||
@@ -490,7 +501,10 @@ def _call_claude(prompt, output_schema, thinking_budget=10000, max_tokens=16000,
|
||||
# models (4.5 and earlier, all 3.x) reject adaptive. Pick by model.
|
||||
if _model_supports_adaptive_thinking(payload["model"]):
|
||||
payload["thinking"] = {"type": "adaptive"}
|
||||
payload["output_config"] = {"effort": "high"}
|
||||
# Merge `effort` into the existing output_config dict (which
|
||||
# now carries the `format` schema) rather than reassigning —
|
||||
# otherwise the schema is silently overwritten. See #2098.
|
||||
payload["output_config"]["effort"] = "high"
|
||||
else:
|
||||
payload["thinking"] = {
|
||||
"type": "enabled",
|
||||
|
||||
@@ -1197,18 +1197,18 @@ def handle_commit_review_posttooluse(input_data):
|
||||
# core.quotePath=false: emit raw UTF-8 in `diff --git a/... b/...`
|
||||
# headers so non-ASCII paths aren't C-quoted past the downstream
|
||||
# parse_diff_into_files regex (sibling of #2056 / #2075). See #2082.
|
||||
# core.quotePath=false comes from GIT_CMD globally (see gitutil.py).
|
||||
if pre_amend_sha:
|
||||
# Delta review: pre-amend → post-amend. `git diff` (not show)
|
||||
# so the output is a pure unified diff with no commit header.
|
||||
result = subprocess.run(
|
||||
[*GIT_CMD, "-c", "core.quotePath=false",
|
||||
"diff", "--no-color", "--no-ext-diff", pre_amend_sha, sha, "--"],
|
||||
[*GIT_CMD, "diff", "--no-color", "--no-ext-diff",
|
||||
pre_amend_sha, sha, "--"],
|
||||
cwd=repo_root, capture_output=True, timeout=15
|
||||
)
|
||||
else:
|
||||
result = subprocess.run(
|
||||
[*GIT_CMD, "-c", "core.quotePath=false",
|
||||
"show", "-p", "--no-color", "--no-ext-diff", sha, "--"],
|
||||
[*GIT_CMD, "show", "-p", "--no-color", "--no-ext-diff", sha, "--"],
|
||||
cwd=repo_root, capture_output=True, timeout=15
|
||||
)
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
|
||||
|
||||
Reference in New Issue
Block a user