@softspark/ai-toolkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +412 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +632 -0
- package/action.yml +53 -0
- package/app/.claude-plugin/plugin.json +44 -0
- package/app/ARCHITECTURE.md +306 -0
- package/app/CLAUDE.md.template +23 -0
- package/app/agents/ai-engineer.md +128 -0
- package/app/agents/backend-specialist.md +193 -0
- package/app/agents/business-intelligence.md +54 -0
- package/app/agents/chaos-monkey.md +67 -0
- package/app/agents/chief-of-staff.md +51 -0
- package/app/agents/code-archaeologist.md +127 -0
- package/app/agents/code-reviewer.md +184 -0
- package/app/agents/command-expert.md +131 -0
- package/app/agents/data-analyst.md +205 -0
- package/app/agents/data-scientist.md +151 -0
- package/app/agents/database-architect.md +317 -0
- package/app/agents/debugger.md +238 -0
- package/app/agents/devops-implementer.md +194 -0
- package/app/agents/documenter.md +364 -0
- package/app/agents/explorer-agent.md +145 -0
- package/app/agents/fact-checker.md +172 -0
- package/app/agents/frontend-specialist.md +209 -0
- package/app/agents/game-developer.md +216 -0
- package/app/agents/incident-responder.md +226 -0
- package/app/agents/infrastructure-architect.md +127 -0
- package/app/agents/infrastructure-validator.md +247 -0
- package/app/agents/llm-ops-engineer.md +237 -0
- package/app/agents/mcp-expert.md +228 -0
- package/app/agents/mcp-server-architect.md +195 -0
- package/app/agents/mcp-testing-engineer.md +292 -0
- package/app/agents/meta-architect.md +58 -0
- package/app/agents/ml-engineer.md +136 -0
- package/app/agents/mobile-developer.md +190 -0
- package/app/agents/night-watchman.md +55 -0
- package/app/agents/nlp-engineer.md +154 -0
- package/app/agents/orchestrator.md +437 -0
- package/app/agents/performance-optimizer.md +254 -0
- package/app/agents/predictive-analyst.md +57 -0
- package/app/agents/product-manager.md +194 -0
- package/app/agents/project-planner.md +287 -0
- package/app/agents/prompt-engineer.md +103 -0
- package/app/agents/qa-automation-engineer.md +182 -0
- package/app/agents/rag-engineer.md +201 -0
- package/app/agents/research-synthesizer.md +138 -0
- package/app/agents/search-specialist.md +101 -0
- package/app/agents/security-architect.md +62 -0
- package/app/agents/security-auditor.md +293 -0
- package/app/agents/seo-specialist.md +111 -0
- package/app/agents/system-governor.md +57 -0
- package/app/agents/tech-lead.md +62 -0
- package/app/agents/technical-researcher.md +103 -0
- package/app/agents/test-engineer.md +264 -0
- package/app/constitution.md +38 -0
- package/app/hooks/_profile-check.sh +11 -0
- package/app/hooks/guard-destructive.sh +74 -0
- package/app/hooks/guard-path.sh +73 -0
- package/app/hooks/post-tool-use.sh +35 -0
- package/app/hooks/pre-compact.sh +31 -0
- package/app/hooks/quality-check.sh +22 -0
- package/app/hooks/quality-gate.sh +49 -0
- package/app/hooks/save-session.sh +24 -0
- package/app/hooks/session-end.sh +37 -0
- package/app/hooks/session-start.sh +29 -0
- package/app/hooks/subagent-start.sh +16 -0
- package/app/hooks/subagent-stop.sh +16 -0
- package/app/hooks/track-usage.sh +50 -0
- package/app/hooks/user-prompt-submit.sh +25 -0
- package/app/hooks.json +178 -0
- package/app/mcp-defaults.json +23 -0
- package/app/output-styles/golden-rules.md +43 -0
- package/app/plugins/README.md +19 -0
- package/app/plugins/csharp-pack/README.md +11 -0
- package/app/plugins/csharp-pack/plugin.json +18 -0
- package/app/plugins/enterprise-pack/README.md +16 -0
- package/app/plugins/enterprise-pack/hooks/output-style.sh +6 -0
- package/app/plugins/enterprise-pack/hooks/status-line.sh +8 -0
- package/app/plugins/enterprise-pack/plugin.json +24 -0
- package/app/plugins/frontend-pack/README.md +14 -0
- package/app/plugins/frontend-pack/plugin.json +22 -0
- package/app/plugins/java-pack/README.md +11 -0
- package/app/plugins/java-pack/plugin.json +18 -0
- package/app/plugins/kotlin-pack/README.md +11 -0
- package/app/plugins/kotlin-pack/plugin.json +18 -0
- package/app/plugins/memory-pack/README.md +24 -0
- package/app/plugins/memory-pack/hooks/observation-capture.sh +67 -0
- package/app/plugins/memory-pack/hooks/session-summary.sh +71 -0
- package/app/plugins/memory-pack/plugin.json +22 -0
- package/app/plugins/memory-pack/scripts/init_db.py +81 -0
- package/app/plugins/memory-pack/scripts/strip_private.py +22 -0
- package/app/plugins/memory-pack/skills/mem-search/SKILL.md +70 -0
- package/app/plugins/research-pack/README.md +14 -0
- package/app/plugins/research-pack/plugin.json +22 -0
- package/app/plugins/ruby-pack/README.md +11 -0
- package/app/plugins/ruby-pack/plugin.json +18 -0
- package/app/plugins/rust-pack/README.md +11 -0
- package/app/plugins/rust-pack/plugin.json +18 -0
- package/app/plugins/security-pack/README.md +15 -0
- package/app/plugins/security-pack/plugin.json +23 -0
- package/app/plugins/swift-pack/README.md +11 -0
- package/app/plugins/swift-pack/plugin.json +18 -0
- package/app/rules/claude-toolkit-rules.md +21 -0
- package/app/rules/git-conventions.md +5 -0
- package/app/rules/quality-gates.md +10 -0
- package/app/skills/_lib/__init__.py +1 -0
- package/app/skills/_lib/detect_utils.py +150 -0
- package/app/skills/agent-creator/SKILL.md +82 -0
- package/app/skills/analyze/SKILL.md +92 -0
- package/app/skills/analyze/scripts/complexity.py +165 -0
- package/app/skills/api-patterns/SKILL.md +305 -0
- package/app/skills/app-builder/SKILL.md +187 -0
- package/app/skills/architecture-audit/SKILL.md +141 -0
- package/app/skills/architecture-decision/SKILL.md +55 -0
- package/app/skills/architecture-decision/templates/adr-template.md +36 -0
- package/app/skills/biz-scan/SKILL.md +30 -0
- package/app/skills/briefing/SKILL.md +27 -0
- package/app/skills/build/SKILL.md +97 -0
- package/app/skills/build/scripts/detect-build.py +151 -0
- package/app/skills/chaos/SKILL.md +32 -0
- package/app/skills/ci/SKILL.md +77 -0
- package/app/skills/ci/scripts/ci-detect.py +135 -0
- package/app/skills/ci/templates/github-actions-node.yml +38 -0
- package/app/skills/ci/templates/github-actions-python.yml +42 -0
- package/app/skills/ci-cd-patterns/SKILL.md +299 -0
- package/app/skills/clean-code/SKILL.md +110 -0
- package/app/skills/clean-code/reference/dart.md +18 -0
- package/app/skills/clean-code/reference/go.md +23 -0
- package/app/skills/clean-code/reference/php.md +32 -0
- package/app/skills/clean-code/reference/python.md +180 -0
- package/app/skills/clean-code/reference/typescript.md +26 -0
- package/app/skills/command-creator/SKILL.md +83 -0
- package/app/skills/commit/SKILL.md +98 -0
- package/app/skills/commit/scripts/pre-commit-check.py +87 -0
- package/app/skills/commit/templates/conventional-commit.md +52 -0
- package/app/skills/csharp-patterns/SKILL.md +450 -0
- package/app/skills/database-patterns/SKILL.md +297 -0
- package/app/skills/debug/SKILL.md +154 -0
- package/app/skills/debug/scripts/error-parser.py +187 -0
- package/app/skills/debugging-tactics/SKILL.md +136 -0
- package/app/skills/deploy/SKILL.md +130 -0
- package/app/skills/deploy/scripts/pre_deploy_check.py +171 -0
- package/app/skills/deploy/templates/deployment-checklist.md +31 -0
- package/app/skills/design-an-interface/SKILL.md +105 -0
- package/app/skills/design-engineering/SKILL.md +260 -0
- package/app/skills/docker-devops/SKILL.md +303 -0
- package/app/skills/docs/SKILL.md +145 -0
- package/app/skills/docs/scripts/doc-inventory.py +176 -0
- package/app/skills/docs/templates/adr-template.md +36 -0
- package/app/skills/docs/templates/readme-template.md +67 -0
- package/app/skills/documentation-standards/SKILL.md +191 -0
- package/app/skills/ecommerce-patterns/SKILL.md +209 -0
- package/app/skills/evaluate/SKILL.md +132 -0
- package/app/skills/evolve/SKILL.md +27 -0
- package/app/skills/explain/SKILL.md +54 -0
- package/app/skills/explain/scripts/dependency-graph.py +215 -0
- package/app/skills/explore/SKILL.md +112 -0
- package/app/skills/explore/scripts/visualize.py +117 -0
- package/app/skills/fix/SKILL.md +78 -0
- package/app/skills/fix/scripts/error-classifier.py +191 -0
- package/app/skills/flutter-patterns/SKILL.md +254 -0
- package/app/skills/git-mastery/SKILL.md +70 -0
- package/app/skills/grill-me/SKILL.md +38 -0
- package/app/skills/health/SKILL.md +91 -0
- package/app/skills/health/scripts/health_check.py +162 -0
- package/app/skills/hive-mind/SKILL.md +56 -0
- package/app/skills/hook-creator/SKILL.md +107 -0
- package/app/skills/index/SKILL.md +74 -0
- package/app/skills/instinct-review/SKILL.md +77 -0
- package/app/skills/java-patterns/SKILL.md +442 -0
- package/app/skills/kotlin-patterns/SKILL.md +446 -0
- package/app/skills/lint/SKILL.md +103 -0
- package/app/skills/lint/scripts/detect-linters.py +112 -0
- package/app/skills/mcp-patterns/SKILL.md +270 -0
- package/app/skills/mem-search/SKILL.md +70 -0
- package/app/skills/migrate/SKILL.md +90 -0
- package/app/skills/migrate/scripts/migration-status.py +195 -0
- package/app/skills/migration-patterns/SKILL.md +260 -0
- package/app/skills/night-watch/SKILL.md +28 -0
- package/app/skills/observability-patterns/SKILL.md +203 -0
- package/app/skills/onboard/SKILL.md +76 -0
- package/app/skills/orchestrate/SKILL.md +86 -0
- package/app/skills/panic/SKILL.md +30 -0
- package/app/skills/performance-profiling/SKILL.md +59 -0
- package/app/skills/plan/SKILL.md +110 -0
- package/app/skills/plan/templates/plan-template.md +40 -0
- package/app/skills/plan-writing/SKILL.md +201 -0
- package/app/skills/plugin-creator/SKILL.md +78 -0
- package/app/skills/pr/SKILL.md +129 -0
- package/app/skills/pr/scripts/pr-summary.py +175 -0
- package/app/skills/prd-to-issues/SKILL.md +108 -0
- package/app/skills/prd-to-plan/SKILL.md +120 -0
- package/app/skills/predict/SKILL.md +30 -0
- package/app/skills/qa-session/SKILL.md +110 -0
- package/app/skills/rag-patterns/SKILL.md +203 -0
- package/app/skills/refactor/SKILL.md +124 -0
- package/app/skills/refactor/scripts/refactor-scan.py +210 -0
- package/app/skills/refactor-plan/SKILL.md +112 -0
- package/app/skills/repeat/SKILL.md +149 -0
- package/app/skills/research-mastery/SKILL.md +56 -0
- package/app/skills/review/SKILL.md +141 -0
- package/app/skills/review/scripts/diff-analyzer.py +170 -0
- package/app/skills/rollback/SKILL.md +87 -0
- package/app/skills/rollback/scripts/rollback_info.py +149 -0
- package/app/skills/ruby-patterns/SKILL.md +454 -0
- package/app/skills/rust-patterns/SKILL.md +446 -0
- package/app/skills/search/SKILL.md +64 -0
- package/app/skills/security-patterns/SKILL.md +91 -0
- package/app/skills/security-patterns/reference/authentication.md +37 -0
- package/app/skills/security-patterns/reference/authorization.md +22 -0
- package/app/skills/security-patterns/reference/input-validation.md +30 -0
- package/app/skills/security-patterns/reference/oauth-csrf-audit.md +131 -0
- package/app/skills/skill-creator/SKILL.md +154 -0
- package/app/skills/skill-creator/templates/dashboard/index.html +130 -0
- package/app/skills/skill-creator/templates/reasoning-engine/assets/example.json +12 -0
- package/app/skills/skill-creator/templates/reasoning-engine/search.py +110 -0
- package/app/skills/subagent-development/SKILL.md +225 -0
- package/app/skills/subagent-development/reference/code-quality-reviewer-prompt.md +145 -0
- package/app/skills/subagent-development/reference/implementer-prompt.md +118 -0
- package/app/skills/subagent-development/reference/spec-reviewer-prompt.md +100 -0
- package/app/skills/swarm/SKILL.md +81 -0
- package/app/skills/swift-patterns/SKILL.md +500 -0
- package/app/skills/tdd/SKILL.md +174 -0
- package/app/skills/tdd/reference/deep-modules.md +32 -0
- package/app/skills/tdd/reference/interface-design.md +32 -0
- package/app/skills/tdd/reference/mocking.md +52 -0
- package/app/skills/tdd/reference/refactoring.md +10 -0
- package/app/skills/tdd/reference/tests.md +59 -0
- package/app/skills/teams/SKILL.md +101 -0
- package/app/skills/test/SKILL.md +107 -0
- package/app/skills/test/scripts/detect-runner.py +113 -0
- package/app/skills/testing-patterns/SKILL.md +73 -0
- package/app/skills/testing-patterns/reference/flutter-testing.md +33 -0
- package/app/skills/testing-patterns/reference/go-testing.md +52 -0
- package/app/skills/testing-patterns/reference/php-phpunit.md +39 -0
- package/app/skills/testing-patterns/reference/python-pytest.md +228 -0
- package/app/skills/testing-patterns/reference/typescript-vitest.md +50 -0
- package/app/skills/triage-issue/SKILL.md +120 -0
- package/app/skills/typescript-patterns/SKILL.md +256 -0
- package/app/skills/ubiquitous-language/SKILL.md +74 -0
- package/app/skills/verification-before-completion/SKILL.md +108 -0
- package/app/skills/workflow/SKILL.md +250 -0
- package/app/skills/write-a-prd/SKILL.md +129 -0
- package/app/skills/write-a-prd/reference/visual-companion.md +78 -0
- package/app/skills/write-a-prd/scripts/frame-template.html +111 -0
- package/app/skills/write-a-prd/scripts/visual-server.cjs +79 -0
- package/app/templates/skill/generator/SKILL.md.template +40 -0
- package/app/templates/skill/knowledge/SKILL.md.template +52 -0
- package/app/templates/skill/linter/SKILL.md.template +34 -0
- package/app/templates/skill/reviewer/SKILL.md.template +51 -0
- package/app/templates/skill/workflow/SKILL.md.template +49 -0
- package/benchmarks/README.md +111 -0
- package/benchmarks/ecosystem-dashboard.json +148 -0
- package/benchmarks/ecosystem-harvest.json +148 -0
- package/benchmarks/results.json +38 -0
- package/benchmarks/run.py +351 -0
- package/bin/ai-toolkit.js +345 -0
- package/kb/best-practices/README.md +11 -0
- package/kb/howto/README.md +11 -0
- package/kb/procedures/maintenance-sop.md +306 -0
- package/kb/reference/agents-catalog.md +124 -0
- package/kb/reference/anti-pattern-registry-format.md +221 -0
- package/kb/reference/architecture-overview.md +232 -0
- package/kb/reference/benchmark-config.md +62 -0
- package/kb/reference/ci-integration.md +66 -0
- package/kb/reference/claude-ecosystem-benchmark-snapshot.md +80 -0
- package/kb/reference/claude-ecosystem-expansion-foundations.md +102 -0
- package/kb/reference/commands-catalog.md +21 -0
- package/kb/reference/distribution-model.md +63 -0
- package/kb/reference/global-install-model.md +56 -0
- package/kb/reference/hierarchical-override-pattern.md +200 -0
- package/kb/reference/hooks-catalog.md +306 -0
- package/kb/reference/integrations.md +88 -0
- package/kb/reference/language-packs.md +52 -0
- package/kb/reference/merge-friendly-install-model.md +58 -0
- package/kb/reference/plugin-pack-conventions.md +151 -0
- package/kb/reference/quick-wins-implementation-summary.md +70 -0
- package/kb/reference/skill-templates.md +50 -0
- package/kb/reference/skills-catalog.md +215 -0
- package/kb/reference/skills-unification.md +57 -0
- package/kb/reference/stats.md +69 -0
- package/kb/reference/sync.md +76 -0
- package/kb/troubleshooting/README.md +11 -0
- package/llms-full.txt +3068 -0
- package/llms.txt +39 -0
- package/package.json +75 -0
- package/scripts/_common.py +160 -0
- package/scripts/add_rule.py +50 -0
- package/scripts/benchmark_config.py +127 -0
- package/scripts/benchmark_ecosystem.py +288 -0
- package/scripts/check_deps.py +260 -0
- package/scripts/create_skill.py +118 -0
- package/scripts/doctor.py +504 -0
- package/scripts/eject.py +113 -0
- package/scripts/emission.py +256 -0
- package/scripts/evaluate_skills.py +260 -0
- package/scripts/frontmatter.py +58 -0
- package/scripts/generate_agents_md.py +91 -0
- package/scripts/generate_aider_conf.py +51 -0
- package/scripts/generate_cline.py +35 -0
- package/scripts/generate_copilot.py +30 -0
- package/scripts/generate_cursor_rules.py +35 -0
- package/scripts/generate_gemini.py +28 -0
- package/scripts/generate_llms_txt.py +164 -0
- package/scripts/generate_roo_modes.py +80 -0
- package/scripts/generate_windsurf.py +35 -0
- package/scripts/generator_base.py +140 -0
- package/scripts/harvest_ecosystem.py +50 -0
- package/scripts/inject_rule_cli.py +101 -0
- package/scripts/inject_section_cli.py +47 -0
- package/scripts/injection.py +180 -0
- package/scripts/install.py +236 -0
- package/scripts/install_git_hooks.py +71 -0
- package/scripts/install_steps/__init__.py +5 -0
- package/scripts/install_steps/ai_tools.py +261 -0
- package/scripts/install_steps/hooks.py +90 -0
- package/scripts/install_steps/markers.py +79 -0
- package/scripts/install_steps/symlinks.py +87 -0
- package/scripts/merge-hooks.py +192 -0
- package/scripts/plugin.py +642 -0
- package/scripts/plugin_schema.py +138 -0
- package/scripts/remove_rule.py +58 -0
- package/scripts/stats.py +81 -0
- package/scripts/sync.py +215 -0
- package/scripts/uninstall.py +292 -0
- package/scripts/validate.py +700 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Merge ai-toolkit hooks into a settings.json file (or strip them).
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
merge-hooks.py inject <toolkit-hooks.json> <target-settings.json>
|
|
6
|
+
merge-hooks.py strip <target-settings.json>
|
|
7
|
+
|
|
8
|
+
inject: Reads toolkit hooks (tagged with "_source": "ai-toolkit"),
|
|
9
|
+
removes any previous toolkit entries from target's "hooks" key,
|
|
10
|
+
appends current toolkit entries, and writes the result.
|
|
11
|
+
Preserves all other keys in the target settings file.
|
|
12
|
+
Creates target with just {"hooks": ...} if missing.
|
|
13
|
+
|
|
14
|
+
strip: Removes all entries with "_source": "ai-toolkit" from target's
|
|
15
|
+
"hooks" key. Removes the "hooks" key if empty. Never deletes
|
|
16
|
+
the target file (it may contain other settings).
|
|
17
|
+
|
|
18
|
+
Exit codes:
|
|
19
|
+
0 success
|
|
20
|
+
1 usage error
|
|
21
|
+
2 JSON parse error
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import json
|
|
26
|
+
import os
|
|
27
|
+
import sys
|
|
28
|
+
|
|
29
|
+
SOURCE_TAG = "ai-toolkit"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def load_json(path: str) -> dict:
|
|
33
|
+
"""Load and parse a JSON file.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
path: Filesystem path to the JSON file.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Parsed JSON content as a dictionary.
|
|
40
|
+
"""
|
|
41
|
+
with open(path) as f:
|
|
42
|
+
return json.load(f)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def save_json(path: str, data: dict) -> None:
|
|
46
|
+
"""Write a dictionary to a JSON file with 4-space indent and trailing newline.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
path: Filesystem path for the output JSON file.
|
|
50
|
+
data: Dictionary to serialize.
|
|
51
|
+
"""
|
|
52
|
+
with open(path, "w") as f:
|
|
53
|
+
json.dump(data, f, indent=4, ensure_ascii=False)
|
|
54
|
+
f.write("\n")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _is_toolkit_entry(entry: dict) -> bool:
|
|
58
|
+
"""Check if a hook entry (at any nesting level) is from ai-toolkit."""
|
|
59
|
+
if entry.get("_source") == SOURCE_TAG:
|
|
60
|
+
return True
|
|
61
|
+
# Check nested hooks array for _source tag
|
|
62
|
+
for hook in entry.get("hooks", []):
|
|
63
|
+
if isinstance(hook, dict) and hook.get("_source") == SOURCE_TAG:
|
|
64
|
+
return True
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def strip_toolkit(hooks: dict) -> dict:
|
|
69
|
+
"""Remove all entries tagged with _source == SOURCE_TAG."""
|
|
70
|
+
result = {}
|
|
71
|
+
for event, entries in hooks.items():
|
|
72
|
+
filtered = [e for e in entries if not _is_toolkit_entry(e)]
|
|
73
|
+
if filtered:
|
|
74
|
+
result[event] = filtered
|
|
75
|
+
return result
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def merge(toolkit_hooks: dict, target_hooks: dict) -> dict:
|
|
79
|
+
"""Strip old toolkit entries, then append current toolkit entries.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
toolkit_hooks: Hook entries from the toolkit source file.
|
|
83
|
+
target_hooks: Existing hook entries in the target settings.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Merged hooks dictionary with old toolkit entries replaced by new ones.
|
|
87
|
+
"""
|
|
88
|
+
merged = strip_toolkit(target_hooks)
|
|
89
|
+
for event, entries in toolkit_hooks.items():
|
|
90
|
+
if event not in merged:
|
|
91
|
+
merged[event] = []
|
|
92
|
+
merged[event].extend(entries)
|
|
93
|
+
return merged
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def cmd_inject(toolkit_path: str, target_path: str) -> None:
|
|
97
|
+
"""Inject toolkit hooks into a target settings file.
|
|
98
|
+
|
|
99
|
+
Reads toolkit hooks, strips previous toolkit entries from the target,
|
|
100
|
+
appends the current toolkit entries, and writes the result. Creates
|
|
101
|
+
the target file if it does not exist.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
toolkit_path: Path to the toolkit hooks JSON file.
|
|
105
|
+
target_path: Path to the target settings JSON file.
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
toolkit_data = load_json(toolkit_path)
|
|
109
|
+
except (json.JSONDecodeError, OSError) as e:
|
|
110
|
+
print(f"Error reading toolkit hooks: {e}", file=sys.stderr)
|
|
111
|
+
sys.exit(2)
|
|
112
|
+
|
|
113
|
+
toolkit_hooks = toolkit_data.get("hooks", {})
|
|
114
|
+
|
|
115
|
+
# Load existing target settings (preserving all non-hooks keys)
|
|
116
|
+
target_settings: dict = {}
|
|
117
|
+
if os.path.islink(target_path):
|
|
118
|
+
# Old-style symlink — remove it, start fresh
|
|
119
|
+
os.remove(target_path)
|
|
120
|
+
elif os.path.isfile(target_path):
|
|
121
|
+
try:
|
|
122
|
+
target_settings = load_json(target_path)
|
|
123
|
+
except json.JSONDecodeError as e:
|
|
124
|
+
print(f"Error parsing target settings: {e}", file=sys.stderr)
|
|
125
|
+
sys.exit(2)
|
|
126
|
+
|
|
127
|
+
target_hooks = target_settings.get("hooks", {})
|
|
128
|
+
result = merge(toolkit_hooks, target_hooks)
|
|
129
|
+
|
|
130
|
+
target_settings["hooks"] = result
|
|
131
|
+
save_json(target_path, target_settings)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def cmd_strip(target_path: str) -> None:
|
|
135
|
+
"""Remove all ai-toolkit hook entries from a target settings file.
|
|
136
|
+
|
|
137
|
+
Removes entries tagged with the ai-toolkit source marker. If no hooks
|
|
138
|
+
remain, the ``hooks`` key is removed from the settings. Handles
|
|
139
|
+
legacy symlink targets by deleting the symlink.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
target_path: Path to the target settings JSON file.
|
|
143
|
+
"""
|
|
144
|
+
if os.path.islink(target_path):
|
|
145
|
+
os.remove(target_path)
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
if not os.path.isfile(target_path):
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
target_settings = load_json(target_path)
|
|
153
|
+
except json.JSONDecodeError as e:
|
|
154
|
+
print(f"Error parsing target settings: {e}", file=sys.stderr)
|
|
155
|
+
sys.exit(2)
|
|
156
|
+
|
|
157
|
+
result = strip_toolkit(target_settings.get("hooks", {}))
|
|
158
|
+
if result:
|
|
159
|
+
target_settings["hooks"] = result
|
|
160
|
+
else:
|
|
161
|
+
target_settings.pop("hooks", None)
|
|
162
|
+
|
|
163
|
+
save_json(target_path, target_settings)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def main() -> None:
|
|
167
|
+
"""Parse CLI arguments and dispatch to inject or strip sub-commands."""
|
|
168
|
+
if len(sys.argv) < 2:
|
|
169
|
+
print(__doc__, file=sys.stderr)
|
|
170
|
+
sys.exit(1)
|
|
171
|
+
|
|
172
|
+
cmd = sys.argv[1]
|
|
173
|
+
|
|
174
|
+
if cmd == "inject":
|
|
175
|
+
if len(sys.argv) != 4:
|
|
176
|
+
print("Usage: merge-hooks.py inject <toolkit-hooks> <target-settings>", file=sys.stderr)
|
|
177
|
+
sys.exit(1)
|
|
178
|
+
cmd_inject(sys.argv[2], sys.argv[3])
|
|
179
|
+
|
|
180
|
+
elif cmd == "strip":
|
|
181
|
+
if len(sys.argv) != 3:
|
|
182
|
+
print("Usage: merge-hooks.py strip <target-settings>", file=sys.stderr)
|
|
183
|
+
sys.exit(1)
|
|
184
|
+
cmd_strip(sys.argv[2])
|
|
185
|
+
|
|
186
|
+
else:
|
|
187
|
+
print(f"Unknown command: {cmd}", file=sys.stderr)
|
|
188
|
+
sys.exit(1)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
if __name__ == "__main__":
|
|
192
|
+
main()
|