snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
This commit is contained in:
86
.claude/scripts/check-config-sync.mjs
Executable file
86
.claude/scripts/check-config-sync.mjs
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env node
|
||||
// Verify that every agent-role referenced by a settings.json SubagentStop matcher
|
||||
// is a declared role in harness.config.json (config.roles). Claude Code requires
|
||||
// settings.json matchers to be literal strings (they cannot be computed from the
|
||||
// config), so this check is the bridge that keeps the two in sync: rename a role
|
||||
// in config AND settings -> the matcher token still resolves, pass; rename it in
|
||||
// config only -> the stale settings token is not a config role, fail.
|
||||
//
|
||||
// Usage: node .claude/scripts/check-config-sync.mjs [--app <repo>]
|
||||
// Exit 0 = in sync; exit 1 = drift (prints the offending tokens).
|
||||
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { loadConfig, roleNames } from "../hooks/lib/config.mjs";
|
||||
|
||||
function resolveRepo(argv) {
|
||||
const flag = argv.indexOf("--app");
|
||||
if (flag !== -1 && argv[flag + 1]) return argv[flag + 1];
|
||||
return process.env.APP_DIR || process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
||||
}
|
||||
|
||||
// SubagentStop matchers are role tokens (possibly `a|b`); PreToolUse/PostToolUse
|
||||
// matchers are tool names (Bash, Agent, Write|Edit) and are NOT roles, so only
|
||||
// SubagentStop is checked here.
|
||||
function settingsRoleTokens(settings) {
|
||||
const entries = settings.hooks?.SubagentStop ?? [];
|
||||
const tokens = new Set();
|
||||
for (const entry of entries) {
|
||||
const matcher = entry.matcher;
|
||||
if (!matcher || typeof matcher !== "string") continue;
|
||||
for (const t of matcher
|
||||
.split("|")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean)) {
|
||||
tokens.add(t);
|
||||
}
|
||||
}
|
||||
return [...tokens];
|
||||
}
|
||||
|
||||
export function checkConfigSync(repo) {
|
||||
const settingsPath = join(repo, ".claude", "settings.json");
|
||||
if (!existsSync(settingsPath)) {
|
||||
return { ok: false, error: `settings.json not found at ${settingsPath}` };
|
||||
}
|
||||
let settings;
|
||||
try {
|
||||
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
||||
} catch (e) {
|
||||
return {
|
||||
ok: false,
|
||||
error: `settings.json is not valid JSON: ${e.message}`,
|
||||
};
|
||||
}
|
||||
let roles;
|
||||
try {
|
||||
roles = new Set(roleNames(loadConfig(repo)));
|
||||
} catch (e) {
|
||||
return { ok: false, error: e.message };
|
||||
}
|
||||
const tokens = settingsRoleTokens(settings);
|
||||
const missing = tokens.filter((t) => !roles.has(t));
|
||||
return { ok: missing.length === 0, missing, tokens, roles: [...roles] };
|
||||
}
|
||||
|
||||
// Run as CLI when invoked directly (not when imported by a test).
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
const repo = resolveRepo(process.argv.slice(2));
|
||||
const r = checkConfigSync(repo);
|
||||
if (r.error) {
|
||||
console.error(`check-config-sync: ${r.error}`);
|
||||
process.exit(1);
|
||||
}
|
||||
if (!r.ok) {
|
||||
console.error(
|
||||
`check-config-sync: settings.json SubagentStop matcher(s) reference roles not in harness.config.json: ${r.missing.join(", ")}.\n` +
|
||||
`Declared roles: ${r.roles.join(", ")}.\n` +
|
||||
`Rename the role in BOTH files, or add it to config.roles.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
process.stdout.write(
|
||||
`check-config-sync: OK (${r.tokens.length} role matcher(s) all declared)\n`,
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user