sinapse-ai 9.4.0 → 9.5.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/.claude/CLAUDE.md +10 -4
- package/.claude/hooks/enforce-architecture-first.py +197 -197
- package/.claude/hooks/enforce-git-push-authority.sh +25 -4
- package/.claude/hooks/mind-clone-governance.py +193 -193
- package/.claude/hooks/read-protection.py +152 -152
- package/.claude/hooks/sql-governance.py +183 -183
- package/.claude/hooks/verify-packages.cjs +83 -0
- package/.claude/hooks/write-path-validation.py +195 -195
- package/.claude/rules/hook-governance.md +1 -0
- package/.claude/rules/mandatory-delegation.md +24 -0
- package/.claude/rules/project-intelligence.md +63 -0
- package/.claude/rules/response-format.md +4 -0
- package/.claude/rules/safe-collaboration.md +4 -2
- package/.claude/rules/security-data-protection.md +18 -0
- package/.claude/rules/squad-awareness.md +93 -67
- package/.claude/rules/token-economy.md +148 -0
- package/.codex/agents/analyst.md +90 -0
- package/.codex/agents/architect.md +78 -0
- package/.codex/agents/data-engineer.md +38 -0
- package/.codex/agents/developer.md +97 -0
- package/.codex/agents/devops.md +121 -0
- package/.codex/agents/product-lead.md +27 -0
- package/.codex/agents/project-lead.md +28 -0
- package/.codex/agents/quality-gate.md +89 -0
- package/.codex/agents/sprint-lead.md +28 -0
- package/.codex/agents/squad-creator.md +58 -0
- package/.codex/agents/ux-design-expert.md +28 -0
- package/.sinapse-ai/core/code-intel/registry-syncer.js +56 -3
- package/.sinapse-ai/core/doctor/checks/agent-memory.js +5 -1
- package/.sinapse-ai/core/doctor/checks/claude-md.js +4 -1
- package/.sinapse-ai/core/doctor/checks/code-intel.js +5 -1
- package/.sinapse-ai/core/doctor/checks/commands-count.js +4 -1
- package/.sinapse-ai/core/doctor/checks/constitution-consistency.js +4 -1
- package/.sinapse-ai/core/doctor/checks/core-config.js +4 -1
- package/.sinapse-ai/core/doctor/checks/entity-registry.js +6 -1
- package/.sinapse-ai/core/doctor/checks/git-hooks.js +5 -1
- package/.sinapse-ai/core/doctor/checks/graph-dashboard.js +4 -1
- package/.sinapse-ai/core/doctor/checks/hooks-claude-count.js +5 -1
- package/.sinapse-ai/core/doctor/checks/ide-sync.js +4 -1
- package/.sinapse-ai/core/doctor/checks/node-version.js +4 -1
- package/.sinapse-ai/core/doctor/checks/npm-packages.js +4 -1
- package/.sinapse-ai/core/doctor/checks/rules-files.js +4 -1
- package/.sinapse-ai/core/doctor/checks/settings-json.js +4 -1
- package/.sinapse-ai/core/doctor/checks/skills-count.js +4 -1
- package/.sinapse-ai/core/doctor/index.js +157 -50
- package/.sinapse-ai/core/ids/registry-updater.js +6 -1
- package/.sinapse-ai/core/logger/index.js +319 -0
- package/.sinapse-ai/core/orchestration/terminal-spawner.js +2 -2
- package/.sinapse-ai/core/telemetry/index.js +247 -0
- package/.sinapse-ai/data/entity-registry.yaml +1384 -944
- package/.sinapse-ai/development/agents/architect.md +5 -0
- package/.sinapse-ai/development/agents/data-engineer.md +38 -0
- package/.sinapse-ai/development/agents/developer.md +28 -0
- package/.sinapse-ai/development/agents/devops.md +4 -0
- package/.sinapse-ai/development/agents/product-lead.md +27 -0
- package/.sinapse-ai/development/agents/project-lead.md +28 -0
- package/.sinapse-ai/development/agents/quality-gate.md +4 -0
- package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +8 -0
- package/.sinapse-ai/development/agents/sprint-lead.md +28 -0
- package/.sinapse-ai/development/agents/squad-creator.md +58 -0
- package/.sinapse-ai/development/agents/ux-design-expert.md +28 -0
- package/.sinapse-ai/development/knowledge-base/agent-communication-protocol.md +127 -0
- package/.sinapse-ai/development/knowledge-base/database-scaling-patterns.md +374 -0
- package/.sinapse-ai/development/knowledge-base/environment-deployment-patterns.md +353 -0
- package/.sinapse-ai/development/knowledge-base/gotchas-patterns.md +224 -0
- package/.sinapse-ai/development/knowledge-base/infrastructure-decision-framework.md +221 -0
- package/.sinapse-ai/development/knowledge-base/security-pre-deploy-checklist.md +410 -0
- package/.sinapse-ai/development/knowledge-base/software-architecture-patterns.md +299 -0
- package/.sinapse-ai/development/knowledge-base/token-economy-guide.md +198 -0
- package/.sinapse-ai/development/scripts/populate-entity-registry.js +5 -1
- package/.sinapse-ai/development/skills/captcha-handler.md +82 -0
- package/.sinapse-ai/development/skills/chrome-brain.md +81 -0
- package/.sinapse-ai/development/skills/deploy-readiness.md +93 -0
- package/.sinapse-ai/development/skills/model-router.md +92 -0
- package/.sinapse-ai/development/skills/sinapse-methodology.md +175 -0
- package/.sinapse-ai/development/skills/story-fast-track.md +71 -0
- package/.sinapse-ai/development/tasks/dev-develop-story.md +10 -0
- package/.sinapse-ai/development/tasks/environment-promotion-pipeline.md +582 -0
- package/.sinapse-ai/development/tasks/generate-agent-handoff.md +223 -0
- package/.sinapse-ai/development/tasks/infrastructure-assessment.md +432 -0
- package/.sinapse-ai/development/tasks/load-testing-setup.md +611 -0
- package/.sinapse-ai/development/tasks/observability-blueprint.md +562 -0
- package/.sinapse-ai/development/templates/legal/breach-notification-tmpl.md +113 -0
- package/.sinapse-ai/development/templates/legal/privacy-policy-tmpl.md +93 -0
- package/.sinapse-ai/development/templates/legal/terms-of-service-tmpl.md +85 -0
- package/.sinapse-ai/development/templates/service-template/README.md.hbs +159 -159
- package/.sinapse-ai/development/templates/service-template/__tests__/index.test.ts.hbs +238 -238
- package/.sinapse-ai/development/templates/service-template/client.ts.hbs +404 -404
- package/.sinapse-ai/development/templates/service-template/errors.ts.hbs +183 -183
- package/.sinapse-ai/development/templates/service-template/index.ts.hbs +121 -121
- package/.sinapse-ai/development/templates/service-template/package.json.hbs +88 -88
- package/.sinapse-ai/development/templates/service-template/types.ts.hbs +146 -146
- package/.sinapse-ai/development/templates/squad-template/LICENSE +22 -22
- package/.sinapse-ai/development/workflows/story-development-cycle.yaml +40 -1
- package/.sinapse-ai/hooks/ids-post-commit.js +22 -0
- package/.sinapse-ai/infrastructure/contracts/compatibility/README.md +42 -0
- package/.sinapse-ai/infrastructure/contracts/compatibility/sinapse-current.yaml +35 -0
- package/.sinapse-ai/infrastructure/scripts/llm-routing/templates/claude-free-tracked.cmd +127 -127
- package/.sinapse-ai/infrastructure/scripts/llm-routing/templates/deepseek-proxy.cmd +71 -71
- package/.sinapse-ai/infrastructure/scripts/llm-routing/templates/deepseek-usage.cmd +51 -51
- package/.sinapse-ai/infrastructure/scripts/pr-review-ai.js +16 -13
- package/.sinapse-ai/infrastructure/scripts/setup-project-infra.js +128 -0
- package/.sinapse-ai/infrastructure/scripts/test-discovery.js +8 -3
- package/.sinapse-ai/infrastructure/scripts/validate-manifest-parity.js +380 -0
- package/.sinapse-ai/infrastructure/scripts/validate-parity.js +76 -25
- package/.sinapse-ai/infrastructure/templates/coderabbit.yaml.template +280 -280
- package/.sinapse-ai/infrastructure/templates/config/env.example +16 -0
- package/.sinapse-ai/infrastructure/templates/config/gitignore-additions.tmpl +59 -0
- package/.sinapse-ai/infrastructure/templates/github/CODEOWNERS.template +12 -0
- package/.sinapse-ai/infrastructure/templates/github/PULL_REQUEST_TEMPLATE.md +29 -0
- package/.sinapse-ai/infrastructure/templates/github/ci-template.yml +77 -0
- package/.sinapse-ai/infrastructure/templates/github/issue-templates/bug_report.md +34 -0
- package/.sinapse-ai/infrastructure/templates/github/issue-templates/feature_request.md +19 -0
- package/.sinapse-ai/infrastructure/templates/github-workflows/ci.yml.template +170 -170
- package/.sinapse-ai/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -331
- package/.sinapse-ai/infrastructure/templates/github-workflows/release.yml.template +197 -197
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +19 -19
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -86
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -146
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-sinapse-base.tmpl +64 -64
- package/.sinapse-ai/infrastructure/templates/sinapse-sync.yaml.template +183 -183
- package/.sinapse-ai/install-manifest.yaml +275 -140
- package/.sinapse-ai/local-config.yaml.template +65 -65
- package/.sinapse-ai/monitor/hooks/lib/__init__.py +2 -2
- package/.sinapse-ai/monitor/hooks/lib/enrich.py +59 -59
- package/.sinapse-ai/monitor/hooks/lib/send_event.py +48 -48
- package/.sinapse-ai/monitor/hooks/notification.py +30 -30
- package/.sinapse-ai/monitor/hooks/post_tool_use.py +46 -46
- package/.sinapse-ai/monitor/hooks/pre_compact.py +30 -30
- package/.sinapse-ai/monitor/hooks/pre_tool_use.py +41 -41
- package/.sinapse-ai/monitor/hooks/stop.py +30 -30
- package/.sinapse-ai/monitor/hooks/subagent_stop.py +30 -30
- package/.sinapse-ai/monitor/hooks/user_prompt_submit.py +39 -39
- package/.sinapse-ai/product/templates/adr.hbs +126 -126
- package/.sinapse-ai/product/templates/dbdr.hbs +242 -242
- package/.sinapse-ai/product/templates/epic.hbs +213 -213
- package/.sinapse-ai/product/templates/pmdr.hbs +187 -187
- package/.sinapse-ai/product/templates/prd-v2.0.hbs +217 -217
- package/.sinapse-ai/product/templates/prd.hbs +202 -202
- package/.sinapse-ai/product/templates/story-tmpl.yaml +59 -0
- package/.sinapse-ai/product/templates/story.hbs +264 -264
- package/.sinapse-ai/product/templates/task.hbs +171 -171
- package/.sinapse-ai/product/templates/tmpl-comment-on-examples.sql +159 -159
- package/.sinapse-ai/product/templates/tmpl-migration-script.sql +92 -92
- package/.sinapse-ai/product/templates/tmpl-rls-granular-policies.sql +105 -105
- package/.sinapse-ai/product/templates/tmpl-rls-kiss-policy.sql +11 -11
- package/.sinapse-ai/product/templates/tmpl-rls-roles.sql +136 -136
- package/.sinapse-ai/product/templates/tmpl-rls-simple.sql +78 -78
- package/.sinapse-ai/product/templates/tmpl-rls-tenant.sql +153 -153
- package/.sinapse-ai/product/templates/tmpl-rollback-script.sql +78 -78
- package/.sinapse-ai/product/templates/tmpl-seed-data.sql +141 -141
- package/.sinapse-ai/product/templates/tmpl-smoke-test.sql +17 -17
- package/.sinapse-ai/product/templates/tmpl-staging-copy-merge.sql +140 -140
- package/.sinapse-ai/product/templates/tmpl-stored-proc.sql +141 -141
- package/.sinapse-ai/product/templates/tmpl-trigger.sql +153 -153
- package/.sinapse-ai/product/templates/tmpl-view-materialized.sql +134 -134
- package/.sinapse-ai/product/templates/tmpl-view.sql +178 -178
- package/.sinapse-ai/scripts/diagnostics/health-dashboard/package-lock.json +427 -355
- package/LICENSE +34 -34
- package/README.en.md +167 -20
- package/README.md +190 -22
- package/bin/cli.js +510 -196
- package/bin/postinstall.js +564 -0
- package/bin/sinapse-cli +283 -283
- package/bin/sinapse-graph.js +9 -0
- package/bin/sinapse-init.js +36 -4
- package/bin/sinapse-minimal.js +20 -9
- package/bin/sinapse.js +202 -122
- package/bin/utils/deprecation-warning.js +46 -0
- package/bin/utils/pre-push-safety.js +14 -0
- package/docs/TELEMETRY.md +131 -0
- package/docs/chrome-brain-upgrade-plan.md +624 -0
- package/docs/framework/orqx-plan.md +1 -1
- package/docs/installation/chrome-brain.md +17 -7
- package/docs/mega-upgrade-orchestration-plan.md +71 -0
- package/docs/pt/contributing.md +20 -0
- package/docs/research-synthesis-for-upgrade.md +511 -0
- package/docs/security-audit-report.md +306 -0
- package/package.json +20 -8
- package/packages/installer/src/config/configure-environment.js +19 -44
- package/packages/installer/src/detection/detect-project-type.js +181 -63
- package/packages/installer/src/installer/manifest-signature.js +32 -17
- package/packages/installer/src/wizard/i18n.js +12 -0
- package/packages/installer/src/wizard/ide-config-generator.js +8 -39
- package/packages/installer/src/wizard/index.js +119 -14
- package/packages/installer/src/wizard/questions.js +2 -3
- package/packages/installer/tests/integration/environment-configuration.test.js +7 -5
- package/packages/installer/tests/unit/detection/detect-project-type.test.js +138 -1
- package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +3 -3
- package/packages/sinapse-install/bin/edmcp.js +0 -0
- package/packages/sinapse-install/bin/sinapse-install.js +0 -0
- package/packages/sinapse-pro-cli/bin/sinapse-pro.js +0 -0
- package/scripts/check-markdown-links.py +353 -353
- package/scripts/coverage-report-summary.js +169 -0
- package/scripts/generate-install-manifest.js +6 -2
- package/scripts/release-readiness.js +169 -0
- package/scripts/test-install-matrix-local.sh +153 -0
- package/scripts/validate-install-docs.js +394 -0
- package/scripts/validate-no-external-refs.js +376 -0
- package/scripts/validate-squad-orqx.js +302 -0
- package/scripts/validate-story-meta.js +263 -0
- package/squads/claude-code-mastery/CHANGELOG.md +1 -1
- package/squads/claude-code-mastery/README.md +2 -2
- package/squads/claude-code-mastery/squad.yaml +1 -1
- package/squads/squad-artdir/README.md +90 -0
- package/squads/squad-artdir/agents/accessibility-guardian.md +184 -0
- package/squads/squad-artdir/agents/artdir-orqx.md +145 -0
- package/squads/squad-artdir/agents/color-psychologist.md +166 -0
- package/squads/squad-artdir/agents/cro-persuasion.md +161 -0
- package/squads/squad-artdir/agents/design-system-architect.md +100 -0
- package/squads/squad-artdir/agents/ia-architect.md +169 -0
- package/squads/squad-artdir/agents/interaction-designer.md +162 -0
- package/squads/squad-artdir/agents/layout-engineer.md +163 -0
- package/squads/squad-artdir/agents/motion-architect.md +185 -0
- package/squads/squad-artdir/agents/platform-aesthetic-director.md +84 -0
- package/squads/squad-artdir/agents/premium-packaging-strategist.md +107 -0
- package/squads/squad-artdir/agents/product-surface-director.md +86 -0
- package/squads/squad-artdir/agents/type-systemist.md +138 -0
- package/squads/squad-artdir/agents/visual-strategist.md +127 -0
- package/squads/squad-artdir/checklists/seven-pillars-validation-checklist.md +172 -0
- package/squads/squad-artdir/knowledge-base/case-nyo-ia-reference.md +289 -0
- package/squads/squad-artdir/knowledge-base/deliverables-templates.md +457 -0
- package/squads/squad-artdir/knowledge-base/motion-technique-catalog.md +247 -0
- package/squads/squad-artdir/knowledge-base/premium-packaging-principles.md +133 -0
- package/squads/squad-artdir/knowledge-base/psychological-toolkit.md +229 -0
- package/squads/squad-artdir/knowledge-base/saas-art-direction-canon.md +242 -0
- package/squads/squad-artdir/knowledge-base/seven-pillars-framework.md +289 -0
- package/squads/squad-artdir/knowledge-base/ten-pillars-framework.md +221 -0
- package/squads/squad-artdir/package.json +20 -0
- package/squads/squad-artdir/squad.yaml +271 -0
- package/squads/squad-artdir/tasks/audit-conversion.md +97 -0
- package/squads/squad-artdir/tasks/audit-drift-multi-surface.md +55 -0
- package/squads/squad-artdir/tasks/consult-saas-canon.md +54 -0
- package/squads/squad-artdir/tasks/create-art-direction-brief.md +110 -0
- package/squads/squad-artdir/tasks/create-premium-packaging-brief.md +61 -0
- package/squads/squad-artdir/tasks/create-wireflow.md +84 -0
- package/squads/squad-artdir/tasks/design-color-system.md +81 -0
- package/squads/squad-artdir/tasks/design-product-surface.md +60 -0
- package/squads/squad-artdir/tasks/design-token-system.md +58 -0
- package/squads/squad-artdir/tasks/diagnose-visual-language.md +92 -0
- package/squads/squad-artdir/tasks/first-5-minutes-choreography.md +65 -0
- package/squads/squad-artdir/tasks/specify-motion-system.md +84 -0
- package/squads/squad-artdir/tasks/validate-against-pillars.md +143 -0
- package/squads/squad-artdir/templates/art-direction-brief-template.md +215 -0
- package/squads/squad-artdir/workflows/conversion-audit-cycle.yaml +78 -0
- package/squads/squad-artdir/workflows/full-art-direction-cycle.yaml +98 -0
- package/squads/squad-artdir/workflows/saas-platform-art-direction-cycle.yaml +174 -0
- package/squads/squad-brand/knowledge-base/ai-visual-generation-canon.md +234 -0
- package/squads/squad-brand/squad.yaml +20 -6
- package/squads/squad-claude/knowledge-base/context-window-optimization.md +1 -1
- package/squads/squad-claude/knowledge-base/swarm-orchestration-patterns.md +2 -2
- package/squads/squad-content/knowledge-base/ai-native-content-loop.md +220 -0
- package/squads/squad-content/knowledge-base/signal-intelligence-v2.md +234 -0
- package/squads/squad-content/knowledge-base/task-ownership-map.md +235 -0
- package/squads/squad-content/squad.yaml +187 -27
- package/squads/squad-copy/knowledge-base/ai-copy-human-loop-canon.md +235 -0
- package/squads/squad-copy/squad.yaml +19 -4
- package/squads/squad-design/knowledge-base/cross-surface-token-canon.md +209 -0
- package/squads/squad-design/squad.yaml +19 -4
- package/.sinapse-ai/core/registry/service-registry.json +0 -6346
- package/.sinapse-ai/data/registry-update-log.jsonl +0 -1323
- package/.sinapse-ai/manifests/agents.csv +0 -29
- package/.sinapse-ai/manifests/tasks.csv +0 -204
- package/.sinapse-ai/manifests/workers.csv +0 -196
- package/squads/squad-growth/tasks/calculate-sample-size.md +0 -121
- package/squads/squad-paidmedia/tasks/calculate-sample-size.md +0 -57
|
@@ -1,152 +1,152 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Hook: Read Protection
|
|
4
|
-
|
|
5
|
-
REGRA: Arquivos protegidos DEVEM ser lidos completamente (sem limit/offset).
|
|
6
|
-
|
|
7
|
-
Este hook intercepta chamadas Read e bloqueia leitura parcial em arquivos
|
|
8
|
-
que requerem contexto completo para edição segura.
|
|
9
|
-
|
|
10
|
-
Exit Codes:
|
|
11
|
-
- 0: Permitido
|
|
12
|
-
- 2: Bloqueado (arquivo protegido com limit/offset)
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
import json
|
|
16
|
-
import sys
|
|
17
|
-
import os
|
|
18
|
-
import fnmatch
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
|
|
21
|
-
# =============================================================================
|
|
22
|
-
# CONFIGURAÇÃO: Arquivos que DEVEM ser lidos completamente
|
|
23
|
-
# =============================================================================
|
|
24
|
-
|
|
25
|
-
PROTECTED_PATTERNS = [
|
|
26
|
-
# Configuração do Claude
|
|
27
|
-
".claude/CLAUDE.md",
|
|
28
|
-
".claude/rules/*.md",
|
|
29
|
-
".claude/settings*.json",
|
|
30
|
-
|
|
31
|
-
# Definições de agentes
|
|
32
|
-
".sinapse-ai/development/agents/*.md",
|
|
33
|
-
".sinapse-upstream/.sinapse-ai/development/agents/*.md",
|
|
34
|
-
|
|
35
|
-
# Documentação crítica
|
|
36
|
-
"docs/mmos/ARCHITECTURE_RULES.md",
|
|
37
|
-
"supabase/docs/SCHEMA.md",
|
|
38
|
-
|
|
39
|
-
# Configuração do projeto
|
|
40
|
-
"package.json",
|
|
41
|
-
"tsconfig.json",
|
|
42
|
-
"tsconfig.*.json",
|
|
43
|
-
|
|
44
|
-
# Arquivos de código críticos
|
|
45
|
-
"app/components/ui/icons/icon-map.ts",
|
|
46
|
-
|
|
47
|
-
# Migrations (sempre ler completo antes de editar)
|
|
48
|
-
"supabase/migrations/*.sql",
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
# =============================================================================
|
|
52
|
-
# LÓGICA DO HOOK
|
|
53
|
-
# =============================================================================
|
|
54
|
-
|
|
55
|
-
def get_project_root():
|
|
56
|
-
"""Obtém o root do projeto via variável de ambiente ou cwd."""
|
|
57
|
-
return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
58
|
-
|
|
59
|
-
def normalize_path(file_path: str, project_root: str) -> str:
|
|
60
|
-
"""Normaliza path para relativo ao projeto."""
|
|
61
|
-
if file_path.startswith(project_root):
|
|
62
|
-
return file_path[len(project_root):].lstrip("/")
|
|
63
|
-
if file_path.startswith("/"):
|
|
64
|
-
# Path absoluto fora do projeto
|
|
65
|
-
return file_path
|
|
66
|
-
return file_path
|
|
67
|
-
|
|
68
|
-
def matches_protected_pattern(relative_path: str) -> bool:
|
|
69
|
-
"""Verifica se o path corresponde a algum padrão protegido."""
|
|
70
|
-
for pattern in PROTECTED_PATTERNS:
|
|
71
|
-
if fnmatch.fnmatch(relative_path, pattern):
|
|
72
|
-
return True
|
|
73
|
-
# Também verificar se é substring (para paths com wildcards)
|
|
74
|
-
if "*" not in pattern and pattern in relative_path:
|
|
75
|
-
return True
|
|
76
|
-
return False
|
|
77
|
-
|
|
78
|
-
def has_partial_read_params(tool_input: dict) -> tuple[bool, str]:
|
|
79
|
-
"""Verifica se a chamada Read tem parâmetros de leitura parcial."""
|
|
80
|
-
limit = tool_input.get("limit")
|
|
81
|
-
offset = tool_input.get("offset")
|
|
82
|
-
|
|
83
|
-
reasons = []
|
|
84
|
-
if limit is not None:
|
|
85
|
-
reasons.append(f"limit={limit}")
|
|
86
|
-
if offset is not None and offset != 0:
|
|
87
|
-
reasons.append(f"offset={offset}")
|
|
88
|
-
|
|
89
|
-
return len(reasons) > 0, ", ".join(reasons)
|
|
90
|
-
|
|
91
|
-
def main():
|
|
92
|
-
# Ler input do stdin
|
|
93
|
-
try:
|
|
94
|
-
input_data = json.load(sys.stdin)
|
|
95
|
-
except json.JSONDecodeError:
|
|
96
|
-
# Se não conseguir parsear, permitir (fail-open)
|
|
97
|
-
sys.exit(0)
|
|
98
|
-
|
|
99
|
-
tool_name = input_data.get("tool_name", "")
|
|
100
|
-
tool_input = input_data.get("tool_input", {})
|
|
101
|
-
|
|
102
|
-
# Só processar Read
|
|
103
|
-
if tool_name != "Read":
|
|
104
|
-
sys.exit(0)
|
|
105
|
-
|
|
106
|
-
file_path = tool_input.get("file_path", "")
|
|
107
|
-
if not file_path:
|
|
108
|
-
sys.exit(0)
|
|
109
|
-
|
|
110
|
-
# Normalizar path
|
|
111
|
-
project_root = get_project_root()
|
|
112
|
-
relative_path = normalize_path(file_path, project_root)
|
|
113
|
-
|
|
114
|
-
# Verificar se é arquivo protegido
|
|
115
|
-
if not matches_protected_pattern(relative_path):
|
|
116
|
-
sys.exit(0)
|
|
117
|
-
|
|
118
|
-
# Verificar se tem parâmetros de leitura parcial
|
|
119
|
-
is_partial, partial_reason = has_partial_read_params(tool_input)
|
|
120
|
-
|
|
121
|
-
if not is_partial:
|
|
122
|
-
# Leitura completa, permitir
|
|
123
|
-
sys.exit(0)
|
|
124
|
-
|
|
125
|
-
# BLOQUEAR: Tentando ler arquivo protegido parcialmente
|
|
126
|
-
error_message = f"""
|
|
127
|
-
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
128
|
-
║ 🛑 READ PROTECTION: Arquivo protegido deve ser lido completamente ║
|
|
129
|
-
╠══════════════════════════════════════════════════════════════════════════════╣
|
|
130
|
-
║ ║
|
|
131
|
-
║ Arquivo: {relative_path[:58]:<58} ║
|
|
132
|
-
║ Problema: {partial_reason:<57} ║
|
|
133
|
-
║ ║
|
|
134
|
-
║ REGRA: Este arquivo está na lista de arquivos protegidos. ║
|
|
135
|
-
║ Arquivos protegidos DEVEM ser lidos completamente para evitar: ║
|
|
136
|
-
║ - Edições com contexto incompleto ║
|
|
137
|
-
║ - Duplicações acidentais ║
|
|
138
|
-
║ - Breaking changes não intencionais ║
|
|
139
|
-
║ ║
|
|
140
|
-
║ SOLUÇÃO: Remova os parâmetros 'limit' e 'offset' da chamada Read. ║
|
|
141
|
-
║ ║
|
|
142
|
-
║ ✅ Read(file_path="{relative_path[:40]}")
|
|
143
|
-
║ ❌ Read(file_path="...", limit=100) ║
|
|
144
|
-
║ ║
|
|
145
|
-
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
146
|
-
"""
|
|
147
|
-
print(error_message, file=sys.stderr)
|
|
148
|
-
sys.exit(2)
|
|
149
|
-
|
|
150
|
-
if __name__ == "__main__":
|
|
151
|
-
main()
|
|
152
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Hook: Read Protection
|
|
4
|
+
|
|
5
|
+
REGRA: Arquivos protegidos DEVEM ser lidos completamente (sem limit/offset).
|
|
6
|
+
|
|
7
|
+
Este hook intercepta chamadas Read e bloqueia leitura parcial em arquivos
|
|
8
|
+
que requerem contexto completo para edição segura.
|
|
9
|
+
|
|
10
|
+
Exit Codes:
|
|
11
|
+
- 0: Permitido
|
|
12
|
+
- 2: Bloqueado (arquivo protegido com limit/offset)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import sys
|
|
17
|
+
import os
|
|
18
|
+
import fnmatch
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
# =============================================================================
|
|
22
|
+
# CONFIGURAÇÃO: Arquivos que DEVEM ser lidos completamente
|
|
23
|
+
# =============================================================================
|
|
24
|
+
|
|
25
|
+
PROTECTED_PATTERNS = [
|
|
26
|
+
# Configuração do Claude
|
|
27
|
+
".claude/CLAUDE.md",
|
|
28
|
+
".claude/rules/*.md",
|
|
29
|
+
".claude/settings*.json",
|
|
30
|
+
|
|
31
|
+
# Definições de agentes
|
|
32
|
+
".sinapse-ai/development/agents/*.md",
|
|
33
|
+
".sinapse-upstream/.sinapse-ai/development/agents/*.md",
|
|
34
|
+
|
|
35
|
+
# Documentação crítica
|
|
36
|
+
"docs/mmos/ARCHITECTURE_RULES.md",
|
|
37
|
+
"supabase/docs/SCHEMA.md",
|
|
38
|
+
|
|
39
|
+
# Configuração do projeto
|
|
40
|
+
"package.json",
|
|
41
|
+
"tsconfig.json",
|
|
42
|
+
"tsconfig.*.json",
|
|
43
|
+
|
|
44
|
+
# Arquivos de código críticos
|
|
45
|
+
"app/components/ui/icons/icon-map.ts",
|
|
46
|
+
|
|
47
|
+
# Migrations (sempre ler completo antes de editar)
|
|
48
|
+
"supabase/migrations/*.sql",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
# =============================================================================
|
|
52
|
+
# LÓGICA DO HOOK
|
|
53
|
+
# =============================================================================
|
|
54
|
+
|
|
55
|
+
def get_project_root():
|
|
56
|
+
"""Obtém o root do projeto via variável de ambiente ou cwd."""
|
|
57
|
+
return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
58
|
+
|
|
59
|
+
def normalize_path(file_path: str, project_root: str) -> str:
|
|
60
|
+
"""Normaliza path para relativo ao projeto."""
|
|
61
|
+
if file_path.startswith(project_root):
|
|
62
|
+
return file_path[len(project_root):].lstrip("/")
|
|
63
|
+
if file_path.startswith("/"):
|
|
64
|
+
# Path absoluto fora do projeto
|
|
65
|
+
return file_path
|
|
66
|
+
return file_path
|
|
67
|
+
|
|
68
|
+
def matches_protected_pattern(relative_path: str) -> bool:
|
|
69
|
+
"""Verifica se o path corresponde a algum padrão protegido."""
|
|
70
|
+
for pattern in PROTECTED_PATTERNS:
|
|
71
|
+
if fnmatch.fnmatch(relative_path, pattern):
|
|
72
|
+
return True
|
|
73
|
+
# Também verificar se é substring (para paths com wildcards)
|
|
74
|
+
if "*" not in pattern and pattern in relative_path:
|
|
75
|
+
return True
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
def has_partial_read_params(tool_input: dict) -> tuple[bool, str]:
|
|
79
|
+
"""Verifica se a chamada Read tem parâmetros de leitura parcial."""
|
|
80
|
+
limit = tool_input.get("limit")
|
|
81
|
+
offset = tool_input.get("offset")
|
|
82
|
+
|
|
83
|
+
reasons = []
|
|
84
|
+
if limit is not None:
|
|
85
|
+
reasons.append(f"limit={limit}")
|
|
86
|
+
if offset is not None and offset != 0:
|
|
87
|
+
reasons.append(f"offset={offset}")
|
|
88
|
+
|
|
89
|
+
return len(reasons) > 0, ", ".join(reasons)
|
|
90
|
+
|
|
91
|
+
def main():
|
|
92
|
+
# Ler input do stdin
|
|
93
|
+
try:
|
|
94
|
+
input_data = json.load(sys.stdin)
|
|
95
|
+
except json.JSONDecodeError:
|
|
96
|
+
# Se não conseguir parsear, permitir (fail-open)
|
|
97
|
+
sys.exit(0)
|
|
98
|
+
|
|
99
|
+
tool_name = input_data.get("tool_name", "")
|
|
100
|
+
tool_input = input_data.get("tool_input", {})
|
|
101
|
+
|
|
102
|
+
# Só processar Read
|
|
103
|
+
if tool_name != "Read":
|
|
104
|
+
sys.exit(0)
|
|
105
|
+
|
|
106
|
+
file_path = tool_input.get("file_path", "")
|
|
107
|
+
if not file_path:
|
|
108
|
+
sys.exit(0)
|
|
109
|
+
|
|
110
|
+
# Normalizar path
|
|
111
|
+
project_root = get_project_root()
|
|
112
|
+
relative_path = normalize_path(file_path, project_root)
|
|
113
|
+
|
|
114
|
+
# Verificar se é arquivo protegido
|
|
115
|
+
if not matches_protected_pattern(relative_path):
|
|
116
|
+
sys.exit(0)
|
|
117
|
+
|
|
118
|
+
# Verificar se tem parâmetros de leitura parcial
|
|
119
|
+
is_partial, partial_reason = has_partial_read_params(tool_input)
|
|
120
|
+
|
|
121
|
+
if not is_partial:
|
|
122
|
+
# Leitura completa, permitir
|
|
123
|
+
sys.exit(0)
|
|
124
|
+
|
|
125
|
+
# BLOQUEAR: Tentando ler arquivo protegido parcialmente
|
|
126
|
+
error_message = f"""
|
|
127
|
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
128
|
+
║ 🛑 READ PROTECTION: Arquivo protegido deve ser lido completamente ║
|
|
129
|
+
╠══════════════════════════════════════════════════════════════════════════════╣
|
|
130
|
+
║ ║
|
|
131
|
+
║ Arquivo: {relative_path[:58]:<58} ║
|
|
132
|
+
║ Problema: {partial_reason:<57} ║
|
|
133
|
+
║ ║
|
|
134
|
+
║ REGRA: Este arquivo está na lista de arquivos protegidos. ║
|
|
135
|
+
║ Arquivos protegidos DEVEM ser lidos completamente para evitar: ║
|
|
136
|
+
║ - Edições com contexto incompleto ║
|
|
137
|
+
║ - Duplicações acidentais ║
|
|
138
|
+
║ - Breaking changes não intencionais ║
|
|
139
|
+
║ ║
|
|
140
|
+
║ SOLUÇÃO: Remova os parâmetros 'limit' e 'offset' da chamada Read. ║
|
|
141
|
+
║ ║
|
|
142
|
+
║ ✅ Read(file_path="{relative_path[:40]}")
|
|
143
|
+
║ ❌ Read(file_path="...", limit=100) ║
|
|
144
|
+
║ ║
|
|
145
|
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
146
|
+
"""
|
|
147
|
+
print(error_message, file=sys.stderr)
|
|
148
|
+
sys.exit(2)
|
|
149
|
+
|
|
150
|
+
if __name__ == "__main__":
|
|
151
|
+
main()
|
|
152
|
+
|