sinapse-ai 1.12.2 → 1.14.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.
Files changed (244) hide show
  1. package/.claude/CLAUDE.md +2 -2
  2. package/.claude/rules/agent-memory-imports.md +4 -0
  3. package/.sinapse-ai/cli/commands/pro/index.js +8 -48
  4. package/.sinapse-ai/constitution.md +6 -2
  5. package/.sinapse-ai/data/entity-registry.yaml +63 -429
  6. package/.sinapse-ai/development/agents/analyst/MEMORY.md +19 -0
  7. package/.sinapse-ai/development/agents/architect/MEMORY.md +52 -0
  8. package/.sinapse-ai/development/agents/data-engineer/MEMORY.md +55 -0
  9. package/.sinapse-ai/development/agents/developer/MEMORY.md +53 -0
  10. package/.sinapse-ai/development/agents/devops/MEMORY.md +56 -0
  11. package/.sinapse-ai/development/agents/product-lead/MEMORY.md +53 -0
  12. package/.sinapse-ai/development/agents/project-lead/MEMORY.md +53 -0
  13. package/.sinapse-ai/development/agents/quality-gate/MEMORY.md +52 -0
  14. package/.sinapse-ai/development/agents/snps-orqx.md +15 -0
  15. package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +53 -0
  16. package/.sinapse-ai/development/agents/squad-creator.md +15 -0
  17. package/.sinapse-ai/development/agents/ux/MEMORY.md +21 -0
  18. package/.sinapse-ai/development/templates/chrome-brain/knowledge-base/chrome-brain.md +2 -2
  19. package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +15 -0
  20. package/.sinapse-ai/infrastructure/scripts/validate-agents.js +159 -8
  21. package/.sinapse-ai/install-manifest.yaml +16 -152
  22. package/AGENTS.md +13 -2
  23. package/CHANGELOG.md +135 -3
  24. package/README.en.md +1 -1
  25. package/README.md +6 -26
  26. package/bin/cli.js +2 -7
  27. package/bin/commands/install.js +19 -257
  28. package/bin/commands/update.js +18 -78
  29. package/bin/lib/command-generator.js +261 -0
  30. package/bin/lib/prompts.js +2 -65
  31. package/bin/modules/chrome-brain-installer.js +2 -1
  32. package/bin/postinstall.js +6 -6
  33. package/docs/getting-started.md +0 -1
  34. package/docs/pt/getting-started.md +1 -1
  35. package/docs/security/dependabot-triage.md +17 -17
  36. package/package.json +6 -3
  37. package/packages/installer/src/wizard/i18n.js +3 -204
  38. package/packages/installer/src/wizard/index.js +1 -1
  39. package/packages/installer/src/wizard/questions.js +5 -368
  40. package/packages/installer/src/wizard/wizard.js +0 -9
  41. package/scripts/generate-install-manifest.js +6 -0
  42. package/scripts/validate-changelog-tags.js +97 -0
  43. package/scripts/validate-no-personal-leaks.js +184 -28
  44. package/scripts/validate-schemas.js +55 -10
  45. package/scripts/validate-story-meta.js +25 -12
  46. package/squads/claude-code-mastery/agents/claude-mastery-chief.md +15 -1
  47. package/squads/claude-code-mastery/agents/config-engineer.md +15 -0
  48. package/squads/claude-code-mastery/agents/hooks-architect.md +27 -20
  49. package/squads/claude-code-mastery/agents/mcp-integrator.md +15 -0
  50. package/squads/claude-code-mastery/agents/project-integrator.md +15 -0
  51. package/squads/claude-code-mastery/agents/roadmap-sentinel.md +15 -0
  52. package/squads/claude-code-mastery/agents/skill-craftsman.md +15 -0
  53. package/squads/claude-code-mastery/agents/swarm-orqx.md +15 -0
  54. package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
  55. package/squads/squad-animations/agents/animation-interpreter.md +15 -0
  56. package/squads/squad-animations/agents/animation-performance-engineer.md +15 -0
  57. package/squads/squad-animations/agents/animations-orqx.md +13 -0
  58. package/squads/squad-animations/agents/css-motion-artist.md +15 -0
  59. package/squads/squad-animations/agents/generative-particle-engineer.md +15 -0
  60. package/squads/squad-animations/agents/motion-choreographer.md +15 -0
  61. package/squads/squad-animations/agents/scroll-narrative-engineer.md +15 -0
  62. package/squads/squad-animations/agents/shader-artist.md +15 -0
  63. package/squads/squad-animations/agents/threejs-architect.md +15 -0
  64. package/squads/squad-brand/agents/brand-archetype-strategist.md +13 -0
  65. package/squads/squad-brand/agents/brand-auditor.md +15 -0
  66. package/squads/squad-brand/agents/brand-collateral-designer.md +15 -0
  67. package/squads/squad-brand/agents/brand-compiler.md +13 -0
  68. package/squads/squad-brand/agents/brand-creative-engineer.md +15 -0
  69. package/squads/squad-brand/agents/brand-culture-architect.md +15 -0
  70. package/squads/squad-brand/agents/brand-growth-strategist.md +15 -0
  71. package/squads/squad-brand/agents/brand-identity-designer.md +15 -0
  72. package/squads/squad-brand/agents/brand-motion-vfx.md +15 -0
  73. package/squads/squad-brand/agents/brand-naming-specialist.md +15 -0
  74. package/squads/squad-brand/agents/brand-orqx.md +13 -0
  75. package/squads/squad-brand/agents/brand-positioning-strategist.md +15 -0
  76. package/squads/squad-brand/agents/brand-sonic-designer.md +15 -0
  77. package/squads/squad-brand/agents/brand-strategist.md +15 -0
  78. package/squads/squad-brand/agents/brand-system-architect.md +15 -0
  79. package/squads/squad-cloning/agents/agent-forger.md +15 -0
  80. package/squads/squad-cloning/agents/cloning-orqx.md +15 -0
  81. package/squads/squad-cloning/agents/cognitive-extractor.md +15 -0
  82. package/squads/squad-cloning/agents/content-capturer.md +15 -0
  83. package/squads/squad-cloning/agents/kb-architect.md +15 -0
  84. package/squads/squad-cloning/agents/mind-synthesizer.md +15 -0
  85. package/squads/squad-cloning/agents/sop-extractor.md +15 -0
  86. package/squads/squad-cloning/agents/source-hunter.md +13 -0
  87. package/squads/squad-cloning/agents/squad-assembler.md +15 -0
  88. package/squads/squad-commercial/agents/commercial-orqx.md +13 -0
  89. package/squads/squad-commercial/agents/cs-business-auditor.md +15 -0
  90. package/squads/squad-commercial/agents/cs-client-success.md +15 -0
  91. package/squads/squad-commercial/agents/cs-crm-specialist.md +15 -0
  92. package/squads/squad-commercial/agents/cs-funnel-architect.md +15 -0
  93. package/squads/squad-commercial/agents/cs-lead-generation-strategist.md +15 -0
  94. package/squads/squad-commercial/agents/cs-offer-designer.md +15 -0
  95. package/squads/squad-commercial/agents/cs-revops-analyst.md +15 -0
  96. package/squads/squad-commercial/agents/cs-sales-closer.md +13 -0
  97. package/squads/squad-commercial/agents/cs-sales-enablement.md +15 -0
  98. package/squads/squad-content/agents/content-analyst.md +13 -0
  99. package/squads/squad-content/agents/content-engineer.md +15 -0
  100. package/squads/squad-content/agents/content-governor.md +13 -0
  101. package/squads/squad-content/agents/content-orqx.md +13 -0
  102. package/squads/squad-content/agents/editorial-strategist.md +15 -0
  103. package/squads/squad-content/agents/platform-specialist.md +15 -0
  104. package/squads/squad-content/agents/signal-intelligence.md +13 -0
  105. package/squads/squad-copy/agents/ad-copywriter.md +13 -0
  106. package/squads/squad-copy/agents/brand-voice-writer.md +15 -0
  107. package/squads/squad-copy/agents/conversion-writer.md +13 -0
  108. package/squads/squad-copy/agents/copy-editor.md +15 -0
  109. package/squads/squad-copy/agents/copy-orqx.md +13 -0
  110. package/squads/squad-copy/agents/copy-strategist.md +15 -0
  111. package/squads/squad-copy/agents/direct-response-writer.md +15 -0
  112. package/squads/squad-copy/agents/email-sequence-strategist.md +15 -0
  113. package/squads/squad-copy/agents/funnel-copywriter.md +15 -0
  114. package/squads/squad-copy/agents/headline-specialist.md +13 -0
  115. package/squads/squad-copy/agents/long-form-writer.md +15 -0
  116. package/squads/squad-copy/agents/persuasion-psychologist.md +15 -0
  117. package/squads/squad-copy/agents/proof-architect.md +15 -0
  118. package/squads/squad-council/agents/brene-brown.md +13 -0
  119. package/squads/squad-council/agents/charlie-munger.md +13 -0
  120. package/squads/squad-council/agents/council-orqx.md +13 -0
  121. package/squads/squad-council/agents/derek-sivers.md +13 -0
  122. package/squads/squad-council/agents/naval-ravikant.md +13 -0
  123. package/squads/squad-council/agents/patrick-lencioni.md +15 -0
  124. package/squads/squad-council/agents/peter-thiel.md +13 -0
  125. package/squads/squad-council/agents/ray-dalio.md +13 -0
  126. package/squads/squad-council/agents/reid-hoffman.md +13 -0
  127. package/squads/squad-council/agents/simon-sinek.md +15 -0
  128. package/squads/squad-council/agents/yvon-chouinard.md +13 -0
  129. package/squads/squad-courses/agents/assessment-creator.md +15 -0
  130. package/squads/squad-courses/agents/content-writer.md +15 -0
  131. package/squads/squad-courses/agents/courses-orqx.md +15 -0
  132. package/squads/squad-courses/agents/curriculum-designer.md +15 -0
  133. package/squads/squad-courses/agents/launch-strategist.md +15 -0
  134. package/squads/squad-courses/agents/lesson-architect.md +15 -0
  135. package/squads/squad-courses/agents/production-director.md +13 -0
  136. package/squads/squad-courses/agents/slide-designer.md +15 -0
  137. package/squads/squad-cybersecurity/agents/cloud-security-engineer.md +15 -0
  138. package/squads/squad-cybersecurity/agents/compliance-officer.md +15 -0
  139. package/squads/squad-cybersecurity/agents/cyber-orqx.md +15 -0
  140. package/squads/squad-cybersecurity/agents/incident-responder.md +15 -0
  141. package/squads/squad-cybersecurity/agents/network-security-engineer.md +15 -0
  142. package/squads/squad-cybersecurity/agents/penetration-tester.md +15 -0
  143. package/squads/squad-cybersecurity/agents/soc-analyst.md +15 -0
  144. package/squads/squad-cybersecurity/agents/threat-analyst.md +15 -0
  145. package/squads/squad-design/agents/cro-persuasion.md +15 -0
  146. package/squads/squad-design/agents/design-orqx.md +13 -0
  147. package/squads/squad-design/agents/design-system.md +15 -0
  148. package/squads/squad-design/agents/dx-accessibility-specialist.md +15 -0
  149. package/squads/squad-design/agents/dx-design-system-architect.md +15 -0
  150. package/squads/squad-design/agents/dx-frontend-engineer.md +15 -0
  151. package/squads/squad-design/agents/dx-interaction-designer.md +15 -0
  152. package/squads/squad-design/agents/dx-performance-engineer.md +15 -0
  153. package/squads/squad-design/agents/dx-ui-designer.md +15 -0
  154. package/squads/squad-design/agents/dx-ux-strategist.md +15 -0
  155. package/squads/squad-design/agents/platform-aesthetic-director.md +15 -0
  156. package/squads/squad-design/agents/premium-packaging-strategist.md +15 -0
  157. package/squads/squad-design/agents/product-surface-director.md +15 -0
  158. package/squads/squad-design/agents/ux-designer.md +15 -0
  159. package/squads/squad-finance/agents/budget-controller.md +15 -0
  160. package/squads/squad-finance/agents/cost-optimizer.md +15 -0
  161. package/squads/squad-finance/agents/finance-orqx.md +15 -0
  162. package/squads/squad-finance/agents/fiscal-compliance-br.md +15 -0
  163. package/squads/squad-finance/agents/forecast-strategist.md +15 -0
  164. package/squads/squad-finance/agents/pricing-strategist.md +15 -0
  165. package/squads/squad-finance/agents/profitability-analyst.md +15 -0
  166. package/squads/squad-finance/agents/revenue-analyst.md +15 -0
  167. package/squads/squad-growth/agents/ga-analytics-engineer.md +15 -0
  168. package/squads/squad-growth/agents/ga-campaign-analyst.md +15 -0
  169. package/squads/squad-growth/agents/ga-cro-specialist.md +15 -0
  170. package/squads/squad-growth/agents/ga-data-analyst.md +13 -0
  171. package/squads/squad-growth/agents/ga-growth-hacker.md +15 -0
  172. package/squads/squad-growth/agents/ga-seo-strategist.md +15 -0
  173. package/squads/squad-growth/agents/growth-orqx.md +15 -0
  174. package/squads/squad-paidmedia/agents/campaign-analyst.md +15 -0
  175. package/squads/squad-paidmedia/agents/creative-strategist.md +15 -0
  176. package/squads/squad-paidmedia/agents/cro-specialist.md +15 -0
  177. package/squads/squad-paidmedia/agents/google-ads-specialist.md +15 -0
  178. package/squads/squad-paidmedia/agents/meta-ads-specialist.md +15 -0
  179. package/squads/squad-paidmedia/agents/paidmedia-orqx.md +15 -0
  180. package/squads/squad-paidmedia/agents/performance-engineer.md +15 -0
  181. package/squads/squad-paidmedia/agents/pm-creative-performance-analyst.md +15 -0
  182. package/squads/squad-paidmedia/agents/pm-youtube-ads-specialist.md +15 -0
  183. package/squads/squad-product/agents/product-orqx.md +13 -1
  184. package/squads/squad-product/agents/ps-client-product-manager.md +13 -1
  185. package/squads/squad-product/agents/ps-delivery-manager.md +13 -1
  186. package/squads/squad-product/agents/ps-discovery-lead.md +15 -1
  187. package/squads/squad-product/agents/ps-product-analyst.md +15 -1
  188. package/squads/squad-product/agents/ps-product-ops-specialist.md +15 -1
  189. package/squads/squad-product/agents/ps-product-strategist.md +15 -1
  190. package/squads/squad-research/agents/audience-intelligence.md +15 -0
  191. package/squads/squad-research/agents/competitive-intelligence.md +15 -0
  192. package/squads/squad-research/agents/data-synthesizer.md +15 -0
  193. package/squads/squad-research/agents/deep-researcher.md +15 -0
  194. package/squads/squad-research/agents/market-analyst.md +15 -0
  195. package/squads/squad-research/agents/research-orqx.md +15 -0
  196. package/squads/squad-research/agents/trend-forecaster.md +15 -0
  197. package/squads/squad-storytelling/agents/blake-snyder.md +13 -0
  198. package/squads/squad-storytelling/agents/dan-harmon.md +13 -0
  199. package/squads/squad-storytelling/agents/joseph-campbell.md +13 -0
  200. package/squads/squad-storytelling/agents/keith-johnstone.md +13 -0
  201. package/squads/squad-storytelling/agents/kindra-hall.md +15 -0
  202. package/squads/squad-storytelling/agents/marshall-ganz.md +15 -0
  203. package/squads/squad-storytelling/agents/nancy-duarte.md +15 -0
  204. package/squads/squad-storytelling/agents/oren-klaff.md +15 -0
  205. package/squads/squad-storytelling/agents/park-howell.md +13 -0
  206. package/squads/squad-storytelling/agents/storytelling-orqx.md +13 -0
  207. package/.sinapse-ai/core/grounding/README.md +0 -83
  208. package/.sinapse-ai/core/grounding/brand.cjs +0 -29
  209. package/.sinapse-ai/core/grounding/config-loader.cjs +0 -52
  210. package/.sinapse-ai/core/grounding/design-system.cjs +0 -29
  211. package/.sinapse-ai/core/grounding/vault.cjs +0 -36
  212. package/.sinapse-ai/development/scripts/approval-workflow.js +0 -643
  213. package/.sinapse-ai/development/scripts/backup-manager.js +0 -607
  214. package/.sinapse-ai/development/scripts/branch-manager.js +0 -390
  215. package/.sinapse-ai/development/scripts/code-quality-improver.js +0 -1329
  216. package/.sinapse-ai/development/scripts/commit-message-generator.js +0 -850
  217. package/.sinapse-ai/development/scripts/conflict-resolver.js +0 -675
  218. package/.sinapse-ai/development/scripts/dependency-analyzer.js +0 -638
  219. package/.sinapse-ai/development/scripts/diff-generator.js +0 -352
  220. package/.sinapse-ai/development/scripts/git-wrapper.js +0 -462
  221. package/.sinapse-ai/development/scripts/modification-validator.js +0 -555
  222. package/.sinapse-ai/development/scripts/performance-analyzer.js +0 -758
  223. package/.sinapse-ai/development/scripts/refactoring-suggester.js +0 -1148
  224. package/.sinapse-ai/development/scripts/rollback-handler.js +0 -531
  225. package/.sinapse-ai/development/scripts/security-checker.js +0 -359
  226. package/.sinapse-ai/development/scripts/template-engine.js +0 -240
  227. package/.sinapse-ai/development/scripts/template-validator.js +0 -279
  228. package/.sinapse-ai/development/scripts/test-generator.js +0 -844
  229. package/.sinapse-ai/development/scripts/transaction-manager.js +0 -590
  230. package/.sinapse-ai/development/scripts/yaml-validator.js +0 -397
  231. package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +0 -162
  232. package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +0 -211
  233. package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +0 -194
  234. package/bin/lib/register-grounding-hooks.js +0 -145
  235. package/docs/guides/agents/traces/execution-traces.zip +0 -0
  236. package/docs/guides/grounding-setup.md +0 -154
  237. package/docs/guides/workflows/SINAPSE-WORKFLOWS.zip +0 -0
  238. package/packages/installer/src/pro/pro-scaffolder.js +0 -449
  239. package/packages/installer/src/wizard/grounding-config.js +0 -131
  240. package/packages/installer/src/wizard/pro-setup.js +0 -1439
  241. package/packages/installer/templates/README.md +0 -16
  242. package/packages/installer/templates/brand-routing.example.json +0 -12
  243. package/packages/installer/templates/ds-routing.example.json +0 -12
  244. package/packages/installer/templates/vault-routing.example.json +0 -12
