aios-core 4.2.5 → 4.2.7

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 (32) hide show
  1. package/.aios-core/core/code-intel/code-intel-client.js +280 -0
  2. package/.aios-core/core/code-intel/code-intel-enricher.js +159 -0
  3. package/.aios-core/core/code-intel/index.js +137 -0
  4. package/.aios-core/core/code-intel/providers/code-graph-provider.js +201 -0
  5. package/.aios-core/core/code-intel/providers/provider-interface.js +108 -0
  6. package/.aios-core/core/orchestration/context-manager.js +333 -5
  7. package/.aios-core/core/orchestration/dashboard-integration.js +17 -1
  8. package/.aios-core/core/orchestration/execution-profile-resolver.js +107 -0
  9. package/.aios-core/core/orchestration/index.js +3 -0
  10. package/.aios-core/core/orchestration/skill-dispatcher.js +2 -0
  11. package/.aios-core/core/orchestration/subagent-prompt-builder.js +2 -0
  12. package/.aios-core/core/orchestration/workflow-orchestrator.js +113 -5
  13. package/.aios-core/data/entity-registry.yaml +44 -22
  14. package/.aios-core/development/agents/ux-design-expert.md +1 -1
  15. package/.aios-core/development/checklists/brownfield-compatibility-checklist.md +114 -0
  16. package/.aios-core/development/scripts/workflow-state-manager.js +128 -1
  17. package/.aios-core/development/tasks/next.md +36 -5
  18. package/.aios-core/hooks/ids-post-commit.js +29 -1
  19. package/.aios-core/hooks/ids-pre-push.js +29 -1
  20. package/.aios-core/infrastructure/contracts/compatibility/aios-4.0.4.yaml +44 -0
  21. package/.aios-core/infrastructure/scripts/validate-parity.js +238 -2
  22. package/.aios-core/install-manifest.yaml +63 -27
  23. package/.aios-core/product/templates/brownfield-risk-report-tmpl.yaml +277 -0
  24. package/.aios-core/workflow-intelligence/engine/suggestion-engine.js +114 -5
  25. package/LICENSE +13 -1
  26. package/README.md +39 -9
  27. package/package.json +8 -6
  28. package/packages/installer/src/wizard/ide-config-generator.js +0 -117
  29. package/packages/installer/src/wizard/index.js +2 -118
  30. package/packages/installer/src/wizard/pro-setup.js +58 -12
  31. package/pro/license/license-api.js +9 -9
  32. package/scripts/semantic-lint.js +190 -0
package/README.md CHANGED
@@ -12,6 +12,30 @@
12
12
 
13
13
  Framework de Desenvolvimento Auto-Modificável Alimentado por IA. Fundado em Desenvolvimento Ágil Dirigido por Agentes, oferecendo capacidades revolucionárias para desenvolvimento dirigido por IA e muito mais. Transforme qualquer domínio com expertise especializada de IA: desenvolvimento de software, entretenimento, escrita criativa, estratégia de negócios, bem-estar pessoal e muito mais.
14
14
 
15
+ ## Comece Aqui (10 Min)
16
+
17
+ Se é sua primeira vez no AIOS, siga este caminho linear:
18
+
19
+ 1. Instale em um projeto novo ou existente:
20
+ ```bash
21
+ # novo projeto
22
+ npx aios-core init meu-projeto
23
+
24
+ # projeto existente
25
+ cd seu-projeto
26
+ npx aios-core install
27
+ ```
28
+ 2. Escolha sua IDE/CLI e o caminho de ativação:
29
+ - Claude Code: `/agent-name`
30
+ - Gemini CLI: `/aios-menu` → `/aios-<agent>`
31
+ - Codex CLI: `/skills` → `aios-<agent-id>`
32
+ - Cursor/Copilot/AntiGravity: siga os limites e workarounds em `docs/ide-integration.md`
33
+ 3. Ative 1 agente e confirme o greeting.
34
+ 4. Rode 1 comando inicial (`*help` ou equivalente) para validar first-value.
35
+
36
+ Definição de first-value (binária): ativação de agente + greeting válido + comando inicial com output útil em <= 10 minutos.
37
+
38
+
15
39
  ## Compatibilidade de Hooks por IDE (Realidade AIOS 4.0.4)
