aios-core 4.2.13 → 4.2.15

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 (95) hide show
  1. package/.aios-core/core/code-intel/helpers/dev-helper.js +206 -0
  2. package/.aios-core/core/registry/registry-schema.json +166 -166
  3. package/.aios-core/core/synapse/diagnostics/collectors/hook-collector.js +3 -3
  4. package/.aios-core/data/entity-registry.yaml +27 -0
  5. package/.aios-core/development/scripts/approval-workflow.js +642 -642
  6. package/.aios-core/development/scripts/backup-manager.js +606 -606
  7. package/.aios-core/development/scripts/branch-manager.js +389 -389
  8. package/.aios-core/development/scripts/code-quality-improver.js +1311 -1311
  9. package/.aios-core/development/scripts/commit-message-generator.js +849 -849
  10. package/.aios-core/development/scripts/conflict-resolver.js +674 -674
  11. package/.aios-core/development/scripts/dependency-analyzer.js +637 -637
  12. package/.aios-core/development/scripts/diff-generator.js +351 -351
  13. package/.aios-core/development/scripts/elicitation-engine.js +384 -384
  14. package/.aios-core/development/scripts/elicitation-session-manager.js +299 -299
  15. package/.aios-core/development/scripts/git-wrapper.js +461 -461
  16. package/.aios-core/development/scripts/manifest-preview.js +244 -244
  17. package/.aios-core/development/scripts/metrics-tracker.js +775 -775
  18. package/.aios-core/development/scripts/modification-validator.js +554 -554
  19. package/.aios-core/development/scripts/pattern-learner.js +1224 -1224
  20. package/.aios-core/development/scripts/performance-analyzer.js +757 -757
  21. package/.aios-core/development/scripts/refactoring-suggester.js +1138 -1138
  22. package/.aios-core/development/scripts/rollback-handler.js +530 -530
  23. package/.aios-core/development/scripts/security-checker.js +358 -358
  24. package/.aios-core/development/scripts/template-engine.js +239 -239
  25. package/.aios-core/development/scripts/template-validator.js +278 -278
  26. package/.aios-core/development/scripts/test-generator.js +843 -843
  27. package/.aios-core/development/scripts/transaction-manager.js +589 -589
  28. package/.aios-core/development/scripts/usage-tracker.js +673 -673
  29. package/.aios-core/development/scripts/validate-filenames.js +226 -226
  30. package/.aios-core/development/scripts/version-tracker.js +526 -526
  31. package/.aios-core/development/scripts/yaml-validator.js +396 -396
  32. package/.aios-core/development/tasks/build-autonomous.md +10 -4
  33. package/.aios-core/development/tasks/create-service.md +23 -0
  34. package/.aios-core/development/tasks/dev-develop-story.md +12 -6
  35. package/.aios-core/development/tasks/dev-suggest-refactoring.md +7 -1
  36. package/.aios-core/development/tasks/publish-npm.md +3 -3
  37. package/.aios-core/hooks/unified/README.md +1 -1
  38. package/.aios-core/install-manifest.yaml +65 -61
  39. package/.aios-core/manifests/schema/manifest-schema.json +190 -190
  40. package/.aios-core/product/templates/component-react-tmpl.tsx +98 -98
  41. package/.aios-core/product/templates/engine/schemas/adr.schema.json +102 -102
  42. package/.aios-core/product/templates/engine/schemas/dbdr.schema.json +205 -205
  43. package/.aios-core/product/templates/engine/schemas/epic.schema.json +175 -175
  44. package/.aios-core/product/templates/engine/schemas/pmdr.schema.json +175 -175
  45. package/.aios-core/product/templates/engine/schemas/prd-v2.schema.json +300 -300
  46. package/.aios-core/product/templates/engine/schemas/prd.schema.json +152 -152
  47. package/.aios-core/product/templates/engine/schemas/story.schema.json +222 -222
  48. package/.aios-core/product/templates/engine/schemas/task.schema.json +154 -154
  49. package/.aios-core/product/templates/eslintrc-security.json +32 -32
  50. package/.aios-core/product/templates/github-actions-cd.yml +212 -212
  51. package/.aios-core/product/templates/github-actions-ci.yml +172 -172
  52. package/.aios-core/product/templates/shock-report-tmpl.html +502 -502
  53. package/.aios-core/product/templates/token-exports-css-tmpl.css +240 -240
  54. package/.aios-core/quality/schemas/quality-metrics.schema.json +233 -233
  55. package/.aios-core/scripts/migrate-framework-docs.sh +300 -300
  56. package/README.en.md +747 -0
  57. package/README.md +4 -2
  58. package/bin/aios.js +7 -4
  59. package/package.json +1 -1
  60. package/packages/aios-pro-cli/src/recover.js +1 -1
  61. package/packages/installer/src/wizard/ide-config-generator.js +6 -6
  62. package/packages/installer/src/wizard/pro-setup.js +3 -3
  63. package/pro/license/degradation.js +220 -220
  64. package/pro/license/errors.js +450 -450
  65. package/pro/license/feature-gate.js +354 -354
  66. package/pro/license/index.js +181 -181
  67. package/pro/license/license-cache.js +523 -523
  68. package/pro/license/license-crypto.js +303 -303
  69. package/scripts/package-synapse.js +5 -5
  70. package/scripts/validate-package-completeness.js +3 -3
  71. package/.aios-core/.session/current-session.json +0 -14
  72. package/.aios-core/data/registry-update-log.jsonl +0 -191
  73. package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +0 -335
  74. package/.aios-core/docs/component-creation-guide.md +0 -458
  75. package/.aios-core/docs/session-update-pattern.md +0 -307
  76. package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +0 -1963
  77. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +0 -1190
  78. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +0 -439
  79. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +0 -5398
  80. package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +0 -523
  81. package/.aios-core/docs/template-syntax.md +0 -267
  82. package/.aios-core/docs/troubleshooting-guide.md +0 -625
  83. package/.aios-core/infrastructure/tests/utilities-audit-results.json +0 -501
  84. package/.aios-core/manifests/agents.csv +0 -29
  85. package/.aios-core/manifests/tasks.csv +0 -198
  86. package/.aios-core/manifests/workers.csv +0 -204
  87. package/.claude/rules/agent-authority.md +0 -105
  88. package/.claude/rules/coderabbit-integration.md +0 -93
  89. package/.claude/rules/ids-principles.md +0 -112
  90. package/.claude/rules/story-lifecycle.md +0 -139
  91. package/.claude/rules/workflow-execution.md +0 -150
  92. package/scripts/glue/README.md +0 -355
  93. package/scripts/glue/compose-agent-prompt.cjs +0 -362
  94. /package/.claude/hooks/{precompact-session-digest.js → precompact-session-digest.cjs} +0 -0
  95. /package/.claude/hooks/{synapse-engine.js → synapse-engine.cjs} +0 -0
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Synkra AIOS: Framework Universal de Agentes IA 🚀
2
2
 