@@ -1,211 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * SINAPSE Design System Grounding Hook — UserPromptSubmit (framework-shipped).
6
- *
7
- * @story GA-1.6
8
- *
9
- * Reads `~/.claude/sinapse-ai-config.yaml` (Story 10.47 schema) `designSystem`
10
- * section. Activates only when the user prompt contains UI keywords
11
- * (PT + EN). Injects the first 3000 chars of the DS law file as
12
- * `<ds-grounding>` context.
13
- *
14
- * Coexistence: the user's personal `~/.claude/hooks/design-system-grounding.cjs` (if present)
15
- * reads `ds-routing.json` and is unaffected by this file.
16
- */
17
-
18
- const fs = require('fs');
19
- const os = require('os');
20
- const path = require('path');
21
-
22
- const HOOK_TIMEOUT_MS = 3500;
23
- const MAX_INJECTION_SIZE = 3000; // chars (story says 3000 for DS)
24
- const MAX_LAW_PREVIEW = 3000;
25
- const MIN_PROMPT_CHARS = 15;
26
- const CONFIG_PATH = path.join(os.homedir(), '.claude', 'sinapse-ai-config.yaml');
27
-
28
- const UI_KEYWORDS = [
29
- // PT
30
- 'pagina', 'página', 'lp', 'landing', 'componente', 'interface', 'tela',
31
- 'layout', 'hero', 'dashboard', 'carrossel', 'slide', 'mockup',
32
- 'wireframe', 'prototipo', 'protótipo', 'design', 'visual', 'site',
33
- 'website', 'menu', 'navbar', 'footer', 'botao', 'botão', 'card', 'cards',
34
- 'secao', 'seção', 'frontend', 'front-end', 'figma', 'react', 'tailwind',
35
- 'nextjs', 'next.js', 'redesign', 'tipografia', 'paleta',
36
- // EN
37
- 'page', 'component', 'screen', 'section', 'button', 'typography',
38
- 'palette', 'web app', 'ui ', ' ui',
39
- ];
40
-
41
- // Candidate filenames to read as the DS law, in priority order.
42
- const LAW_CANDIDATES = [
43
- '0.0-guidelines.md',
44
- 'guidelines.md',
45
- 'principles.md',
46
- 'README.md',
47
- 'tokens.json',
48
- 'design-system.md',
49
- ];
50
-
51
- function readStdin() {
52
- return new Promise((resolve) => {
53
- let data = '';
54
- let settled = false;
55
- const finish = (val) => { if (!settled) { settled = true; resolve(val); } };
56
- try {
57
- process.stdin.setEncoding('utf8');
58
- process.stdin.on('error', () => finish(null));
59
- process.stdin.on('data', (chunk) => { data += chunk; });
60
- process.stdin.on('end', () => {
61
- try { finish(JSON.parse(data)); } catch { finish(null); }
62
- });
63
- } catch {
64
- finish(null);
65
- }
66
- });
67
- }
68
-
69
- // Story 10.47: delegate to the shared grounding config loader instead of
70
- // duplicating the read+parse. The require is guarded so the hook stays
71
- // fail-open even if the shared module is somehow absent at runtime.
72
- function loadConfig() {
73
- try {
74
- return require('../core/grounding/config-loader.cjs').loadGroundingConfig(CONFIG_PATH);
75
- } catch {
76
- return null;
77
- }
78
- }
79
-
80
- function getSection(cfg, name) {
81
- if (!cfg || !cfg.grounding) return null;
82
- const s = cfg.grounding[name];
83
- if (!s || typeof s !== 'object' || !s.enabled) return null;
84
- return s;
85
- }
86
-
87
- function isUIPrompt(prompt) {
88
- if (!prompt || typeof prompt !== 'string') return false;
89
- if (prompt.trim().length < MIN_PROMPT_CHARS) return false;
90
- const lower = prompt.toLowerCase();
91
- return UI_KEYWORDS.some((k) => lower.includes(k));
92
- }
93
-
94
- function findLawFile(rootPath) {
95
- try {
96
- if (!rootPath || !fs.existsSync(rootPath)) return null;
97
- const stat = fs.statSync(rootPath);
98
- if (!stat.isDirectory()) {
99
- // If user passed a file directly, use it.
100
- return rootPath;
101
- }
102
- for (const candidate of LAW_CANDIDATES) {
103
- const full = path.join(rootPath, candidate);
104
- if (fs.existsSync(full)) return full;
105
- }
106
- // Fallback: first .md/.json in the dir
107
- const entries = fs.readdirSync(rootPath).filter(
108
- (f) => f.endsWith('.md') || f.endsWith('.json')
109
- );
110
- if (entries.length > 0) return path.join(rootPath, entries[0]);
111
- return null;
112
- } catch {
113
- return null;
114
- }
115
- }
116
-
117
- function readLaw(lawFile) {
118
- try {
119
- if (!lawFile || !fs.existsSync(lawFile)) return null;
120
- let content = fs.readFileSync(lawFile, 'utf8');
121
- if (content.length > MAX_LAW_PREVIEW) {
122
- content = content.substring(0, MAX_LAW_PREVIEW) + '\n[...truncated...]';
123
- }
124
- return content;
125
- } catch {
126
- return null;
127
- }
128
- }
129
-
130
- function buildInjection(section, lawContent, projectCwd) {
131
- const profileName = section.profileName || 'Custom DS';
132
- const rootPath = section.rootPath || '';
133
- const parts = [];
134
- parts.push(`<ds-grounding source="filesystem" name="${profileName}" project="${projectCwd}">`);
135
- parts.push(`DS detectado: ${profileName}`);
136
- parts.push(`Localizacao: ${rootPath}`);
137
- if (lawContent) {
138
- parts.push('--- LEI DO DS (primeiros 3000 chars) ---');
139
- parts.push(lawContent);
140
- } else {
141
- parts.push('(nenhum arquivo de lei encontrado em rootPath)');
142
- }
143
- parts.push('</ds-grounding>');
144
-
145
- let full = parts.join('\n');
146
- if (full.length > MAX_INJECTION_SIZE) {
147
- const trailer = '\n[...truncated...]\n</ds-grounding>';
148
- full = full.substring(0, MAX_INJECTION_SIZE - trailer.length) + trailer;
149
- }
150
- return full;
151
- }
152
-
153
- async function main() {
154
- const input = await readStdin();
155
- if (!input || typeof input !== 'object') return;
156
-
157
- const userPrompt = input.prompt || input.user_prompt || input.message || '';
158
- if (!isUIPrompt(userPrompt)) return;
159
-
160
- // Anti-double-injection
161
- if (userPrompt.includes('<ds-grounding')) return;
162
-
163
- const cfg = loadConfig();
164
- const section = getSection(cfg, 'designSystem');
165
- if (!section || !section.rootPath) return;
166
-
167
- const lawFile = findLawFile(section.rootPath);
168
- const lawContent = readLaw(lawFile);
169
- const projectCwd = input.cwd || process.cwd();
170
- const context = buildInjection(section, lawContent, projectCwd);
171
-
172
- const output = JSON.stringify({
173
- hookSpecificOutput: {
174
- hookEventName: 'UserPromptSubmit',
175
- additionalContext: context,
176
- },
177
- });
178
-
179
- await new Promise((resolve) => {
180
- let settled = false;
181
- const finish = () => { if (!settled) { settled = true; resolve(); } };
182
- try {
183
- const flushed = process.stdout.write(output, () => finish());
184
- if (flushed) setImmediate(finish);
185
- } catch {
186
- finish();
187
- }
188
- });
189
- }
190
-
191
- function run() {
192
- const timer = setTimeout(() => process.exit(0), HOOK_TIMEOUT_MS);
193
- timer.unref();
194
- main()
195
- .then(() => { clearTimeout(timer); process.exitCode = 0; })
196
- .catch(() => { clearTimeout(timer); process.exitCode = 0; });
197
- }
198
-
199
- if (require.main === module) run();
200
-
201
- module.exports = {
202
- loadConfig,
203
- getSection,
204
- isUIPrompt,
205
- findLawFile,
206
- readLaw,
207
- buildInjection,
208
- UI_KEYWORDS,
209
- CONFIG_PATH,
210
- MAX_INJECTION_SIZE,
211
- };
@@ -1,194 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * SINAPSE Vault Grounding Hook — UserPromptSubmit (framework-shipped).
6
- *
7
- * @story GA-1.6
8
- *
9
- * Reads `~/.claude/sinapse-ai-config.yaml` (Story 10.47 schema) and, if the
10
- * `vault` section is enabled, injects `<vault-grounding>` context into the
11
- * Claude Code prompt. Closes the gap left by Story 10.47 (which shipped the
12
- * wizard + library hooks but no executable Claude Code hooks).
13
- *
14
- * Coexistence with personal hooks: this file lives at
15
- * .sinapse-ai/hooks/sinapse-vault-grounding.cjs
16
- * and reads `sinapse-ai-config.yaml`. The user's personal
17
- * `~/.claude/hooks/vault-grounding.cjs` (if present) reads `vault-routing.json`. The two
18
- * files do not collide (different filenames, different config sources, and
19
- * fail-open guarantees that running both is safe).
20
- *
21
- * Contract:
22
- * stdin : JSON `{ "prompt": "...", "session_id": "...", "cwd": "..." }`
23
- * stdout : JSON `{ "hookSpecificOutput": { "hookEventName":
24
- * "UserPromptSubmit", "additionalContext": "<vault-grounding>...</vault-grounding>" } }`
25
- * exit 0 always (fail-open: silent on every error path).
26
- */
27
-
28
- const fs = require('fs');
29
- const os = require('os');
30
- const path = require('path');
31
-
32
- const HOOK_TIMEOUT_MS = 3500;
33
- const MAX_INJECTION_SIZE = 6000; // chars
34
- const MAX_NOTES = 5;
35
- const MAX_NOTE_PREVIEW = 500; // chars per note
36
- const MIN_PROMPT_CHARS = 10;
37
- const CONFIG_PATH = path.join(os.homedir(), '.claude', 'sinapse-ai-config.yaml');
38
-
39
- function readStdin() {
40
- return new Promise((resolve) => {
41
- let data = '';
42
- let settled = false;
43
- const finish = (val) => { if (!settled) { settled = true; resolve(val); } };
44
- try {
45
- process.stdin.setEncoding('utf8');
46
- process.stdin.on('error', () => finish(null));
47
- process.stdin.on('data', (chunk) => { data += chunk; });
48
- process.stdin.on('end', () => {
49
- try { finish(JSON.parse(data)); } catch { finish(null); }
50
- });
51
- } catch {
52
- finish(null);
53
- }
54
- });
55
- }
56
-
57
- // Story 10.47: delegate to the shared grounding config loader instead of
58
- // duplicating the read+parse. The require is guarded so the hook stays
59
- // fail-open even if the shared module is somehow absent at runtime.
60
- function loadConfig() {
61
- try {
62
- return require('../core/grounding/config-loader.cjs').loadGroundingConfig(CONFIG_PATH);
63
- } catch {
64
- return null;
65
- }
66
- }
67
-
68
- function getSection(cfg, name) {
69
- if (!cfg || !cfg.grounding) return null;
70
- const s = cfg.grounding[name];
71
- if (!s || typeof s !== 'object' || !s.enabled) return null;
72
- return s;
73
- }
74
-
75
- /**
76
- * Pick top-N markdown notes from the vault root, ranked by mtime descending.
77
- * Returns [{ name, content }]. Truncates each note to MAX_NOTE_PREVIEW chars.
78
- */
79
- function pickNotes(vaultPath) {
80
- try {
81
- if (!vaultPath || !fs.existsSync(vaultPath)) return [];
82
- const stat = fs.statSync(vaultPath);
83
- if (!stat.isDirectory()) return [];
84
-
85
- const entries = fs.readdirSync(vaultPath, { withFileTypes: true })
86
- .filter((e) => e.isFile() && e.name.toLowerCase().endsWith('.md'))
87
- .map((e) => {
88
- const full = path.join(vaultPath, e.name);
89
- try {
90
- const s = fs.statSync(full);
91
- return { name: e.name, full, mtime: s.mtimeMs };
92
- } catch { return null; }
93
- })
94
- .filter(Boolean);
95
-
96
- entries.sort((a, b) => b.mtime - a.mtime);
97
-
98
- const notes = [];
99
- for (const ent of entries.slice(0, MAX_NOTES)) {
100
- try {
101
- let content = fs.readFileSync(ent.full, 'utf8');
102
- if (content.length > MAX_NOTE_PREVIEW) {
103
- content = content.substring(0, MAX_NOTE_PREVIEW) + '\n[...truncated...]';
104
- }
105
- notes.push({ name: ent.name, content });
106
- } catch { /* skip unreadable */ }
107
- }
108
- return notes;
109
- } catch {
110
- return [];
111
- }
112
- }
113
-
114
- function buildInjection(section, notes) {
115
- const domain = (Array.isArray(section.domains) && section.domains.length)
116
- ? section.domains.join(',')
117
- : 'default';
118
- const parts = [];
119
- parts.push(`<vault-grounding domain="${domain}" mode="summary" vault="${section.path}">`);
120
- parts.push('Indice do vault (top notas mais recentes):');
121
- if (notes.length === 0) {
122
- parts.push('(nenhuma nota .md encontrada no path do vault)');
123
- } else {
124
- for (const n of notes) {
125
- parts.push(`--- ${n.name} ---`);
126
- parts.push(n.content);
127
- }
128
- }
129
- parts.push('</vault-grounding>');
130
-
131
- let full = parts.join('\n');
132
- if (full.length > MAX_INJECTION_SIZE) {
133
- const trailer = '\n[...truncated...]\n</vault-grounding>';
134
- full = full.substring(0, MAX_INJECTION_SIZE - trailer.length) + trailer;
135
- }
136
- return full;
137
- }
138
-
139
- async function main() {
140
- const input = await readStdin();
141
- if (!input || typeof input !== 'object') return;
142
-
143
- const userPrompt = input.prompt || input.user_prompt || input.message || '';
144
- if (typeof userPrompt !== 'string' || userPrompt.trim().length < MIN_PROMPT_CHARS) return;
145
-
146
- // Anti-double-injection: if the prompt already contains <vault-grounding>,
147
- // assume another hook (or a previous run) has already injected it.
148
- if (userPrompt.includes('<vault-grounding')) return;
149
-
150
- const cfg = loadConfig();
151
- const section = getSection(cfg, 'vault');
152
- if (!section || !section.path) return;
153
-
154
- const notes = pickNotes(section.path);
155
- const context = buildInjection(section, notes);
156
-
157
- const output = JSON.stringify({
158
- hookSpecificOutput: {
159
- hookEventName: 'UserPromptSubmit',
160
- additionalContext: context,
161
- },
162
- });
163
-
164
- await new Promise((resolve) => {
165
- let settled = false;
166
- const finish = () => { if (!settled) { settled = true; resolve(); } };
167
- try {
168
- const flushed = process.stdout.write(output, () => finish());
169
- if (flushed) setImmediate(finish);
170
- } catch {
171
- finish();
172
- }
173
- });
174
- }
175
-
176
- function run() {
177
- const timer = setTimeout(() => process.exit(0), HOOK_TIMEOUT_MS);
178
- timer.unref();
179
- main()
180
- .then(() => { clearTimeout(timer); process.exitCode = 0; })
181
- .catch(() => { clearTimeout(timer); process.exitCode = 0; });
182
- }
183
-
184
- if (require.main === module) run();
185
-
186
- module.exports = {
187
- // Exposed for tests — the executable contract is stdin/stdout.
188
- loadConfig,
189
- getSection,
190
- pickNotes,
191
- buildInjection,
192
- CONFIG_PATH,
193
- MAX_INJECTION_SIZE,
194
- };
@@ -1,145 +0,0 @@
1
- // bin/lib/register-grounding-hooks.js — register the 3 framework grounding
2
- // hooks (sinapse-vault, sinapse-ds, sinapse-brand) in `~/.claude/settings.json`.
3
- //
4
- // @story GA-1.6
5
- //
6
- // Contract:
7
- // - Idempotent: re-running never duplicates an entry.
8
- // - Non-destructive: existing UserPromptSubmit hooks (e.g. user's personal
9
- // `vault-grounding.cjs`, terminal-bus, etc.) are preserved.
10
- // - Fail-soft: every error is caught and logged via `notify`; settings.json
11
- // is never left in a corrupted state (we read → mutate → write atomically).
12
-
13
- 'use strict';
14
-
15
- const fs = require('fs');
16
- const path = require('path');
17
-
18
- const HOOK_FILENAMES = [
19
- 'sinapse-vault-grounding.cjs',
20
- 'sinapse-ds-grounding.cjs',
21
- 'sinapse-brand-grounding.cjs',
22
- ];
23
-
24
- const HOOK_TIMEOUT_MS = 4000;
25
-
26
- /**
27
- * Convert a path to forward slashes for use inside a JSON string. Claude Code
28
- * on Windows tolerates both, but forward slashes avoid double-escaping issues.
29
- */
30
- function toForwardSlash(p) {
31
- return p.replace(/\\/g, '/');
32
- }
33
-
34
- /**
35
- * Build a UserPromptSubmit hook entry block for a given hook absolute path.
36
- */
37
- function buildHookEntry(absHookPath) {
38
- return {
39
- type: 'command',
40
- command: `node "${toForwardSlash(absHookPath)}"`,
41
- timeout: HOOK_TIMEOUT_MS,
42
- };
43
- }
44
-
45
- /**
46
- * Determine if a UserPromptSubmit `hooks[].command` entry already references
47
- * one of our hook filenames. Filename-based detection lets us survive path
48
- * differences (case, trailing slash, .sinapse-ai relocation).
49
- */
50
- function commandReferencesHook(commandStr, hookFilename) {
51
- if (!commandStr || typeof commandStr !== 'string') return false;
52
- return commandStr.includes(hookFilename);
53
- }
54
-
55
- /**
56
- * Register all 3 grounding hooks in settings.json.
57
- *
58
- * @param {object} opts
59
- * @param {string} opts.settingsPath Absolute path to `~/.claude/settings.json`.
60
- * @param {string} opts.hooksDir Absolute path to `<install>/.sinapse-ai/hooks`.
61
- * @param {function} [opts.notify] Optional logger `(msg) => void`.
62
- * @returns {{added: string[], skipped: string[], errors: string[]}}
63
- */
64
- function registerGroundingHooks(opts) {
65
- const { settingsPath, hooksDir } = opts;
66
- const notify = typeof opts.notify === 'function' ? opts.notify : () => {};
67
- const result = { added: [], skipped: [], errors: [] };
68
-
69
- let settings = {};
70
- try {
71
- if (fs.existsSync(settingsPath)) {
72
- const raw = fs.readFileSync(settingsPath, 'utf8');
73
- settings = raw.trim() ? JSON.parse(raw) : {};
74
- }
75
- } catch (err) {
76
- result.errors.push(`Could not parse ${settingsPath}: ${err.message}`);
77
- notify(`WARN: skipping grounding hook registration — ${err.message}`);
78
- return result;
79
- }
80
-
81
- if (!settings || typeof settings !== 'object') settings = {};
82
- if (!settings.hooks || typeof settings.hooks !== 'object') settings.hooks = {};
83
- if (!Array.isArray(settings.hooks.UserPromptSubmit)) settings.hooks.UserPromptSubmit = [];
84
-
85
- // Find or create the matcher block we'll mutate. Prefer an existing block
86
- // with `matcher === ''` (the default catch-all) so we group with whatever
87
- // is already there.
88
- let block = settings.hooks.UserPromptSubmit.find(
89
- (b) => b && typeof b === 'object' && (b.matcher === '' || b.matcher === undefined || b.matcher === null),
90
- );
91
- if (!block) {
92
- block = { matcher: '', hooks: [] };
93
- settings.hooks.UserPromptSubmit.push(block);
94
- }
95
- if (!Array.isArray(block.hooks)) block.hooks = [];
96
-
97
- for (const hookName of HOOK_FILENAMES) {
98
- const absHookPath = path.join(hooksDir, hookName);
99
-
100
- // Skip registration if the hook file does not exist on disk — registering
101
- // a missing file would crash Claude Code on every prompt.
102
- if (!fs.existsSync(absHookPath)) {
103
- result.errors.push(`Hook file missing: ${absHookPath}`);
104
- notify(`WARN: hook file missing, skipping ${hookName}`);
105
- continue;
106
- }
107
-
108
- // Idempotency: skip if any existing entry references this filename.
109
- const alreadyRegistered = settings.hooks.UserPromptSubmit.some((b) => {
110
- if (!b || !Array.isArray(b.hooks)) return false;
111
- return b.hooks.some((h) => h && commandReferencesHook(h.command, hookName));
112
- });
113
-
114
- if (alreadyRegistered) {
115
- result.skipped.push(hookName);
116
- continue;
117
- }
118
-
119
- block.hooks.push(buildHookEntry(absHookPath));
120
- result.added.push(hookName);
121
- notify(`Registered hook: ${hookName.replace(/\.cjs$/, '')}`);
122
- }
123
-
124
- // Persist only if we changed something
125
- if (result.added.length > 0) {
126
- try {
127
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
128
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
129
- } catch (err) {
130
- result.errors.push(`Could not write ${settingsPath}: ${err.message}`);
131
- notify(`WARN: could not write settings.json — ${err.message}`);
132
- }
133
- }
134
-
135
- return result;
136
- }
137
-
138
- module.exports = {
139
- registerGroundingHooks,
140
- HOOK_FILENAMES,
141
- HOOK_TIMEOUT_MS,
142
- // Exposed for tests
143
- buildHookEntry,
144
- commandReferencesHook,
145
- };