Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1866,7 +1866,7 @@ jobs:
py=$(printf '%s\n' "$notrun" | grep -E '\.py$' || true)
rest=$(printf '%s\n' "$notrun" | grep -Ev '(^$|\.py$)' || true)
if [ -n "$py" ]; then
printf '%s\n' "$py" | tr '\n' '\0' | xargs -0 python -m pytest -q --
printf '%s\n' "$py" | tr '\n' '\0' | xargs -0 python -m pytest -q -o tmp_path_retention_policy=none --
fi
if [ -n "$rest" ]; then
printf '%s\n' "$rest" >"$RUNNER_TEMP/outside-node-paths.txt"
Expand Down
2 changes: 1 addition & 1 deletion lib/hook-utils.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,7 @@ fi
FAKEBIN17="$(make_stub_bin)"
run17b() {
local args="$1"
CLAUDE_PLUGIN_DATA="$(mktemp -d)" "$BASH" -c '
CLAUDE_PLUGIN_DATA="$(mktemp -d "$WORK/data17b.XXXXXX")" "$BASH" -c '
PATH="'"$FAKEBIN17"'"
source "'"$HOOK_DIR"'/hook-utils.sh"
hook::require_jq_blocking '"$args"'
Expand Down
2 changes: 1 addition & 1 deletion plugins/actionlint/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "actionlint",
"version": "0.11.3",
"version": "0.11.4",
"description": "Lint GitHub Actions workflow files on edit via actionlint, surfacing findings as advisory context.",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/actionlint/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to the `actionlint` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.11.4] - 2026-09-30

### Changed

- Test-only: the suites remove their temporary directories on exit. No behavior change.

## [0.11.3] - 2026-09-30

### Changed
Expand Down
8 changes: 4 additions & 4 deletions plugins/actionlint/hooks/actionlint-check.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ ERRBIN="$(mktemp -d "$WORK/errbin.XXXXXX")"
wrap_real_tools "$ERRBIN"
printf '#!/bin/sh\necho "fatal: simulated actionlint failure" >&2\nexit 3\n' >"$ERRBIN/actionlint"
chmod +x "$ERRBIN/actionlint"
ERR_TEL="$(mktemp)"
ERR_TEL="$(mktemp "$WORK/tel.XXXXXX")"
ERR_SINK="$(make_sink "cat >\"$ERR_TEL\"")"
OUT_ERR=$(
cd "$UNRELATED" || exit 1
Expand Down Expand Up @@ -273,7 +273,7 @@ else
fi

# --- Stub sink + violation -> envelope status ok with findings --------------
TEL="$(mktemp)"
TEL="$(mktemp "$WORK/tel.XXXXXX")"
SINK="$(make_sink "cat >\"$TEL\"")"
run_hook_env "$REPO/.github/workflows/violation.yml" CLAUDE_PLUGIN_OPTION_ACTIONLINT_ENABLED=true HOOK_TELEMETRY_SINK="$SINK" >/dev/null
wait_for_sink "$TEL"
Expand All @@ -293,7 +293,7 @@ fi
rm -f "$TEL"

# --- Stub sink + clean file -> status ok, findings [] -----------------------
TELC="$(mktemp)"
TELC="$(mktemp "$WORK/tel.XXXXXX")"
SINKC="$(make_sink "cat >\"$TELC\"")"
run_hook_env "$REPO/.github/workflows/clean.yml" CLAUDE_PLUGIN_OPTION_ACTIONLINT_ENABLED=true HOOK_TELEMETRY_SINK="$SINKC" >/dev/null
wait_for_sink "$TELC"
Expand All @@ -309,7 +309,7 @@ rm -f "$TELC"
# The fake-bin dir shadows actionlint. First run must emit the skip notice on
# both channels; a second run in the same session (same CLAUDE_PLUGIN_DATA +
# session_id) must be silent; telemetry still records status "skipped".
ABSENT_TEL="$(mktemp)"
ABSENT_TEL="$(mktemp "$WORK/tel.XXXXXX")"
ABSENT_SINK="$(make_sink "cat >\"$ABSENT_TEL\"")"
FAKEBIN="$(mktemp -d "$WORK/fakebin.XXXXXX")"
wrap_real_tools "$FAKEBIN"
Expand Down
2 changes: 1 addition & 1 deletion plugins/ai-briefing/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "ai-briefing",
"version": "0.7.47",
"version": "0.7.48",
"description": "Build source-backed AI-industry briefings from official vendor publications, configured RSS/Atom feeds, GitHub releases, reputable secondary reporting, and user-supplied URLs. Deduplicate, rank, and present results as markdown or optional HTML/PPTX decks, with repository-owned profile, audience, and brand configuration. Automated X/Twitter collection is disabled; Playwright is used only for deterministic local rendering.",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/ai-briefing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to the `ai-briefing` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.7.48] - 2026-09-30