3
+ > 🌍 [English](README.en.md) | **[Português](README.md)**
4
+
3
5
  [![Versão NPM](https://img.shields.io/npm/v/aios-core.svg)](https://www.npmjs.com/package/aios-core)
4
6
  [![Licença: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
7
  [![Versão Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org/)
@@ -479,7 +481,7 @@ O Synkra AIOS vem com 11 agentes especializados:
479
481
  ### Guias Essenciais
480
482
 
481
483
  - 📖 **[Guia do Usuário](docs/guides/user-guide.md)** - Passo a passo completo desde a concepção até a conclusão do projeto
482
- - 🏗️ **[Arquitetura Principal](docs/architecture/ARCHITECTURE-INDEX.md)** - Mergulho técnico profundo e design do sistema
484
+ - 🏗️ **[Arquitetura Principal](docs/architecture/AIOS-VISUAL-OVERVIEW.md)** - Mergulho técnico profundo e design do sistema
483
485
  - 🚀 **[Guia de Squads](docs/guides/squads-guide.md)** - Estenda o AIOS para qualquer domínio além do desenvolvimento de software
484
486
 
485
487
  ### Documentação Adicional
@@ -488,7 +490,7 @@ O Synkra AIOS vem com 11 agentes especializados:
488
490
  - 📋 **[Primeiros Passos](docs/getting-started.md)** - Tutorial passo a passo para iniciantes
489
491
  - 🔧 **[Solução de Problemas](docs/troubleshooting.md)** - Soluções para problemas comuns
490
492
  - 🎯 **[Princípios Orientadores](docs/GUIDING-PRINCIPLES.md)** - Filosofia e melhores práticas do AIOS
491
- - 🏛️ **[Visão Geral da Arquitetura](docs/architecture/ARCHITECTURE-INDEX.md)** - Visão detalhada da arquitetura do sistema
493
+ - 🏛️ **[Visão Geral da Arquitetura](docs/architecture/AIOS-VISUAL-OVERVIEW.md)** - Visão detalhada da arquitetura do sistema
492
494
  - ⚙️ **[Guia de Ajuste de Performance](docs/performance-tuning-guide.md)** - Otimize seu fluxo de trabalho AIOS
493
495
  - 🔒 **[Melhores Práticas de Segurança](docs/security-best-practices.md)** - Segurança e proteção de dados
494
496
  - 🔄 **[Guia de Migração](docs/migration-guide.md)** - Migração de versões anteriores
package/bin/aios.js CHANGED
@@ -199,10 +199,13 @@ function showInfo() {
199
199
  }
200
200
  };
201
201
 
202
- console.log(` - Agents: ${countFiles(path.join(aiosCoreDir, 'agents'))}`);
203
- console.log(` - Tasks: ${countFiles(path.join(aiosCoreDir, 'tasks'))}`);
204
- console.log(` - Templates: ${countFiles(path.join(aiosCoreDir, 'templates'))}`);
205
- console.log(` - Workflows: ${countFiles(path.join(aiosCoreDir, 'workflows'))}`);
202
+ const devDir = path.join(aiosCoreDir, 'development');
203
+ const componentBase = fs.existsSync(devDir) ? devDir : aiosCoreDir;
204
+
205
+ console.log(` - Agents: ${countFiles(path.join(componentBase, 'agents'))}`);
206
+ console.log(` - Tasks: ${countFiles(path.join(componentBase, 'tasks'))}`);
207
+ console.log(` - Templates: ${countFiles(path.join(componentBase, 'templates'))}`);
208
+ console.log(` - Workflows: ${countFiles(path.join(componentBase, 'workflows'))}`);
206
209
  } else {
207
210
  console.log('\n⚠️ AIOS Core not found');
208
211
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aios-core",
3
- "version": "4.2.13",
3
+ "version": "4.2.15",
4
4
  "description": "Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework",
5
5
  "bin": {
6
6
  "aios": "bin/aios.js",
@@ -14,7 +14,7 @@
14
14
 
15
15
  const readline = require('readline');
16
16
 
17
- const RECOVERY_URL = 'https://pro.synkra.ai/recover';
17
+ const RECOVERY_URL = 'https://aios-license-server.vercel.app/reset-password';
18
18
 
19
19
  const RECOVERY_MESSAGE =
20
20
  'Se este email estiver associado a uma licenca, voce recebera instrucoes de recuperacao.';
@@ -659,8 +659,8 @@ async function copyClaudeHooksFolder(projectRoot) {
659
659
 
660
660
  // Only copy JS hooks that work standalone (no Python/shell deps)
661
661
  const HOOKS_TO_COPY = [
662
- 'synapse-engine.js',
663
- 'precompact-session-digest.js',
662
+ 'synapse-engine.cjs',
663
+ 'precompact-session-digest.cjs',
664
664
  'README.md',
665
665
  ];
666
666
 
@@ -692,7 +692,7 @@ async function copyClaudeHooksFolder(projectRoot) {
692
692
  */
693
693
  async function createClaudeSettingsLocal(projectRoot) {
694
694
  const settingsPath = path.join(projectRoot, '.claude', 'settings.local.json');
695
- const hookFile = path.join(projectRoot, '.claude', 'hooks', 'synapse-engine.js');
695
+ const hookFile = path.join(projectRoot, '.claude', 'hooks', 'synapse-engine.cjs');
696
696
 
697
697
  // Only create if the hook file was actually copied
698
698
  if (!await fs.pathExists(hookFile)) {
@@ -705,7 +705,7 @@ async function createClaudeSettingsLocal(projectRoot) {
705
705
  hooks: [
706
706
  {
707
707
  type: 'command',
708
- command: 'node ".claude/hooks/synapse-engine.js"',
708
+ command: 'node ".claude/hooks/synapse-engine.cjs"',
709
709
  },
710
710
  ],
711
711
  };
@@ -736,10 +736,10 @@ async function createClaudeSettingsLocal(projectRoot) {
736
736
  const alreadyRegistered = settings.hooks.UserPromptSubmit.some(entry => {
737
737
  // Nested format: entry.hooks[].command
738
738
  if (Array.isArray(entry.hooks)) {
739
- return entry.hooks.some(h => h.command && h.command.includes('synapse-engine.js'));
739
+ return entry.hooks.some(h => h.command && h.command.includes('synapse-engine'));
740
740
  }
741
741
  // Flat format (legacy): entry.command
742
- return entry.command && entry.command.includes('synapse-engine.js');
742
+ return entry.command && entry.command.includes('synapse-engine');
743
743
  });
744
744
 
745
745
  if (!alreadyRegistered) {
@@ -426,11 +426,11 @@ async function loginWithRetry(client, email) {
426
426
  const remaining = MAX_RETRIES - attempt;
427
427
  if (remaining > 0) {
428
428
  spinner.fail(`Incorrect password. ${remaining} attempt${remaining > 1 ? 's' : ''} remaining.`);
429
- showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password');
429
+ showInfo('Forgot your password? Visit https://aios-license-server.vercel.app/reset-password');
430
430
  } else {
431
431
  spinner.fail('Maximum login attempts reached.');
432
- showInfo('Forgot your password? Visit https://pro.synkra.ai/reset-password');
433
- showInfo('Or contact support: support@synkra.ai');
432
+ showInfo('Forgot your password? Visit https://aios-license-server.vercel.app/reset-password');
433
+ showInfo('Or open an issue: https://github.com/SynkraAI/aios-core/issues');
434
434
  return { success: false, error: 'Maximum login attempts reached.' };
435
435
  }
436
436
  } else if (loginError.code === 'AUTH_RATE_LIMITED') {
@@ -1,220 +1,220 @@
1
- /**
2
- * Graceful Degradation Module
3
- *
4
- * Utilities for handling pro feature unavailability with user-friendly
5
- * messages that preserve data and provide clear next steps.
6
- *
7
- * Per ADR-PRO-003 and AC-8:
8
- * - Never show upgrade prompts on core features
9
- * - Never delete or corrupt user data
10
- * - Always provide actionable next steps
11
- * - Keep messages non-intrusive
12
- *
13
- * @module pro/license/degradation
14
- * @see ADR-PRO-003 - Feature Gating & Licensing
15
- * @see Story PRO-6 - License Key & Feature Gating System
16
- */
17
-
18
- 'use strict';
19
-
20
- const { featureGate } = require('./feature-gate');
21
- const { ProFeatureError } = require('./errors');
22
-
23
- /**
24
- * Default degradation message template.
25
- * @private Reserved for future customization support.
26
- */
27
- const _DEFAULT_MESSAGE_TEMPLATE = `
28
- {featureName} requires an active AIOS Pro license.
29
-
30
- Your data and configurations are preserved.
31
-
32
- Activate: aios pro activate --key <KEY>
33
- Purchase: https://synkra.ai/pro
34
- `;
35
-
36
- /**
37
- * Handle pro feature gracefully - return fallback instead of throwing.
38
- *
39
- * Use this when you want to provide a degraded experience instead
40
- * of completely blocking the feature.
41
- *
42
- * @param {string} featureId - Feature ID to check
43
- * @param {Function} proAction - Function to execute if feature is available
44
- * @param {Function} [fallbackAction] - Function to execute if not available
45
- * @param {object} [options] - Options
46
- * @param {boolean} [options.silent=false] - Don't log degradation message
47
- * @returns {*} Result of proAction or fallbackAction
48
- */
49
- function withGracefulDegradation(featureId, proAction, fallbackAction, options = {}) {
50
- if (featureGate.isAvailable(featureId)) {
51
- return proAction();
52
- }
53
-
54
- if (!options.silent) {
55
- const featureName = getFeatureFriendlyName(featureId);
56
- logDegradationMessage(featureName, featureId);
57
- }
58
-
59
- if (typeof fallbackAction === 'function') {
60
- return fallbackAction();
61
- }
62
-
63
- return null;
64
- }
65
-
66
- /**
67
- * Execute action only if pro feature is available.
68
- *
69
- * Unlike featureGate.require(), this doesn't throw - it just
70
- * returns undefined if the feature isn't available.
71
- *
72
- * @param {string} featureId - Feature ID to check
73
- * @param {Function} action - Action to execute if available
74
- * @returns {*|undefined} Result of action or undefined
75
- */
76
- function ifProAvailable(featureId, action) {
77
- if (featureGate.isAvailable(featureId)) {
78
- return action();
79
- }
80
- return undefined;
81
- }
82
-
83
- /**
84
- * Get a user-friendly name for a feature.
85
- *
86
- * @param {string} featureId - Feature ID
87
- * @returns {string} Friendly name
88
- */
89
- function getFeatureFriendlyName(featureId) {
90
- const all = featureGate.listAll();
91
- const feature = all.find((f) => f.id === featureId);
92
- return feature ? feature.name : featureId;
93
- }
94
-
95
- /**
96
- * Log a degradation message to the console.
97
- *
98
- * This is used internally when a pro feature is accessed without
99
- * a license. Messages are non-intrusive and informative.
100
- *
101
- * @param {string} featureName - Human-friendly feature name
102
- * @param {string} _featureId - Feature ID for reference (reserved for logging)
103
- */
104
- function logDegradationMessage(featureName, _featureId) {
105
- console.log('');
106
- console.log(` ${featureName} requires an active AIOS Pro license.`);
107
- console.log('');
108
- console.log(' Your data and configurations are preserved.');
109
- console.log('');
110
- console.log(' Activate: aios pro activate --key <KEY>');
111
- console.log(' Purchase: https://synkra.ai/pro');
112
- console.log('');
113
- }
114
-
115
- /**
116
- * Create a degradation-aware wrapper for a pro module.
117
- *
118
- * This creates a proxy that catches ProFeatureError and provides
119
- * a graceful degradation experience.
120
- *
121
- * @param {object} proModule - Pro module with methods
122
- * @param {object} fallbacks - Map of method names to fallback functions
123
- * @returns {Proxy} Wrapped module
124
- *
125
- * @example
126
- * const safePremiumSquads = createDegradationWrapper(
127
- * PremiumSquads,
128
- * {
129
- * listTemplates: () => ['basic'], // Fallback to basic templates
130
- * exportSquad: () => null, // No export without license
131
- * }
132
- * );
133
- */
134
- function createDegradationWrapper(proModule, fallbacks = {}) {
135
- return new Proxy(proModule, {
136
- get(target, prop) {
137
- const original = target[prop];
138
-
139
- if (typeof original !== 'function') {
140
- return original;
141
- }
142
-
143
- return function (...args) {
144
- try {
145
- return original.apply(target, args);
146
- } catch (error) {
147
- if (error instanceof ProFeatureError) {
148
- if (fallbacks[prop]) {
149
- logDegradationMessage(error.friendlyName, error.featureId);
150
- return fallbacks[prop](...args);
151
- }
152
- // Re-throw if no fallback
153
- throw error;
154
- }
155
- // Re-throw non-license errors
156
- throw error;
157
- }
158
- };
159
- },
160
- });
161
- }
162
-
163
- /**
164
- * Check if the system is in degraded mode (expired/no license).
165
- *
166
- * @returns {boolean} true if pro features are unavailable
167
- */
168
- function isInDegradedMode() {
169
- const state = featureGate.getLicenseState();
170
- return state === 'Expired' || state === 'Not Activated';
171
- }
172
-
173
- /**
174
- * Get degradation status summary.
175
- *
176
- * @returns {{ degraded: boolean, reason: string, action: string }}
177
- */
178
- function getDegradationStatus() {
179
- const state = featureGate.getLicenseState();
180
-
181
- if (state === 'Active') {
182
- return {
183
- degraded: false,
184
- reason: 'License is active',
185
- action: null,
186
- };
187
- }
188
-
189
- if (state === 'Grace') {
190
- return {
191
- degraded: false,
192
- reason: 'License in grace period - revalidate soon',
193
- action: 'aios pro validate',
194
- };
195
- }
196
-
197
- if (state === 'Expired') {
198
- return {
199
- degraded: true,
200
- reason: 'License has expired',
201
- action: 'aios pro activate --key <KEY>',
202
- };
203
- }
204
-
205
- return {
206
- degraded: true,
207
- reason: 'No license activated',
208
- action: 'aios pro activate --key <KEY>',
209
- };
210
- }
211
-
212
- module.exports = {
213
- withGracefulDegradation,
214
- ifProAvailable,
215
- getFeatureFriendlyName,
216
- logDegradationMessage,
217
- createDegradationWrapper,
218
- isInDegradedMode,
219
- getDegradationStatus,
220
- };
1
+ /**
2
+ * Graceful Degradation Module
3
+ *
4
+ * Utilities for handling pro feature unavailability with user-friendly
5
+ * messages that preserve data and provide clear next steps.
6
+ *
7
+ * Per ADR-PRO-003 and AC-8:
8
+ * - Never show upgrade prompts on core features
9
+ * - Never delete or corrupt user data
10
+ * - Always provide actionable next steps
11
+ * - Keep messages non-intrusive
12
+ *
13
+ * @module pro/license/degradation
14
+ * @see ADR-PRO-003 - Feature Gating & Licensing
15
+ * @see Story PRO-6 - License Key & Feature Gating System
16
+ */
17
+
18
+ 'use strict';
19
+
20
+ const { featureGate } = require('./feature-gate');
21
+ const { ProFeatureError } = require('./errors');
22
+
23
+ /**
24
+ * Default degradation message template.
25
+ * @private Reserved for future customization support.
26
+ */
27
+ const _DEFAULT_MESSAGE_TEMPLATE = `
28
+ {featureName} requires an active AIOS Pro license.
29
+
30
+ Your data and configurations are preserved.
31
+
32
+ Activate: aios pro activate --key <KEY>
33
+ Purchase: https://synkra.ai/pro
34
+ `;
35
+
36
+ /**
37
+ * Handle pro feature gracefully - return fallback instead of throwing.
38
+ *
39
+ * Use this when you want to provide a degraded experience instead
40
+ * of completely blocking the feature.
41
+ *
42
+ * @param {string} featureId - Feature ID to check
43
+ * @param {Function} proAction - Function to execute if feature is available
44
+ * @param {Function} [fallbackAction] - Function to execute if not available
45
+ * @param {object} [options] - Options
46
+ * @param {boolean} [options.silent=false] - Don't log degradation message
47
+ * @returns {*} Result of proAction or fallbackAction
48
+ */
49
+ function withGracefulDegradation(featureId, proAction, fallbackAction, options = {}) {
50
+ if (featureGate.isAvailable(featureId)) {
51
+ return proAction();
52
+ }
53
+
54
+ if (!options.silent) {
55
+ const featureName = getFeatureFriendlyName(featureId);
56
+ logDegradationMessage(featureName, featureId);
57
+ }
58
+
59
+ if (typeof fallbackAction === 'function') {
60
+ return fallbackAction();
61
+ }
62
+
63
+ return null;
64
+ }
65
+
66
+ /**
67
+ * Execute action only if pro feature is available.
68
+ *
69
+ * Unlike featureGate.require(), this doesn't throw - it just
70
+ * returns undefined if the feature isn't available.
71
+ *
72
+ * @param {string} featureId - Feature ID to check
73
+ * @param {Function} action - Action to execute if available
74
+ * @returns {*|undefined} Result of action or undefined
75
+ */
76
+ function ifProAvailable(featureId, action) {
77
+ if (featureGate.isAvailable(featureId)) {
78
+ return action();
79
+ }
80
+ return undefined;
81
+ }
82
+
83
+ /**
84
+ * Get a user-friendly name for a feature.
85
+ *
86
+ * @param {string} featureId - Feature ID
87
+ * @returns {string} Friendly name
88
+ */
89
+ function getFeatureFriendlyName(featureId) {
90
+ const all = featureGate.listAll();
91
+ const feature = all.find((f) => f.id === featureId);
92
+ return feature ? feature.name : featureId;
93
+ }
94
+
95
+ /**
96
+ * Log a degradation message to the console.
97
+ *
98
+ * This is used internally when a pro feature is accessed without
99
+ * a license. Messages are non-intrusive and informative.
100
+ *
101
+ * @param {string} featureName - Human-friendly feature name
102
+ * @param {string} _featureId - Feature ID for reference (reserved for logging)
103
+ */
104
+ function logDegradationMessage(featureName, _featureId) {
105
+ console.log('');
106
+ console.log(` ${featureName} requires an active AIOS Pro license.`);
107
+ console.log('');
108
+ console.log(' Your data and configurations are preserved.');
109
+ console.log('');
110
+ console.log(' Activate: aios pro activate --key <KEY>');
111
+ console.log(' Purchase: https://synkra.ai/pro');
112
+ console.log('');
113
+ }
114
+
115
+ /**
116
+ * Create a degradation-aware wrapper for a pro module.
117
+ *
118
+ * This creates a proxy that catches ProFeatureError and provides
119
+ * a graceful degradation experience.
120
+ *
121
+ * @param {object} proModule - Pro module with methods
122
+ * @param {object} fallbacks - Map of method names to fallback functions
123
+ * @returns {Proxy} Wrapped module
124
+ *
125
+ * @example
126
+ * const safePremiumSquads = createDegradationWrapper(
127
+ * PremiumSquads,
128
+ * {
129
+ * listTemplates: () => ['basic'], // Fallback to basic templates
130
+ * exportSquad: () => null, // No export without license
131
+ * }
132
+ * );
133
+ */
134
+ function createDegradationWrapper(proModule, fallbacks = {}) {
135
+ return new Proxy(proModule, {
136
+ get(target, prop) {
137
+ const original = target[prop];
138
+
139
+ if (typeof original !== 'function') {
140
+ return original;
141
+ }
142
+
143
+ return function (...args) {
144
+ try {
145
+ return original.apply(target, args);
146
+ } catch (error) {
147
+ if (error instanceof ProFeatureError) {
148
+ if (fallbacks[prop]) {
149
+ logDegradationMessage(error.friendlyName, error.featureId);
150
+ return fallbacks[prop](...args);
151
+ }
152
+ // Re-throw if no fallback
153
+ throw error;
154
+ }
155
+ // Re-throw non-license errors
156
+ throw error;
157
+ }
158
+ };
159
+ },
160
+ });
161
+ }
162
+
163
+ /**
164
+ * Check if the system is in degraded mode (expired/no license).
165
+ *
166
+ * @returns {boolean} true if pro features are unavailable
167
+ */
168
+ function isInDegradedMode() {
169
+ const state = featureGate.getLicenseState();
170
+ return state === 'Expired' || state === 'Not Activated';
171
+ }
172
+
173
+ /**
174
+ * Get degradation status summary.
175
+ *
176
+ * @returns {{ degraded: boolean, reason: string, action: string }}
177
+ */
178
+ function getDegradationStatus() {
179
+ const state = featureGate.getLicenseState();
180
+
181
+ if (state === 'Active') {
182
+ return {
183
+ degraded: false,
184
+ reason: 'License is active',
185
+ action: null,
186
+ };
187
+ }
188
+
189
+ if (state === 'Grace') {
190
+ return {
191
+ degraded: false,
192
+ reason: 'License in grace period - revalidate soon',
193
+ action: 'aios pro validate',
194
+ };
195
+ }
196
+
197
+ if (state === 'Expired') {
198
+ return {
199
+ degraded: true,
200
+ reason: 'License has expired',
201
+ action: 'aios pro activate --key <KEY>',
202
+ };
203
+ }
204
+
205
+ return {
206
+ degraded: true,
207
+ reason: 'No license activated',
208
+ action: 'aios pro activate --key <KEY>',
209
+ };
210
+ }
211
+
212
+ module.exports = {
213
+ withGracefulDegradation,
214
+ ifProAvailable,
215
+ getFeatureFriendlyName,
216
+ logDegradationMessage,
217
+ createDegradationWrapper,
218
+ isInDegradedMode,
219
+ getDegradationStatus,
220
+ };