sinapse-ai 1.12.1 → 1.13.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 (93) hide show
  1. package/.claude/CLAUDE.md +2 -2
  2. package/.claude/rules/agent-memory-imports.md +2 -0
  3. package/.sinapse-ai/cli/commands/pro/index.js +8 -48
  4. package/.sinapse-ai/constitution.md +6 -2
  5. package/.sinapse-ai/core-config.yaml +5 -1
  6. package/.sinapse-ai/data/entity-registry.yaml +95 -95
  7. package/.sinapse-ai/development/agents/architect/MEMORY.md +35 -0
  8. package/.sinapse-ai/development/agents/data-engineer/MEMORY.md +38 -0
  9. package/.sinapse-ai/development/agents/developer/MEMORY.md +36 -0
  10. package/.sinapse-ai/development/agents/devops/MEMORY.md +39 -0
  11. package/.sinapse-ai/development/agents/devops.md +0 -1
  12. package/.sinapse-ai/development/agents/product-lead/MEMORY.md +36 -0
  13. package/.sinapse-ai/development/agents/project-lead/MEMORY.md +36 -0
  14. package/.sinapse-ai/development/agents/quality-gate/MEMORY.md +35 -0
  15. package/.sinapse-ai/development/agents/quality-gate.md +1 -1
  16. package/.sinapse-ai/development/agents/snps-orqx.md +4 -0
  17. package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +36 -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 +20 -156
  22. package/AGENTS.md +13 -2
  23. package/CHANGELOG.md +119 -4
  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 +1 -1
  47. package/squads/claude-code-mastery/agents/hooks-architect.md +12 -20
  48. package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
  49. package/squads/squad-product/agents/product-orqx.md +0 -1
  50. package/squads/squad-product/agents/ps-client-product-manager.md +0 -1
  51. package/squads/squad-product/agents/ps-delivery-manager.md +0 -1
  52. package/squads/squad-product/agents/ps-discovery-lead.md +0 -1
  53. package/squads/squad-product/agents/ps-product-analyst.md +0 -1
  54. package/squads/squad-product/agents/ps-product-ops-specialist.md +0 -1
  55. package/squads/squad-product/agents/ps-product-strategist.md +0 -1
  56. package/.sinapse-ai/core/grounding/README.md +0 -83
  57. package/.sinapse-ai/core/grounding/brand.cjs +0 -29
  58. package/.sinapse-ai/core/grounding/config-loader.cjs +0 -52
  59. package/.sinapse-ai/core/grounding/design-system.cjs +0 -29
  60. package/.sinapse-ai/core/grounding/vault.cjs +0 -36
  61. package/.sinapse-ai/development/scripts/approval-workflow.js +0 -643
  62. package/.sinapse-ai/development/scripts/backup-manager.js +0 -607
  63. package/.sinapse-ai/development/scripts/branch-manager.js +0 -390
  64. package/.sinapse-ai/development/scripts/code-quality-improver.js +0 -1329
  65. package/.sinapse-ai/development/scripts/commit-message-generator.js +0 -850
  66. package/.sinapse-ai/development/scripts/conflict-resolver.js +0 -675
  67. package/.sinapse-ai/development/scripts/dependency-analyzer.js +0 -638
  68. package/.sinapse-ai/development/scripts/diff-generator.js +0 -352
  69. package/.sinapse-ai/development/scripts/git-wrapper.js +0 -462
  70. package/.sinapse-ai/development/scripts/modification-validator.js +0 -555
  71. package/.sinapse-ai/development/scripts/performance-analyzer.js +0 -758
  72. package/.sinapse-ai/development/scripts/refactoring-suggester.js +0 -1148
  73. package/.sinapse-ai/development/scripts/rollback-handler.js +0 -531
  74. package/.sinapse-ai/development/scripts/security-checker.js +0 -359
  75. package/.sinapse-ai/development/scripts/template-engine.js +0 -240
  76. package/.sinapse-ai/development/scripts/template-validator.js +0 -279
  77. package/.sinapse-ai/development/scripts/test-generator.js +0 -844
  78. package/.sinapse-ai/development/scripts/transaction-manager.js +0 -590
  79. package/.sinapse-ai/development/scripts/yaml-validator.js +0 -397
  80. package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +0 -162
  81. package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +0 -211
  82. package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +0 -194
  83. package/bin/lib/register-grounding-hooks.js +0 -145
  84. package/docs/guides/agents/traces/execution-traces.zip +0 -0
  85. package/docs/guides/grounding-setup.md +0 -154
  86. package/docs/guides/workflows/SINAPSE-WORKFLOWS.zip +0 -0
  87. package/packages/installer/src/pro/pro-scaffolder.js +0 -449
  88. package/packages/installer/src/wizard/grounding-config.js +0 -131
  89. package/packages/installer/src/wizard/pro-setup.js +0 -1439
  90. package/packages/installer/templates/README.md +0 -16
  91. package/packages/installer/templates/brand-routing.example.json +0 -12
  92. package/packages/installer/templates/ds-routing.example.json +0 -12
  93. package/packages/installer/templates/vault-routing.example.json +0 -12
