sinapse-ai 1.11.3 → 1.12.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 (77) hide show
  1. package/.claude/hooks/enforce-architecture-first.cjs +2 -2
  2. package/.claude/hooks/enforce-delegation.cjs +2 -2
  3. package/.claude/hooks/enforce-permission-mode.cjs +12 -12
  4. package/.claude/hooks/enforce-story-gate.cjs +5 -5
  5. package/.claude/hooks/precompact-session-digest.cjs +2 -2
  6. package/.claude/hooks/secret-scanning.cjs +6 -6
  7. package/.claude/hooks/telemetry-post-tool.cjs +0 -1
  8. package/.claude/hooks/write-path-validation.cjs +2 -2
  9. package/.sinapse-ai/core/code-intel/helpers/dev-helper.js +1 -1
  10. package/.sinapse-ai/core/code-intel/helpers/devops-helper.js +0 -1
  11. package/.sinapse-ai/core/code-intel/helpers/planning-helper.js +1 -1
  12. package/.sinapse-ai/core/code-intel/helpers/qa-helper.js +2 -2
  13. package/.sinapse-ai/core/config/template-overrides.js +1 -1
  14. package/.sinapse-ai/core/doctor/checks/git-hooks.js +6 -3
  15. package/.sinapse-ai/core/doctor/checks/npm-packages.js +1 -1
  16. package/.sinapse-ai/core/doctor/checks/rules-files.js +0 -1
  17. package/.sinapse-ai/core/doctor/index.js +0 -1
  18. package/.sinapse-ai/core/graph-dashboard/cli.js +1 -1
  19. package/.sinapse-ai/core/graph-dashboard/data-sources/code-intel-source.js +1 -1
  20. package/.sinapse-ai/core/health-check/checks/project/constitution-consistency.js +0 -1
  21. package/.sinapse-ai/core/ideation/ideation-engine.js +0 -2
  22. package/.sinapse-ai/core/ids/layer-classifier.js +1 -1
  23. package/.sinapse-ai/core/registry/build-registry.js +12 -2
  24. package/.sinapse-ai/core/registry/service-registry.json +178 -55
  25. package/.sinapse-ai/core/registry/squad-agent-resolver.js +6 -0
  26. package/.sinapse-ai/core/synapse/layers/layer-processor.js +1 -1
  27. package/.sinapse-ai/data/capability-detection.js +15 -15
  28. package/.sinapse-ai/data/tok3-token-comparison.js +0 -3
  29. package/.sinapse-ai/data/tool-search-validation.js +1 -1
  30. package/.sinapse-ai/development/agents/snps-orqx.md +109 -0
  31. package/.sinapse-ai/development/scripts/agent-config-loader.js +8 -2
  32. package/.sinapse-ai/development/templates/sinapse-doc-template.md +6 -6
  33. package/.sinapse-ai/git-hooks/lib/framework-guard.js +1 -0
  34. package/.sinapse-ai/git-hooks/lib/staged-protected-files-guard.js +63 -0
  35. package/.sinapse-ai/git-hooks/pre-commit +3 -1
  36. package/.sinapse-ai/index.d.ts +19 -0
  37. package/.sinapse-ai/install-manifest.yaml +59 -55
  38. package/.sinapse-ai/package.json +0 -1
  39. package/.sinapse-ai/utils/filters/index.js +2 -1
  40. package/CHANGELOG.md +31 -2
  41. package/bin/commands/doctor.js +1 -1
  42. package/bin/commands/help.js +3 -4
  43. package/bin/commands/install.js +7 -7
  44. package/bin/commands/status.js +3 -3
  45. package/bin/modules/chrome-brain-installer.js +3 -3
  46. package/bin/postinstall.js +1 -1
  47. package/bin/sinapse-init.js +11 -9
  48. package/bin/sinapse.js +1 -1
  49. package/bin/utils/framework-guard.js +1 -0
  50. package/bin/utils/staged-protected-files-guard.js +63 -0
  51. package/package.json +19 -2
  52. package/packages/installer/src/index.js +1 -1
  53. package/packages/installer/src/installer/brownfield-upgrader.js +1 -1
  54. package/packages/installer/src/installer/git-hooks-installer.js +10 -3
  55. package/packages/installer/src/pro/pro-scaffolder.js +3 -3
  56. package/packages/installer/src/wizard/ide-config-generator.js +1 -1
  57. package/packages/installer/src/wizard/index.js +4 -41
  58. package/scripts/audit-tasks.cjs +1 -1
  59. package/scripts/package-synapse.js +1 -1
  60. package/scripts/sinapse-patch.js +31 -31
  61. package/scripts/sync-squad-yaml-components.js +3 -3
  62. package/scripts/validate-agents-md.js +1 -1
  63. package/scripts/validate-no-personal-leaks.js +1 -1
  64. package/scripts/validate-orqx-discipline.js +0 -2
  65. package/scripts/validate-package-completeness.js +7 -7
  66. package/scripts/validate-squad-yaml.js +6 -6
  67. package/sinapse/agents/sinapse-orqx.md +1 -1
  68. package/sinapse/agents/snps-orqx.md +110 -1
  69. package/squads/claude-code-mastery/agents/swarm-orqx.md +12 -11
  70. package/squads/claude-code-mastery/scripts/validate-setup.js +2 -2
  71. package/squads/squad-brand/agents/brand-orqx.md +16 -1
  72. package/squads/squad-cloning/agents/cloning-orqx.md +2 -0
  73. package/squads/squad-commercial/agents/commercial-orqx.md +7 -4
  74. package/squads/squad-council/squad.yaml +67 -11
  75. package/squads/squad-design/agents/design-orqx.md +20 -0
  76. package/squads/squad-finance/agents/finance-orqx.md +6 -0
  77. package/squads/squad-paidmedia/agents/paidmedia-orqx.md +3 -1
