aios-core 4.0.2 → 4.1.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/.aios-core/cli/commands/migrate/analyze.js +6 -6
- package/.aios-core/cli/commands/migrate/backup.js +2 -2
- package/.aios-core/cli/commands/migrate/execute.js +4 -4
- package/.aios-core/cli/commands/migrate/index.js +5 -5
- package/.aios-core/cli/commands/migrate/rollback.js +6 -6
- package/.aios-core/cli/commands/migrate/update-imports.js +2 -2
- package/.aios-core/cli/commands/migrate/validate.js +2 -2
- package/.aios-core/cli/commands/pro/index.js +52 -0
- package/.aios-core/cli/index.js +1 -1
- package/.aios-core/core/ids/registry-updater.js +29 -3
- package/.aios-core/core/migration/migration-config.yaml +2 -2
- package/.aios-core/core/migration/module-mapping.yaml +2 -2
- package/.aios-core/core/registry/README.md +2 -2
- package/.aios-core/core/synapse/context/context-builder.js +34 -0
- package/.aios-core/core/synapse/diagnostics/collectors/consistency-collector.js +168 -0
- package/.aios-core/core/synapse/diagnostics/collectors/hook-collector.js +129 -0
- package/.aios-core/core/synapse/diagnostics/collectors/manifest-collector.js +82 -0
- package/.aios-core/core/synapse/diagnostics/collectors/output-analyzer.js +134 -0
- package/.aios-core/core/synapse/diagnostics/collectors/pipeline-collector.js +75 -0
- package/.aios-core/core/synapse/diagnostics/collectors/quality-collector.js +252 -0
- package/.aios-core/core/synapse/diagnostics/collectors/relevance-matrix.js +174 -0
- package/.aios-core/core/synapse/diagnostics/collectors/safe-read-json.js +31 -0
- package/.aios-core/core/synapse/diagnostics/collectors/session-collector.js +102 -0
- package/.aios-core/core/synapse/diagnostics/collectors/timing-collector.js +126 -0
- package/.aios-core/core/synapse/diagnostics/collectors/uap-collector.js +83 -0
- package/.aios-core/core/synapse/diagnostics/report-formatter.js +484 -0
- package/.aios-core/core/synapse/diagnostics/synapse-diagnostics.js +95 -0
- package/.aios-core/core/synapse/engine.js +73 -20
- package/.aios-core/core/synapse/runtime/hook-runtime.js +60 -0
- package/.aios-core/core-config.yaml +6 -0
- package/.aios-core/data/agent-config-requirements.yaml +2 -2
- package/.aios-core/data/aios-kb.md +4 -4
- package/.aios-core/data/entity-registry.yaml +5 -5
- package/.aios-core/development/agents/architect.md +10 -10
- package/.aios-core/development/agents/devops.md +93 -50
- package/.aios-core/development/agents/qa.md +94 -40
- package/.aios-core/development/agents/ux-design-expert.md +25 -25
- package/.aios-core/development/scripts/activation-runtime.js +63 -0
- package/.aios-core/development/scripts/generate-greeting.js +9 -8
- package/.aios-core/development/scripts/unified-activation-pipeline.js +102 -2
- package/.aios-core/development/tasks/{db-expansion-pack-integration.md → db-squad-integration.md} +5 -5
- package/.aios-core/development/tasks/{integrate-expansion-pack.md → integrate-squad.md} +2 -2
- package/.aios-core/development/tasks/next.md +3 -3
- package/.aios-core/development/tasks/pr-automation.md +2 -2
- package/.aios-core/development/tasks/publish-npm.md +257 -0
- package/.aios-core/development/tasks/release-management.md +4 -4
- package/.aios-core/development/tasks/setup-github.md +1 -1
- package/.aios-core/development/tasks/squad-creator-migrate.md +1 -1
- package/.aios-core/development/tasks/squad-creator-sync-ide-command.md +14 -14
- package/.aios-core/development/tasks/update-aios.md +1 -1
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-QUICK-REFERENCE.md +1 -1
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +5 -5
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +21 -21
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +25 -25
- package/.aios-core/docs/standards/OPEN-SOURCE-VS-SERVICE-DIFFERENCES.md +4 -4
- package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +3 -3
- package/.aios-core/docs/standards/STANDARDS-INDEX.md +13 -13
- package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +1 -1
- package/.aios-core/framework-config.yaml +4 -0
- package/.aios-core/infrastructure/scripts/codex-skills-sync/index.js +182 -0
- package/.aios-core/infrastructure/scripts/codex-skills-sync/validate.js +172 -0
- package/.aios-core/infrastructure/scripts/ide-sync/README.md +14 -0
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +6 -0
- package/.aios-core/infrastructure/scripts/tool-resolver.js +4 -4
- package/.aios-core/infrastructure/scripts/validate-paths.js +142 -0
- package/.aios-core/infrastructure/templates/aios-sync.yaml.template +11 -11
- package/.aios-core/infrastructure/templates/github-workflows/README.md +1 -1
- package/.aios-core/install-manifest.yaml +190 -106
- package/.aios-core/local-config.yaml.template +2 -0
- package/.aios-core/product/README.md +2 -2
- package/.aios-core/product/data/integration-patterns.md +1 -1
- package/.aios-core/product/templates/ide-rules/cline-rules.md +1 -1
- package/.aios-core/product/templates/ide-rules/codex-rules.md +65 -0
- package/.aios-core/product/templates/ide-rules/copilot-rules.md +1 -1
- package/.aios-core/product/templates/ide-rules/roo-rules.md +1 -1
- package/.aios-core/user-guide.md +15 -14
- package/.aios-core/workflow-intelligence/engine/output-formatter.js +1 -1
- package/.claude/hooks/enforce-architecture-first.py +196 -0
- package/.claude/hooks/install-hooks.sh +41 -0
- package/.claude/hooks/mind-clone-governance.py +192 -0
- package/.claude/hooks/pre-commit-mmos-guard.sh +99 -0
- package/.claude/hooks/pre-commit-version-check.sh +156 -0
- package/.claude/hooks/read-protection.py +151 -0
- package/.claude/hooks/slug-validation.py +176 -0
- package/.claude/hooks/sql-governance.py +182 -0
- package/.claude/hooks/synapse-engine.js +9 -20
- package/.claude/hooks/write-path-validation.py +194 -0
- package/README.md +44 -14
- package/bin/aios-init.js +255 -184
- package/bin/aios-minimal.js +2 -2
- package/bin/aios.js +19 -19
- package/package.json +7 -4
- package/packages/aios-pro-cli/bin/aios-pro.js +75 -2
- package/packages/aios-pro-cli/package.json +5 -1
- package/packages/aios-pro-cli/src/recover.js +100 -0
- package/packages/installer/src/__tests__/performance-benchmark.js +382 -0
- package/packages/installer/src/config/ide-configs.js +12 -1
- package/packages/installer/src/config/templates/core-config-template.js +2 -2
- package/packages/installer/src/installer/aios-core-installer.js +2 -2
- package/packages/installer/src/installer/file-hasher.js +97 -0
- package/packages/installer/src/installer/post-install-validator.js +41 -1
- package/packages/installer/src/pro/pro-scaffolder.js +335 -0
- package/packages/installer/src/utils/aios-colors.js +2 -2
- package/packages/installer/src/wizard/feedback.js +1 -1
- package/packages/installer/src/wizard/ide-config-generator.js +2 -2
- package/packages/installer/src/wizard/index.js +58 -19
- package/packages/installer/src/wizard/pro-setup.js +547 -0
- package/packages/installer/src/wizard/questions.js +20 -14
- package/packages/installer/src/wizard/validators.js +1 -1
- package/scripts/package-synapse.js +323 -0
- package/scripts/validate-package-completeness.js +317 -0
package/bin/aios-minimal.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* AIOS-FullStack Minimal Installation
|
|
5
5
|
*
|
|
6
6
|
* DEPRECATED (since v3.11.1, scheduled for removal in v5.0.0):
|
|
7
|
-
* The --minimal mode was designed for
|
|
7
|
+
* The --minimal mode was designed for squads which have been
|
|
8
8
|
* replaced by the Squads system (OSR-8). This command now runs the
|
|
9
9
|
* standard wizard through the main router.
|
|
10
10
|
*/
|
|
@@ -14,7 +14,7 @@ const path = require('path');
|
|
|
14
14
|
|
|
15
15
|
// Show deprecation warning
|
|
16
16
|
console.log('\n⚠️ DEPRECATION WARNING: aios-minimal is deprecated.');
|
|
17
|
-
console.log(' The --minimal mode (
|
|
17
|
+
console.log(' The --minimal mode (squads) was replaced by Squads.');
|
|
18
18
|
console.log(' Running standard installation wizard instead.\n');
|
|
19
19
|
|
|
20
20
|
// Get the path to the main router (aios.js)
|
package/bin/aios.js
CHANGED
|
@@ -20,7 +20,7 @@ const command = args[0];
|
|
|
20
20
|
|
|
21
21
|
// Helper: Run initialization wizard
|
|
22
22
|
async function runWizard(options = {}) {
|
|
23
|
-
// Use the
|
|
23
|
+
// Use the v4 wizard from packages/installer/src/wizard/index.js
|
|
24
24
|
const wizardPath = path.join(__dirname, '..', 'packages', 'installer', 'src', 'wizard', 'index.js');
|
|
25
25
|
|
|
26
26
|
if (!fs.existsSync(wizardPath)) {
|
|
@@ -43,7 +43,7 @@ async function runWizard(options = {}) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
try {
|
|
46
|
-
// Run the
|
|
46
|
+
// Run the v4 wizard with options
|
|
47
47
|
const { runWizard: executeWizard } = require(wizardPath);
|
|
48
48
|
await executeWizard(options);
|
|
49
49
|
} catch (error) {
|
|
@@ -59,16 +59,16 @@ AIOS-FullStack v${packageJson.version}
|
|
|
59
59
|
AI-Orchestrated System for Full Stack Development
|
|
60
60
|
|
|
61
61
|
USAGE:
|
|
62
|
-
npx
|
|
63
|
-
npx
|
|
64
|
-
npx
|
|
65
|
-
npx
|
|
66
|
-
npx
|
|
67
|
-
npx
|
|
68
|
-
npx
|
|
69
|
-
npx
|
|
70
|
-
npx
|
|
71
|
-
npx
|
|
62
|
+
npx aios-core@latest # Run installation wizard
|
|
63
|
+
npx aios-core@latest install # Install in current project
|
|
64
|
+
npx aios-core@latest init <name> # Create new project
|
|
65
|
+
npx aios-core@latest update # Update to latest version
|
|
66
|
+
npx aios-core@latest validate # Validate installation integrity
|
|
67
|
+
npx aios-core@latest info # Show system info
|
|
68
|
+
npx aios-core@latest doctor # Run diagnostics
|
|
69
|
+
npx aios-core@latest --version # Show version
|
|
70
|
+
npx aios-core@latest --version -d # Show detailed version info
|
|
71
|
+
npx aios-core@latest --help # Show this help
|
|
72
72
|
|
|
73
73
|
UPDATE:
|
|
74
74
|
aios update # Update to latest version
|
|
@@ -99,13 +99,13 @@ SERVICE DISCOVERY:
|
|
|
99
99
|
|
|
100
100
|
EXAMPLES:
|
|
101
101
|
# Install in current directory
|
|
102
|
-
npx
|
|
102
|
+
npx aios-core@latest
|
|
103
103
|
|
|
104
104
|
# Install with minimal mode (only expansion-creator)
|
|
105
|
-
npx
|
|
105
|
+
npx aios-core-minimal@latest
|
|
106
106
|
|
|
107
107
|
# Create new project
|
|
108
|
-
npx
|
|
108
|
+
npx aios-core@latest init my-project
|
|
109
109
|
|
|
110
110
|
# Search for workers
|
|
111
111
|
aios workers search "json csv"
|
|
@@ -126,7 +126,7 @@ async function showVersion() {
|
|
|
126
126
|
|
|
127
127
|
// Detailed version output (Story 7.2: Version Tracking)
|
|
128
128
|
console.log(`AIOS-FullStack v${packageJson.version}`);
|
|
129
|
-
console.log('Package:
|
|
129
|
+
console.log('Package: aios-core');
|
|
130
130
|
|
|
131
131
|
// Check for local installation
|
|
132
132
|
const localVersionPath = path.join(process.cwd(), '.aios-core', 'version.json');
|
|
@@ -485,7 +485,7 @@ Examples:
|
|
|
485
485
|
});
|
|
486
486
|
hasErrors = true;
|
|
487
487
|
console.log('✗ AIOS Core not installed');
|
|
488
|
-
console.log(' Run: npx
|
|
488
|
+
console.log(' Run: npx aios-core@latest');
|
|
489
489
|
}
|
|
490
490
|
|
|
491
491
|
// Check 5: AIOS Pro license status (Task 5.1)
|
|
@@ -633,7 +633,7 @@ Options:
|
|
|
633
633
|
What gets removed:
|
|
634
634
|
- .aios-core/ Framework core files
|
|
635
635
|
- docs/stories/ Story files (if created by AIOS)
|
|
636
|
-
- squads/ Squad
|
|
636
|
+
- squads/ Squad definitions
|
|
637
637
|
- .gitignore AIOS-added entries only
|
|
638
638
|
|
|
639
639
|
What is preserved (with --keep-data):
|
|
@@ -702,7 +702,7 @@ async function runUninstall(options = {}) {
|
|
|
702
702
|
// Items to remove
|
|
703
703
|
const itemsToRemove = [
|
|
704
704
|
{ path: '.aios-core', description: 'Framework core' },
|
|
705
|
-
{ path: 'squads', description: 'Squad
|
|
705
|
+
{ path: 'squads', description: 'Squad definitions' },
|
|
706
706
|
];
|
|
707
707
|
|
|
708
708
|
// Optionally remove .aios
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aios-core",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aios": "bin/aios.js",
|
|
@@ -18,9 +18,7 @@
|
|
|
18
18
|
".aios-core/",
|
|
19
19
|
".claude/CLAUDE.md",
|
|
20
20
|
".claude/rules/",
|
|
21
|
-
".claude/hooks/
|
|
22
|
-
".claude/hooks/precompact-session-digest.js",
|
|
23
|
-
".claude/hooks/README.md",
|
|
21
|
+
".claude/hooks/",
|
|
24
22
|
"README.md",
|
|
25
23
|
"LICENSE"
|
|
26
24
|
],
|
|
@@ -41,6 +39,11 @@
|
|
|
41
39
|
"sync:ide": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync",
|
|
42
40
|
"sync:ide:validate": "node .aios-core/infrastructure/scripts/ide-sync/index.js validate",
|
|
43
41
|
"sync:ide:check": "node .aios-core/infrastructure/scripts/ide-sync/index.js validate --strict",
|
|
42
|
+
"sync:ide:codex": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide codex",
|
|
43
|
+
"sync:skills:codex": "node .aios-core/infrastructure/scripts/codex-skills-sync/index.js",
|
|
44
|
+
"sync:skills:codex:global": "node .aios-core/infrastructure/scripts/codex-skills-sync/index.js --global --global-only",
|
|
45
|
+
"validate:codex-skills": "node .aios-core/infrastructure/scripts/codex-skills-sync/validate.js --strict",
|
|
46
|
+
"validate:paths": "node .aios-core/infrastructure/scripts/validate-paths.js",
|
|
44
47
|
"sync:ide:cursor": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide cursor",
|
|
45
48
|
"sync:ide:windsurf": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide windsurf",
|
|
46
49
|
"prepublishOnly": "npm run generate:manifest && npm run validate:manifest",
|
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
* status Show license status
|
|
14
14
|
* features List available pro features
|
|
15
15
|
* validate Force online license revalidation
|
|
16
|
+
* recover Recover lost license key via email
|
|
16
17
|
* help Show help
|
|
17
18
|
*/
|
|
18
19
|
|
|
19
20
|
const { execSync, spawnSync } = require('child_process');
|
|
20
21
|
const path = require('path');
|
|
21
22
|
const fs = require('fs');
|
|
23
|
+
const { recoverLicense } = require('../src/recover');
|
|
22
24
|
|
|
23
25
|
const PRO_PACKAGE = '@aios-fullstack/pro';
|
|
24
26
|
const VERSION = require('../package.json').version;
|
|
@@ -76,6 +78,51 @@ function delegateToAios(subcommand) {
|
|
|
76
78
|
process.exit(result.status ?? 0);
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Get value of a CLI argument (e.g., --key VALUE).
|
|
83
|
+
*
|
|
84
|
+
* @param {string} flag - Flag name (e.g., '--key')
|
|
85
|
+
* @returns {string|null} Value or null
|
|
86
|
+
*/
|
|
87
|
+
function getArgValue(flag) {
|
|
88
|
+
const idx = args.indexOf(flag);
|
|
89
|
+
if (idx !== -1 && idx + 1 < args.length) {
|
|
90
|
+
return args[idx + 1];
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Run the Pro Installation Wizard.
|
|
97
|
+
*
|
|
98
|
+
* @param {string} [key] - Pre-provided license key
|
|
99
|
+
*/
|
|
100
|
+
function runProWizard(key) {
|
|
101
|
+
// Lazy import to avoid requiring installer when not needed
|
|
102
|
+
let proSetup;
|
|
103
|
+
try {
|
|
104
|
+
proSetup = require('../../installer/src/wizard/pro-setup');
|
|
105
|
+
} catch {
|
|
106
|
+
console.error('Pro wizard module not found.');
|
|
107
|
+
console.error('Ensure aios-core installer is available.\n');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const options = {};
|
|
112
|
+
if (key) {
|
|
113
|
+
options.key = key;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
proSetup.runProWizard(options).then((result) => {
|
|
117
|
+
if (!result.success) {
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
}).catch((err) => {
|
|
121
|
+
console.error(`\n Wizard failed: ${err.message}\n`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
79
126
|
// ─── Commands ───────────────────────────────────────────────────────────────
|
|
80
127
|
|
|
81
128
|
function showHelp() {
|
|
@@ -87,17 +134,23 @@ Usage:
|
|
|
87
134
|
|
|
88
135
|
Commands:
|
|
89
136
|
install Install ${PRO_PACKAGE} in the current project
|
|
137
|
+
install --wizard Install and run the setup wizard
|
|
138
|
+
setup, wizard Run Pro setup wizard (license gate + scaffold + verify)
|
|
90
139
|
activate --key KEY Activate a license key
|
|
91
140
|
deactivate Deactivate the current license
|
|
92
141
|
status Show license status
|
|
93
142
|
features List available pro features
|
|
94
143
|
validate Force online license revalidation
|
|
144
|
+
recover Recover lost license key via email
|
|
95
145
|
help Show this help message
|
|
96
146
|
|
|
97
147
|
Examples:
|
|
98
148
|
npx aios-pro install
|
|
149
|
+
npx aios-pro setup
|
|
150
|
+
npx aios-pro wizard --key PRO-XXXX-XXXX-XXXX-XXXX
|
|
99
151
|
npx aios-pro activate --key PRO-XXXX-XXXX-XXXX-XXXX
|
|
100
152
|
npx aios-pro status
|
|
153
|
+
npx aios-pro recover
|
|
101
154
|
|
|
102
155
|
Documentation: https://synkra.ai/pro/docs
|
|
103
156
|
`);
|
|
@@ -133,9 +186,29 @@ if (command === '--version' || command === '-v') {
|
|
|
133
186
|
}
|
|
134
187
|
|
|
135
188
|
switch (command) {
|
|
136
|
-
case 'install':
|
|
137
|
-
|
|
189
|
+
case 'install': {
|
|
190
|
+
// Check for --wizard flag to run wizard after install
|
|
191
|
+
const runWizardAfter = args.includes('--wizard');
|
|
138
192
|
installPro();
|
|
193
|
+
if (runWizardAfter) {
|
|
194
|
+
runProWizard();
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
case 'setup':
|
|
200
|
+
case 'wizard': {
|
|
201
|
+
// Run the Pro Installation Wizard with license gate
|
|
202
|
+
const wizardKey = getArgValue('--key');
|
|
203
|
+
runProWizard(wizardKey);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
case 'recover':
|
|
208
|
+
recoverLicense().catch((err) => {
|
|
209
|
+
console.error(`\n Recovery failed: ${err.message}\n`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
});
|
|
139
212
|
break;
|
|
140
213
|
|
|
141
214
|
case 'activate':
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* License Recovery Flow
|
|
5
|
+
*
|
|
6
|
+
* Implements OWASP-compliant license key recovery via portal redirect.
|
|
7
|
+
* Decision 3 (D1 Section 4): Portal-first — CLI redirects to web portal.
|
|
8
|
+
*
|
|
9
|
+
* Security:
|
|
10
|
+
* - Anti-enumeration: identical message for any email input
|
|
11
|
+
* - No API calls — purely local CLI + browser redirect
|
|
12
|
+
* - Rate limiting is server-side (3/email/hour) — documented, not enforced here
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const readline = require('readline');
|
|
16
|
+
|
|
17
|
+
const RECOVERY_URL = 'https://pro.synkra.ai/recover';
|
|
18
|
+
|
|
19
|
+
const RECOVERY_MESSAGE =
|
|
20
|
+
'Se este email estiver associado a uma licenca, voce recebera instrucoes de recuperacao.';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Mask email for display: u***@example.com
|
|
24
|
+
* @param {string} email
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
function maskEmail(email) {
|
|
28
|
+
const atIndex = email.indexOf('@');
|
|
29
|
+
if (atIndex <= 0) {
|
|
30
|
+
return '***';
|
|
31
|
+
}
|
|
32
|
+
return email[0] + '***' + email.slice(atIndex);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Prompt user for email input via readline
|
|
37
|
+
* @returns {Promise<string>}
|
|
38
|
+
*/
|
|
39
|
+
function promptEmail() {
|
|
40
|
+
const rl = readline.createInterface({
|
|
41
|
+
input: process.stdin,
|
|
42
|
+
output: process.stdout,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
rl.question(' Enter your email: ', (answer) => {
|
|
47
|
+
rl.close();
|
|
48
|
+
resolve(answer.trim());
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Open URL in default browser with offline fallback
|
|
55
|
+
* @param {string} url
|
|
56
|
+
* @param {Function} [openFn] - Optional override for testing (defaults to dynamic import of 'open')
|
|
57
|
+
* @returns {Promise<boolean>} true if browser opened, false if fallback
|
|
58
|
+
*/
|
|
59
|
+
async function openBrowser(url, openFn) {
|
|
60
|
+
try {
|
|
61
|
+
const open = openFn || (await import('open')).default;
|
|
62
|
+
await open(url);
|
|
63
|
+
return true;
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Main recovery flow
|
|
71
|
+
* @returns {Promise<void>}
|
|
72
|
+
*/
|
|
73
|
+
async function recoverLicense() {
|
|
74
|
+
console.log('\naios-pro — License Recovery\n');
|
|
75
|
+
|
|
76
|
+
const email = await promptEmail();
|
|
77
|
+
|
|
78
|
+
if (!email) {
|
|
79
|
+
console.error('\n Error: Email is required.\n');
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const masked = maskEmail(email);
|
|
84
|
+
|
|
85
|
+
// Anti-enumeration: identical message regardless of email validity
|
|
86
|
+
console.log(`\n ${RECOVERY_MESSAGE}`);
|
|
87
|
+
console.log(` Email: ${masked}\n`);
|
|
88
|
+
|
|
89
|
+
const browserOpened = await openBrowser(RECOVERY_URL);
|
|
90
|
+
|
|
91
|
+
if (browserOpened) {
|
|
92
|
+
console.log(' Recovery portal opened in your browser.');
|
|
93
|
+
} else {
|
|
94
|
+
console.log(' Could not open browser automatically.');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log(` You can also visit: ${RECOVERY_URL}\n`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = { recoverLicense, maskEmail, promptEmail, openBrowser, RECOVERY_URL, RECOVERY_MESSAGE };
|