16
40
 
17
41
  Muitos recursos avançados do AIOS dependem de eventos de ciclo de vida (hooks). A tabela abaixo mostra a paridade real entre IDEs/plataformas:
@@ -27,11 +51,15 @@ Muitos recursos avançados do AIOS dependem de eventos de ciclo de vida (hooks).
27
51
 
28
52
  Impactos e mitigação detalhados: `docs/ide-integration.md`.
29
53
 
30
- ## Nota Sobre BMAD
54
+ ## Acknowledgments & Attribution
55
+
56
+ Synkra AIOS was originally derived from the [BMad Method](https://github.com/bmad-code-org/BMAD-METHOD), created by [Brian Madison](https://github.com/bmadcode) (BMad Code, LLC). We gratefully acknowledge the BMad Method for providing the foundation from which this project began.
31
57
 
32
- O AIOS evoluiu significativamente e **não depende de BMAD** para operação atual.
33
- Quando BMAD aparece em histórico de changelog/migração, é apenas contexto histórico.
34
- O caminho oficial e atual é AIOS 4.x com terminologia e arquitetura próprias.
58
+ **Important:** This project is **NOT affiliated with, endorsed by, or sanctioned by** the BMad Method or BMad Code, LLC. Contributors appearing in the git history from the original BMad Method repository do not imply active participation in or endorsement of Synkra AIOS.
59
+
60
+ Since its origin, AIOS has evolved significantly with its own architecture, terminology, and features (v4.x+), and does not depend on BMad for current operation. The BMad Method remains an excellent framework in its own right — please visit the [official BMad Method repository](https://github.com/bmad-code-org/BMAD-METHOD) to learn more.
61
+
62
+ BMad, BMad Method, and BMad Core are trademarks of BMad Code, LLC. See [TRADEMARK.md](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/TRADEMARK.md) for usage guidelines.
35
63
 
36
64
  ## Visão Geral
37
65
 
@@ -104,7 +132,7 @@ Esta abordagem de duas fases elimina tanto a **inconsistência de planejamento**
104
132
  - **[Criar meus próprios agentes IA](#criando-seu-próprio-squad)** → Construir agentes para seu domínio
105
133
  - **[Navegar Squads prontos](docs/guides/squads-overview.md)** → Veja como criar e usar equipes de agentes IA
106
134
  - **[Entender a arquitetura](docs/architecture/ARCHITECTURE-INDEX.md)** → Mergulho técnico profundo
107
- - **[Juntar-se à comunidade](https://discord.gg/gk8jAdXWmj)** → Obter ajuda e compartilhar ideias
135
+ - **[Reportar problemas](https://github.com/SynkraAI/aios-core/issues)** → Bug reports e feature requests
108
136
 
109
137
  ## Importante: Mantenha Sua Instalação AIOS Atualizada
110
138
 
@@ -601,12 +629,10 @@ npm install @aios-fullstack/pro
601
629
 
602
630
  Para mais informações, execute `npx aios-core pro --help` após a instalação.
603
631
 
604
- ## Suporte & Comunidade
632
+ ## Suporte
605
633
 
606
- - 📖 [Guia da Comunidade](docs/community.md) - Como participar e contribuir
607
- - 💬 [Discussões GitHub](https://github.com/SynkraAI/aios-core/discussions) - Hub central da comunidade
634
+ - 🐛 [Rastreador de Issues](https://github.com/SynkraAI/aios-core/issues) - Bug reports e feature requests
608
635
  - 💡 [Processo de Features](docs/FEATURE_PROCESS.md) - Como propor novas funcionalidades
609
- - 🐛 [Rastreador de Issues](https://github.com/SynkraAI/aios-core/issues)
610
636
  - 📋 [Como Contribuir](CONTRIBUTING.md)
611
637
  - 🗺️ [Roadmap](docs/roadmap.md) - Veja o que estamos construindo
612
638
  - 🤖 [Guia de Squads](docs/guides/squads-guide.md) - Crie equipes de agentes IA
@@ -704,6 +730,10 @@ Veja também:
704
730
 
705
731
  ## Reconhecimentos
706
732
 
733
+ This project was originally derived from the [BMad Method](https://github.com/bmad-code-org/BMAD-METHOD) by [Brian Madison](https://github.com/bmadcode). We thank Brian and all BMad Method contributors for the original work that made this project possible.
734
+
735
+ **Note:** Some contributors shown in the GitHub contributors graph are inherited from the original BMad Method git history and do not represent active participation in or endorsement of Synkra AIOS.
736
+
707
737
  [![Contributors](https://contrib.rocks/image?repo=SynkraAI/aios-core)](https://github.com/SynkraAI/aios-core/graphs/contributors)
708
738
 
709
739
  <sub>Construído com ❤️ para a comunidade de desenvolvimento assistido por IA</sub>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aios-core",
3
- "version": "4.2.5",
3
+ "version": "4.2.7",
4
4
  "description": "Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework",
5
5
  "bin": {
6
6
  "aios": "bin/aios.js",
@@ -56,10 +56,11 @@
56
56
  "sync:skills:codex": "node .aios-core/infrastructure/scripts/codex-skills-sync/index.js",
57
57
  "sync:skills:codex:global": "node .aios-core/infrastructure/scripts/codex-skills-sync/index.js --global --global-only",
58
58
  "validate:codex-skills": "node .aios-core/infrastructure/scripts/codex-skills-sync/validate.js --strict",
59
- "validate:paths": "node .aios-core/infrastructure/scripts/validate-paths.js",
60
- "validate:parity": "node .aios-core/infrastructure/scripts/validate-parity.js",
61
- "manifest:ensure": "node scripts/ensure-manifest.js",
62
- "sync:ide:cursor": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide cursor",
59
+ "validate:paths": "node .aios-core/infrastructure/scripts/validate-paths.js",
60
+ "validate:parity": "node .aios-core/infrastructure/scripts/validate-parity.js",
61
+ "validate:semantic-lint": "node scripts/semantic-lint.js",
62
+ "manifest:ensure": "node scripts/ensure-manifest.js",
63
+ "sync:ide:cursor": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide cursor",
63
64
  "prepublishOnly": "npm run generate:manifest && npm run validate:manifest",
64
65
  "prepare": "husky"
65
66
  },
@@ -139,7 +140,8 @@
139
140
  "prettier --write"
140
141
  ],
141
142
  "*.md": [
142
- "prettier --write"
143
+ "prettier --write",
144
+ "node scripts/semantic-lint.js --staged"
143
145
  ],
144
146
  ".aios-core/development/agents/*.md": [
145
147
  "npm run sync:ide"
@@ -539,12 +539,6 @@ async function generateIDEConfigs(selectedIDEs, wizardState, options = {}) {
539
539
  } else {
540
540
  spinner.info('Skipped settings.local.json (no hooks to register)');
541
541
  }
542
-
543
- // Silent statusline setup (graceful skip if user already has one)
544
- const statuslineResult = await setupGlobalStatusline();
545
- if (statuslineResult.installed) {
546
- createdFiles.push(...statuslineResult.files);
547
- }
548
542
  }
549
543
 
550
544
  // Gemini parity with Claude Code: copy hooks and configure settings
@@ -764,7 +758,6 @@ async function createClaudeSettingsLocal(projectRoot) {
764
758
  }
765
759
 
766
760
  /**
767
- <<<<<<< HEAD
768
761
  * Copy .aios-core/hooks/gemini folder into .gemini/hooks during installation
769
762
  * @param {string} projectRoot - Project root directory
770
763
  * @returns {Promise<string[]>} List of copied files
@@ -982,115 +975,6 @@ async function linkGeminiExtension(projectRoot) {
982
975
  return { status: 'skipped', reason: 'link-failed' };
983
976
  }
984
977
 
985
- /**
986
- * Setup global statusline for Claude Code
987
- *
988
- * Copies statusline-script.js and track-agent.sh to ~/.claude/
989
- * and configures ~/.claude/settings.json with statusLine + hook entries.
990
- *
991
- * GRACEFUL SKIP: If user already has a statusLine configured, this function
992
- * returns silently without any output — the user never knows it was checked.
993
- *
994
- * @returns {Promise<{installed: boolean, files: string[]}>}
995
- */
996
- async function setupGlobalStatusline() {
997
- const homeDir = require('os').homedir();
998
- const globalSettingsPath = path.join(homeDir, '.claude', 'settings.json');
999
- const result = { installed: false, files: [] };
1000
-
1001
- // Read existing global settings
1002
- let settings = {};
1003
- try {
1004
- if (await fs.pathExists(globalSettingsPath)) {
1005
- const content = await fs.readFile(globalSettingsPath, 'utf8');
1006
- settings = JSON.parse(content);
1007
- }
1008
- } catch {
1009
- // Corrupted or unreadable — treat as empty
1010
- settings = {};
1011
- }
1012
-
1013
- // GRACEFUL SKIP: User already has a statusLine configured
1014
- if (settings.statusLine) {
1015
- return result;
1016
- }
1017
-
1018
- // Source templates
1019
- const templatesDir = path.join(__dirname, '..', '..', '..', '..', '.aios-core', 'product', 'templates', 'statusline');
1020
-
1021
- const scriptSource = path.join(templatesDir, 'statusline-script.js');
1022
- const hookSource = path.join(templatesDir, 'track-agent.sh');
1023
-
1024
- // Verify templates exist
1025
- if (!await fs.pathExists(scriptSource) || !await fs.pathExists(hookSource)) {
1026
- return result;
1027
- }
1028
-
1029
- // Target paths
1030
- const scriptTarget = path.join(homeDir, '.claude', 'statusline-script.js');
1031
- const hookTarget = path.join(homeDir, '.claude', 'hooks', 'track-agent.sh');
1032
- const cacheDir = path.join(homeDir, '.claude', 'session-cache');
1033
-
1034
- // Copy files
1035
- try {
1036
- await fs.ensureDir(path.join(homeDir, '.claude', 'hooks'));
1037
- await fs.ensureDir(cacheDir);
1038
- await fs.copy(scriptSource, scriptTarget);
1039
- await fs.copy(hookSource, hookTarget);
1040
- result.files.push(scriptTarget, hookTarget);
1041
- } catch {
1042
- return result;
1043
- }
1044
-
1045
- // Build the statusLine command with platform-appropriate path
1046
- const scriptPathEscaped = scriptTarget.replace(/\\/g, '\\\\');
1047
-
1048
- // Add statusLine to settings
1049
- settings.statusLine = {
1050
- type: 'command',
1051
- command: `node "${scriptPathEscaped}"`,
1052
- };
1053
-
1054
- // Add track-agent hook to UserPromptSubmit (if not already present)
1055
- if (!settings.hooks) {
1056
- settings.hooks = {};
1057
- }
1058
- if (!Array.isArray(settings.hooks.UserPromptSubmit)) {
1059
- settings.hooks.UserPromptSubmit = [];
1060
- }
1061
-
1062
- const hookPathEscaped = hookTarget.replace(/\\/g, '\\\\');
1063
- const alreadyHasTrackAgent = settings.hooks.UserPromptSubmit.some(entry => {
1064
- if (Array.isArray(entry.hooks)) {
1065
- return entry.hooks.some(h => h.command && h.command.includes('track-agent'));
1066
- }
1067
- return entry.command && entry.command.includes('track-agent');
1068
- });
1069
-
1070
- if (!alreadyHasTrackAgent) {
1071
- settings.hooks.UserPromptSubmit.push({
1072
- matcher: '',
1073
- hooks: [
1074
- {
1075
- type: 'command',
1076
- command: `bash "${hookPathEscaped}"`,
1077
- },
1078
- ],
1079
- });
1080
- }
1081
-
1082
- // Write settings back
1083
- try {
1084
- await fs.ensureDir(path.dirname(globalSettingsPath));
1085
- await fs.writeFile(globalSettingsPath, JSON.stringify(settings, null, 2), 'utf8');
1086
- result.installed = true;
1087
- } catch {
1088
- return result;
1089
- }
1090
-
1091
- return result;
1092
- }
1093
-
1094
978
  module.exports = {
1095
979
  generateIDEConfigs,
1096
980
  showSuccessSummary,
@@ -1104,5 +988,4 @@ module.exports = {
1104
988
  copyGeminiHooksFolder,
1105
989
  createGeminiSettings,
1106
990
  linkGeminiExtension,
1107
- setupGlobalStatusline,
1108
991
  };
@@ -461,67 +461,7 @@ async function runWizard(options = {}) {
461
461
  answers.techPresetResult = { preset: 'none', success: true };
462
462
  }
463
463
 
464
- // DISABLED: Legacy installation block superseded by squads flow (OSR-8)
465
- // Install Squads if selected
466
- // if (answers.selectedExpansionPacks && answers.selectedExpansionPacks.length > 0) {
467
- // console.log('\n🎁 Installing Squads...');
468
- //
469
- // // Detect source squads directory (npm package location)
470
- // const possibleSourceDirs = [
471
- // path.join(__dirname, '..', '..', 'squads'),
472
- // path.join(__dirname, '..', '..', '..', 'squads'),
473
- // path.join(process.cwd(), 'node_modules', '@synkra/aios-core', 'squads'),
474
- // ];
475
- //
476
- // let sourceExpansionDir = null;
477
- // for (const dir of possibleSourceDirs) {
478
- // if (fse.existsSync(dir)) {
479
- // sourceExpansionDir = dir;
480
- // break;
481
- // }
482
- // }
483
- //
484
- // if (sourceExpansionDir) {
485
- // const targetExpansionDir = path.join(process.cwd(), 'squads');
486
- // await fse.ensureDir(targetExpansionDir);
487
- //
488
- // const installedPacks = [];
489
- // const failedPacks = [];
490
- //
491
- // for (const pack of answers.selectedExpansionPacks) {
492
- // const sourcePack = path.join(sourceExpansionDir, pack);
493
- // const targetPack = path.join(targetExpansionDir, pack);
494
- //
495
- // try {
496
- // if (fse.existsSync(sourcePack)) {
497
- // await fse.copy(sourcePack, targetPack);
498
- // installedPacks.push(pack);
499
- // console.log(` ✅ ${pack}`);
500
- // } else {
501
- // failedPacks.push({ pack, reason: 'not found' });
502
- // console.log(` ⚠️ ${pack} - not found in source`);
503
- // }
504
- // } catch (packError) {
505
- // failedPacks.push({ pack, reason: packError.message });
506
- // console.log(` ⚠️ ${pack} - ${packError.message}`);
507
- // }
508
- // }
509
- //
510
- // answers.expansionPacksInstalled = installedPacks.length > 0;
511
- // answers.expansionPacksResult = {
512
- // installed: installedPacks,
513
- // failed: failedPacks,
514
- // targetDir: targetExpansionDir,
515
- // };
516
- //
517
- // if (installedPacks.length > 0) {
518
- // console.log(`\n✅ Squads installed (${installedPacks.length}/${answers.selectedExpansionPacks.length})`);
519
- // }
520
- // } else {
521
- // console.log(' ⚠️ Squads source directory not found');
522
- // answers.expansionPacksInstalled = false;
523
- // }
524
- // }
464
+ // Legacy squad installation path removed; unified squads flow is now the only supported path.
525
465
 
526
466
  // Story 1.4: Generate IDE configs if IDEs were selected
527
467
  let ideConfigResult = null;
@@ -545,63 +485,7 @@ async function runWizard(options = {}) {
545
485
  }
546
486
  }
547
487
 
548
- // DISABLED: Legacy installation block superseded by squads flow (OSR-8)
549
- // Install squad agents to each selected IDE
550
- // if (answers.expansionPacksResult && answers.expansionPacksResult.installed.length > 0) {
551
- // console.log('\n📦 Installing squad agents to IDEs...');
552
- //
553
- // for (const packName of answers.expansionPacksResult.installed) {
554
- // const packAgentsDir = path.join(answers.expansionPacksResult.targetDir, packName, 'agents');
555
- //
556
- // if (await fse.pathExists(packAgentsDir)) {
557
- // const agentFiles = (await fse.readdir(packAgentsDir)).filter(f => f.endsWith('.md'));
558
- //
559
- // if (agentFiles.length > 0) {
560
- // for (const ideKey of answers.selectedIDEs) {
561
- // const ideConfig = getIDEConfig(ideKey);
562
- // if (!ideConfig || !ideConfig.agentFolder) continue;
563
- //
564
- // const isAntiGravity = ideConfig.specialConfig && ideConfig.specialConfig.type === 'antigravity';
565
- //
566
- // // Determine target folder for this squad
567
- // let targetFolder;
568
- // if (isAntiGravity) {
569
- // // AntiGravity: workflows go to .agent/workflows/{packName}/
570
- // targetFolder = path.join(process.cwd(), ideConfig.agentFolder, packName);
571
- // // Also need to copy actual agents to .antigravity/agents/{packName}/
572
- // const agentsTargetFolder = path.join(process.cwd(), ideConfig.specialConfig.agentsFolder, packName);
573
- // await fse.ensureDir(agentsTargetFolder);
574
- //
575
- // for (const agentFile of agentFiles) {
576
- // const sourcePath = path.join(packAgentsDir, agentFile);
577
- // const agentName = agentFile.replace('.md', '');
578
- //
579
- // // Create workflow file
580
- // const workflowContent = generateExpansionPackWorkflow(agentName, packName);
581
- // await fse.ensureDir(targetFolder);
582
- // await fse.writeFile(path.join(targetFolder, agentFile), workflowContent, 'utf8');
583
- //
584
- // // Copy actual agent
585
- // await fse.copy(sourcePath, path.join(agentsTargetFolder, agentFile));
586
- // }
587
- // } else {
588
- // // Other IDEs: copy directly to agentFolder/{packName}/
589
- // targetFolder = path.join(process.cwd(), ideConfig.agentFolder, packName);
590
- // await fse.ensureDir(targetFolder);
591
- //
592
- // for (const agentFile of agentFiles) {
593
- // await fse.copy(
594
- // path.join(packAgentsDir, agentFile),
595
- // path.join(targetFolder, agentFile),
596
- // );
597
- // }
598
- // }
599
- // }
600
- // console.log(` ✅ ${packName}: ${agentFiles.length} agents installed to ${answers.selectedIDEs.length} IDE(s)`);
601
- // }
602
- // }
603
- // }
604
- // }
488
+ // Legacy per-squad IDE copy path removed; sync pipeline handles IDE propagation.
605
489
  }
606
490
 
607
491
  // Story 1.6: Environment Configuration
@@ -16,7 +16,7 @@
16
16
  'use strict';
17
17
 
18
18
  const { createSpinner, showSuccess, showError, showWarning, showInfo } = require('./feedback');
19
- const { colors, headings, status } = require('../utils/aios-colors');
19
+ const { colors, status } = require('../utils/aios-colors');
20
20
 
21
21
  /**
22
22
  * Gold color for Pro branding.
@@ -386,7 +386,7 @@ async function loginWithRetry(client, email) {
386
386
 
387
387
  // Wait for email verification if needed
388
388
  if (!loginResult.emailVerified) {
389
- const verifyResult = await waitForEmailVerification(client, loginResult.sessionToken);
389
+ const verifyResult = await waitForEmailVerification(client, loginResult.sessionToken, email);
390
390
  if (!verifyResult.success) {
391
391
  return verifyResult;
392
392
  }
@@ -495,7 +495,7 @@ async function createAccountFlow(client, email) {
495
495
  }
496
496
 
497
497
  if (sessionToken) {
498
- const verifyResult = await waitForEmailVerification(client, sessionToken);
498
+ const verifyResult = await waitForEmailVerification(client, sessionToken, email);
499
499
  if (!verifyResult.success) {
500
500
  return verifyResult;
501
501
  }
@@ -516,7 +516,7 @@ async function createAccountFlow(client, email) {
516
516
  break;
517
517
  }
518
518
  // Got session but not verified yet — use the verification polling
519
- const verifyResult = await waitForEmailVerification(client, sessionToken);
519
+ const verifyResult = await waitForEmailVerification(client, sessionToken, email);
520
520
  if (!verifyResult.success) {
521
521
  return verifyResult;
522
522
  }
@@ -625,7 +625,7 @@ async function authenticateWithEmail(email, password) {
625
625
 
626
626
  // Wait for email verification if needed
627
627
  if (!emailVerified) {
628
- const verifyResult = await waitForEmailVerification(client, sessionToken);
628
+ const verifyResult = await waitForEmailVerification(client, sessionToken, email);
629
629
  if (!verifyResult.success) {
630
630
  return verifyResult;
631
631
  }
@@ -642,10 +642,11 @@ async function authenticateWithEmail(email, password) {
642
642
  * User can press R to resend verification email.
643
643
  *
644
644
  * @param {object} client - LicenseApiClient instance
645
- * @param {string} sessionToken - Session token
645
+ * @param {string} sessionToken - Session token (accessToken)
646
+ * @param {string} email - User email for resend functionality
646
647
  * @returns {Promise<Object>} Result with { success }
647
648
  */
648
- async function waitForEmailVerification(client, sessionToken) {
649
+ async function waitForEmailVerification(client, sessionToken, email) {
649
650
  console.log('');
650
651
  showInfo('Waiting for email verification...');
651
652
  showInfo('Open your email and click the verification link.');
@@ -692,7 +693,7 @@ async function waitForEmailVerification(client, sessionToken) {
692
693
  if (resendHint) {
693
694
  resendHint = false;
694
695
  try {
695
- await client.resendVerification(sessionToken);
696
+ await client.resendVerification(email);
696
697
  showInfo('Verification email resent.');
697
698
  } catch (error) {
698
699
  showWarning(`Could not resend: ${error.message}`);
@@ -946,6 +947,55 @@ async function validateKeyWithApi(key) {
946
947
  async function stepInstallScaffold(targetDir, options = {}) {
947
948
  showStep(2, 3, 'Pro Content Installation');
948
949
 
950
+ const path = require('path');
951
+ const fs = require('fs');
952
+ const { execSync } = require('child_process');
953
+
954
+ const proSourceDir = path.join(targetDir, 'node_modules', '@aios-fullstack', 'pro');
955
+
956
+ // Step 2a: Ensure package.json exists (greenfield projects)
957
+ const packageJsonPath = path.join(targetDir, 'package.json');
958
+ if (!fs.existsSync(packageJsonPath)) {
959
+ const initSpinner = createSpinner('Initializing package.json...');
960
+ initSpinner.start();
961
+ try {
962
+ execSync('npm init -y', { cwd: targetDir, stdio: 'pipe' });
963
+ initSpinner.succeed('package.json created');
964
+ } catch (err) {
965
+ initSpinner.fail('Failed to create package.json');
966
+ return { success: false, error: `npm init failed: ${err.message}` };
967
+ }
968
+ }
969
+
970
+ // Step 2b: Install @aios-fullstack/pro if not present
971
+ if (!fs.existsSync(proSourceDir)) {
972
+ const installSpinner = createSpinner('Installing @aios-fullstack/pro...');
973
+ installSpinner.start();
974
+ try {
975
+ execSync('npm install @aios-fullstack/pro', {
976
+ cwd: targetDir,
977
+ stdio: 'pipe',
978
+ timeout: 120000,
979
+ });
980
+ installSpinner.succeed('Pro package installed');
981
+ } catch (err) {
982
+ installSpinner.fail('Failed to install Pro package');
983
+ return {
984
+ success: false,
985
+ error: `npm install @aios-fullstack/pro failed: ${err.message}. Try manually: npm install @aios-fullstack/pro`,
986
+ };
987
+ }
988
+
989
+ // Validate installation
990
+ if (!fs.existsSync(proSourceDir)) {
991
+ return {
992
+ success: false,
993
+ error: 'Pro package not found after npm install. Check npm output.',
994
+ };
995
+ }
996
+ }
997
+
998
+ // Step 2c: Scaffold pro content
949
999
  const scaffolderModule = loadProScaffolder();
950
1000
 
951
1001
  if (!scaffolderModule) {
@@ -954,10 +1004,6 @@ async function stepInstallScaffold(targetDir, options = {}) {
954
1004
  }
955
1005
 
956
1006
  const { scaffoldProContent } = scaffolderModule;
957
- const path = require('path');
958
-
959
- // Determine pro source directory
960
- const proSourceDir = path.join(targetDir, 'node_modules', '@aios-fullstack', 'pro');
961
1007
 
962
1008
  const spinner = createSpinner('Scaffolding pro content...');
963
1009
  spinner.start();
@@ -426,7 +426,7 @@ class LicenseApiClient {
426
426
  });
427
427
 
428
428
  return {
429
- sessionToken: response.sessionToken,
429
+ sessionToken: response.accessToken,
430
430
  userId: response.userId,
431
431
  emailVerified: response.emailVerified !== false,
432
432
  };
@@ -455,11 +455,11 @@ class LicenseApiClient {
455
455
  async checkEmailVerified(sessionToken) {
456
456
  try {
457
457
  const response = await this._request('POST', '/api/v1/auth/verify-status', {
458
- sessionToken,
458
+ accessToken: sessionToken,
459
459
  });
460
460
 
461
461
  return {
462
- verified: response.verified === true,
462
+ verified: response.emailVerified === true,
463
463
  email: response.email,
464
464
  };
465
465
  } catch (error) {
@@ -487,7 +487,7 @@ class LicenseApiClient {
487
487
  async activateByAuth(sessionToken, machineId, aiosCoreVersion) {
488
488
  try {
489
489
  const response = await this._request('POST', '/api/v1/auth/activate-pro', {
490
- sessionToken,
490
+ accessToken: sessionToken,
491
491
  machineId,
492
492
  aiosCoreVersion,
493
493
  });
@@ -500,9 +500,9 @@ class LicenseApiClient {
500
500
  }
501
501
 
502
502
  return {
503
- key: response.key,
503
+ key: response.licenseKey || response.key,
504
504
  features: response.features,
505
- seats: response.seats || { used: 1, max: 2 },
505
+ seats: response.seats || { used: 1, max: 3 },
506
506
  expiresAt: response.expiresAt,
507
507
  cacheValidDays: response.cacheValidDays || 30,
508
508
  gracePeriodDays: response.gracePeriodDays || 7,
@@ -541,14 +541,14 @@ class LicenseApiClient {
541
541
  /**
542
542
  * Resend email verification.
543
543
  *
544
- * @param {string} sessionToken - Session token
544
+ * @param {string} email - User email address
545
545
  * @returns {Promise<object>} Result with { message }
546
546
  * @throws {AuthError} On failure
547
547
  */
548
- async resendVerification(sessionToken) {
548
+ async resendVerification(email) {
549
549
  try {
550
550
  const response = await this._request('POST', '/api/v1/auth/resend-verification', {
551
- sessionToken,
551
+ email,
552
552
  });
553
553
 
554
554
  return {