### Changed

- Test-only: the suites remove their temporary directories on exit. No behavior change.

## [0.7.47] - 2026-09-29

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { mkdtempSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
import { mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import test from "node:test";
import test, { after } from "node:test";
import { pathToFileURL } from "node:url";

const buildDir = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
const script = path.join(buildDir, "emit-slides-data.js");

const scratchDirs = [];
after(() => {
for (const dir of scratchDirs) rmSync(dir, { recursive: true, force: true });
});

function scratch(prefix) {
const dir = mkdtempSync(path.join(tmpdir(), prefix));
scratchDirs.push(dir);
return dir;
}

function run(args, env = {}) {
return spawnSync(process.execPath, [script, ...args], {
encoding: "utf8",
Expand Down Expand Up @@ -38,7 +49,7 @@ test("a missing briefing exits 1", () => {
});

test("argv writes slides-data.js and formats an ASCII-arrow window", () => {
const root = mkdtempSync(path.join(tmpdir(), "slides-"));
const root = scratch("slides-");
const briefing = path.join(root, "briefing.md");
const out = path.join(root, "slides-data.js");
writeFileSync(
Expand Down Expand Up @@ -68,7 +79,7 @@ test("argv writes slides-data.js and formats an ASCII-arrow window", () => {
});

test("runs as the entrypoint through a symlinked build directory", () => {
const link = path.join(mkdtempSync(path.join(tmpdir(), "emit-link-")), "build");
const link = path.join(scratch("emit-link-"), "build");
symlinkSync(buildDir, link, "junction");
const missing = path.join(tmpdir(), "no-such-briefing.md");
const result = spawnSync(
Expand Down
2 changes: 1 addition & 1 deletion plugins/claude-config/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "claude-config",
"version": "0.55.1",
"version": "0.55.2",
"description": "Nine configuration-health skills (plus setup) for a repo's Claude Code configuration: audit (settings.json / .mcp.json / hooks / plugins / permissions drift), audit-automation-gaps (evidence-gated verdicts on automation gaps), audit-permission-grants (allow-rule / allowed-tools grants for auto-mode durability and portability), audit-permission-state (the permission rules actually in effect: every settings scope merged with per-rule provenance, what auto mode drops on entry, config written where nothing reads it, and which managed intents are enforced versus loosenable), draft-auto-mode-rules (interview and draft a paste-ready autoMode classifier block; prints only, never writes), audit-instructions (locally-owned instruction surfaces vs current model capability, proposing removals/rewrites of instructions the model no longer needs, and detecting cross-surface instruction conflicts), audit-prompting-postures (the additive lane: posture guidance the prompting guide says a component's purpose needs but the component does not carry), audit-pass (one coordinated, ordered, resumable pass over a named target: three-scope inventory, run-time-derived exclusion set, stable finding identity, suppression memory, resume, one human gate, delegating every check to the plugin that owns it), and unhobble (the empirical bare-baseline experiment: reversibly strip a repo's standing instructions, log real stumbles against the current model, re-add only what evidence earns).",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/claude-config/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to the `claude-config` plugin are documented here. Format fo

Versions 0.51.8 to 0.51.9 and 0.51.11 to 0.51.14 were reserved by parallel branches and never released.

## [0.55.2] - 2026-09-30

### Changed

- `automode-entry-diff.sh --oracle` removes its scratch directory on exit; the suites remove their temporary directories.

## [0.55.1] - 2026-09-30

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ EOF
echo "oracle UNAVAILABLE: could not create a scratch directory — the prediction above stands, uncorroborated."
exit 0
}
trap 'rm -rf "$scratch"' EXIT
capture="$scratch/capture.log"
# `--permission-mode auto` is passed so the probe does not depend on the
# consumer's own defaultMode. What was actually MEASURED is narrower than that
Expand Down
2 changes: 1 addition & 1 deletion plugins/code-metrics/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "code-metrics",
"version": "0.4.4",
"version": "0.4.5",
"description": "Read-only code measures for a change, with cited references and no verdict: lines per file (audit-size), cyclomatic, cognitive, and Halstead complexity (audit-complexity), duplication with sanctioned-replication exclusions (audit-duplication), coverage per function with CRAP from existing lcov, Cobertura, coverage.py, or Go artifacts (audit-coverage), type debt for TypeScript and Python (audit-type-debt), the literacy router for what each number can and cannot say (principles), and a setup skill for the consumer's .claude/code-metrics.yaml. Runs external collectors only when they already resolve, never installs, never runs tests, never emits a finding.",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/code-metrics/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to the `code-metrics` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.4.5] - 2026-09-30

### Changed

- README: the pytest command passes `-o tmp_path_retention_policy=none` so test directories are not kept under `$TMPDIR`.

## [0.4.4] - 2026-09-30

### Fixed
Expand Down
7 changes: 4 additions & 3 deletions plugins/code-metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,12 @@ is named explicitly or listed under `coverage.artifacts` in the configuration.
## Testing the plugin

The Python suites are the `test_*.py` files beside the scripts they cover, and `python3 -m pytest -q`
from this directory runs all of them. To measure them, run the same command under coverage.py from
this directory:
from this directory runs all of them. Add `-o tmp_path_retention_policy=none` so pytest deletes each
test's `tmp_path` directories instead of keeping the last three runs under `$TMPDIR/pytest-of-<user>`.
To measure them, run the same command under coverage.py from this directory:
Comment thread
kyle-sexton marked this conversation as resolved.

```shell
python3 -m coverage run -m pytest -q && python3 -m coverage json
python3 -m coverage run -m pytest -q -o tmp_path_retention_policy=none && python3 -m coverage json
```

The `.coveragerc` here sets `source = .`, so every module under the plugin is reported whether or
Expand Down
2 changes: 1 addition & 1 deletion plugins/docs-hygiene/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "docs-hygiene",
"version": "0.23.20",
"version": "0.23.21",
"description": "Documentation-hygiene toolkit: compress (flavor-trim markdown with a semantic-diff safety net), audit-noise (classify markdown noise), extract-ssot (deduplicate repeated content into a single source of truth), audit-encapsulation (detect citations into skill-private surfaces), rename-references (sweep stale references after renames), audit-derivability (classify whether a whole document earns its existence: could a fresh agent re-derive it from the code?), audit-progressive-disclosure (grade instruction files against a load-tier model for split opportunities and hub/spoke disclosure defects), write-for-agents (authoring-time doctrine that fires while agent-consumed markdown is being written), write-for-humans (the same moment for the other reader, covering end-user READMEs, RFCs, release notes and guides, and resolving the consuming project's own style guide first), and a file-name set that plans, applies, and enforces a casing rule across a doc tree: setup (the one configuration surface), audit-file-names (read-only inventory plus the reference sweep), realign-file-names (the executor, one human acceptance per file), and generate-file-name-gate (emits the standalone check that keeps the tree from drifting back).",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/docs-hygiene/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog: docs-hygiene plugin

## [0.23.21] - 2026-09-30

### Changed

- Test-only: the suites remove their temporary directories on exit. No behavior change.

## [0.23.20] - 2026-09-29

### Changed
Expand Down
13 changes: 7 additions & 6 deletions plugins/docs-hygiene/skills/compress/scripts/audit-scan.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ assert_classify "lean fixture classifies SKIP" '| SKIP |' "$FIX/audit-fixture-di
# is already absolute, so invoking the scanner with that path would match the
# old `*/.claude/rules/` glob and never exercise the repo-relative arm. Run
# from the temp dir with the relative argument the matcher is supposed to see.
RULES_REL="$(mktemp -d)"
SCRATCH="$(mktemp -d)"
trap 'rm -rf "$SCRATCH"' EXIT
RULES_REL="$SCRATCH/rules"
mkdir -p "$RULES_REL/.claude/rules"
printf '# rule\n\njust really basically actually simply perhaps somewhat very quite might note that keep in mind\n' >"$RULES_REL/.claude/rules/example.md"
# Enough flavor tokens that a missed signal-1 would fall through to COMPRESS
Expand All @@ -61,32 +63,31 @@ case "$out4" in
*'author-time-disciplined path (signal 1)'*) ok "repo-relative .claude/rules classifies as signal 1" ;;
*) fail "repo-relative .claude/rules should be signal 1 (got: $out4)" ;;
esac
rm -rf "$RULES_REL"

# Five path refs on one line, ~500 words: line-count density is 1*1000/500 = 2
# (COMPRESS), occurrence density is 5*1000/500 = 10 > 8 (UNCERTAIN). Flavor
# tokens keep the file out of the flavor-density SKIP. The scanner itself must
# classify — a regex-only check never exercises path_dens.
OCC="$(mktemp -d)"
OCC="$SCRATCH/occ"
mkdir -p "$OCC"
write_padded_md "$OCC/occ.md" \
'see docs/a.md and docs/b.md and docs/c.md and docs/d.md and docs/e.md. just really basically ' 480
out_occ="$(bash "$SCAN" "$OCC/occ.md" 2>/dev/null)" || true
case "$out_occ" in
*'| UNCERTAIN |'*'cross-ref density'*) ok "one-line path refs classify UNCERTAIN by occurrence density" ;;
*) fail "one-line path refs should classify UNCERTAIN (got: $out_occ)" ;;
esac
rm -rf "$OCC"

# `@docs/a.md` is one occurrence. The old `(@|path.ext)` regex emitted `@` and
# `docs/a.md`, doubling density over the 8/kw threshold at ~200 words.
AT="$(mktemp -d)"
AT="$SCRATCH/at"
mkdir -p "$AT"
write_padded_md "$AT/at.md" 'see @docs/a.md on one line. just really ' 200
out_at="$(bash "$SCAN" "$AT/at.md" 2>/dev/null)" || true
case "$out_at" in
*'| COMPRESS |'*) ok "@-prefixed path ref counts as one occurrence (COMPRESS)" ;;
*) fail "@-prefixed path ref should classify COMPRESS, not double-count (got: $out_at)" ;;
esac
rm -rf "$AT"

if [[ $FAIL -ne 0 ]]; then
echo "$FAIL check(s) failed." >&2
Expand Down
2 changes: 1 addition & 1 deletion plugins/firecrawl/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "firecrawl",
"version": "0.5.20",
"version": "0.5.21",
"description": "Web scraping, search, crawling, and file parsing through the firecrawl-cli binary with a write-to-disk-then-Read pattern that keeps large results out of context: a user-facing wrapper skill, a lazy-install setup skill, and a separate gated maintainer update skill tracking the upstream CLI and skill source.",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/firecrawl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to the `firecrawl` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.5.21] - 2026-09-30

### Changed

- Test-only: the suites remove their temporary directories on exit. No behavior change.

## [0.5.20] - 2026-09-29

### Added
Expand Down
5 changes: 2 additions & 3 deletions plugins/firecrawl/skills/update/scripts/update.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ assert_contains "unknown flag mentions expected modes" "$unknown_out" "expected"
# --- 3. Source-guard: helpers callable when sourced ------------------------------

# Sourcing installs the script's own EXIT trap (cleanup of its TMPDIR_RUN); the
# test tmpdir is removed explicitly at the end instead of via trap.
# trap set after it replaces that one and removes both directories.
# shellcheck source=update.sh
source "$SCRIPT" 2>/dev/null
SOURCED_TMPDIR="$TMPDIR_RUN"
trap 'rm -rf "$TEST_TMPDIR" "$SOURCED_TMPDIR"' EXIT
if declare -F recorded_field >/dev/null; then
pass "source-guard: helpers exposed after source"
else
Expand Down Expand Up @@ -118,8 +119,6 @@ assert_eq "sha256 helper matches direct call" "$sha_direct" "$sha_via_helper"

# --- Final report ---------------------------------------------------------------------

rm -rf "$TEST_TMPDIR" "$SOURCED_TMPDIR"

if [[ "$FAILED" -eq 0 ]]; then
printf '\nAll %d checks passed.\n' "$CASE_NUM"
exit 0
Expand Down
2 changes: 1 addition & 1 deletion plugins/instruction-placement/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "instruction-placement",
"version": "0.16.5",
"version": "0.16.6",
"description": "Routes agent-instruction content to the surface that loads it at the right moment. The audit skill sweeps a repository's instruction layer and its ordinary markdown for content whose scope is narrower than the surface carrying it, meaning conventions keyed to one file type or one subtree sitting in an always-loaded CLAUDE.md or AGENTS.md, and for normative conventions stranded in documentation Claude never loads at all, then classifies each against a routing rubric and proposes a destination whose `paths:` glob is machine-validated before it is ever offered. Safety-class content (irreversible actions, secrets, data integrity, external publication, compliance, agent authority) is hard-denied from demotion and reported as held back rather than proposed, because demotion trades guaranteed presence for conditional presence: a deferred surface is absent until a read matches it, absent after a compaction until that trigger recurs, and never inherited by a subagent, which re-acquires it only by reading a covered path itself. Every accepted move regenerates an always-loaded index of deferred surfaces, which is what keeps a demoted rule discoverable from any context that has not happened to touch a path it covers. The audit is read-only and emits a diffable findings artifact; realignment is a separate skill gated per item with no blanket-approve path; a deterministic check skill gates that every rule glob still resolves and the index is current; a migrate skill moves a repository to AGENTS.md as the content home and keeps a CLAUDE.md shim while one is needed; and a setup skill verifies the one thing no other gate can see: that nothing in the repository stops Claude Code reading the index target, since a CLAUDE.md in the working directory or above it is read instead of the AGENTS.md beside it.",
"author": {
"name": "Melodic Software",
Expand Down
6 changes: 6 additions & 0 deletions plugins/instruction-placement/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to the `instruction-placement` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.16.6] - 2026-09-30

### Changed

- `cutover-check.sh` removes its action-map temp file when the release-map parse fails; the suites remove their temporary directories.

## [0.16.5] - 2026-09-30

### Changed
Expand Down
Loading
Loading