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.
- package/.claude/CLAUDE.md +2 -2
- package/.claude/rules/agent-memory-imports.md +2 -0
- package/.sinapse-ai/cli/commands/pro/index.js +8 -48
- package/.sinapse-ai/constitution.md +6 -2
- package/.sinapse-ai/core-config.yaml +5 -1
- package/.sinapse-ai/data/entity-registry.yaml +95 -95
- package/.sinapse-ai/development/agents/architect/MEMORY.md +35 -0
- package/.sinapse-ai/development/agents/data-engineer/MEMORY.md +38 -0
- package/.sinapse-ai/development/agents/developer/MEMORY.md +36 -0
- package/.sinapse-ai/development/agents/devops/MEMORY.md +39 -0
- package/.sinapse-ai/development/agents/devops.md +0 -1
- package/.sinapse-ai/development/agents/product-lead/MEMORY.md +36 -0
- package/.sinapse-ai/development/agents/project-lead/MEMORY.md +36 -0
- package/.sinapse-ai/development/agents/quality-gate/MEMORY.md +35 -0
- package/.sinapse-ai/development/agents/quality-gate.md +1 -1
- package/.sinapse-ai/development/agents/snps-orqx.md +4 -0
- package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +36 -0
- package/.sinapse-ai/development/templates/chrome-brain/knowledge-base/chrome-brain.md +2 -2
- package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +15 -0
- package/.sinapse-ai/infrastructure/scripts/validate-agents.js +159 -8
- package/.sinapse-ai/install-manifest.yaml +20 -156
- package/AGENTS.md +13 -2
- package/CHANGELOG.md +119 -4
- package/README.en.md +1 -1
- package/README.md +6 -26
- package/bin/cli.js +2 -7
- package/bin/commands/install.js +19 -257
- package/bin/commands/update.js +18 -78
- package/bin/lib/command-generator.js +261 -0
- package/bin/lib/prompts.js +2 -65
- package/bin/modules/chrome-brain-installer.js +2 -1
- package/bin/postinstall.js +6 -6
- package/docs/getting-started.md +0 -1
- package/docs/pt/getting-started.md +1 -1
- package/docs/security/dependabot-triage.md +17 -17
- package/package.json +6 -3
- package/packages/installer/src/wizard/i18n.js +3 -204
- package/packages/installer/src/wizard/index.js +1 -1
- package/packages/installer/src/wizard/questions.js +5 -368
- package/packages/installer/src/wizard/wizard.js +0 -9
- package/scripts/generate-install-manifest.js +6 -0
- package/scripts/validate-changelog-tags.js +97 -0
- package/scripts/validate-no-personal-leaks.js +184 -28
- package/scripts/validate-schemas.js +55 -10
- package/scripts/validate-story-meta.js +25 -12
- package/squads/claude-code-mastery/agents/claude-mastery-chief.md +1 -1
- package/squads/claude-code-mastery/agents/hooks-architect.md +12 -20
- package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
- package/squads/squad-product/agents/product-orqx.md +0 -1
- package/squads/squad-product/agents/ps-client-product-manager.md +0 -1
- package/squads/squad-product/agents/ps-delivery-manager.md +0 -1
- package/squads/squad-product/agents/ps-discovery-lead.md +0 -1
- package/squads/squad-product/agents/ps-product-analyst.md +0 -1
- package/squads/squad-product/agents/ps-product-ops-specialist.md +0 -1
- package/squads/squad-product/agents/ps-product-strategist.md +0 -1
- package/.sinapse-ai/core/grounding/README.md +0 -83
- package/.sinapse-ai/core/grounding/brand.cjs +0 -29
- package/.sinapse-ai/core/grounding/config-loader.cjs +0 -52
- package/.sinapse-ai/core/grounding/design-system.cjs +0 -29
- package/.sinapse-ai/core/grounding/vault.cjs +0 -36
- package/.sinapse-ai/development/scripts/approval-workflow.js +0 -643
- package/.sinapse-ai/development/scripts/backup-manager.js +0 -607
- package/.sinapse-ai/development/scripts/branch-manager.js +0 -390
- package/.sinapse-ai/development/scripts/code-quality-improver.js +0 -1329
- package/.sinapse-ai/development/scripts/commit-message-generator.js +0 -850
- package/.sinapse-ai/development/scripts/conflict-resolver.js +0 -675
- package/.sinapse-ai/development/scripts/dependency-analyzer.js +0 -638
- package/.sinapse-ai/development/scripts/diff-generator.js +0 -352
- package/.sinapse-ai/development/scripts/git-wrapper.js +0 -462
- package/.sinapse-ai/development/scripts/modification-validator.js +0 -555
- package/.sinapse-ai/development/scripts/performance-analyzer.js +0 -758
- package/.sinapse-ai/development/scripts/refactoring-suggester.js +0 -1148
- package/.sinapse-ai/development/scripts/rollback-handler.js +0 -531
- package/.sinapse-ai/development/scripts/security-checker.js +0 -359
- package/.sinapse-ai/development/scripts/template-engine.js +0 -240
- package/.sinapse-ai/development/scripts/template-validator.js +0 -279
- package/.sinapse-ai/development/scripts/test-generator.js +0 -844
- package/.sinapse-ai/development/scripts/transaction-manager.js +0 -590
- package/.sinapse-ai/development/scripts/yaml-validator.js +0 -397
- package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +0 -162
- package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +0 -211
- package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +0 -194
- package/bin/lib/register-grounding-hooks.js +0 -145
- package/docs/guides/agents/traces/execution-traces.zip +0 -0
- package/docs/guides/grounding-setup.md +0 -154
- package/docs/guides/workflows/SINAPSE-WORKFLOWS.zip +0 -0
- package/packages/installer/src/pro/pro-scaffolder.js +0 -449
- package/packages/installer/src/wizard/grounding-config.js +0 -131
- package/packages/installer/src/wizard/pro-setup.js +0 -1439
- package/packages/installer/templates/README.md +0 -16
- package/packages/installer/templates/brand-routing.example.json +0 -12
- package/packages/installer/templates/ds-routing.example.json +0 -12
- package/packages/installer/templates/vault-routing.example.json +0 -12
package/bin/commands/install.js
CHANGED
|
@@ -22,7 +22,7 @@ const {
|
|
|
22
22
|
NC,
|
|
23
23
|
} = require('../lib/constants');
|
|
24
24
|
const { header } = require('../lib/header');
|
|
25
|
-
const { getSquads, getAgentFiles
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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}
|
|
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}
|
|
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 });
|
package/bin/commands/update.js
CHANGED
|
@@ -18,19 +18,18 @@ const {
|
|
|
18
18
|
NC,
|
|
19
19
|
} = require('../lib/constants');
|
|
20
20
|
const { header } = require('../lib/header');
|
|
21
|
-
const { getSquads
|
|
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 {
|
|
33
|
-
const {
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
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
|
-
//
|
|
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}
|
|
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}
|
|
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
|
}
|