From dark-factory
When writing hooks or other structured data into .claude/settings.json, always read the existing file, merge new entries, and deduplicate — never overwrite the whole file.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dark-factory:additive-merge-settings-jsonThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Any time a script or agent needs to add entries to `.claude/settings.json` — particularly the `hooks` key — without clobbering existing entries that were placed there by the user, another plugin, or a previous run.
Any time a script or agent needs to add entries to .claude/settings.json — particularly the hooks key — without clobbering existing entries that were placed there by the user, another plugin, or a previous run.
Read the existing file if it exists; treat a missing file as an empty object {}:
import json
from pathlib import Path
settings_path = Path(project_dir) / ".claude" / "settings.json"
settings = {}
if settings_path.exists():
with open(settings_path, "r") as f:
settings = json.load(f)
Navigate to the target key without replacing sibling keys:
if "hooks" not in settings:
settings["hooks"] = {}
existing = settings["hooks"]
Append new entries; deduplicate by the field that uniquely identifies an entry. For hook entries, deduplicate by exact command string across all matcher objects in the event list:
command_str = f"bash {hook_path}"
already_present = any(
entry.get("command") == command_str
for matcher_obj in existing.get(event_type, [])
for entry in matcher_obj.get("hooks", [])
)
if not already_present:
existing.setdefault(event_type, []).append({
"matcher": "",
"hooks": [{"type": "command", "command": command_str}]
})
Write the full settings dict back (not just the mutated sub-key):
settings["hooks"] = existing
settings_path.parent.mkdir(parents=True, exist_ok=True)
with open(settings_path, "w") as f:
json.dump(settings, f, indent=2)
settings dict back to disk, not just the sub-key you modified. Writing only settings["hooks"] to the file would delete all other top-level keys (e.g., permissions, model).settings_path.parent.mkdir(parents=True, exist_ok=True) handles the case where .claude/ does not yet exist.gen-hooks runs) produces only one entry. If you need multiple different matchers for the same script, they will have different matcher values and will both be kept.settings.json likely indicates a user error that should not be masked.scripts/gen_hooks.py (mergeIntoSettings function).npx claudepluginhub lewibs/dark-factory --plugin dark-factoryFetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Applies a firm's KYC/AML rules grid to parsed onboarding records: assigns risk rating, checks required documents, outputs rule outcomes with citations, and routes for escalation.
Generates daily or weekly digests of activity from connected sources (chat, email, docs, tasks, CRM), highlighting action items, decisions, mentions, and project updates.