sinapse-ai 1.26.0 → 1.27.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.
@@ -134,17 +134,18 @@ async function cmdInstallGlobal(opts = {}) {
134
134
 
135
135
  // LLM selection (skipped in upsert mode if previous llm known)
136
136
  // Story 10.35: --reconfigure forces prompt even in upsert mode
137
- let llmChoice;
138
- let llmWasReused = false;
139
- if (requestedLlm) {
140
- llmChoice = requestedLlm;
141
- } else if (isUpsert && !reconfigure && existing.llm) {
142
- llmChoice = existing.llm;
143
- llmWasReused = true;
137
+ const llmChoice = await resolveLlmChoice({
138
+ requestedLlm,
139
+ isUpsert,
140
+ reconfigure,
141
+ existingLlm: existing.llm,
142
+ });
143
+ const llmWasReused = Boolean(isUpsert && !reconfigure && !requestedLlm && existing.llm);
144
+ if (llmWasReused) {
144
145
  const ideLabel = Array.isArray(llmChoice) ? llmChoice.join(', ') : String(llmChoice);
145
146
  logger.always(`${DIM} IDE: ${ideLabel} (from saved config; pass --reconfigure to change)${NC}`);
146
- } else {
147
- llmChoice = await promptLlmChoice();
147
+ } else if (!requestedLlm && !reconfigure) {
148
+ logger.always(`${DIM} IDE: Claude Code + Codex (padrao; use --llm para limitar)${NC}`);
148
149
  }
149
150
  if (languageWasReused || llmWasReused) logger.always('');
150
151
 
@@ -382,6 +383,24 @@ async function cmdInstallGlobal(opts = {}) {
382
383
  logger.always('');
383
384
  }
384
385
 
386
+ /**
387
+ * Resolves provider selection independently of filesystem writes and prompts.
388
+ * Explicit flags win; existing configured installs remain stable until the
389
+ * user reconfigures them; fresh or legacy-unconfigured installs use both.
390
+ */
391
+ async function resolveLlmChoice({
392
+ requestedLlm = null,
393
+ isUpsert = false,
394
+ reconfigure = false,
395
+ existingLlm = null,
396
+ prompt = promptLlmChoice,
397
+ } = {}) {
398
+ if (requestedLlm) return requestedLlm;
399
+ if (isUpsert && !reconfigure && existingLlm) return existingLlm;
400
+ if (reconfigure) return prompt();
401
+ return 'both';
402
+ }
403
+
385
404
  // ── Transactional install helpers (follow-up #13) ────────────────────────────
386
405
 
387
406
  /**
@@ -871,6 +890,7 @@ function ensurePathWindows() {
871
890
 
872
891
  module.exports = {
873
892
  cmdInstallGlobal,
893
+ resolveLlmChoice,
874
894
  generateCommandMd,
875
895
  generateSquadAwareness,
876
896
  createLauncher,
@@ -27,7 +27,6 @@ const {
27
27
  detectExistingInstall,
28
28
  detectStaleness,
29
29
  } = require('../lib/detection');
30
- const { promptLlmChoice } = require('../lib/prompts');
31
30
  const { generateSquadAwareness } = require('./install');
32
31
  const {
33
32
  recordInstalledAgents,
@@ -122,9 +121,12 @@ async function cmdUpdateGlobal() {
122
121
  logger.always('');
123
122
  }
124
123
 
125
- // Story 10.22 — skip LLM prompt when previous llm known. To re-prompt,
126
- // run `npx sinapse-ai install --force`.
127
- const llmChoice = existing.llm || await promptLlmChoice();
124
+ // Story 10.22 — preserve the saved provider selection. To choose again,
125
+ // run `npx sinapse-ai@latest install --reconfigure`.
126
+ const llmChoice = existing.llm || 'both';
127
+ if (!existing.llm) {
128
+ logger.always(`${DIM} IDE: Claude Code + Codex (padrao para instalacoes legadas sem provider salvo)${NC}`);
129
+ }
128
130
 
129
131
  logger.always('');
130
132
  logger.always(`${BOLD}Atualizando SINAPSE AI...${NC}\n`);
@@ -82,7 +82,7 @@ function warnNonInteractive() {
82
82
  nonInteractiveWarned = true;
83
83
  // stderr so it never pollutes stdout consumers (CI logs, pipes).
84
84
  process.stderr.write(
85
- `${YELLOW}INFO${NC} ambiente nao-interativo detectado, usando defaults pt + claude-code ` +
85
+ `${YELLOW}INFO${NC} ambiente nao-interativo detectado, usando defaults pt + Claude Code + Codex ` +
86
86
  `${DIM}(use --interactive pra forcar prompts)${NC}\n`,
87
87
  );
88
88
  }
@@ -15,7 +15,7 @@ async function promptLlmChoice() {
15
15
  // check that silently skipped this prompt in Git Bash + Windows.
16
16
  if (!detectInteractiveMode()) {
17
17
  warnNonInteractive();
18
- return 'claude-code';
18
+ return 'both';
19
19
  }
20
20
  try {
21
21
  const inquirer = require('inquirer');
@@ -24,11 +24,11 @@ async function promptLlmChoice() {
24
24
  name: 'llms',
25
25
  message: 'Escolha sua LLM (espaco seleciona, enter confirma):',
26
26
  choices: [
27
- { name: 'Claude Code (Recomendado)', value: 'claude-code', checked: true },
28
- { name: 'Codex CLI', value: 'codex' },
27
+ { name: 'Claude Code', value: 'claude-code', checked: true },
28
+ { name: 'Codex CLI', value: 'codex', checked: true },
29
29
  ],
30
30
  }]);
31
- if (llms.length === 0) return 'claude-code'; // default if none selected
31
+ if (llms.length === 0) return 'both'; // default if none selected
32
32
  if (llms.length === 2) return 'both';
33
33
  return llms[0];
34
34
  } catch {
@@ -37,16 +37,16 @@ async function promptLlmChoice() {
37
37
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
38
38
  return new Promise((resolve) => {
39
39
  logger.always(`${CYAN} Escolha sua LLM:${NC}`);
40
- logger.always(` ${GREEN}1${NC}) Claude Code ${DIM}(Recomendado)${NC}`);
40
+ logger.always(` ${GREEN}1${NC}) Claude Code`);
41
41
  logger.always(` ${GREEN}2${NC}) Codex CLI`);
42
- logger.always(` ${GREEN}3${NC}) Ambos`);
42
+ logger.always(` ${GREEN}3${NC}) Ambos ${DIM}(Recomendado)${NC}`);
43
43
  logger.always('');
44
44
  rl.question(` ${BOLD}Opcao [1/2/3]:${NC} `, (answer) => {
45
45
  rl.close();
46
- const choice = (answer || '1').trim();
46
+ const choice = (answer || '3').trim();
47
47
  if (choice === '2') resolve('codex');
48
- else if (choice === '3') resolve('both');
49
- else resolve('claude-code');
48
+ else if (choice === '1') resolve('claude-code');
49
+ else resolve('both');
50
50
  });
51
51
  });
52
52
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## Pré-requisitos
6
6
 
7
- - **Node.js** ≥ 20 (LTS recomendado)
7
+ - **Node.js** ≥ 18 (Node 22 LTS recomendado)
8
8
  - **Claude Code** ou **Codex CLI** instalado
9
9
  - **Git** (pra colaboração)
10
10
 
@@ -14,7 +14,7 @@
14
14
  npx sinapse-ai@latest install
15
15
  ```
16
16
 
17
- O wizard detecta seu ambiente, escolhe IDE (Claude Code ou Codex), instala os 17 squads e configura os hooks essenciais automaticamente.
17
+ O wizard detecta seu ambiente e, em instalações novas ou sem provider salvo, instala Claude Code e Codex por padrão, além dos 17 squads e hooks essenciais. Instalações existentes preservam o provider salvo; use `--reconfigure` para alterá-lo. Use `--llm=claude-code` ou `--llm=codex` somente quando quiser limitar a instalação a um provider.
18
18
 
19
19
  ## Validar setup
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinapse-ai",
3
- "version": "1.26.0",
3
+ "version": "1.27.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",