@@ -22,7 +22,7 @@ const {
22
22
  NC,
23
23
  } = require('../lib/constants');
24
24
  const { header } = require('../lib/header');
25
- const { getSquads, getAgentFiles, extractAgentMeta } = require('../lib/squads');
25
+ const { getSquads, getAgentFiles } = require('../lib/squads');
26
26
  const {
27
27
  copyDirSync,
28
28
  rmDirSync,
@@ -34,13 +34,15 @@ const {
34
34
  detectInteractiveMode,
35
35
  warnNonInteractive,
36
36
  } = require('../lib/detection');
37
- const {
38
- promptLlmChoice,
39
- promptGroundingSections,
40
- } = require('../lib/prompts');
37
+ const { promptLlmChoice } = require('../lib/prompts');
41
38
  const { recordInstalledAgents } = require('./uninstall');
42
39
  const { verifyInstall } = require('./status');
43
- const { registerGroundingHooks, HOOK_FILENAMES } = require('../lib/register-grounding-hooks');
40
+ // generateCommandMd is re-exported below for backward-compat (update.js imports it
41
+ // from ./install). regenerateAgentCommands is the shared Phase 2 helper.
42
+ const {
43
+ generateCommandMd,
44
+ regenerateAgentCommands,
45
+ } = require('../lib/command-generator');
44
46
 
45
47
  // ── Global Install ───────────────────────────────────────────────────────────
46
48
 
@@ -63,7 +65,7 @@ async function cmdInstallGlobal(opts = {}) {
63
65
  logger.always(`${DIM} Use --force to wipe and reinstall fresh. Use --reconfigure to re-prompt language/LLM.${NC}`);
64
66
  logger.always('');
65
67
  } else {
66
- logger.always(`${BOLD} Bem-vindo ao SNPS AI!${NC}`);
68
+ logger.always(`${BOLD} Bem-vindo ao SINAPSE AI!${NC}`);
67
69
  logger.always(`${DIM} Vamos configurar seu copiloto de inteligencia artificial.${NC}`);
68
70
  logger.always('');
69
71
  }
@@ -144,11 +146,6 @@ async function cmdInstallGlobal(opts = {}) {
144
146
  }
145
147
  if (languageWasReused || llmWasReused) logger.always('');
146
148
 
147
- // Story 10.47 — grounding (vault / design system / brand) opt-in BYO.
148
- // Each section is independently optional; empty answer = skip = no-op hook.
149
- // Honors upsert + --reconfigure semantics established by Stories 10.20/10.35.
150
- await promptGroundingSections({ isUpsert, reconfigure });
151
-
152
149
  // Validate package + compute what will be installed (squads live in squads/).
153
150
  const squadsDir = path.join(ROOT, 'squads');
154
151
  const squads = getSquads(fs.existsSync(squadsDir) ? squadsDir : ROOT);
@@ -216,7 +213,7 @@ async function cmdInstallGlobal(opts = {}) {
216
213
  }
217
214
  }
218
215
 
219
- logger.always(`\n${BOLD}Instalando Sinapse globalmente...${NC}\n`);
216
+ logger.always(`\n${BOLD}Instalando SINAPSE AI globalmente...${NC}\n`);
220
217
 
221
218
  // Phase 1: Copy squads to ~/.sinapse/
222
219
  logger.always(`${CYAN}Phase 1:${NC} ${isUpsert ? 'Refreshing' : 'Copying'} squads to ~/.sinapse/`);
@@ -266,72 +263,14 @@ async function cmdInstallGlobal(opts = {}) {
266
263
  logger.always(` ${GREEN}OK${NC} sinapse (master, ${masterAgents} agents)`);
267
264
  }
268
265
 
269
- // Phase 2: Generate orqx commands
266
+ // Phase 2: Generate agent commands (shared with `update` via command-generator).
270
267
  logger.always(`\n${CYAN}Phase 2:${NC} Generating agent commands`);