package/CHANGELOG.md CHANGED
@@ -1,8 +1,37 @@
1
- ## [1.11.3](https://github.com/caioimori/sinapse-ai/compare/1.11.2...1.11.3) (2026-06-19)
1
+ ## [1.12.0](https://github.com/caioimori/sinapse-ai/compare/1.11.3...1.12.0) (2026-06-20)
2
+
3
+ ### Features
4
+
5
+ * **git-hooks:** protected-files guard recusa deleção/untrack de arquivos críticos [Story feat-protected-files-commit-guard] ([#257](https://github.com/caioimori/sinapse-ai/issues/257)) ([ee50168](https://github.com/caioimori/sinapse-ai/commit/ee501688d945591e0759c0f84963c6d44ff34f0e))
2
6
 
3
7
  ### Bug Fixes
4
8
 
5
- * **chrome-brain:** nao abrir o browser em toda sessao (remove hook SessionStart) ([63824bf](https://github.com/caioimori/sinapse-ai/commit/63824bfcaef491cb4012d966a05f2a3c32d944fe))
9
+ * **activation:** resolve alias de agent id pro arquivo canonico (greeting degradado em 6/12) [Story fix-agent-activation-alias-resolution] ([#256](https://github.com/caioimori/sinapse-ai/issues/256)) ([dffae0c](https://github.com/caioimori/sinapse-ai/commit/dffae0c1680b7ded166a44185a02be1fbb3bedcc))
10
+ * **doctor:** git-hooks usa WARN p/ hook system proprio (era FAIL) ([#240](https://github.com/caioimori/sinapse-ai/issues/240)) ([d112326](https://github.com/caioimori/sinapse-ai/commit/d1123269cbbe12d14fbedd116a1d92f9c2a86925))
11
+ * **ide-sync:** resync mirror .claude + conserta YAML do swarm-orqx ([#244](https://github.com/caioimori/sinapse-ai/issues/244)) ([bdc93b6](https://github.com/caioimori/sinapse-ai/commit/bdc93b6118389a979289505d37a8eec9752d51b1))
12
+ * **registry:** dedup robusto de IDs + ressync service-registry stale [Story fix-registry-dedup-stale] ([#251](https://github.com/caioimori/sinapse-ai/issues/251)) ([e53eac3](https://github.com/caioimori/sinapse-ai/commit/e53eac3e70a53efdda9102399c90c68bb0c6b425))
13
+ * **squad-commercial:** religa roteamento do orqx aos 9 especialistas reais ([#238](https://github.com/caioimori/sinapse-ai/issues/238)) ([6469883](https://github.com/caioimori/sinapse-ai/commit/64698839ad08ee0a045f90257a1b2fafbc2a5ade))
14
+ * **squad-council:** enumera as 56 tasks no squad.yaml (eram nao-descobriveis) ([#242](https://github.com/caioimori/sinapse-ai/issues/242)) ([20320fd](https://github.com/caioimori/sinapse-ai/commit/20320fd2b21312f64de7faa91a8f3a6e7c54d988))
15
+ * **squads:** religa 16 especialistas orfaos nos orqx de 5 squads ([#241](https://github.com/caioimori/sinapse-ai/issues/241)) ([ac7283b](https://github.com/caioimori/sinapse-ai/commit/ac7283bc03a672fbb9568918b80734cd50ca62f0))
16
+ * **test:** corrige semantica do coverageThreshold + sobe piso real do core/ [Story test-coverage-threshold-semantics] ([#255](https://github.com/caioimori/sinapse-ai/issues/255)) ([e9f80ee](https://github.com/caioimori/sinapse-ai/commit/e9f80eeb57758fdb3f5c408e6459ba8b89f59407)), closes [#254](https://github.com/caioimori/sinapse-ai/issues/254) [#254](https://github.com/caioimori/sinapse-ai/issues/254)
17
+
18
+ ### Maintenance
19
+
20
+ * **ci:** renomeia workflow 'Test' -> 'Post-Merge Smoke & Build Checks' ([#249](https://github.com/caioimori/sinapse-ai/issues/249)) ([a40b0c7](https://github.com/caioimori/sinapse-ai/commit/a40b0c7ca9355a715424858813c02f416e4e87de))
21
+ * **conformance:** assisted-mode default + rebrand instalador legado + remove residuo ES [Story chore-sinapse-conformance] ([#258](https://github.com/caioimori/sinapse-ai/issues/258)) ([3fb88a3](https://github.com/caioimori/sinapse-ai/commit/3fb88a3712d0e44fa53fdc3e984a8c0cf30d265f))
22
+ * **deps:** bump undici dev (6.27.0/7.28.0) p/ corrigir HIGH dev-only ([#243](https://github.com/caioimori/sinapse-ai/issues/243)) ([9940576](https://github.com/caioimori/sinapse-ai/commit/99405767012b5cd06d942a1ed47148e4b9fd93c0))
23
+ * ignora colaborator/ (pasta local de referencia, fora do git e do npm) ([34bc1bc](https://github.com/caioimori/sinapse-ai/commit/34bc1bc07fa9f44df9c8259ace099f5f5a5aedf0))
24
+ * **lint:** autofix triviais (392->44 warns, 0 errors) + ignora colaborator/ ([#245](https://github.com/caioimori/sinapse-ai/issues/245)) ([70c54ae](https://github.com/caioimori/sinapse-ai/commit/70c54ae01403825724f3987e72ce70978c41b074))
25
+ * **lint:** zera os 33 warnings remanescentes (0 errors, 0 warnings) ([#250](https://github.com/caioimori/sinapse-ai/issues/250)) ([0ac779a](https://github.com/caioimori/sinapse-ai/commit/0ac779a7855166e3ab6cae7b74f163a9f2fa5efc))
26
+ * **packaging:** corta node_modules do tarball + higiene de deps runtime ([#239](https://github.com/caioimori/sinapse-ai/issues/239)) ([d36afb0](https://github.com/caioimori/sinapse-ai/commit/d36afb09da96c946ab9f06743306513ff6aa55ce))
27
+ * **pkg:** expoe API programatica (main/module/types/exports) + index.d.ts honesto ([#253](https://github.com/caioimori/sinapse-ai/issues/253)) ([4971413](https://github.com/caioimori/sinapse-ai/commit/4971413b419fe41000c0fbfffe668eaec39cc013))
28
+ * **test:** deleta 22 testes mortos do tools-system (codigo removido v4.31->v2.1) ([#252](https://github.com/caioimori/sinapse-ai/issues/252)) ([8ed5bd6](https://github.com/caioimori/sinapse-ai/commit/8ed5bd61c150e4c25f04fef70d8d60dc9325aeb1))
29
+ * **test:** exclui colaborator/ do jest (local test passa a espelhar CI) ([#248](https://github.com/caioimori/sinapse-ai/issues/248)) ([3eae775](https://github.com/caioimori/sinapse-ai/commit/3eae775298d2686f679fcadbb80994044d974874)), closes [#245](https://github.com/caioimori/sinapse-ai/issues/245)
30
+
31
+ ### Refactoring
32
+
33
+ * **identity:** SINAPSE canonico — remove dir SNPS/ stale + corrige help ([#246](https://github.com/caioimori/sinapse-ai/issues/246)) ([3a805fa](https://github.com/caioimori/sinapse-ai/commit/3a805fa5366dce9881125521a41e90d6eb4a0e80))
34
+ * **identity:** unifica conteudo do Imperator (snps-orqx desatualizado) ([#247](https://github.com/caioimori/sinapse-ai/issues/247)) ([f52376d](https://github.com/caioimori/sinapse-ai/commit/f52376d040fdfc2c3f3c4f95789249d5cae6f8ef))
6
35
 
7
36
  # Changelog
8
37
 
@@ -33,7 +33,7 @@ Exit codes (Story A.3):
33
33
  }
34
34
 
35
35
  const doctorModulePath = path.join(__dirname, '..', '..', '.sinapse-ai', 'core', 'doctor');
36
- // eslint-disable-next-line global-require
36
+
37
37
  const { runDoctorChecks, resolveExitCode } = require(doctorModulePath);
38
38
  const result = await runDoctorChecks({
39
39
  fix: Boolean(opts.fix),
@@ -31,10 +31,9 @@ function cmdHelp() {
31
31
  logger.always(` ${CYAN}sinapse --continue${NC} Continua última sessão`);
32
32
  logger.always('');
33
33
  logger.always(`${BOLD}Agents:${NC}\n`);
34
- logger.always(` Invocação canônica: ${CYAN}/SNPS:agents:{agent-id}${NC}`);
35
- logger.always(` Exemplo: ${CYAN}/SNPS:agents:brand-orqx${NC}`);
36
- logger.always(` Master orchestrator: ${CYAN}@snps-orqx${NC} (alias: ${DIM}@sinapse-orqx${NC})`);
37
- logger.always(` ${DIM}Alias /SINAPSE:agents:* preservado até v1.3.0 (deprecação suave).${NC}`);
34
+ logger.always(` Invocação canônica: ${CYAN}/SINAPSE:agents:{agent-id}${NC}`);
35
+ logger.always(` Exemplo: ${CYAN}/SINAPSE:agents:brand-orqx${NC}`);
36
+ logger.always(` Master orchestrator: ${CYAN}@sinapse-orqx${NC} (alias: ${DIM}@snps-orqx${NC})`);
38
37
  logger.always('');
39
38
  logger.always(`${BOLD}Ajuda extra:${NC}\n`);
40
39
  logger.always(` Erros comuns + remediação: ${CYAN}docs/guides/cli-errors.md${NC}`);
@@ -155,7 +155,7 @@ async function cmdInstallGlobal(opts = {}) {
155
155
  if (squads.length === 0) {
156
156
  logger.error(`${RED}Erro: nenhum diretório de squad encontrado no pacote.${NC}`);
157
157
  logger.error(`Tente reinstalar: ${CYAN}npm install -g sinapse-ai${NC}`);
158
- logger.error(`Se persistir, abra um issue: https://github.com/caioimori/sinapse-ai/issues`);
158
+ logger.error('Se persistir, abra um issue: https://github.com/caioimori/sinapse-ai/issues');
159
159
  process.exit(1);
160
160
  }
161
161
 
@@ -275,7 +275,7 @@ async function cmdInstallGlobal(opts = {}) {
275
275
  for (const f of fs.readdirSync(CLAUDE_COMMANDS_DIR)) {
276
276
  fs.unlinkSync(path.join(CLAUDE_COMMANDS_DIR, f));
277
277
  }
278
- } catch {}
278
+ } catch { /* dir may not exist on a fresh install */ }
279
279
 
280
280
  const sinapseBase = toForwardSlash(SINAPSE_HOME);
281
281
  const writtenAgents = new Set();
@@ -622,13 +622,13 @@ function generateCommandMd(agentId, agentName, agentIcon, squadName, squadPath,
622
622
  ? `4. Briefing-on-activation check (this agent is an ORCHESTRATOR):
623
623
  - If user provided briefing/context with the activation → proceed IMMEDIATELY: absorb → diagnose → plan with phases + agents + handoffs → execute (YOLO). NEVER ask "do you want me to plan?".
624
624
  - If bare activation only → await briefing. On receipt, apply same flow automatically.`
625
- : `4. HALT and await user input`;
625
+ : '4. HALT and await user input';
626
626
 
627
627
  const step6 = isOrchestrator
628
628
  ? `6. Briefing-on-activation check (ORCHESTRATOR):
629
629
  - If user provided briefing → proceed IMMEDIATELY: absorb → diagnose → plan → execute
630
630
  - If bare activation → await briefing, then plan automatically. NEVER ask "do you want me to plan?".`
631
- : `6. HALT and await user input`;
631
+ : '6. HALT and await user input';
632
632
 
633
633
  // Frontmatter (name + description) is REQUIRED so the file resolves as a Claude Code
634
634
  // subagent (@id) — without it, @id matches nothing. The same file doubles as a slash
@@ -754,7 +754,7 @@ See \`.claude/rules/squad-awareness.md\` for the full delegation map.
754
754
  try {
755
755
  const orqxFile = fs.readdirSync(sAgentsDir).find(f => f.endsWith('-orqx.md'));
756
756
  if (orqxFile) orqxName = orqxFile.replace('.md', '');
757
- } catch {}
757
+ } catch { /* fall back to the derived orqx name */ }
758
758
  return `| ${s.name} | @${orqxName} | ${s.agents} agents, ${s.tasks} tasks |`;
759
759
  }).join('\n');
760
760
 
@@ -828,12 +828,12 @@ exec claude --add-dir "${sinapsePathForBash}" --agent sinapse-orqx "$@"
828
828
  `;
829
829
  const bashPath = path.join(BIN_DIR, 'sinapse');
830
830
  fs.writeFileSync(bashPath, bashLauncher);
831
- try { fs.chmodSync(bashPath, 0o755); } catch {}
831
+ try { fs.chmodSync(bashPath, 0o755); } catch { /* chmod is best-effort (no-op on non-POSIX) */ }
832
832
  logger.always(` ${GREEN}OK${NC} ~/bin/sinapse`);
833
833
 
834
834
  // Windows CMD launcher
835
835
  if (IS_WIN) {
836
- const cmdLauncher = `@echo off\r\nclaude --add-dir "%USERPROFILE%\\.sinapse" --agent sinapse-orqx %*\r\n`;
836
+ const cmdLauncher = '@echo off\r\nclaude --add-dir "%USERPROFILE%\\.sinapse" --agent sinapse-orqx %*\r\n';
837
837
  fs.writeFileSync(path.join(BIN_DIR, 'sinapse.cmd'), cmdLauncher);
838
838
  logger.always(` ${GREEN}OK${NC} ~/bin/sinapse.cmd`);
839
839
  }
@@ -23,9 +23,9 @@ function verifyInstall() {
23
23
  const logger = getLogger();
24
24
  const checks = [
25
25
  [fs.existsSync(SINAPSE_HOME), `${getSquads(SINAPSE_HOME).length} squads in ~/.sinapse/`],
26
- [fs.existsSync(CLAUDE_COMMANDS_DIR), `Commands in ~/.claude/commands/SINAPSE/agents/`],
27
- [fs.existsSync(path.join(BIN_DIR, 'sinapse')), `Launcher at ~/bin/sinapse`],
28
- [fs.existsSync(path.join(SINAPSE_HOME, '.claude', 'rules', 'squad-awareness.md')), `squad-awareness.md`],
26
+ [fs.existsSync(CLAUDE_COMMANDS_DIR), 'Commands in ~/.claude/commands/SINAPSE/agents/'],
27
+ [fs.existsSync(path.join(BIN_DIR, 'sinapse')), 'Launcher at ~/bin/sinapse'],
28
+ [fs.existsSync(path.join(SINAPSE_HOME, '.claude', 'rules', 'squad-awareness.md')), 'squad-awareness.md'],
29
29
  ];
30
30
 
31
31
  for (const [ok, msg] of checks) {
@@ -183,7 +183,7 @@ function removeHooks(settingsPath, matchers) {
183
183
  function sanitizeChromePath(chromePath) {
184
184
  // Validate Chrome path contains only safe characters to prevent shell injection
185
185
  const sanitized = chromePath.replace(/\\/g, '/');
186
- if (!/^[a-zA-Z0-9\s/\-_.:()\[\]]+$/.test(sanitized)) {
186
+ if (!/^[a-zA-Z0-9\s/\-_.:()[\]]+$/.test(sanitized)) {
187
187
  throw new Error(`Unsafe Chrome path detected: ${chromePath}`);
188
188
  }
189
189
  return sanitized;
@@ -201,7 +201,7 @@ if command -v taskkill &>/dev/null; then
201
201
  elif command -v pgrep &>/dev/null; then
202
202
  pgrep -f "user-data-dir=$CHROME_DEBUG_PROFILE" 2>/dev/null | xargs kill 2>/dev/null || true
203
203
  fi`
204
- : `pgrep -f "user-data-dir=$CHROME_DEBUG_PROFILE" 2>/dev/null | xargs kill 2>/dev/null || true`;
204
+ : 'pgrep -f "user-data-dir=$CHROME_DEBUG_PROFILE" 2>/dev/null | xargs kill 2>/dev/null || true';
205
205
 
206
206
  return `#!/bin/bash
207
207
  # Chrome Brain — chrome-ensure (auto-launch)
@@ -253,7 +253,7 @@ if command -v taskkill &>/dev/null; then
253
253
  elif command -v pgrep &>/dev/null; then
254
254
  pgrep -f "user-data-dir=$CHROME_DEBUG_PROFILE" 2>/dev/null | xargs kill 2>/dev/null || true
255
255
  fi`
256
- : `pgrep -f "user-data-dir=$CHROME_DEBUG_PROFILE" 2>/dev/null | xargs kill 2>/dev/null || true`;
256
+ : 'pgrep -f "user-data-dir=$CHROME_DEBUG_PROFILE" 2>/dev/null | xargs kill 2>/dev/null || true';
257
257
 
258
258
  return `#!/bin/bash
259
259
  # Chrome Brain — chrome-debug (manual launch)
@@ -485,7 +485,7 @@ function renderFinalSummary(opts = {}) {
485
485
  }
486
486
  lines.push('');
487
487
  if (isGlobal) {
488
- lines.push(`Próximo passo:`);
488
+ lines.push('Próximo passo:');
489
489
  lines.push(` cd ${c.cyan}seu-projeto${c.reset}`);
490
490
  lines.push(` ${c.cyan}sinapse install${c.reset}`);
491
491
  } else {
@@ -55,17 +55,19 @@ function spawnAsync(command, options = {}) {
55
55
  });
56
56
  }
57
57
 
58
- // ASCII Art Banner (Clean blocky style like reference image)
59
- const BANNER = chalk.cyan(`
60
- █████╗ ██╗ ██████╗ ███████╗ ███████╗██╗ ██╗██╗ ██╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗
61
- ██╔══██╗██║██╔═══██╗██╔════╝ ██╔════╝██║ ██║██║ ██║ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝
62
- ███████║██║██║ ██║███████╗█████╗█████╗ ██║ ██║██║ ██║ ███████╗ ██║ ███████║██║ █████╔╝
63
- ██╔══██║██║██║ ██║╚════██║╚════╝██╔══╝ ██║ ██║██║ ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗
64
- ██║ ██║██║╚██████╔╝███████║ ██║ ╚██████╔╝███████╗███████╗███████║ ██║ ██║ ██║╚██████╗██║ ██╗
65
- ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
58
+ // ASCII Art Banner canonical SNPS AI wordmark in white (matches bin/lib/header.js).
59
+ // Kept in sync with the live banner so the legacy fallback installer never shows
60
+ // off-brand art (this banner predated the SINAPSE rebrand).
61
+ const BANNER = chalk.white.bold(`
62
+ ███████╗███╗ ██╗██████╗ ███████╗ █████╗ ██╗
63
+ ██╔════╝████╗ ██║██╔══██╗██╔════╝ ██╔══██╗██║
64
+ ███████╗██╔██╗ ██║██████╔╝███████╗ ███████║██║
65
+ ╚════██║██║╚██╗██║██╔═══╝ ╚════██║ ██╔══██║██║
66
+ ███████║██║ ╚████║██║ ███████║ ██║ ██║██║
67
+ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝
66
68
  `);
67
69
 
68
- const SUBTITLE = chalk.magenta('Universal AI Agent Framework for Any Domain');
70
+ const SUBTITLE = chalk.dim('Seu copiloto de inteligencia artificial');
69
71
  // Read version from package.json dynamically
70
72
  const packageJsonVersion = require(path.join(__dirname, '..', 'package.json')).version;
71
73
  const VERSION = chalk.yellow(`Installer v${packageJsonVersion}`);
package/bin/sinapse.js CHANGED
@@ -548,7 +548,7 @@ function findClaudeCliPath() {
548
548
  try {
549
549
  const npmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
550
550
  candidates.unshift(path.join(npmRoot, '@anthropic-ai/claude-code/cli.js'));
551
- } catch {}
551
+ } catch { /* npm root -g may be unavailable; fall through to other candidates */ }
552
552
  for (const p of candidates) {
553
553
  if (fs.existsSync(p)) return p;
554
554
  }
@@ -54,6 +54,7 @@ function globToRegex(glob) {
54
54
  pattern = pattern.replace(/\*/g, '[^/]+');
55
55
 
56
56
  // 4. Restore ** placeholder to any-depth matcher
57
+ // eslint-disable-next-line no-control-regex -- internal placeholder char (set above), never user input
57
58
  pattern = pattern.replace(/\u0000/g, '.+');
58
59
 
59
60
  // If pattern ends with .+ (was **), match prefix
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * staged-protected-files-guard — blocks a commit that DELETES (or untracks) a
6
+ * protected, committed-but-critical framework file.
7
+ *
8
+ * Why: on 2026-06-20 a "snapshot migracao notebook" sweep (`git add -A`) untracked
9
+ * `.sinapse-ai/core/registry/service-registry.json` (the committed registry drift
10
+ * detector, ~12k lines), bundled it with unrelated work, and pushed it. The
11
+ * framework-boundary guard is a no-op in contributor mode
12
+ * (boundary.frameworkProtection=false), so nothing stopped the deletion. This guard
13
+ * is ALWAYS on and narrowly targets that class of damage — it never touches normal
14
+ * edits, only the removal of a curated set of protected paths.
15
+ *
16
+ * Intentional removal (done in a story) bypasses with: git commit --no-verify
17
+ *
18
+ * Self-contained: Node built-ins + `git` only (matches the other lib guards so it
19
+ * bundles into <hooksDir>/lib/ with no extra deps).
20
+ */
21
+
22
+ const { spawnSync } = require('child_process');
23
+
24
+ // Curated, high-signal list. Keep small to guarantee zero false positives on
25
+ // normal work. These files are committed on purpose and must never be removed by
26
+ // an automated sweep without an explicit story.
27
+ const PROTECTED = ['.sinapse-ai/core/registry/service-registry.json'];
28
+
29
+ function stagedDeletions() {
30
+ // --no-renames forces a rename-away of a protected file to surface as a real
31
+ // deletion (D) of the old path, so moving the file out also trips the guard.
32
+ const res = spawnSync('git', ['diff', '--cached', '--name-status', '--no-renames'], {
33
+ encoding: 'utf8',
34
+ });
35
+ if (!res || res.status !== 0 || typeof res.stdout !== 'string') return [];
36
+ const deleted = [];
37
+ for (const line of res.stdout.split('\n')) {
38
+ if (!line) continue;
39
+ const parts = line.split('\t');
40
+ const status = parts[0];
41
+ const file = (parts[parts.length - 1] || '').replace(/\\/g, '/');
42
+ if (status === 'D') deleted.push(file);
43
+ }
44
+ return deleted;
45
+ }
46
+
47
+ const offenders = stagedDeletions().filter((f) => PROTECTED.includes(f));
48
+
49
+ if (offenders.length > 0) {
50
+ process.stderr.write(
51
+ 'SINAPSE Protected Files: blocking commit — it deletes/untracks a protected file:\n',
52
+ );
53
+ for (const f of offenders) process.stderr.write(' - ' + f + '\n');
54
+ process.stderr.write(
55
+ '\nThese files are committed on purpose (e.g. service-registry.json is the registry\n' +
56
+ 'drift detector). They must not be removed by an automated sweep (git add -A) or a\n' +
57
+ 'machine-migration snapshot. If this removal is intentional, do it in a story and\n' +
58
+ 'bypass once with: git commit --no-verify\n',
59
+ );
60
+ process.exit(1);
61
+ }
62
+
63
+ process.exit(0);
package/package.json CHANGED
@@ -1,12 +1,23 @@
1
1
  {
2
2
  "name": "sinapse-ai",
3
- "version": "1.11.3",
3
+ "version": "1.12.0",
4
4
  "description": "SINAPSE AI: Framework de orquestracao de IA — 17 squads, 172 agentes especializados",
5
5
  "bin": {
6
6
  "sinapse": "bin/sinapse.js",
7
7
  "sinapse-ai": "bin/cli.js",
8
8
  "sinapse-delegate": "bin/sinapse-delegate.js"
9
9
  },
10
+ "main": ".sinapse-ai/index.js",
11
+ "module": ".sinapse-ai/index.esm.js",
12
+ "types": ".sinapse-ai/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./.sinapse-ai/index.d.ts",
16
+ "default": "./.sinapse-ai/index.js"
17
+ },
18
+ "./package.json": "./package.json",
19
+ "./*": "./*"
20
+ },
10
21
  "preferGlobal": false,
11
22
  "workspaces": [
12
23
  "packages/*"
@@ -16,6 +27,8 @@
16
27
  "scripts/",
17
28
  "packages/",
18
29
  ".sinapse-ai/",
30
+ "!.sinapse-ai/node_modules",
31
+ "!**/node_modules/**",
19
32
  ".claude/CLAUDE.md",
20
33
  ".claude/rules/",
21
34
  ".claude/hooks/",
@@ -139,6 +152,7 @@
139
152
  "cli-progress": "^3.12.0",
140
153
  "commander": "^12.1.0",
141
154
  "cross-spawn": "^7.0.6",
155
+ "diff": "^5.2.0",
142
156
  "execa": "^5.1.1",
143
157
  "fast-glob": "^3.3.3",
144
158
  "fs-extra": "^11.3.2",
@@ -178,6 +192,9 @@
178
192
  "url": "https://github.com/caioimori/sinapse-ai/issues"
179
193
  },
180
194
  "homepage": "https://github.com/caioimori/sinapse-ai#readme",
195
+ "publishConfig": {
196
+ "access": "public"
197
+ },
181
198
  "engines": {
182
199
  "node": ">=18.0.0",
183
200
  "npm": ">=9.0.0"
@@ -216,7 +233,7 @@
216
233
  ]
217
234
  },
218
235
  "overrides": {
219
- "diff": "^8.0.3",
236
+ "diff": "^5.2.0",
220
237
  "serialize-javascript": "^7.0.5",
221
238
  "picomatch": "^4.0.4",
222
239
  "brace-expansion": "^5.0.6",
@@ -19,7 +19,7 @@ if (require.main === module) {
19
19
  Promise.resolve()
20
20
  .then(() => wizard.runWizard())
21
21
  .catch((error) => {
22
- // eslint-disable-next-line no-console
22
+
23
23
  console.error('Installer failed:', error && error.message ? error.message : error);
24
24
  process.exit(1);
25
25
  });
@@ -287,7 +287,7 @@ async function applyUpgrade(report, sourceDir, targetDir, options = {}) {
287
287
  result.mergeWarnings = result.mergeWarnings || [];
288
288
  for (const conflict of conflicts) {
289
289
  result.mergeWarnings.push(
290
- `core-config.yaml: ${conflict.identifier} — ${conflict.reason}`
290
+ `core-config.yaml: ${conflict.identifier} — ${conflict.reason}`,
291
291
  );
292
292
  }
293
293
  }
@@ -67,6 +67,9 @@ const SCANNER_SOURCES = [
67
67
  { from: path.join(BIN_UTILS, 'staged-sql-guard.js'), to: 'staged-sql-guard.js' },
68
68
  // --- framework boundary guard (FASE C; respects boundary.frameworkProtection) ---
69
69
  { from: path.join(BIN_UTILS, 'framework-guard.js'), to: 'framework-guard.js' },
70
+ // --- protected-files guard (always-on; blocks deletion/untrack of committed
71
+ // critical files like service-registry.json — anti git-add-A-sweep) ---
72
+ { from: path.join(BIN_UTILS, 'staged-protected-files-guard.js'), to: 'staged-protected-files-guard.js' },
70
73
  ];
71
74
 
72
75
  /**
@@ -173,13 +176,15 @@ function copyScannerLib(hooksDir) {
173
176
  /**
174
177
  * Build the content of the managed `pre-commit` Node hook.
175
178
  *
176
- * The hook runs THREE bundled guards in sequence (each a standalone module
179
+ * The hook runs FOUR bundled guards in sequence (each a standalone module
177
180
  * under ./lib that exits non-zero on a finding), then chains to a pre-existing
178
181
  * husky hook:
179
182
  * 1. staged-secret-scan.js — secret/.env/private-key/entropy leak (fail-CLOSED)
180
183
  * 2. staged-sql-guard.js — destructive DDL/DML (DROP/TRUNCATE/DELETE-no-WHERE)
181
184
  * 3. framework-guard.js — L1/L2 boundary (no-op unless boundary
182
185
  * .frameworkProtection is true in core-config.yaml)
186
+ * 4. staged-protected-files-guard.js — always-on; blocks deletion/untrack of
187
+ * committed critical files (e.g. service-registry.json)
183
188
  *
184
189
  * Each guard is spawned as a child Node process (cwd = project root, where git
185
190
  * already runs hooks) so it gets the same staged index and reuses its own
@@ -209,13 +214,15 @@ const { spawnSync } = require('child_process');
209
214
  const projectRoot = process.cwd();
210
215
  const libDir = path.join(__dirname, 'lib');
211
216
 
212
- // --- 1-3. SINAPSE staged guards (each fail-CLOSED) ---------------------------
213
- // Order: secret scan, then destructive-SQL guard, then framework-boundary guard.
217
+ // --- 1-4. SINAPSE staged guards (each fail-CLOSED) ---------------------------
218
+ // Order: secret scan, destructive-SQL guard, framework-boundary guard, then
219
+ // protected-files guard (always-on anti-sweep; does NOT respect frameworkProtection).
214
220
  // framework-guard self-disables when boundary.frameworkProtection is false.
215
221
  const GUARDS = [
216
222
  { file: 'staged-secret-scan.js', label: 'Secret Scan' },
217
223
  { file: 'staged-sql-guard.js', label: 'SQL Guard' },
218
224
  { file: 'framework-guard.js', label: 'Framework Boundary' },
225
+ { file: 'staged-protected-files-guard.js', label: 'Protected Files' },
219
226
  ];
220
227
 
221
228
  for (const guard of GUARDS) {
@@ -80,7 +80,7 @@ async function scaffoldProContent(targetDir, proSourceDir, options = {}) {
80
80
  // Validate pro source exists
81
81
  if (!await fs.pathExists(proSourceDir)) {
82
82
  result.errors.push(
83
- `Pro package not found at ${proSourceDir}. Run "npm install @sinapse-fullstack/pro" first.`
83
+ `Pro package not found at ${proSourceDir}. Run "npm install @sinapse-fullstack/pro" first.`,
84
84
  );
85
85
  return result;
86
86
  }
@@ -160,7 +160,7 @@ async function scaffoldProContent(targetDir, proSourceDir, options = {}) {
160
160
  result.errors.push(`Rollback errors: ${rollbackResult.errors.join(', ')}`);
161
161
  }
162
162
  result.warnings.push(
163
- `Scaffolding failed: ${error.message}. ${rollbackResult.removed} files cleaned up.`
163
+ `Scaffolding failed: ${error.message}. ${rollbackResult.removed} files cleaned up.`,
164
164
  );
165
165
  }
166
166
 
@@ -425,7 +425,7 @@ async function installSquadCommands(targetDir) {
425
425
  for (const agentFile of agentFiles) {
426
426
  await fs.copy(
427
427
  path.join(agentsDir, agentFile),
428
- path.join(destDir, agentFile)
428
+ path.join(destDir, agentFile),
429
429
  );
430
430
  files.push(path.relative(targetDir, path.join(destDir, agentFile)).replace(/\\/g, '/'));
431
431
  }
@@ -182,7 +182,7 @@ function generateTemplateVariables(wizardState) {
182
182
  * @param {Object} ideConfig - IDE configuration object (optional, for special handling)
183
183
  * @returns {Promise<string[]>} List of copied files
184
184
  */
185
- async function copyAgentFiles(projectRoot, agentFolder, ideConfig = null) {
185
+ async function copyAgentFiles(projectRoot, agentFolder, _ideConfig = null) {
186
186
  // v4: Agents are in development/agents/ (not root agents/)
187
187
  const sourceDir = path.join(__dirname, '..', '..', '..', '..', '.sinapse-ai', 'development', 'agents');
188
188
  const targetDir = path.join(projectRoot, agentFolder);
@@ -15,14 +15,9 @@ const { execSync } = require('child_process');
15
15
  const { colors } = require('../utils/sinapse-colors');
16
16
  const {
17
17
  getLanguageQuestion,
18
- getUserProfileQuestion,
19
18
  getLLMQuestion,
20
- getProjectTypeQuestion,
21
- getIDEQuestions,
22
- getTechPresetQuestion,
23
19
  } = require('./questions');
24
- const { setLanguage, t, tf } = require('./i18n');
25
- const yaml = require('js-yaml');
20
+ const { setLanguage, t } = require('./i18n');
26
21
  const { detectProjectTypeExtended } = require('../detection/detect-project-type');
27
22
  const { showWelcome, showCompletion, showCancellation } = require('./feedback');
28
23
  const { generateIDEConfigs, showSuccessSummary, copySkillFiles, copyExtraCommandFiles } = require('./ide-config-generator');
@@ -47,38 +42,6 @@ const {
47
42
  isLLMRoutingInstalled,
48
43
  } = require('../../../../.sinapse-ai/infrastructure/scripts/llm-routing/install-llm-routing');
49
44
 
50
- /**
51
- * Check for existing user_profile in core-config.yaml (Story 10.2 - Idempotency)
52
- * Returns the existing profile if found, null otherwise
53
- *
54
- * @param {string} targetDir - Target directory to check
55
- * @returns {Promise<string|null>} Existing user profile or null
56
- */
57
- async function getExistingUserProfile(targetDir = process.cwd()) {
58
- const coreConfigPath = path.join(targetDir, '.sinapse-ai', 'core-config.yaml');
59
-
60
- try {
61
- if (await fse.pathExists(coreConfigPath)) {
62
- const content = await fse.readFile(coreConfigPath, 'utf8');
63
- const config = yaml.load(content);
64
-
65
- if (config && config.user_profile) {
66
- // Validate the value
67
- const validProfiles = ['bob', 'advanced'];
68
- const normalizedProfile = String(config.user_profile).toLowerCase().trim();
69
-
70
- if (validProfiles.includes(normalizedProfile)) {
71
- return normalizedProfile;
72
- }
73
- }
74
- }
75
- } catch {
76
- // Config doesn't exist or is invalid - will ask for profile
77
- }
78
-
79
- return null;
80
- }
81
-
82
45
  /**
83
46
  * Map wizard language code to Claude Code settings.json language name (Story ACT-12)
84
47
  * Claude Code uses full language names, not ISO codes.
@@ -369,7 +332,7 @@ function buildAgentTemplate(agentId, squadName, homedir) {
369
332
  'ACTIVATION-NOTICE: This command activates an agent from sinapse.',
370
333
  '',
371
334
  `CRITICAL: Read the agent definition file at \`${agentDefPath}\` to understand your full operating parameters. Then:`,
372
- `1. Adopt the persona defined in that file`,
335
+ '1. Adopt the persona defined in that file',
373
336
  `2. Load the squad manifest at \`${squadManifestPath}\` for context`,
374
337
  '3. Display a greeting showing your agent name, role, and available commands',
375
338
  '4. Briefing-on-activation check (this agent is an ORCHESTRATOR):',
@@ -781,7 +744,7 @@ async function runWizard(options = {}) {
781
744
  try {
782
745
  await commandValidate({ quiet: true });
783
746
  answers.ideSyncValidation = 'pass';
784
- } catch (validateError) {
747
+ } catch {
785
748
  answers.ideSyncValidation = 'drift';
786
749
  } finally {
787
750
  console.log = _origLog;
@@ -879,7 +842,7 @@ async function runWizard(options = {}) {
879
842
  projectType: answers.projectType || 'greenfield',
880
843
  selectedIDEs: answers.selectedIDEs || [],
881
844
  mcpServers: answers.mcpServers || [],
882
- userProfile: answers.userProfile || 'advanced', // Story 10.2: User Profile
845
+ userProfile: answers.userProfile || 'bob', // Assisted-by-default (open-source p/ leigos); advanced é toggle opt-in pós-install
883
846
  skipPrompts: options.quiet || false, // Skip prompts in quiet mode
884
847
  forceMerge: options.forceMerge, // Story 9.4: Smart Merge support
885
848
  noMerge: options.noMerge, // Story 9.4: Smart Merge support
@@ -246,7 +246,7 @@ async function main() {
246
246
  `${s.avgScore}%`.padEnd(6) +
247
247
  String(s.critical).padEnd(6) +
248
248
  String(s.warning).padEnd(6) +
249
- String(s.passing)
249
+ String(s.passing),
250
250
  );
251
251
  }
252
252
 
@@ -223,7 +223,7 @@ Add to \`.claude/settings.local.json\`:
223
223
  "UserPromptSubmit": [
224
224
  {
225
225
  "type": "command",
226
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/synapse-engine.cjs\"",
226
+ "command": "node \\"$CLAUDE_PROJECT_DIR/.claude/hooks/synapse-engine.cjs\\"",
227
227
  "timeout": 10
228
228
  }
229
229
  ]