oh-my-customcodex 0.1.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/LICENSE +21 -0
- package/README.md +327 -0
- package/dist/cli/index.js +32054 -0
- package/dist/index.js +5469 -0
- package/package.json +89 -0
- package/templates/.claude/agents/arch-documenter.md +38 -0
- package/templates/.claude/agents/arch-speckit-agent.md +66 -0
- package/templates/.claude/agents/be-django-expert.md +47 -0
- package/templates/.claude/agents/be-express-expert.md +31 -0
- package/templates/.claude/agents/be-fastapi-expert.md +45 -0
- package/templates/.claude/agents/be-go-backend-expert.md +45 -0
- package/templates/.claude/agents/be-nestjs-expert.md +29 -0
- package/templates/.claude/agents/be-springboot-expert.md +42 -0
- package/templates/.claude/agents/db-alembic-expert.md +73 -0
- package/templates/.claude/agents/db-postgres-expert.md +38 -0
- package/templates/.claude/agents/db-redis-expert.md +38 -0
- package/templates/.claude/agents/db-supabase-expert.md +37 -0
- package/templates/.claude/agents/de-airflow-expert.md +48 -0
- package/templates/.claude/agents/de-dbt-expert.md +36 -0
- package/templates/.claude/agents/de-kafka-expert.md +83 -0
- package/templates/.claude/agents/de-pipeline-expert.md +34 -0
- package/templates/.claude/agents/de-snowflake-expert.md +38 -0
- package/templates/.claude/agents/de-spark-expert.md +38 -0
- package/templates/.claude/agents/fe-design-expert.md +120 -0
- package/templates/.claude/agents/fe-flutter-agent.md +48 -0
- package/templates/.claude/agents/fe-svelte-agent.md +33 -0
- package/templates/.claude/agents/fe-vercel-agent.md +40 -0
- package/templates/.claude/agents/fe-vuejs-agent.md +34 -0
- package/templates/.claude/agents/infra-aws-expert.md +49 -0
- package/templates/.claude/agents/infra-docker-expert.md +49 -0
- package/templates/.claude/agents/lang-golang-expert.md +46 -0
- package/templates/.claude/agents/lang-java21-expert.md +42 -0
- package/templates/.claude/agents/lang-kotlin-expert.md +45 -0
- package/templates/.claude/agents/lang-python-expert.md +45 -0
- package/templates/.claude/agents/lang-rust-expert.md +45 -0
- package/templates/.claude/agents/lang-typescript-expert.md +45 -0
- package/templates/.claude/agents/mgr-claude-code-bible.md +62 -0
- package/templates/.claude/agents/mgr-creator.md +57 -0
- package/templates/.claude/agents/mgr-gitnerd.md +50 -0
- package/templates/.claude/agents/mgr-sauron.md +163 -0
- package/templates/.claude/agents/mgr-supplier.md +39 -0
- package/templates/.claude/agents/mgr-updater.md +40 -0
- package/templates/.claude/agents/qa-engineer.md +36 -0
- package/templates/.claude/agents/qa-planner.md +78 -0
- package/templates/.claude/agents/qa-writer.md +32 -0
- package/templates/.claude/agents/sec-codeql-expert.md +56 -0
- package/templates/.claude/agents/slack-cli-expert.md +98 -0
- package/templates/.claude/agents/souls/lang-golang-expert.soul.md +21 -0
- package/templates/.claude/agents/sys-memory-keeper.md +123 -0
- package/templates/.claude/agents/sys-naggy.md +76 -0
- package/templates/.claude/agents/tool-bun-expert.md +26 -0
- package/templates/.claude/agents/tool-npm-expert.md +31 -0
- package/templates/.claude/agents/tool-optimizer.md +37 -0
- package/templates/.claude/agents/wiki-curator.md +72 -0
- package/templates/.claude/config/required-plugins.json +30 -0
- package/templates/.claude/contexts/dev.md +20 -0
- package/templates/.claude/contexts/ecomode.md +110 -0
- package/templates/.claude/contexts/index.yaml +41 -0
- package/templates/.claude/contexts/research.md +28 -0
- package/templates/.claude/contexts/review.md +23 -0
- package/templates/.claude/hooks/hooks.json +533 -0
- package/templates/.claude/hooks/scripts/adaptive-harness-scan.sh +45 -0
- package/templates/.claude/hooks/scripts/agent-start-recorder.sh +40 -0
- package/templates/.claude/hooks/scripts/agent-teams-advisor.sh +76 -0
- package/templates/.claude/hooks/scripts/audit-log.sh +64 -0
- package/templates/.claude/hooks/scripts/auto-continue-guard.sh +33 -0
- package/templates/.claude/hooks/scripts/content-hash-validator.sh +75 -0
- package/templates/.claude/hooks/scripts/context-budget-advisor.sh +107 -0
- package/templates/.claude/hooks/scripts/cost-cap-advisor.sh +71 -0
- package/templates/.claude/hooks/scripts/cwd-change-detector.sh +36 -0
- package/templates/.claude/hooks/scripts/eval-core-batch-save.sh +46 -0
- package/templates/.claude/hooks/scripts/feedback-collector.sh +92 -0
- package/templates/.claude/hooks/scripts/file-change-validator.sh +26 -0
- package/templates/.claude/hooks/scripts/git-delegation-guard.sh +57 -0
- package/templates/.claude/hooks/scripts/model-escalation-advisor.sh +106 -0
- package/templates/.claude/hooks/scripts/omcodex-auto-update.sh +4 -0
- package/templates/.claude/hooks/scripts/omcustom-auto-update.sh +177 -0
- package/templates/.claude/hooks/scripts/rtk-intercept.sh +77 -0
- package/templates/.claude/hooks/scripts/rule-deletion-guard.sh +60 -0
- package/templates/.claude/hooks/scripts/schema-validator.sh +106 -0
- package/templates/.claude/hooks/scripts/secret-filter.sh +100 -0
- package/templates/.claude/hooks/scripts/session-autofix-prompt.sh +34 -0
- package/templates/.claude/hooks/scripts/session-autofix.sh +146 -0
- package/templates/.claude/hooks/scripts/session-env-check.sh +254 -0
- package/templates/.claude/hooks/scripts/skill-extractor-analyzer.sh +49 -0
- package/templates/.claude/hooks/scripts/stage-blocker.sh +16 -0
- package/templates/.claude/hooks/scripts/stale-todo-scanner.sh +91 -0
- package/templates/.claude/hooks/scripts/stall-detection-advisor.sh +112 -0
- package/templates/.claude/hooks/scripts/stop-console-audit.sh +46 -0
- package/templates/.claude/hooks/scripts/stuck-detector.sh +199 -0
- package/templates/.claude/hooks/scripts/task-outcome-recorder.sh +119 -0
- package/templates/.claude/hooks/scripts/task-state-precompact.sh +58 -0
- package/templates/.claude/hooks/scripts/user-prompt-preprocessor.sh +32 -0
- package/templates/.claude/hooks/skill-count-reminder.sh +34 -0
- package/templates/.claude/install-hooks.sh +100 -0
- package/templates/.claude/ontology/agents.yaml +546 -0
- package/templates/.claude/ontology/graphs/agent-skill.json +102 -0
- package/templates/.claude/ontology/graphs/full-graph.json +629 -0
- package/templates/.claude/ontology/graphs/routing.json +112 -0
- package/templates/.claude/ontology/graphs/skill-rule.json +78 -0
- package/templates/.claude/ontology/rules.yaml +251 -0
- package/templates/.claude/ontology/schema.yaml +144 -0
- package/templates/.claude/ontology/skills.yaml +575 -0
- package/templates/.claude/rules/MAY-optimization.md +42 -0
- package/templates/.claude/rules/MUST-agent-design.md +340 -0
- package/templates/.claude/rules/MUST-agent-identification.md +77 -0
- package/templates/.claude/rules/MUST-agent-teams.md +293 -0
- package/templates/.claude/rules/MUST-completion-verification.md +112 -0
- package/templates/.claude/rules/MUST-continuous-improvement.md +69 -0
- package/templates/.claude/rules/MUST-enforcement-policy.md +50 -0
- package/templates/.claude/rules/MUST-intent-transparency.md +74 -0
- package/templates/.claude/rules/MUST-language-policy.md +28 -0
- package/templates/.claude/rules/MUST-orchestrator-coordination.md +399 -0
- package/templates/.claude/rules/MUST-parallel-execution.md +184 -0
- package/templates/.claude/rules/MUST-permissions.md +32 -0
- package/templates/.claude/rules/MUST-safety.md +23 -0
- package/templates/.claude/rules/MUST-sync-verification.md +145 -0
- package/templates/.claude/rules/MUST-tool-identification.md +97 -0
- package/templates/.claude/rules/SHOULD-ecomode.md +123 -0
- package/templates/.claude/rules/SHOULD-error-handling.md +33 -0
- package/templates/.claude/rules/SHOULD-hud-statusline.md +51 -0
- package/templates/.claude/rules/SHOULD-interaction.md +77 -0
- package/templates/.claude/rules/SHOULD-memory-integration.md +371 -0
- package/templates/.claude/rules/SHOULD-ontology-rag-routing.md +49 -0
- package/templates/.claude/rules/SHOULD-wiki-sync.md +73 -0
- package/templates/.claude/rules/index.yaml +141 -0
- package/templates/.claude/schemas/tool-inputs.json +62 -0
- package/templates/.claude/skills/action-validator/SKILL.md +89 -0
- package/templates/.claude/skills/adaptive-harness/SKILL.md +335 -0
- package/templates/.claude/skills/adversarial-review/SKILL.md +80 -0
- package/templates/.claude/skills/agora/SKILL.md +194 -0
- package/templates/.claude/skills/airflow-best-practices/SKILL.md +94 -0
- package/templates/.claude/skills/alembic-best-practices/SKILL.md +295 -0
- package/templates/.claude/skills/ambiguity-gate/SKILL.md +94 -0
- package/templates/.claude/skills/analysis/SKILL.md +223 -0
- package/templates/.claude/skills/audit-agents/SKILL.md +118 -0
- package/templates/.claude/skills/aws-best-practices/SKILL.md +281 -0
- package/templates/.claude/skills/claude-code-bible/SKILL.md +93 -0
- package/templates/.claude/skills/claude-code-bible/scripts/fetch-docs.js +244 -0
- package/templates/.claude/skills/claude-native/SKILL.md +215 -0
- package/templates/.claude/skills/codex-exec/SKILL.md +206 -0
- package/templates/.claude/skills/codex-exec/scripts/codex-wrapper.cjs +430 -0
- package/templates/.claude/skills/create-agent/SKILL.md +94 -0
- package/templates/.claude/skills/cve-triage/SKILL.md +91 -0
- package/templates/.claude/skills/dag-orchestration/SKILL.md +201 -0
- package/templates/.claude/skills/dbt-best-practices/SKILL.md +55 -0
- package/templates/.claude/skills/de-lead-routing/SKILL.md +230 -0
- package/templates/.claude/skills/deep-plan/SKILL.md +344 -0
- package/templates/.claude/skills/deep-verify/SKILL.md +111 -0
- package/templates/.claude/skills/dev-lead-routing/SKILL.md +161 -0
- package/templates/.claude/skills/dev-refactor/SKILL.md +234 -0
- package/templates/.claude/skills/dev-review/SKILL.md +172 -0
- package/templates/.claude/skills/django-best-practices/SKILL.md +334 -0
- package/templates/.claude/skills/docker-best-practices/SKILL.md +276 -0
- package/templates/.claude/skills/evaluator-optimizer/SKILL.md +421 -0
- package/templates/.claude/skills/fastapi-best-practices/SKILL.md +271 -0
- package/templates/.claude/skills/fix-refs/SKILL.md +109 -0
- package/templates/.claude/skills/flutter-best-practices/SKILL.md +325 -0
- package/templates/.claude/skills/gemini-exec/SKILL.md +215 -0
- package/templates/.claude/skills/gemini-exec/scripts/gemini-wrapper.cjs +485 -0
- package/templates/.claude/skills/go-backend-best-practices/SKILL.md +135 -0
- package/templates/.claude/skills/go-best-practices/SKILL.md +204 -0
- package/templates/.claude/skills/hada-scout/SKILL.md +92 -0
- package/templates/.claude/skills/harness-eval/SKILL.md +95 -0
- package/templates/.claude/skills/harness-synthesizer/SKILL.md +145 -0
- package/templates/.claude/skills/help/SKILL.md +127 -0
- package/templates/.claude/skills/idea/SKILL.md +88 -0
- package/templates/.claude/skills/impeccable-design/SKILL.md +173 -0
- package/templates/.claude/skills/intent-detection/SKILL.md +293 -0
- package/templates/.claude/skills/intent-detection/patterns/agent-triggers.yaml +438 -0
- package/templates/.claude/skills/java21-best-practices/SKILL.md +190 -0
- package/templates/.claude/skills/jinja2-prompts/SKILL.md +86 -0
- package/templates/.claude/skills/kafka-best-practices/SKILL.md +53 -0
- package/templates/.claude/skills/kotlin-best-practices/SKILL.md +257 -0
- package/templates/.claude/skills/lists/SKILL.md +80 -0
- package/templates/.claude/skills/memory-management/SKILL.md +196 -0
- package/templates/.claude/skills/memory-recall/SKILL.md +172 -0
- package/templates/.claude/skills/memory-save/SKILL.md +128 -0
- package/templates/.claude/skills/model-escalation/SKILL.md +62 -0
- package/templates/.claude/skills/monitoring-setup/SKILL.md +215 -0
- package/templates/.claude/skills/multi-model-verification/SKILL.md +130 -0
- package/templates/.claude/skills/npm-audit/SKILL.md +74 -0
- package/templates/.claude/skills/npm-publish/SKILL.md +65 -0
- package/templates/.claude/skills/npm-version/SKILL.md +104 -0
- package/templates/.claude/skills/omcodex-auto-improve/SKILL.md +136 -0
- package/templates/.claude/skills/omcodex-feedback/SKILL.md +205 -0
- package/templates/.claude/skills/omcodex-improve-report/SKILL.md +65 -0
- package/templates/.claude/skills/omcodex-loop/SKILL.md +45 -0
- package/templates/.claude/skills/omcodex-release-notes/SKILL.md +117 -0
- package/templates/.claude/skills/omcodex-takeover/SKILL.md +115 -0
- package/templates/.claude/skills/omcodex-web/SKILL.md +95 -0
- package/templates/.claude/skills/optimize-analyze/SKILL.md +57 -0
- package/templates/.claude/skills/optimize-bundle/SKILL.md +69 -0
- package/templates/.claude/skills/optimize-report/SKILL.md +76 -0
- package/templates/.claude/skills/peer-messaging/SKILL.md +59 -0
- package/templates/.claude/skills/pipeline/SKILL.md +103 -0
- package/templates/.claude/skills/pipeline-architecture-patterns/SKILL.md +84 -0
- package/templates/.claude/skills/pipeline-guards/SKILL.md +173 -0
- package/templates/.claude/skills/post-release-followup/SKILL.md +134 -0
- package/templates/.claude/skills/postgres-best-practices/SKILL.md +67 -0
- package/templates/.claude/skills/pr-auto-improve/SKILL.md +129 -0
- package/templates/.claude/skills/professor-triage/SKILL.md +321 -0
- package/templates/.claude/skills/python-best-practices/SKILL.md +223 -0
- package/templates/.claude/skills/qa-lead-routing/SKILL.md +104 -0
- package/templates/.claude/skills/react-best-practices/SKILL.md +102 -0
- package/templates/.claude/skills/reasoning-sandwich/SKILL.md +64 -0
- package/templates/.claude/skills/redis-best-practices/SKILL.md +84 -0
- package/templates/.claude/skills/release-plan/SKILL.md +207 -0
- package/templates/.claude/skills/research/SKILL.md +493 -0
- package/templates/.claude/skills/result-aggregation/SKILL.md +165 -0
- package/templates/.claude/skills/rtk-exec/SKILL.md +199 -0
- package/templates/.claude/skills/rtk-exec/scripts/rtk-wrapper.cjs +377 -0
- package/templates/.claude/skills/rust-best-practices/SKILL.md +268 -0
- package/templates/.claude/skills/sauron-watch/SKILL.md +239 -0
- package/templates/.claude/skills/scout/SKILL.md +250 -0
- package/templates/.claude/skills/sdd/SKILL.md +24 -0
- package/templates/.claude/skills/sdd-dev/SKILL.md +257 -0
- package/templates/.claude/skills/sdd-development/SKILL.md +24 -0
- package/templates/.claude/skills/secretary-routing/SKILL.md +132 -0
- package/templates/.claude/skills/skill-extractor/SKILL.md +155 -0
- package/templates/.claude/skills/skills-sh-search/SKILL.md +210 -0
- package/templates/.claude/skills/snowflake-best-practices/SKILL.md +66 -0
- package/templates/.claude/skills/spark-best-practices/SKILL.md +53 -0
- package/templates/.claude/skills/springboot-best-practices/SKILL.md +74 -0
- package/templates/.claude/skills/springboot-best-practices/examples/config-properties-example.java +22 -0
- package/templates/.claude/skills/springboot-best-practices/examples/controller-example.java +28 -0
- package/templates/.claude/skills/springboot-best-practices/examples/controller-test-example.java +33 -0
- package/templates/.claude/skills/springboot-best-practices/examples/entity-example.java +22 -0
- package/templates/.claude/skills/springboot-best-practices/examples/exception-handler-example.java +30 -0
- package/templates/.claude/skills/springboot-best-practices/examples/repository-example.java +17 -0
- package/templates/.claude/skills/springboot-best-practices/examples/repository-test-example.java +23 -0
- package/templates/.claude/skills/springboot-best-practices/examples/security-config-example.java +27 -0
- package/templates/.claude/skills/springboot-best-practices/examples/service-example.java +33 -0
- package/templates/.claude/skills/status/SKILL.md +155 -0
- package/templates/.claude/skills/structured-dev-cycle/SKILL.md +200 -0
- package/templates/.claude/skills/stuck-recovery/SKILL.md +80 -0
- package/templates/.claude/skills/supabase-postgres-best-practices/SKILL.md +100 -0
- package/templates/.claude/skills/systematic-debugging/SKILL.md +288 -0
- package/templates/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +278 -0
- package/templates/.claude/skills/systematic-debugging/condition-based-waiting.md +240 -0
- package/templates/.claude/skills/systematic-debugging/defense-in-depth.md +252 -0
- package/templates/.claude/skills/systematic-debugging/find-polluter.sh +147 -0
- package/templates/.claude/skills/systematic-debugging/root-cause-tracing.md +87 -0
- package/templates/.claude/skills/task-decomposition/SKILL.md +197 -0
- package/templates/.claude/skills/typescript-best-practices/SKILL.md +322 -0
- package/templates/.claude/skills/update-docs/SKILL.md +142 -0
- package/templates/.claude/skills/update-external/SKILL.md +169 -0
- package/templates/.claude/skills/vercel-deploy/SKILL.md +75 -0
- package/templates/.claude/skills/web-design-guidelines/SKILL.md +119 -0
- package/templates/.claude/skills/wiki/SKILL.md +426 -0
- package/templates/.claude/skills/wiki-rag/SKILL.md +154 -0
- package/templates/.claude/skills/worker-reviewer-pipeline/SKILL.md +165 -0
- package/templates/.claude/skills/writing-clearly-and-concisely/SKILL.md +66 -0
- package/templates/.claude/statusline.sh +380 -0
- package/templates/.claude/uninstall-hooks.sh +52 -0
- package/templates/.github/workflows/wiki-sync.yml +132 -0
- package/templates/AGENTS.md.en +255 -0
- package/templates/AGENTS.md.ko +255 -0
- package/templates/CLAUDE.md +263 -0
- package/templates/CLAUDE.md.en +256 -0
- package/templates/CLAUDE.md.ko +256 -0
- package/templates/deprecated-files.json +10 -0
- package/templates/guides/agents-md-quality/README.md +110 -0
- package/templates/guides/airflow/README.md +47 -0
- package/templates/guides/alembic/README.md +438 -0
- package/templates/guides/aws/common-patterns.md +169 -0
- package/templates/guides/aws/index.yaml +26 -0
- package/templates/guides/aws/well-architected.md +143 -0
- package/templates/guides/cc-token-saver/README.md +97 -0
- package/templates/guides/claude-code/01-overview.md +42 -0
- package/templates/guides/claude-code/03-tools.md +107 -0
- package/templates/guides/claude-code/04-agent-skills.md +90 -0
- package/templates/guides/claude-code/05-agent-sdk.md +129 -0
- package/templates/guides/claude-code/06-mcp.md +165 -0
- package/templates/guides/claude-code/07-prompt-engineering.md +100 -0
- package/templates/guides/claude-code/08-testing.md +56 -0
- package/templates/guides/claude-code/09-guardrails.md +78 -0
- package/templates/guides/claude-code/10-monitoring.md +87 -0
- package/templates/guides/claude-code/11-sub-agents.md +159 -0
- package/templates/guides/claude-code/12-workflow-patterns.md +182 -0
- package/templates/guides/claude-code/13-cli-flags.md +151 -0
- package/templates/guides/claude-code/index.yaml +61 -0
- package/templates/guides/dbt/README.md +32 -0
- package/templates/guides/django-best-practices/README.md +476 -0
- package/templates/guides/docker/compose-best-practices.md +284 -0
- package/templates/guides/docker/dockerfile-best-practices.md +262 -0
- package/templates/guides/docker/index.yaml +26 -0
- package/templates/guides/drizzle-orm/README.md +69 -0
- package/templates/guides/elements-of-style/elements-of-style.html +2609 -0
- package/templates/guides/fastapi/best-practices.md +232 -0
- package/templates/guides/fastapi/index.yaml +21 -0
- package/templates/guides/flutter/architecture.md +141 -0
- package/templates/guides/flutter/fundamentals.md +119 -0
- package/templates/guides/flutter/index.yaml +44 -0
- package/templates/guides/flutter/performance.md +119 -0
- package/templates/guides/flutter/security.md +120 -0
- package/templates/guides/flutter/state-management.md +144 -0
- package/templates/guides/flutter/testing.md +155 -0
- package/templates/guides/git-worktree-workflow/README.md +138 -0
- package/templates/guides/go-backend/index.yaml +26 -0
- package/templates/guides/go-backend/project-layout.md +243 -0
- package/templates/guides/go-backend/uber-style.md +212 -0
- package/templates/guides/golang/concurrency.md +282 -0
- package/templates/guides/golang/effective-go.md +309 -0
- package/templates/guides/golang/error-handling.md +250 -0
- package/templates/guides/golang/index.yaml +27 -0
- package/templates/guides/hook-data-flow/README.md +135 -0
- package/templates/guides/iceberg/README.md +49 -0
- package/templates/guides/impeccable-design/color-and-contrast.md +278 -0
- package/templates/guides/impeccable-design/index.yaml +12 -0
- package/templates/guides/impeccable-design/motion-design.md +390 -0
- package/templates/guides/impeccable-design/typography.md +386 -0
- package/templates/guides/impeccable-design/ux-writing.md +400 -0
- package/templates/guides/index.yaml +265 -0
- package/templates/guides/java21/index.yaml +29 -0
- package/templates/guides/java21/java-style-guide.md +248 -0
- package/templates/guides/java21/modern-java21.md +303 -0
- package/templates/guides/kafka/README.md +32 -0
- package/templates/guides/kotlin/coding-conventions.md +247 -0
- package/templates/guides/kotlin/idioms.md +234 -0
- package/templates/guides/kotlin/index.yaml +26 -0
- package/templates/guides/multi-model-routing/README.md +101 -0
- package/templates/guides/multi-provider-exec/README.md +83 -0
- package/templates/guides/postgres/README.md +58 -0
- package/templates/guides/python/index.yaml +26 -0
- package/templates/guides/python/pep8-style-guide.md +202 -0
- package/templates/guides/python/zen-of-python.md +79 -0
- package/templates/guides/redis/README.md +50 -0
- package/templates/guides/rust/error-handling.md +262 -0
- package/templates/guides/rust/index.yaml +26 -0
- package/templates/guides/rust/ownership.md +180 -0
- package/templates/guides/skill-bundle-design/README.md +106 -0
- package/templates/guides/slack-cli/README.md +145 -0
- package/templates/guides/snowflake/README.md +32 -0
- package/templates/guides/spark/README.md +32 -0
- package/templates/guides/springboot/best-practices.md +361 -0
- package/templates/guides/springboot/index.yaml +22 -0
- package/templates/guides/supabase-postgres/README.md +32 -0
- package/templates/guides/supabase-postgres/index.yaml +19 -0
- package/templates/guides/typescript/advanced-types.md +225 -0
- package/templates/guides/typescript/index.yaml +26 -0
- package/templates/guides/typescript/type-system.md +219 -0
- package/templates/guides/web-design/accessibility.md +66 -0
- package/templates/guides/web-design/index.yaml +20 -0
- package/templates/guides/web-design/performance.md +102 -0
- package/templates/guides/web-scraping/README.md +926 -0
- package/templates/guides/web-scraping/index.yaml +19 -0
- package/templates/guides/worktree-lifecycle/README.md +104 -0
- package/templates/index.yaml +18 -0
- package/templates/manifest.json +49 -0
- package/templates/workflows/auto-dev.yaml +46 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# R010 git-delegation-guard hook
|
|
3
|
+
# Warns when git operations are delegated to a non-mgr-gitnerd agent via Agent/Task tool.
|
|
4
|
+
# WARN only - does NOT block (exit 0, passes input through).
|
|
5
|
+
#
|
|
6
|
+
# PPID Scoping Convention:
|
|
7
|
+
# All session-scoped temp files MUST use $PPID (Claude Code parent PID),
|
|
8
|
+
# NOT $$ (subprocess PID which changes per hook invocation).
|
|
9
|
+
# Pattern: /tmp/.codex-{purpose}-${PPID}
|
|
10
|
+
# See also: agent-teams-advisor.sh, context-budget-advisor.sh, stuck-detector.sh
|
|
11
|
+
|
|
12
|
+
# Dependency check: exit silently if jq not available
|
|
13
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
14
|
+
|
|
15
|
+
input=$(cat)
|
|
16
|
+
|
|
17
|
+
agent_type=$(echo "$input" | jq -r '.tool_input.subagent_type // ""')
|
|
18
|
+
prompt=$(echo "$input" | jq -r '.tool_input.prompt // ""')
|
|
19
|
+
|
|
20
|
+
# R010 violation tracking file (PPID-scoped for session persistence)
|
|
21
|
+
VIOLATION_FILE="/tmp/.codex-r010-violations-${PPID}"
|
|
22
|
+
|
|
23
|
+
# Only warn when the delegated agent is NOT mgr-gitnerd
|
|
24
|
+
if [ "$agent_type" != "mgr-gitnerd" ]; then
|
|
25
|
+
git_keywords=(
|
|
26
|
+
"git add"
|
|
27
|
+
"git commit"
|
|
28
|
+
"git push"
|
|
29
|
+
"git revert"
|
|
30
|
+
"git merge"
|
|
31
|
+
"git rebase"
|
|
32
|
+
"git checkout"
|
|
33
|
+
"git branch"
|
|
34
|
+
"git reset"
|
|
35
|
+
"git cherry-pick"
|
|
36
|
+
"git tag"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
for keyword in "${git_keywords[@]}"; do
|
|
40
|
+
if echo "$prompt" | grep -qi "$keyword"; then
|
|
41
|
+
echo "[Hook] WARNING: R010 violation detected - git operation ('$keyword') delegated to '$agent_type' instead of 'mgr-gitnerd'" >&2
|
|
42
|
+
echo "[Hook] Per R010, all git operations (commit/push/branch/merge/etc.) MUST be delegated to mgr-gitnerd" >&2
|
|
43
|
+
|
|
44
|
+
# Record violation for R021 promotion tracking
|
|
45
|
+
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $keyword $agent_type" >> "$VIOLATION_FILE"
|
|
46
|
+
violation_count=$(wc -l < "$VIOLATION_FILE" 2>/dev/null | tr -d ' ')
|
|
47
|
+
if [ "$violation_count" -ge 3 ]; then
|
|
48
|
+
echo "[Hook] R010 violations: ${violation_count} this session — R021 promotion threshold reached" >&2
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
break
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Always pass through - this hook is advisory only
|
|
57
|
+
echo "$input"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Dependency check: exit silently if jq not available
|
|
5
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
6
|
+
|
|
7
|
+
# Model Escalation Advisor Hook
|
|
8
|
+
# Trigger: PreToolUse, tool == "Task" || tool == "Agent"
|
|
9
|
+
# Purpose: Advise model escalation when failure patterns detected
|
|
10
|
+
# Protocol: stdin JSON -> process -> stdout pass-through, exit 0 always
|
|
11
|
+
|
|
12
|
+
input=$(cat)
|
|
13
|
+
|
|
14
|
+
# Extract current task info
|
|
15
|
+
agent_type=$(echo "$input" | jq -r '.tool_input.subagent_type // "unknown"')
|
|
16
|
+
current_model=$(echo "$input" | jq -r '.tool_input.model // "inherit"')
|
|
17
|
+
|
|
18
|
+
# Session-scoped outcome log
|
|
19
|
+
OUTCOME_FILE="/tmp/.codex-task-outcomes-${PPID}"
|
|
20
|
+
|
|
21
|
+
# Skip if no history
|
|
22
|
+
if [ ! -f "$OUTCOME_FILE" ]; then
|
|
23
|
+
echo "$input"
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Thresholds
|
|
28
|
+
FAILURE_THRESHOLD=2
|
|
29
|
+
CONSECUTIVE_THRESHOLD=3
|
|
30
|
+
COOLDOWN=5
|
|
31
|
+
|
|
32
|
+
# Count failures for this agent type
|
|
33
|
+
agent_failures=0
|
|
34
|
+
if [ -n "$agent_type" ] && [ "$agent_type" != "unknown" ]; then
|
|
35
|
+
agent_failures=$(grep -c "\"agent_type\":\"${agent_type}\".*\"outcome\":\"failure\"" "$OUTCOME_FILE" 2>/dev/null || echo "0")
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Count consecutive failures (tail entries)
|
|
39
|
+
consecutive_failures=$(tail -${CONSECUTIVE_THRESHOLD} "$OUTCOME_FILE" 2>/dev/null | grep -c '"outcome":"failure"' 2>/dev/null || echo "0")
|
|
40
|
+
|
|
41
|
+
# Escalation path
|
|
42
|
+
next_model=""
|
|
43
|
+
cost_multiplier=""
|
|
44
|
+
case "$current_model" in
|
|
45
|
+
haiku)
|
|
46
|
+
next_model="sonnet"
|
|
47
|
+
cost_multiplier="~3-5x"
|
|
48
|
+
;;
|
|
49
|
+
sonnet)
|
|
50
|
+
next_model="opus"
|
|
51
|
+
cost_multiplier="~5-10x"
|
|
52
|
+
;;
|
|
53
|
+
*)
|
|
54
|
+
next_model=""
|
|
55
|
+
;;
|
|
56
|
+
esac
|
|
57
|
+
|
|
58
|
+
# Advise escalation
|
|
59
|
+
if [ -n "$next_model" ]; then
|
|
60
|
+
should_advise=false
|
|
61
|
+
reason=""
|
|
62
|
+
|
|
63
|
+
if [ "$agent_failures" -ge "$FAILURE_THRESHOLD" ]; then
|
|
64
|
+
should_advise=true
|
|
65
|
+
reason="${agent_type} failed ${agent_failures}x with ${current_model}"
|
|
66
|
+
elif [ "$consecutive_failures" -ge "$CONSECUTIVE_THRESHOLD" ]; then
|
|
67
|
+
should_advise=true
|
|
68
|
+
reason="${consecutive_failures} consecutive failures"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
if [ "$should_advise" = true ]; then
|
|
72
|
+
echo "" >&2
|
|
73
|
+
echo "--- [Model Escalation Advisory] ---" >&2
|
|
74
|
+
echo " Agent type: ${agent_type}" >&2
|
|
75
|
+
echo " Current model: ${current_model}" >&2
|
|
76
|
+
echo " ⚡ Recommended: Escalate to ${next_model}" >&2
|
|
77
|
+
echo " Cost impact: ${cost_multiplier} per task" >&2
|
|
78
|
+
echo " Reason: ${reason}" >&2
|
|
79
|
+
echo "------------------------------------" >&2
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# De-escalation check
|
|
84
|
+
if [ "$current_model" != "haiku" ] && [ "$current_model" != "inherit" ] && [ "$current_model" != "" ]; then
|
|
85
|
+
recent_successes=$(tail -${COOLDOWN} "$OUTCOME_FILE" 2>/dev/null | grep -c '"outcome":"success"' 2>/dev/null || echo "0")
|
|
86
|
+
|
|
87
|
+
if [ "$recent_successes" -ge "$COOLDOWN" ]; then
|
|
88
|
+
lower_model=""
|
|
89
|
+
case "$current_model" in
|
|
90
|
+
opus) lower_model="sonnet" ;;
|
|
91
|
+
sonnet) lower_model="haiku" ;;
|
|
92
|
+
esac
|
|
93
|
+
|
|
94
|
+
if [ -n "$lower_model" ]; then
|
|
95
|
+
echo "" >&2
|
|
96
|
+
echo "--- [Model De-escalation Advisory] ---" >&2
|
|
97
|
+
echo " ↓ Consider: ${current_model} → ${lower_model}" >&2
|
|
98
|
+
echo " ${recent_successes} consecutive successes" >&2
|
|
99
|
+
echo "--------------------------------------" >&2
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Pass through
|
|
105
|
+
echo "$input"
|
|
106
|
+
exit 0
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SessionStart auto-update hook — interactive omcodex update check
|
|
3
|
+
# Trigger: SessionStart (runs BEFORE session-env-check.sh)
|
|
4
|
+
# Purpose: Check for oh-my-customcodex updates, prompt user, optionally update
|
|
5
|
+
# Protocol: stdin JSON -> stdout pass-through, exit 0 ALWAYS
|
|
6
|
+
# Design: GitHub issue #752
|
|
7
|
+
|
|
8
|
+
# Pass through stdin immediately — capture for later output
|
|
9
|
+
input=$(cat)
|
|
10
|
+
|
|
11
|
+
# --- Guard: skip conditions ---
|
|
12
|
+
|
|
13
|
+
# Skip if explicitly disabled
|
|
14
|
+
if [ "${OMCODEX_SKIP_AUTO_UPDATE:-${OMCUSTOM_SKIP_AUTO_UPDATE:-}}" = "true" ]; then
|
|
15
|
+
echo "$input"
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Skip if /dev/tty not available (CI, Docker, non-interactive)
|
|
20
|
+
if ! [ -c /dev/tty ] 2>/dev/null; then
|
|
21
|
+
echo "$input"
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# --- Configuration ---
|
|
26
|
+
CACHE_DIR="$HOME/.oh-my-customcodex"
|
|
27
|
+
LEGACY_CACHE_DIR="$HOME/.oh-my-customcode"
|
|
28
|
+
CACHE_FILE="${CACHE_DIR}/self-update-cache.json"
|
|
29
|
+
CACHE_MAX_AGE=3600 # 1 hour in seconds
|
|
30
|
+
NPM_TIMEOUT=3 # seconds for npm view
|
|
31
|
+
INPUT_TIMEOUT=10 # seconds for user prompt
|
|
32
|
+
PACKAGE_NAME="oh-my-customcodex"
|
|
33
|
+
|
|
34
|
+
# --- Helper: semantic version compare ---
|
|
35
|
+
# Returns 0 if $1 < $2 (update available)
|
|
36
|
+
version_lt() {
|
|
37
|
+
local older
|
|
38
|
+
older=$(printf '%s\n' "$1" "$2" | sort -V | head -1)
|
|
39
|
+
[ "$older" = "$1" ] && [ "$1" != "$2" ]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# --- Step 1: Get current installed version ---
|
|
43
|
+
CURRENT_VERSION=""
|
|
44
|
+
|
|
45
|
+
# Try project rc file in current directory (legacy .omcustomrc.json retained for compatibility)
|
|
46
|
+
if [ -f ".omcodexrc.json" ]; then
|
|
47
|
+
CURRENT_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' .omcodexrc.json 2>/dev/null | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
48
|
+
elif [ -f ".omcustomrc.json" ]; then
|
|
49
|
+
CURRENT_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' .omcustomrc.json 2>/dev/null | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Fallback: try npm list
|
|
53
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
54
|
+
CURRENT_VERSION=$(npm list -g "$PACKAGE_NAME" --depth=0 2>/dev/null | grep -o "${PACKAGE_NAME}@[^ ]*" | cut -d'@' -f2)
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Cannot determine current version — skip
|
|
58
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
59
|
+
echo "$input"
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# --- Step 2: Get latest version (cache-first, network fallback) ---
|
|
64
|
+
LATEST_VERSION=""
|
|
65
|
+
CACHE_HIT=false
|
|
66
|
+
|
|
67
|
+
# Ensure cache directory exists
|
|
68
|
+
mkdir -p "$CACHE_DIR" 2>/dev/null
|
|
69
|
+
|
|
70
|
+
if [ ! -f "$CACHE_FILE" ] && [ -f "${LEGACY_CACHE_DIR}/self-update-cache.json" ]; then
|
|
71
|
+
CACHE_FILE="${LEGACY_CACHE_DIR}/self-update-cache.json"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Check cache freshness
|
|
75
|
+
if [ -f "$CACHE_FILE" ]; then
|
|
76
|
+
CACHE_TIMESTAMP=$(grep -o '"timestamp"[[:space:]]*:[[:space:]]*[0-9]*' "$CACHE_FILE" 2>/dev/null | grep -o '[0-9]*$')
|
|
77
|
+
CACHED_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$CACHE_FILE" 2>/dev/null | grep -o '"[^"]*"$' | tr -d '"')
|
|
78
|
+
|
|
79
|
+
if [ -n "$CACHE_TIMESTAMP" ] && [ -n "$CACHED_VERSION" ]; then
|
|
80
|
+
NOW=$(date +%s)
|
|
81
|
+
AGE=$((NOW - CACHE_TIMESTAMP))
|
|
82
|
+
|
|
83
|
+
if [ "$AGE" -lt "$CACHE_MAX_AGE" ]; then
|
|
84
|
+
LATEST_VERSION="$CACHED_VERSION"
|
|
85
|
+
CACHE_HIT=true
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Cache miss or stale — fetch from npm registry
|
|
91
|
+
if [ "$CACHE_HIT" = false ]; then
|
|
92
|
+
if command -v npm >/dev/null 2>&1; then
|
|
93
|
+
LATEST_VERSION=$(timeout "$NPM_TIMEOUT" npm view "$PACKAGE_NAME" version 2>/dev/null || echo "")
|
|
94
|
+
|
|
95
|
+
# Update cache on successful fetch
|
|
96
|
+
if [ -n "$LATEST_VERSION" ]; then
|
|
97
|
+
NOW=$(date +%s)
|
|
98
|
+
cat > "$CACHE_FILE" << EOF
|
|
99
|
+
{
|
|
100
|
+
"version": "${LATEST_VERSION}",
|
|
101
|
+
"timestamp": ${NOW},
|
|
102
|
+
"source": "npm-registry"
|
|
103
|
+
}
|
|
104
|
+
EOF
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Could not determine latest version — skip
|
|
110
|
+
if [ -z "$LATEST_VERSION" ]; then
|
|
111
|
+
echo "$input"
|
|
112
|
+
exit 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# --- Step 3: Compare versions ---
|
|
116
|
+
if ! version_lt "$CURRENT_VERSION" "$LATEST_VERSION"; then
|
|
117
|
+
# Already up to date
|
|
118
|
+
echo "$input"
|
|
119
|
+
exit 0
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# --- Step 4: Prompt user for update ---
|
|
123
|
+
echo "" >&2
|
|
124
|
+
echo "--- [oh-my-customcodex Update Available] ---" >&2
|
|
125
|
+
echo " New version: v${LATEST_VERSION} (current: v${CURRENT_VERSION})" >&2
|
|
126
|
+
echo "" >&2
|
|
127
|
+
|
|
128
|
+
# Interactive prompt via /dev/tty (SessionStart stdin is JSON pipe)
|
|
129
|
+
printf " Update oh-my-customcodex to v%s? [y/N] " "$LATEST_VERSION" >/dev/tty 2>/dev/null
|
|
130
|
+
if read -r -t "$INPUT_TIMEOUT" answer </dev/tty 2>/dev/null; then
|
|
131
|
+
case "$answer" in
|
|
132
|
+
[yY]|[yY][eE][sS])
|
|
133
|
+
echo " Installing oh-my-customcodex@${LATEST_VERSION}..." >&2
|
|
134
|
+
if npm install -g "${PACKAGE_NAME}@latest" >&2 2>&1; then
|
|
135
|
+
echo " ✓ Updated to v${LATEST_VERSION}" >&2
|
|
136
|
+
|
|
137
|
+
# Check if project harness should be updated too
|
|
138
|
+
if [ -f ".omcustomrc.json" ]; then
|
|
139
|
+
printf " Update project harness too? [y/N] " >/dev/tty 2>/dev/null
|
|
140
|
+
if read -r -t "$INPUT_TIMEOUT" harness_answer </dev/tty 2>/dev/null; then
|
|
141
|
+
case "$harness_answer" in
|
|
142
|
+
[yY]|[yY][eE][sS])
|
|
143
|
+
echo " Updating project harness..." >&2
|
|
144
|
+
if command -v omcustom >/dev/null 2>&1; then
|
|
145
|
+
omcustom update --force >&2 2>&1 || echo " ⚠ Harness update failed (non-blocking)" >&2
|
|
146
|
+
echo " ✓ Project harness updated" >&2
|
|
147
|
+
else
|
|
148
|
+
echo " ⚠ omcustom command not found after install" >&2
|
|
149
|
+
fi
|
|
150
|
+
;;
|
|
151
|
+
*)
|
|
152
|
+
echo " Skipped harness update" >&2
|
|
153
|
+
;;
|
|
154
|
+
esac
|
|
155
|
+
else
|
|
156
|
+
echo "" >&2
|
|
157
|
+
echo " Timed out — skipped harness update" >&2
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
else
|
|
161
|
+
echo " ⚠ Update failed (non-blocking, continuing session)" >&2
|
|
162
|
+
fi
|
|
163
|
+
;;
|
|
164
|
+
*)
|
|
165
|
+
echo " Skipped update" >&2
|
|
166
|
+
;;
|
|
167
|
+
esac
|
|
168
|
+
else
|
|
169
|
+
echo "" >&2
|
|
170
|
+
echo " Timed out — skipped update" >&2
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
echo "------------------------------------" >&2
|
|
174
|
+
|
|
175
|
+
# Always pass through and exit 0
|
|
176
|
+
echo "$input"
|
|
177
|
+
exit 0
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# RTK Auto-Intercept Hook
|
|
3
|
+
# Trigger: PreToolUse (Bash matcher)
|
|
4
|
+
# Purpose: Transparently rewrite CLI commands through RTK proxy
|
|
5
|
+
# Protocol: stdin JSON → stdout modified JSON, exit 0 always
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
input=$(cat)
|
|
10
|
+
|
|
11
|
+
# Only intercept Bash tool calls
|
|
12
|
+
tool_name=$(echo "$input" | jq -r '.tool // empty' 2>/dev/null || echo "")
|
|
13
|
+
if [ "$tool_name" != "Bash" ]; then
|
|
14
|
+
echo "$input"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Check RTK availability
|
|
19
|
+
RTK_AVAILABLE=false
|
|
20
|
+
STATUS_FILE="/tmp/.codex-env-status-${PPID}"
|
|
21
|
+
if [ -f "$STATUS_FILE" ] && grep -q "rtk=available" "$STATUS_FILE" 2>/dev/null; then
|
|
22
|
+
RTK_AVAILABLE=true
|
|
23
|
+
elif command -v rtk >/dev/null 2>&1; then
|
|
24
|
+
RTK_AVAILABLE=true
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
if [ "$RTK_AVAILABLE" != "true" ]; then
|
|
28
|
+
echo "$input"
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Extract command
|
|
33
|
+
cmd=$(echo "$input" | jq -r '.tool_input.command // empty' 2>/dev/null || echo "")
|
|
34
|
+
if [ -z "$cmd" ]; then
|
|
35
|
+
echo "$input"
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Skip if already using rtk
|
|
40
|
+
if echo "$cmd" | grep -qE '^rtk\b'; then
|
|
41
|
+
echo "$input"
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Skip complex commands (pipes, redirections, background, subshells, semicolons with multiple commands)
|
|
46
|
+
if echo "$cmd" | grep -qE '[|><&]|;\s*\w'; then
|
|
47
|
+
echo "$input"
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# RTK-supported command prefixes
|
|
52
|
+
RTK_CMDS="ls find tree du cat head tail wc grep rg git cargo npm pnpm bun pip pytest vitest jest rspec eslint tsc ruff docker kubectl"
|
|
53
|
+
|
|
54
|
+
# Extract first word of command (skip env var assignments like FOO=bar)
|
|
55
|
+
first_word=$(echo "$cmd" | sed 's/^[A-Z_]*=[^ ]* //' | awk '{print $1}')
|
|
56
|
+
|
|
57
|
+
# Check if command is RTK-supported
|
|
58
|
+
SUPPORTED=false
|
|
59
|
+
for rtk_cmd in $RTK_CMDS; do
|
|
60
|
+
if [ "$first_word" = "$rtk_cmd" ]; then
|
|
61
|
+
SUPPORTED=true
|
|
62
|
+
break
|
|
63
|
+
fi
|
|
64
|
+
done
|
|
65
|
+
|
|
66
|
+
if [ "$SUPPORTED" != "true" ]; then
|
|
67
|
+
echo "$input"
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Rewrite command with rtk prefix
|
|
72
|
+
new_cmd="rtk $cmd"
|
|
73
|
+
echo "[RTK] Intercepted: $cmd → $new_cmd" >&2
|
|
74
|
+
|
|
75
|
+
# Output modified JSON
|
|
76
|
+
echo "$input" | jq --arg new_cmd "$new_cmd" '.tool_input.command = $new_cmd'
|
|
77
|
+
exit 0
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# rule-deletion-guard.sh — Block rule file deletion without individual user confirmation
|
|
3
|
+
# Requires: jq
|
|
4
|
+
|
|
5
|
+
set -uo pipefail
|
|
6
|
+
|
|
7
|
+
input=$(cat)
|
|
8
|
+
|
|
9
|
+
# Dependency check — allow if jq missing
|
|
10
|
+
if ! command -v jq &>/dev/null; then
|
|
11
|
+
echo "$input"
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Parse tool input
|
|
16
|
+
tool=$(echo "$input" | jq -r '.tool // ""' 2>/dev/null) || { echo "$input"; exit 0; }
|
|
17
|
+
cmd=$(echo "$input" | jq -r '.tool_input.command // ""' 2>/dev/null) || { echo "$input"; exit 0; }
|
|
18
|
+
|
|
19
|
+
# Only check Bash tool
|
|
20
|
+
if [ "$tool" != "Bash" ]; then
|
|
21
|
+
echo "$input"
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Check if command would delete parent directories containing rules
|
|
26
|
+
if echo "$cmd" | grep -qE '(^|\s)(rm|git\s+rm|mv|unlink)\s' && echo "$cmd" | grep -qE '\.codex/?(\s|$)'; then
|
|
27
|
+
echo "[Hook] ⛔ RULE DELETION BLOCKED — Parent directory deletion detected" >&2
|
|
28
|
+
echo "[Hook] This command would delete the entire .codex/ directory including all rules." >&2
|
|
29
|
+
echo "[Hook] Delete rules individually with user confirmation." >&2
|
|
30
|
+
exit 2
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Check if command targets .codex/rules/ for deletion (including mv, unlink)
|
|
34
|
+
if echo "$cmd" | grep -qE '(^|\s)(rm|git\s+rm|mv|unlink)\s' && echo "$cmd" | grep -qE '\.codex/rules(/|\s|$)'; then
|
|
35
|
+
# Extract target files
|
|
36
|
+
targets=$(echo "$cmd" | grep -oE '\.codex/rules/[^ ]+' | tr '\n' ', ' | sed 's/,$//')
|
|
37
|
+
target_count=$(echo "$cmd" | grep -oE '\.codex/rules/[^ ]+' | wc -l | tr -d ' ')
|
|
38
|
+
|
|
39
|
+
# Check for glob/wildcard patterns or multiple targets
|
|
40
|
+
if echo "$cmd" | grep -qE '\.codex/rules/\*|\.codex/rules/[^ ]*\*' || [ "$target_count" -gt 1 ]; then
|
|
41
|
+
echo "[Hook] ⛔ RULE DELETION BLOCKED — Multiple rules detected" >&2
|
|
42
|
+
echo "[Hook] Targets: $targets" >&2
|
|
43
|
+
echo "[Hook] Rule files must be deleted ONE AT A TIME with user confirmation." >&2
|
|
44
|
+
echo "[Hook] Delete each rule individually after asking: \"정말 {파일명}을(를) 삭제하시겠습니까?\"" >&2
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Single rule file
|
|
49
|
+
filename=$(basename "$targets" 2>/dev/null || echo "$targets")
|
|
50
|
+
echo "[Hook] ⛔ RULE DELETION BLOCKED" >&2
|
|
51
|
+
echo "[Hook] Target: $filename" >&2
|
|
52
|
+
echo "[Hook] Rule files require individual user confirmation before deletion." >&2
|
|
53
|
+
echo "[Hook] Ask the user: \"정말 ${filename}을(를) 삭제하시겠습니까?\"" >&2
|
|
54
|
+
echo "[Hook] Only proceed after explicit user approval." >&2
|
|
55
|
+
exit 2
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Not a rule deletion — pass through
|
|
59
|
+
echo "$input"
|
|
60
|
+
exit 0
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Schema Validator Hook — PreToolUse input validation
|
|
3
|
+
# Trigger: PreToolUse on Write, Edit, Bash
|
|
4
|
+
# Purpose: Validate tool inputs against JSON Schema definitions
|
|
5
|
+
# Phase 1: Advisory only (exit 0 with stderr warning)
|
|
6
|
+
# Protocol: stdin JSON -> validate -> stdout pass-through
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Dependency check: exit silently if jq not available
|
|
11
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
12
|
+
|
|
13
|
+
input=$(cat)
|
|
14
|
+
|
|
15
|
+
# Extract tool info
|
|
16
|
+
tool_name=$(echo "$input" | jq -r '.tool_name // "unknown"')
|
|
17
|
+
tool_input=$(echo "$input" | jq -r '.tool_input // {}')
|
|
18
|
+
|
|
19
|
+
SCHEMA_FILE=".codex/schemas/tool-inputs.json"
|
|
20
|
+
|
|
21
|
+
# Skip if schema file doesn't exist
|
|
22
|
+
if [ ! -f "$SCHEMA_FILE" ]; then
|
|
23
|
+
echo "$input"
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
warnings=()
|
|
28
|
+
|
|
29
|
+
case "$tool_name" in
|
|
30
|
+
"Write")
|
|
31
|
+
file_path=$(echo "$tool_input" | jq -r '.file_path // ""')
|
|
32
|
+
content=$(echo "$tool_input" | jq -r '.content // ""')
|
|
33
|
+
|
|
34
|
+
if [ -z "$file_path" ]; then
|
|
35
|
+
warnings+=("[Schema] Write: file_path is empty or missing")
|
|
36
|
+
fi
|
|
37
|
+
if [ -z "$content" ]; then
|
|
38
|
+
warnings+=("[Schema] Write: content is empty — creating empty file?")
|
|
39
|
+
fi
|
|
40
|
+
;;
|
|
41
|
+
|
|
42
|
+
"Edit")
|
|
43
|
+
file_path=$(echo "$tool_input" | jq -r '.file_path // ""')
|
|
44
|
+
old_string=$(echo "$tool_input" | jq -r '.old_string // ""')
|
|
45
|
+
new_string=$(echo "$tool_input" | jq -r '.new_string // ""')
|
|
46
|
+
|
|
47
|
+
if [ -z "$file_path" ]; then
|
|
48
|
+
warnings+=("[Schema] Edit: file_path is empty or missing")
|
|
49
|
+
fi
|
|
50
|
+
if [ -z "$old_string" ]; then
|
|
51
|
+
warnings+=("[Schema] Edit: old_string is empty")
|
|
52
|
+
fi
|
|
53
|
+
if [ "$old_string" = "$new_string" ]; then
|
|
54
|
+
warnings+=("[Schema] Edit: old_string equals new_string — no-op edit")
|
|
55
|
+
fi
|
|
56
|
+
;;
|
|
57
|
+
|
|
58
|
+
"Bash")
|
|
59
|
+
command=$(echo "$tool_input" | jq -r '.command // ""')
|
|
60
|
+
|
|
61
|
+
if [ -z "$command" ]; then
|
|
62
|
+
warnings+=("[Schema] Bash: command is empty")
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Check dangerous patterns
|
|
66
|
+
if echo "$command" | grep -qE 'rm\s+-rf\s+/[^.]'; then
|
|
67
|
+
warnings+=("[Schema] Bash: DANGER — recursive delete from root detected")
|
|
68
|
+
fi
|
|
69
|
+
if echo "$command" | grep -qE '^\s*sudo\s+'; then
|
|
70
|
+
warnings+=("[Schema] Bash: elevated privilege command detected")
|
|
71
|
+
fi
|
|
72
|
+
if echo "$command" | grep -qE '> /dev/sd'; then
|
|
73
|
+
warnings+=("[Schema] Bash: direct disk write detected")
|
|
74
|
+
fi
|
|
75
|
+
if echo "$command" | grep -qE 'mkfs\.'; then
|
|
76
|
+
warnings+=("[Schema] Bash: filesystem format command detected")
|
|
77
|
+
fi
|
|
78
|
+
# Remote code execution via pipe
|
|
79
|
+
if echo "$command" | grep -qE 'curl\s+.*\|\s*(ba)?sh'; then
|
|
80
|
+
warnings+=("[Schema] Bash: remote code execution pattern (curl | bash) detected")
|
|
81
|
+
fi
|
|
82
|
+
if echo "$command" | grep -qE 'wget\s+.*\|\s*(ba)?sh'; then
|
|
83
|
+
warnings+=("[Schema] Bash: remote code execution pattern (wget | sh) detected")
|
|
84
|
+
fi
|
|
85
|
+
# Dynamic code execution
|
|
86
|
+
if echo "$command" | grep -qE 'eval\s+\$\('; then
|
|
87
|
+
warnings+=("[Schema] Bash: dynamic code execution (eval) detected")
|
|
88
|
+
fi
|
|
89
|
+
# Broad permission grant
|
|
90
|
+
if echo "$command" | grep -qE 'chmod\s+777'; then
|
|
91
|
+
warnings+=("[Schema] Bash: broad permission grant (chmod 777) detected")
|
|
92
|
+
fi
|
|
93
|
+
;;
|
|
94
|
+
esac
|
|
95
|
+
|
|
96
|
+
# Output warnings (advisory only)
|
|
97
|
+
if [ ${#warnings[@]} -gt 0 ]; then
|
|
98
|
+
for w in "${warnings[@]}"; do
|
|
99
|
+
echo "$w" >&2
|
|
100
|
+
done
|
|
101
|
+
echo "[Schema] Phase 1: advisory only — not blocking" >&2
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Always pass through (Phase 1)
|
|
105
|
+
echo "$input"
|
|
106
|
+
exit 0
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Secret Output Filter Hook — Detect potential secrets in tool output
|
|
3
|
+
# Trigger: PostToolUse on Bash, Read, Grep
|
|
4
|
+
# Purpose: Advisory warning when potential secrets detected in output
|
|
5
|
+
# Protocol: stdin JSON -> scan -> stdout pass-through
|
|
6
|
+
# Always exits 0 (advisory only, never blocks)
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Dependency check: exit silently if jq not available
|
|
11
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
12
|
+
|
|
13
|
+
input=$(cat)
|
|
14
|
+
|
|
15
|
+
# Extract output to scan
|
|
16
|
+
tool_name=$(echo "$input" | jq -r '.tool_name // "unknown"')
|
|
17
|
+
output=$(echo "$input" | jq -r '.tool_output.output // ""')
|
|
18
|
+
|
|
19
|
+
# Skip if no output
|
|
20
|
+
if [ -z "$output" ] || [ "$output" = "null" ]; then
|
|
21
|
+
echo "$input"
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Secret patterns to detect
|
|
26
|
+
detected=false
|
|
27
|
+
|
|
28
|
+
# AWS Access Key ID
|
|
29
|
+
if echo "$output" | grep -qE 'AKIA[0-9A-Z]{16}'; then
|
|
30
|
+
echo "[Security] Potential AWS Access Key detected in ${tool_name} output" >&2
|
|
31
|
+
detected=true
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# OpenAI/Anthropic API Key
|
|
35
|
+
if echo "$output" | grep -qE 'sk-[a-zA-Z0-9]{32,}'; then
|
|
36
|
+
echo "[Security] Potential API key (sk-*) detected in ${tool_name} output" >&2
|
|
37
|
+
detected=true
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# GitHub Personal Access Token
|
|
41
|
+
if echo "$output" | grep -qE 'ghp_[a-zA-Z0-9]{36}'; then
|
|
42
|
+
echo "[Security] Potential GitHub PAT detected in ${tool_name} output" >&2
|
|
43
|
+
detected=true
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Private Key
|
|
47
|
+
if echo "$output" | grep -qE '-----BEGIN.*PRIVATE KEY-----'; then
|
|
48
|
+
echo "[Security] Potential private key detected in ${tool_name} output" >&2
|
|
49
|
+
detected=true
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Bearer Token (long)
|
|
53
|
+
if echo "$output" | grep -qE 'Bearer [a-zA-Z0-9._-]{20,}'; then
|
|
54
|
+
echo "[Security] Potential Bearer token detected in ${tool_name} output" >&2
|
|
55
|
+
detected=true
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# GitHub OAuth Token
|
|
59
|
+
if echo "$output" | grep -qE 'gho_[a-zA-Z0-9]{36}'; then
|
|
60
|
+
echo "[Security] Potential GitHub OAuth token detected in ${tool_name} output" >&2
|
|
61
|
+
detected=true
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# GitHub Fine-Grained PAT
|
|
65
|
+
if echo "$output" | grep -qE 'github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}'; then
|
|
66
|
+
echo "[Security] Potential GitHub Fine-Grained PAT detected in ${tool_name} output" >&2
|
|
67
|
+
detected=true
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# GitHub Actions Token
|
|
71
|
+
if echo "$output" | grep -qE 'ghs_[a-zA-Z0-9]{36}'; then
|
|
72
|
+
echo "[Security] Potential GitHub Actions token detected in ${tool_name} output" >&2
|
|
73
|
+
detected=true
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# npm Token
|
|
77
|
+
if echo "$output" | grep -qE 'npm_[a-zA-Z0-9]{36}'; then
|
|
78
|
+
echo "[Security] Potential npm token detected in ${tool_name} output" >&2
|
|
79
|
+
detected=true
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# Slack Token
|
|
83
|
+
if echo "$output" | grep -qE 'xox[bsarp]-[a-zA-Z0-9-]{10,}'; then
|
|
84
|
+
echo "[Security] Potential Slack token detected in ${tool_name} output" >&2
|
|
85
|
+
detected=true
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Docker Hub PAT
|
|
89
|
+
if echo "$output" | grep -qE 'dckr_pat_[a-zA-Z0-9_-]{20,}'; then
|
|
90
|
+
echo "[Security] Potential Docker Hub PAT detected in ${tool_name} output" >&2
|
|
91
|
+
detected=true
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
if [ "$detected" = true ]; then
|
|
95
|
+
echo "[Security] Review output carefully — do NOT commit or expose secrets" >&2
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Pass through (always)
|
|
99
|
+
echo "$input"
|
|
100
|
+
exit 0
|