271
- fs.mkdirSync(CLAUDE_COMMANDS_DIR, { recursive: true });
272
-
273
- // Clear old commands
274
- try {
275
- for (const f of fs.readdirSync(CLAUDE_COMMANDS_DIR)) {
276
- fs.unlinkSync(path.join(CLAUDE_COMMANDS_DIR, f));
277
- }
278
- } catch { /* dir may not exist on a fresh install */ }
279
-
280
- const sinapseBase = toForwardSlash(SINAPSE_HOME);
281
- const writtenAgents = new Set();
282
-
283
- // Generate commands for orqx agents from squads (dynamic paths, always correct)
284
- for (const squad of squads) {
285
- const squadPath = `${sinapseBase}/${squad.name}`;
286
- const agentsDir = path.join(SINAPSE_HOME, squad.name, 'agents');
287
- if (!fs.existsSync(agentsDir)) continue;
288
-
289
- // agent-invocation fix: generate a command/subagent for EVERY agent (not only -orqx),
290
- // so every specialist is invokable via @agent and /SINAPSE:agents:agent.
291
- const squadAgents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
292
- for (const file of squadAgents) {
293
- const agentId = file.replace('.md', '');
294
- const meta = extractAgentMeta(path.join(agentsDir, file));
295
- const cmdContent = generateCommandMd(agentId, meta.name, meta.icon, squad.name, squadPath, file);
296
- fs.writeFileSync(path.join(CLAUDE_COMMANDS_DIR, `${agentId}.md`), cmdContent);
297
- writtenAgents.add(file);
298
- }
299
- }
300
-
301
- // Generate commands for sinapse/ orqx squad agents
302
- if (fs.existsSync(sinapseMasterDest)) {
303
- const masterAgentsDir = path.join(sinapseMasterDest, 'agents');
304
- if (fs.existsSync(masterAgentsDir)) {
305
- for (const file of fs.readdirSync(masterAgentsDir).filter(f => f.endsWith('.md'))) {
306
- if (writtenAgents.has(file)) continue;
307
- const agentId = file.replace('.md', '');
308
- const meta = extractAgentMeta(path.join(masterAgentsDir, file));
309
- const squadPath = `${sinapseBase}/sinapse`;
310
- const cmdContent = generateCommandMd(agentId, meta.name, meta.icon, 'sinapse', squadPath, file);
311
- fs.writeFileSync(path.join(CLAUDE_COMMANDS_DIR, `${agentId}.md`), cmdContent);
312
- writtenAgents.add(file);
313
- }
314
- }
315
- }
316
-
317
- // Master entry points (@sinapse, @snps, @sinapse-orqx, @snps-orqx) → rich Imperator stub.
318
- // Overwrites the generic command file for the orqx names and adds the short aliases the
319
- // user actually types. All four carry the baked-in greeting + auto-plan mandate.
320
- if (fs.existsSync(sinapseMasterDest)) {
321
- const masterSquadPath = `${sinapseBase}/sinapse`;
322
- const masterEntryPoints = [
323
- ['sinapse-orqx', 'sinapse-orqx.md'],
324
- ['snps-orqx', 'snps-orqx.md'],
325
- ['sinapse', 'sinapse-orqx.md'],
326
- ['snps', 'snps-orqx.md'],
327
- ];
328
- for (const [id, personaFile] of masterEntryPoints) {
329
- const personaPath = `${masterSquadPath}/agents/${personaFile}`;
330
- const stub = generateMasterStub(id, personaPath, masterSquadPath, squads);
331
- fs.writeFileSync(path.join(CLAUDE_COMMANDS_DIR, `${id}.md`), stub);
332
- writtenAgents.add(`${id}.md`);
333
- }
334
- }
268
+ const { writtenAgents } = regenerateAgentCommands({
269
+ sinapseHome: SINAPSE_HOME,
270
+ commandsDir: CLAUDE_COMMANDS_DIR,
271
+ squads,
272
+ sinapseMasterDest,
273
+ });
335
274
  logger.always(` ${GREEN}OK${NC} ${writtenAgents.size} total command files`);
336
275
 
337
276
  // Phase 2b: Install global agents based on LLM choice
@@ -407,39 +346,6 @@ async function cmdInstallGlobal(opts = {}) {
407
346
  logger.always(` ${CYAN}Last updated:${NC} ${meta.updatedAt}`);
408
347
  }
409
348
 
410
- // Phase 6b — Story GA-1.6: copy framework grounding hooks to a stable
411
- // location and register them in ~/.claude/settings.json. Idempotent and
412
- // non-destructive: existing personal hooks (user's vault-grounding,
413
- // terminal-bus, etc.) are preserved.
414
- if (llmChoice === 'claude-code' || llmChoice === 'both') {
415
- try {
416
- logger.always(`\n${CYAN}Phase 6b:${NC} Grounding hooks (vault / DS / brand)`);
417
- const srcHooksDir = path.join(ROOT, '.sinapse-ai', 'hooks');
418
- const destHooksDir = path.join(SINAPSE_HOME, 'hooks');
419
- fs.mkdirSync(destHooksDir, { recursive: true });
420
- let copied = 0;
421
- for (const hookName of HOOK_FILENAMES) {
422
- const src = path.join(srcHooksDir, hookName);
423
- if (!fs.existsSync(src)) continue;
424
- fs.copyFileSync(src, path.join(destHooksDir, hookName));
425
- copied++;
426
- }
427
- const settingsPath = path.join(HOME, '.claude', 'settings.json');
428
- const result = registerGroundingHooks({
429
- settingsPath,
430
- hooksDir: destHooksDir,
431
- notify: (msg) => logger.always(` ${DIM}${msg}${NC}`),
432
- });
433
- const summary = `${result.added.length} added, ${result.skipped.length} already present`;
434
- logger.always(` ${GREEN}OK${NC} ${copied} hook files copied — ${summary}`);
435
- if (result.errors.length > 0) {
436
- for (const err of result.errors) logger.always(` ${YELLOW}WARN${NC} ${err}`);
437
- }
438
- } catch (error) {
439
- logger.always(` ${YELLOW}SKIP${NC} Grounding hooks: ${error.message}`);
440
- }
441
- }
442
-
443
349
  // Chrome Brain: Auto-install browser automation
444
350
  if (llmChoice === 'claude-code' || llmChoice === 'both') {
445
351
  try {
@@ -528,10 +434,10 @@ async function cmdInstallGlobal(opts = {}) {
528
434
 
529
435
  logger.always('');
530
436
  logger.always(`${GREEN}══════════════════════════════════════════════════════════════${NC}`);
531
- logger.always(`${GREEN} Sinapse installed successfully!${NC}`);
437
+ logger.always(`${GREEN} SINAPSE AI installed successfully!${NC}`);
532
438
  logger.always(`${GREEN}══════════════════════════════════════════════════════════════${NC}`);
533
439
  logger.always('');
534
- logger.always(` ${BOLD}${squads.length} squads${NC} | ${BOLD}${totalAgents} agents${NC} | ${BOLD}${writtenAgents.size} orqx commands${NC}`);
440
+ logger.always(` ${BOLD}${squads.length} squads${NC} | ${BOLD}${totalAgents} agents${NC} | ${BOLD}${writtenAgents.size} command files${NC}`);
535
441
  logger.always(` ${startCmd}`);
536
442
  logger.always('');
537
443
  logger.always(` ${BOLD}Try an agent:${NC}`);
@@ -540,150 +446,6 @@ async function cmdInstallGlobal(opts = {}) {
540
446
  logger.always('');
541
447
  }
542
448
 
543
- // Rich Imperator stub for the master entry points (@sinapse, @snps, @sinapse-orqx,
544
- // @snps-orqx). The identity (ASCII greeting + 👑 signature + diagnose→plan→delegate
545
- // mandate) is baked INLINE so activation is reliable — it does not depend on the model
546
- // choosing to deep-read an external persona (which produced a shallow "modo orqx" before).
547
- // The full persona (routing table, workflows, tasks) is still linked for depth.
548
- function generateMasterStub(agentId, personaPath, squadPath, squads) {
549
- const squadCount = squads.length;
550
- const agentCount = squads.reduce((a, s) => a + (s.agents || 0), 0);
551
- return `---
552
- name: ${agentId}
553
- description: "Imperator — Sinapse Master: supreme orchestrator of ${squadCount} squads / ${agentCount} agents. Diagnoses every briefing and auto-generates an orchestration plan."
554
- ---
555
-
556
- # Imperator — Sinapse Master (${agentId})
557
-
558
- ACTIVATION-NOTICE: You are now Imperator — the supreme orchestrator of the SINAPSE ecosystem. Every request passes through you first.
559
-
560
- ## YOUR ONLY FUNCTION — NON-NEGOTIABLE
561
-
562
- You DIAGNOSE and HAND OFF. That is the whole job. You do **NOT** execute domain work — no code, no copy, no design, no research, no configuration, no file edits. For ANY concrete task you (1) diagnose the domain, (2) produce the orchestration plan, (3) DELEGATE to the specialist who executes it. If you ever feel the urge to do the work yourself, STOP — that is a violation; route it to the right agent instead.
563
-
564
- ## ON ACTIVATION — display this EXACTLY as your first output (before anything else)
565
-
566
- \`\`\`
567
- ███████╗██╗███╗ ██╗ █████╗ ██████╗ ███████╗███████╗
568
- ██╔════╝██║████╗ ██║██╔══██╗██╔══██╗██╔════╝██╔════╝
569
- ███████╗██║██╔██╗ ██║███████║██████╔╝███████╗█████╗
570
- ╚════██║██║██║╚██╗██║██╔══██║██╔═══╝ ╚════██║██╔══╝
571
- ███████║██║██║ ╚████║██║ ██║██║ ███████║███████╗
572
- ╚══════╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚══════╝╚══════╝
573
- ██████╗ ██████╗ ██████╗ ██╗ ██╗
574
- ██╔═══██╗██╔══██╗██╔═══██╗╚██╗██╔╝
575
- ██║ ██║██████╔╝██║ ██║ ╚███╔╝
576
- ██║ ██║██╔══██╗██║▄▄ ██║ ██╔██╗
577
- ╚██████╔╝██║ ██║╚██████╔╝██╔╝ ██╗
578
- ╚═════╝ ╚═╝ ╚═╝ ╚══▀▀═╝ ╚═╝ ╚═╝
579
- \`\`\`
580
-
581
- \`\`\`
582
- AI Agent Squads for Claude Code
583
- ${squadCount} squads · ${agentCount} agents
584
-
585
- 👑 Imperator — Sinapse Master ativado
586
-
587
- Descreva seu objetivo que eu diagnostico o domínio
588
- e roteio para o agente certo.
589
-
590
- Comandos principais:
591
- *route {pedido} — Diagnostica e roteia para a squad certa
592
- *plan {iniciativa} — Desenha um plano de execução multi-squad
593
- *status — Reporta todas as squads e capacidades
594
- *onboard — Tour guiado do ecossistema SINAPSE
595
- *help — Mostra todos os comandos
596
- \`\`\`
597
-
598
- ## AFTER THE GREETING — NON-NEGOTIABLE (Imperator's core function)
599
-
600
- Check if the user provided a briefing with the activation:
601
- - **Briefing provided** → proceed IMMEDIATELY: run the Initial State Audit → classify the request → produce an ORCHESTRATION PLAN (phases + squads + specific agents assigned + handoffs) → delegate to the specialists. NEVER ask "do you want me to plan?" — for Imperator the answer is always YES.
602
- - **Bare activation** → await the briefing, then apply the same flow automatically on receipt.
603
-
604
- You diagnose and DELEGATE — never execute domain work yourself. Route simple, well-defined requests directly to @specialist; complex ones to @{domain}-orqx; cross-domain ones by coordinating multiple orchestrators.
605
-
606
- ## FULL OPERATING PARAMETERS
607
-
608
- For your complete persona — the routing table of all squads, the Initial State Audit, the Documentation-First gate, NSN enforcement, and every workflow and task — read and ADOPT:
609
- \`${personaPath}\`
610
- Tasks: \`${squadPath}/tasks/\` · Workflows: \`${squadPath}/workflows/\` · Manifest: \`${squadPath}/squad.yaml\`
611
-
612
- — Imperator, orchestrating SINAPSE
613
- `;
614
- }
615
-
616
- function generateCommandMd(agentId, agentName, agentIcon, squadName, squadPath, agentFile) {
617
- // Detecta se é orquestrador: id termina em -orqx OU é Imperator (snps-orqx/sinapse-orqx)
618
- // ou um dos apelidos curtos do master (sinapse/snps).
619
- const isOrchestrator = /-orqx$/.test(agentId) || agentId === 'snps-orqx' || agentId === 'sinapse-orqx' || agentId === 'sinapse' || agentId === 'snps';
620
-
621
- const step4 = isOrchestrator
622
- ? `4. Briefing-on-activation check (this agent is an ORCHESTRATOR):
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
- - If bare activation only → await briefing. On receipt, apply same flow automatically.`
625
- : '4. HALT and await user input';
626
-
627
- const step6 = isOrchestrator
628
- ? `6. Briefing-on-activation check (ORCHESTRATOR):
629
- - If user provided briefing → proceed IMMEDIATELY: absorb → diagnose → plan → execute
630
- - If bare activation → await briefing, then plan automatically. NEVER ask "do you want me to plan?".`
631
- : '6. HALT and await user input';
632
-
633
- // Frontmatter (name + description) is REQUIRED so the file resolves as a Claude Code
634
- // subagent (@id) — without it, @id matches nothing. The same file doubles as a slash
635
- // command (/SINAPSE:agents:id); extra frontmatter is harmless there.
636
- const fmDesc = (isOrchestrator
637
- ? `${agentName || agentId} — orchestrator for ${squadName}; diagnoses, routes to specialists and auto-generates an orchestration plan`
638
- : `${agentName || agentId} — ${squadName} specialist`).replace(/["\n\r]/g, ' ').trim();
639
-
640
- return `---
641
- name: ${agentId}
642
- description: "${fmDesc}"
643
- ---
644
-
645
- # ${agentId}
646
-
647
- ACTIVATION-NOTICE: This command activates an agent from ${squadName}.
648
-
649
- CRITICAL: Read the agent definition file at \`${squadPath}/agents/${agentFile}\` to understand your full operating parameters. Then:
650
- 1. Adopt the persona defined in that file (name: ${agentName}, icon: ${agentIcon})
651
- 2. Load the squad manifest at \`${squadPath}/squad.yaml\` for context
652
- 3. Display a greeting showing your agent name, role, and available commands
653
- ${step4}
654
-
655
- ## Agent Reference
656
- - **Agent ID:** ${agentId}
657
- - **Squad:** ${squadName}
658
- - **Definition:** \`${squadPath}/agents/${agentFile}\`
659
- - **Squad Manifest:** \`${squadPath}/squad.yaml\`
660
- - **Tasks:** \`${squadPath}/tasks/\`
661
- - **Knowledge Bases:** \`${squadPath}/knowledge-base/\`
662
- - **Workflows:** \`${squadPath}/workflows/\`
663
-
664
- ## Activation Instructions
665
- 1. Read the full agent definition: \`${squadPath}/agents/${agentFile}\`
666
- 2. Adopt the persona (name, icon, communication style, principles)
667
- 3. Show greeting: "{icon} {name} — {role} ativado"
668
- 4. Show: "Squad: ${squadName} | Invoke: /SINAPSE:agents:${agentId}"
669
- 5. List your key tasks from the agent definition
670
- ${step6}
671
-
672
- ## How to Execute Tasks
673
- When the user requests a task:
674
- 1. Find the matching task in \`${squadPath}/tasks/\`
675
- 2. Read the task file completely
676
- 3. Execute following the task checklist step by step
677
- 4. Consult knowledge bases in \`${squadPath}/knowledge-base/\` as needed
678
-
679
- ## Cross-Squad Handoff
680
- If the task requires expertise outside this squad:
681
- 1. Identify which squad covers the needed domain
682
- 2. Recommend: /SINAPSE:agents:{appropriate-agent}
683
- 3. Provide handoff context
684
- `;
685
- }
686
-
687
449
  function generateSquadAwareness(sinapseDir, squads) {
688
450
  const rulesDir = path.join(sinapseDir, '.claude', 'rules');
689
451
  fs.mkdirSync(rulesDir, { recursive: true });
@@ -18,19 +18,18 @@ const {
18
18
  NC,
19
19
  } = require('../lib/constants');
20
20
  const { header } = require('../lib/header');
21
- const { getSquads, extractAgentMeta } = require('../lib/squads');
21
+ const { getSquads } = require('../lib/squads');
22
22
  const {
23
23
  rmDirSync,
24
24
  syncDirSync,
25
- toForwardSlash,
26
25
  } = require('../lib/fs-utils');
27
26
  const {
28
27
  detectExistingInstall,
29
28
  detectStaleness,
30
29
  } = require('../lib/detection');
31
30
  const { promptLlmChoice } = require('../lib/prompts');
32
- const { generateCommandMd, generateSquadAwareness } = require('./install');
33
- const { registerGroundingHooks, HOOK_FILENAMES } = require('../lib/register-grounding-hooks');
31
+ const { generateSquadAwareness } = require('./install');
32
+ const { regenerateAgentCommands } = require('../lib/command-generator');
34
33
  const { execSync } = require('child_process');
35
34
 
36
35
  // Query the latest version published to npm. Returns null when npm is unreachable.
@@ -99,7 +98,7 @@ async function cmdUpdateGlobal() {
99
98
 
100
99
  // Welcome back screen
101
100
  logger.always(`${BOLD} Que bom que voce voltou!${NC}`);
102
- logger.always(`${DIM} Atualizando SNPS AI: v${prevVer} -> v${VERSION}${NC}`);
101
+ logger.always(`${DIM} Atualizando SINAPSE AI: v${prevVer} -> v${VERSION}${NC}`);
103
102
  logger.always('');
104
103
 
105
104
  // Story 10.40 — Staleness warning (installed vs executing version)
@@ -117,7 +116,7 @@ async function cmdUpdateGlobal() {
117
116
  const llmChoice = existing.llm || await promptLlmChoice();
118
117
 
119
118
  logger.always('');
120
- logger.always(`${BOLD}Atualizando SNPS AI...${NC}\n`);
119
+ logger.always(`${BOLD}Atualizando SINAPSE AI...${NC}\n`);
121
120
 
122
121
  const squadsDir = path.join(ROOT, 'squads');
123
122
  const squadsSrcBase = fs.existsSync(squadsDir) ? squadsDir : ROOT;
@@ -147,53 +146,24 @@ async function cmdUpdateGlobal() {
147
146
  logger.always(` ${GREEN}OK${NC} sinapse (orqx)`);
148
147
  }
149
148
 
150
- // Phase 2: Regenerate commands (reuse install logic)
149
+ // Phase 2: Regenerate commands shared with `install` so `update` produces the
150
+ // SAME complete set (every specialist command + the rich master Imperator stubs),
151
+ // not just the `-orqx` subset it used to write.
151
152
  logger.always(`\n${CYAN}Phase 2:${NC} Regenerating commands`);
152
- // Clear and regenerate
153
153
  rmDirSync(CLAUDE_COMMANDS_DIR);
154
- fs.mkdirSync(CLAUDE_COMMANDS_DIR, { recursive: true });
155
-
156
- const sinapseBase = toForwardSlash(SINAPSE_HOME);
157
- const writtenAgents = new Set();
158
-
159
- // Generate commands for orqx agents from squads (dynamic paths)
160
- let totalAgents = 0;
161
- for (const squad of squads) {
162
- const agentsDir = path.join(SINAPSE_HOME, squad.name, 'agents');
163
- if (!fs.existsSync(agentsDir)) continue;
164
- const allAgents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
165
- totalAgents += allAgents.length;
166
- const orqxAgents = allAgents.filter(f => f.includes('-orqx'));
167
- for (const file of orqxAgents) {
168
- const agentId = file.replace('.md', '');
169
- const meta = extractAgentMeta(path.join(agentsDir, file));
170
- const squadPath = `${sinapseBase}/${squad.name}`;
171
- fs.writeFileSync(path.join(CLAUDE_COMMANDS_DIR, file), generateCommandMd(agentId, meta.name, meta.icon, squad.name, squadPath, file));
172
- writtenAgents.add(file);
173
- }
174
- }
175
-
176
- // Generate commands for sinapse/ orqx squad agents
177
- const sinapseAgentsDir = path.join(SINAPSE_HOME, 'sinapse', 'agents');
178
- if (fs.existsSync(sinapseAgentsDir)) {
179
- const masterAgents = fs.readdirSync(sinapseAgentsDir).filter(f => f.endsWith('.md'));
180
- totalAgents += masterAgents.length;
181
- for (const file of masterAgents) {
182
- if (writtenAgents.has(file)) continue;
183
- const agentId = file.replace('.md', '');
184
- const meta = extractAgentMeta(path.join(sinapseAgentsDir, file));
185
- const squadPath = `${sinapseBase}/sinapse`;
186
- fs.writeFileSync(path.join(CLAUDE_COMMANDS_DIR, file), generateCommandMd(agentId, meta.name, meta.icon, 'sinapse', squadPath, file));
187
- writtenAgents.add(file);
188
- }
189
- }
154
+ const { writtenAgents, totalAgents } = regenerateAgentCommands({
155
+ sinapseHome: SINAPSE_HOME,
156
+ commandsDir: CLAUDE_COMMANDS_DIR,
157
+ squads,
158
+ sinapseMasterDest: path.join(SINAPSE_HOME, 'sinapse'),
159
+ });
190
160
  logger.always(` ${GREEN}OK${NC} ${writtenAgents.size} command files (${totalAgents} agents total)`);
191
161
 
192
162
  // Phase 2b: Install global agents based on LLM choice
193
163
  if (llmChoice === 'claude-code' || llmChoice === 'both') {
194
164
  const globalAgentsDir = path.join(HOME, '.claude', 'agents');
195
165
  fs.mkdirSync(globalAgentsDir, { recursive: true });
196
- // Copy orqx commands as global agents
166
+ // Copy all generated agent commands as global agents
197
167
  for (const f of fs.readdirSync(CLAUDE_COMMANDS_DIR).filter(f => f.endsWith('.md'))) {
198
168
  fs.copyFileSync(path.join(CLAUDE_COMMANDS_DIR, f), path.join(globalAgentsDir, f));
199
169
  }
@@ -203,7 +173,7 @@ async function cmdUpdateGlobal() {
203
173
  if (llmChoice === 'codex' || llmChoice === 'both') {
204
174
  const codexAgentsDir = path.join(HOME, '.codex', 'agents');
205
175
  fs.mkdirSync(codexAgentsDir, { recursive: true });
206
- // Generate orqx agents for Codex
176
+ // Copy all generated agent commands for Codex
207
177
  for (const f of fs.readdirSync(CLAUDE_COMMANDS_DIR).filter(f => f.endsWith('.md'))) {
208
178
  fs.copyFileSync(path.join(CLAUDE_COMMANDS_DIR, f), path.join(codexAgentsDir, f));
209
179
  }
@@ -235,36 +205,6 @@ async function cmdUpdateGlobal() {
235
205
  logger.always(` ${CYAN}First installed:${NC} ${meta.installedAt}`);
236
206
  logger.always(` ${CYAN}Last updated:${NC} ${meta.updatedAt}`);
237
207
 
238
- // Phase 3b — Story GA-1.6: ensure grounding hooks are present + registered.
239
- if (llmChoice === 'claude-code' || llmChoice === 'both') {
240
- try {
241
- logger.always(`\n${CYAN}Phase 3b:${NC} Refreshing grounding hooks`);
242
- const srcHooksDir = path.join(ROOT, '.sinapse-ai', 'hooks');
243
- const destHooksDir = path.join(SINAPSE_HOME, 'hooks');
244
- fs.mkdirSync(destHooksDir, { recursive: true });
245
- let copied = 0;
246
- for (const hookName of HOOK_FILENAMES) {
247
- const src = path.join(srcHooksDir, hookName);
248
- if (!fs.existsSync(src)) continue;
249
- fs.copyFileSync(src, path.join(destHooksDir, hookName));
250
- copied++;
251
- }
252
- const settingsPath = path.join(HOME, '.claude', 'settings.json');
253
- const result = registerGroundingHooks({
254
- settingsPath,
255
- hooksDir: destHooksDir,
256
- notify: (msg) => logger.always(` ${DIM}${msg}${NC}`),
257
- });
258
- const summary = `${result.added.length} added, ${result.skipped.length} already present`;
259
- logger.always(` ${GREEN}OK${NC} ${copied} hook files refreshed — ${summary}`);
260
- if (result.errors.length > 0) {
261
- for (const err of result.errors) logger.always(` ${YELLOW}WARN${NC} ${err}`);
262
- }
263
- } catch (error) {
264
- logger.always(` ${YELLOW}SKIP${NC} Grounding hooks: ${error.message}`);
265
- }
266
- }
267
-
268
208
  // Phase 4: Update project-local files (.sinapse-ai/, .claude/)
269
209
  logger.always(`\n${CYAN}Phase 4:${NC} Updating project files in current directory`);
270
210
  try {
@@ -292,10 +232,10 @@ async function cmdUpdateGlobal() {
292
232
 
293
233
  logger.always('');
294
234
  logger.always(`${GREEN}══════════════════════════════════════════════════════════════${NC}`);
295
- logger.always(`${GREEN} SNPS AI atualizado para v${VERSION}!${NC}`);
235
+ logger.always(`${GREEN} SINAPSE AI atualizado para v${VERSION}!${NC}`);
296
236
  logger.always(`${GREEN}══════════════════════════════════════════════════════════════${NC}`);
297
237
  logger.always('');
298
- logger.always(` ${BOLD}${squads.length} squads${NC} | ${BOLD}${totalAgents} agents${NC} | ${BOLD}${writtenAgents.size} orqx commands${NC}`);
238
+ logger.always(` ${BOLD}${squads.length} squads${NC} | ${BOLD}${totalAgents} agents${NC} | ${BOLD}${writtenAgents.size} command files${NC}`);
299
239
  logger.always(` ${startCmd}`);
300
240
  logger.always('');
301
241
  }