aios-core 3.8.0 → 3.9.1
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/core/session/context-loader.js +2 -2
- package/.aios-core/infrastructure/scripts/test-generator.js +8 -8
- package/.aios-core/infrastructure/scripts/test-quality-assessment.js +5 -5
- package/.aios-core/infrastructure/scripts/test-utilities.js +3 -3
- package/.aios-core/install-manifest.yaml +12 -12
- package/.aios-core/scripts/test-template-system.js +6 -6
- package/package.json +1 -1
- package/src/installer/brownfield-upgrader.js +1 -1
- package/bin/aios-init.backup-v1.1.4.js +0 -352
|
@@ -392,7 +392,7 @@ class SessionContextLoader {
|
|
|
392
392
|
lastActivity: sessionState.lastActivity,
|
|
393
393
|
};
|
|
394
394
|
}
|
|
395
|
-
} catch
|
|
395
|
+
} catch {
|
|
396
396
|
// Ignore
|
|
397
397
|
}
|
|
398
398
|
return null;
|
|
@@ -409,7 +409,7 @@ class SessionContextLoader {
|
|
|
409
409
|
const sessionState = this.loadSessionState();
|
|
410
410
|
const history = sessionState.taskHistory || [];
|
|
411
411
|
return history.slice(-limit);
|
|
412
|
-
} catch
|
|
412
|
+
} catch {
|
|
413
413
|
return [];
|
|
414
414
|
}
|
|
415
415
|
}
|
|
@@ -36,7 +36,7 @@ class TestGenerator {
|
|
|
36
36
|
console.log(chalk.green('✅ Test generator initialized'));
|
|
37
37
|
return true;
|
|
38
38
|
|
|
39
|
-
} catch (
|
|
39
|
+
} catch (error) {
|
|
40
40
|
console.error(chalk.red(`Failed to initialize test generator: ${error.message}`));
|
|
41
41
|
throw error;
|
|
42
42
|
}
|
|
@@ -67,7 +67,7 @@ class TestGenerator {
|
|
|
67
67
|
|
|
68
68
|
return processedContent;
|
|
69
69
|
|
|
70
|
-
} catch (
|
|
70
|
+
} catch (error) {
|
|
71
71
|
this.updateGenerationStats(false, Date.now() - startTime);
|
|
72
72
|
console.error(chalk.red(`Failed to generate test for ${component.name}: ${error.message}`));
|
|
73
73
|
throw error;
|
|
@@ -95,7 +95,7 @@ class TestGenerator {
|
|
|
95
95
|
test_count: testFile.test_count,
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
} catch (
|
|
98
|
+
} catch (error) {
|
|
99
99
|
errors.push({
|
|
100
100
|
file_path: testFile.file_path,
|
|
101
101
|
test_type: testFile.test_type,
|
|
@@ -167,7 +167,7 @@ class TestGenerator {
|
|
|
167
167
|
enhancedContent = this.injectSetupTeardown(enhancedContent, setupTeardown);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
} catch (
|
|
170
|
+
} catch (error) {
|
|
171
171
|
console.warn(chalk.yellow(`Failed to enhance test content: ${error.message}`));
|
|
172
172
|
// Return base content if enhancement fails
|
|
173
173
|
}
|
|
@@ -221,7 +221,7 @@ class TestGenerator {
|
|
|
221
221
|
analysis.configuration = this.extractTaskConfig(content);
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
} catch (
|
|
224
|
+
} catch (error) {
|
|
225
225
|
console.warn(chalk.yellow(`Failed to analyze component ${component.id}: ${error.message}`));
|
|
226
226
|
}
|
|
227
227
|
|
|
@@ -547,7 +547,7 @@ ${content}`;
|
|
|
547
547
|
throw new Error('Unbalanced brackets in generated test');
|
|
548
548
|
}
|
|
549
549
|
|
|
550
|
-
} catch (
|
|
550
|
+
} catch (error) {
|
|
551
551
|
console.warn(chalk.yellow(`Test syntax validation warning: ${error.message}`));
|
|
552
552
|
}
|
|
553
553
|
}
|
|
@@ -723,7 +723,7 @@ ${content}`;
|
|
|
723
723
|
try {
|
|
724
724
|
const yaml = require('js-yaml');
|
|
725
725
|
return yaml.load(yamlMatch[1]);
|
|
726
|
-
} catch
|
|
726
|
+
} catch {
|
|
727
727
|
return null;
|
|
728
728
|
}
|
|
729
729
|
}
|
|
@@ -734,7 +734,7 @@ ${content}`;
|
|
|
734
734
|
try {
|
|
735
735
|
const yaml = require('js-yaml');
|
|
736
736
|
return yaml.load(content);
|
|
737
|
-
} catch
|
|
737
|
+
} catch {
|
|
738
738
|
return null;
|
|
739
739
|
}
|
|
740
740
|
}
|
|
@@ -29,7 +29,7 @@ class TestQualityAssessment {
|
|
|
29
29
|
console.log(chalk.green('✅ Test quality assessment initialized'));
|
|
30
30
|
return true;
|
|
31
31
|
|
|
32
|
-
} catch (
|
|
32
|
+
} catch (error) {
|
|
33
33
|
console.error(chalk.red(`Failed to initialize test quality assessment: ${error.message}`));
|
|
34
34
|
throw error;
|
|
35
35
|
}
|
|
@@ -81,7 +81,7 @@ class TestQualityAssessment {
|
|
|
81
81
|
|
|
82
82
|
return assessment;
|
|
83
83
|
|
|
84
|
-
} catch (
|
|
84
|
+
} catch (error) {
|
|
85
85
|
console.error(chalk.red(`Failed to assess test quality for ${testFilePath}: ${error.message}`));
|
|
86
86
|
throw error;
|
|
87
87
|
}
|
|
@@ -117,7 +117,7 @@ class TestQualityAssessment {
|
|
|
117
117
|
allIssues.push(...assessment.issues);
|
|
118
118
|
qualityRatings[assessment.quality_rating]++;
|
|
119
119
|
|
|
120
|
-
} catch (
|
|
120
|
+
} catch (error) {
|
|
121
121
|
console.warn(chalk.yellow(`Failed to assess ${testFile}: ${error.message}`));
|
|
122
122
|
}
|
|
123
123
|
}
|
|
@@ -985,7 +985,7 @@ class TestQualityAssessment {
|
|
|
985
985
|
const data = JSON.parse(await fs.readFile(historyFile, 'utf-8'));
|
|
986
986
|
this.qualityHistory = data.quality_history || [];
|
|
987
987
|
}
|
|
988
|
-
} catch
|
|
988
|
+
} catch {
|
|
989
989
|
// No existing data, start fresh
|
|
990
990
|
}
|
|
991
991
|
}
|
|
@@ -1015,7 +1015,7 @@ class TestQualityAssessment {
|
|
|
1015
1015
|
|
|
1016
1016
|
console.log(chalk.gray(`Quality assessment saved: ${assessmentFile}`));
|
|
1017
1017
|
|
|
1018
|
-
} catch (
|
|
1018
|
+
} catch (error) {
|
|
1019
1019
|
console.warn(chalk.yellow(`Failed to save quality assessment: ${error.message}`));
|
|
1020
1020
|
}
|
|
1021
1021
|
}
|
|
@@ -41,7 +41,7 @@ async function countIntegrationReferences(utilityName) {
|
|
|
41
41
|
{ shell: '/bin/bash' },
|
|
42
42
|
);
|
|
43
43
|
totalCount += parseInt(stdout.trim()) || 0;
|
|
44
|
-
} catch
|
|
44
|
+
} catch {
|
|
45
45
|
// Directory doesn't exist or grep failed - not a problem
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -98,7 +98,7 @@ async function testUtility(utilityFile) {
|
|
|
98
98
|
: 'Keep but document usage';
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
} catch (
|
|
101
|
+
} catch (error) {
|
|
102
102
|
result.errors.push(error.message);
|
|
103
103
|
|
|
104
104
|
// Classify error type
|
|
@@ -119,7 +119,7 @@ async function testUtility(utilityFile) {
|
|
|
119
119
|
// Count integration even if broken
|
|
120
120
|
try {
|
|
121
121
|
result.integrationCount = await countIntegrationReferences(utilityFile);
|
|
122
|
-
} catch
|
|
122
|
+
} catch {
|
|
123
123
|
// Ignore counting errors
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
# - SHA256 hashes for change detection
|
|
8
8
|
# - File types for categorization
|
|
9
9
|
#
|
|
10
|
-
version: 3.
|
|
11
|
-
generated_at: "2025-12-
|
|
10
|
+
version: 3.9.1
|
|
11
|
+
generated_at: "2025-12-26T23:36:47.885Z"
|
|
12
12
|
generator: scripts/generate-install-manifest.js
|
|
13
13
|
file_count: 595
|
|
14
14
|
files:
|
|
@@ -333,9 +333,9 @@ files:
|
|
|
333
333
|
type: core
|
|
334
334
|
size: 7217
|
|
335
335
|
- path: core/session/context-loader.js
|
|
336
|
-
hash: sha256:
|
|
336
|
+
hash: sha256:eaef1e3a11feb2d355c5dc8fc2813ae095e27911cdf1261e5d003b22be16d8f0
|
|
337
337
|
type: core
|
|
338
|
-
size:
|
|
338
|
+
size: 13729
|
|
339
339
|
- path: core/utils/output-formatter.js
|
|
340
340
|
hash: sha256:9c386d8b0232f92887dc6f8d32671444a5857b6c848c84b561eedef27a178470
|
|
341
341
|
type: core
|
|
@@ -1657,21 +1657,21 @@ files:
|
|
|
1657
1657
|
type: script
|
|
1658
1658
|
size: 8334
|
|
1659
1659
|
- path: infrastructure/scripts/test-generator.js
|
|
1660
|
-
hash: sha256:
|
|
1660
|
+
hash: sha256:90485b00c0b9e490f2394ff0fb456ea5a5614ca2431d9df55d95b54213b15184
|
|
1661
1661
|
type: script
|
|
1662
|
-
size:
|
|
1662
|
+
size: 24945
|
|
1663
1663
|
- path: infrastructure/scripts/test-quality-assessment.js
|
|
1664
|
-
hash: sha256:
|
|
1664
|
+
hash: sha256:300699a7a5003ef1f18b4e865f761a8e76d0b82e001f0ba17317ef05d41c79db
|
|
1665
1665
|
type: script
|
|
1666
|
-
size:
|
|
1666
|
+
size: 36898
|
|
1667
1667
|
- path: infrastructure/scripts/test-utilities-fast.js
|
|
1668
1668
|
hash: sha256:70d87a74dac153c65d622afa4d62816e41d8d81eee6d42e1c0e498999bec7c40
|
|
1669
1669
|
type: script
|
|
1670
1670
|
size: 3743
|
|
1671
1671
|
- path: infrastructure/scripts/test-utilities.js
|
|
1672
|
-
hash: sha256:
|
|
1672
|
+
hash: sha256:da7c868b105892e3995ed6e6517188a79b8f62a079a61d4d38242c4f357c9d75
|
|
1673
1673
|
type: script
|
|
1674
|
-
size:
|
|
1674
|
+
size: 5870
|
|
1675
1675
|
- path: infrastructure/scripts/tool-resolver.js
|
|
1676
1676
|
hash: sha256:94a5ab46dc1939d87fbb741619d8013ce17c5eae1e18ccdc78707eac2c4c927b
|
|
1677
1677
|
type: script
|
|
@@ -2373,9 +2373,9 @@ files:
|
|
|
2373
2373
|
type: script
|
|
2374
2374
|
size: 1583
|
|
2375
2375
|
- path: scripts/test-template-system.js
|
|
2376
|
-
hash: sha256:
|
|
2376
|
+
hash: sha256:87465ac02b079166479b9d50fe6e12a101bcaa81d47f1aace9b346e264c04712
|
|
2377
2377
|
type: script
|
|
2378
|
-
size:
|
|
2378
|
+
size: 26029
|
|
2379
2379
|
- path: scripts/validate-phase1.ps1
|
|
2380
2380
|
hash: sha256:2f694151ae90af1a9cb8fe890037a51e60115ff8edf636704e8f11e7ac23b23a
|
|
2381
2381
|
type: script
|
|
@@ -34,7 +34,7 @@ class TestTemplateSystem {
|
|
|
34
34
|
console.log(chalk.green('✅ Test template system initialized'));
|
|
35
35
|
return true;
|
|
36
36
|
|
|
37
|
-
} catch (
|
|
37
|
+
} catch (error) {
|
|
38
38
|
console.error(chalk.red(`Failed to initialize test template system: ${error.message}`));
|
|
39
39
|
throw error;
|
|
40
40
|
}
|
|
@@ -121,7 +121,7 @@ class TestTemplateSystem {
|
|
|
121
121
|
console.log(chalk.green(`✅ Custom template created: ${templateName}`));
|
|
122
122
|
return templateWrapper;
|
|
123
123
|
|
|
124
|
-
} catch (
|
|
124
|
+
} catch (error) {
|
|
125
125
|
console.error(chalk.red(`Failed to create custom template: ${error.message}`));
|
|
126
126
|
throw error;
|
|
127
127
|
}
|
|
@@ -136,7 +136,7 @@ class TestTemplateSystem {
|
|
|
136
136
|
try {
|
|
137
137
|
const content = await fs.readFile(templatePath, 'utf-8');
|
|
138
138
|
return JSON.parse(content);
|
|
139
|
-
} catch
|
|
139
|
+
} catch {
|
|
140
140
|
// Template file doesn't exist
|
|
141
141
|
return null;
|
|
142
142
|
}
|
|
@@ -837,14 +837,14 @@ afterAll(async () => {
|
|
|
837
837
|
const templateKey = path.basename(templateFile, '.template.js');
|
|
838
838
|
|
|
839
839
|
this.templateCache.set(templateKey, template);
|
|
840
|
-
} catch (
|
|
840
|
+
} catch (error) {
|
|
841
841
|
console.warn(chalk.yellow(`Failed to load template ${templateFile}: ${error.message}`));
|
|
842
842
|
}
|
|
843
843
|
}
|
|
844
844
|
|
|
845
845
|
console.log(chalk.gray(`Loaded ${this.templateCache.size} template(s)`));
|
|
846
846
|
|
|
847
|
-
} catch (
|
|
847
|
+
} catch (error) {
|
|
848
848
|
console.warn(chalk.yellow(`Failed to load templates: ${error.message}`));
|
|
849
849
|
}
|
|
850
850
|
}
|
|
@@ -872,7 +872,7 @@ afterAll(async () => {
|
|
|
872
872
|
templateFiles.push(path.join(this.templatesDir, entry.name));
|
|
873
873
|
}
|
|
874
874
|
}
|
|
875
|
-
} catch
|
|
875
|
+
} catch {
|
|
876
876
|
// Templates directory doesn't exist yet
|
|
877
877
|
}
|
|
878
878
|
|
package/package.json
CHANGED
|
@@ -99,7 +99,7 @@ function isUserModified(filePath, expectedHash) {
|
|
|
99
99
|
try {
|
|
100
100
|
const currentHash = `sha256:${hashFile(filePath)}`;
|
|
101
101
|
return !hashesMatch(currentHash, expectedHash);
|
|
102
|
-
} catch
|
|
102
|
+
} catch {
|
|
103
103
|
// If we can't hash, assume it's modified
|
|
104
104
|
return true;
|
|
105
105
|
}
|
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AIOS-FullStack Modern Installation Wizard
|
|
5
|
-
* Uses @clack/prompts for beautiful CLI experience
|
|
6
|
-
* Version: 1.1.4
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const fs = require('fs');
|
|
11
|
-
const fse = require('fs-extra');
|
|
12
|
-
const yaml = require('yaml');
|
|
13
|
-
const { execSync } = require('child_process');
|
|
14
|
-
const p = require('@clack/prompts');
|
|
15
|
-
const pc = require('picocolors');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Smart path resolution for AIOS Core modules
|
|
19
|
-
*/
|
|
20
|
-
function resolveAiosCoreModule(modulePath) {
|
|
21
|
-
const aiosCoreModule = path.join(__dirname, '..', '.aios-core', modulePath);
|
|
22
|
-
|
|
23
|
-
const moduleExists = fs.existsSync(aiosCoreModule + '.js') ||
|
|
24
|
-
fs.existsSync(aiosCoreModule + '/index.js') ||
|
|
25
|
-
fs.existsSync(aiosCoreModule);
|
|
26
|
-
|
|
27
|
-
if (!moduleExists) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Cannot find AIOS Core module: ${modulePath}\n` +
|
|
30
|
-
`Searched: ${aiosCoreModule}\n` +
|
|
31
|
-
'Please ensure @synkra/aios-core is installed correctly.',
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return require(aiosCoreModule);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Load AIOS Core modules
|
|
39
|
-
const { detectRepositoryContext } = resolveAiosCoreModule('utils/repository-detector');
|
|
40
|
-
const { ClickUpAdapter } = resolveAiosCoreModule('utils/pm-adapters/clickup-adapter');
|
|
41
|
-
const { GitHubProjectsAdapter } = resolveAiosCoreModule('utils/pm-adapters/github-adapter');
|
|
42
|
-
const { JiraAdapter } = resolveAiosCoreModule('utils/pm-adapters/jira-adapter');
|
|
43
|
-
|
|
44
|
-
async function main() {
|
|
45
|
-
console.clear();
|
|
46
|
-
|
|
47
|
-
p.intro(pc.bgCyan(pc.black(' AIOS-FullStack Installation ')));
|
|
48
|
-
|
|
49
|
-
const projectRoot = process.cwd();
|
|
50
|
-
let context = detectRepositoryContext();
|
|
51
|
-
|
|
52
|
-
// Setup prerequisites if needed
|
|
53
|
-
if (!context) {
|
|
54
|
-
const s = p.spinner();
|
|
55
|
-
s.start('Setting up project prerequisites');
|
|
56
|
-
|
|
57
|
-
// Check for git repository
|
|
58
|
-
let hasGit = false;
|
|
59
|
-
try {
|
|
60
|
-
execSync('git rev-parse --git-dir', { cwd: projectRoot, stdio: 'ignore' });
|
|
61
|
-
hasGit = true;
|
|
62
|
-
} catch (err) {
|
|
63
|
-
// Not a git repo
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!hasGit) {
|
|
67
|
-
try {
|
|
68
|
-
execSync('git init', { cwd: projectRoot, stdio: 'ignore' });
|
|
69
|
-
s.message('Git repository initialized');
|
|
70
|
-
} catch (err) {
|
|
71
|
-
s.stop('Failed to initialize git repository');
|
|
72
|
-
p.cancel('Installation cancelled');
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Check for package.json
|
|
78
|
-
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
79
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
80
|
-
const dirName = path.basename(projectRoot);
|
|
81
|
-
const defaultPackage = {
|
|
82
|
-
name: dirName.toLowerCase().replace(/\s+/g, '-'),
|
|
83
|
-
version: '1.0.0',
|
|
84
|
-
description: 'AIOS-FullStack project',
|
|
85
|
-
main: 'index.js',
|
|
86
|
-
scripts: { test: 'echo "Error: no test specified" && exit 1' },
|
|
87
|
-
keywords: [],
|
|
88
|
-
author: '',
|
|
89
|
-
license: 'ISC',
|
|
90
|
-
};
|
|
91
|
-
fs.writeFileSync(packageJsonPath, JSON.stringify(defaultPackage, null, 2));
|
|
92
|
-
s.message('package.json created');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
s.stop('Prerequisites ready');
|
|
96
|
-
|
|
97
|
-
// Try to detect context again
|
|
98
|
-
context = detectRepositoryContext();
|
|
99
|
-
|
|
100
|
-
// If still no context, create minimal one
|
|
101
|
-
if (!context) {
|
|
102
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
103
|
-
context = {
|
|
104
|
-
projectRoot,
|
|
105
|
-
packageName: packageJson.name,
|
|
106
|
-
packageVersion: packageJson.version,
|
|
107
|
-
repositoryUrl: 'local-repository',
|
|
108
|
-
frameworkLocation: path.join(__dirname, '..'),
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
p.note(`Package: ${context.packageName}`, 'Project Context');
|
|
114
|
-
|
|
115
|
-
// Step 1: Installation Mode
|
|
116
|
-
const installMode = await p.select({
|
|
117
|
-
message: 'How are you using AIOS-FullStack?',
|
|
118
|
-
options: [
|
|
119
|
-
{
|
|
120
|
-
value: 'project-development',
|
|
121
|
-
label: 'Using AIOS in a project',
|
|
122
|
-
hint: 'Framework files added to .gitignore',
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
value: 'framework-development',
|
|
126
|
-
label: 'Developing AIOS framework itself',
|
|
127
|
-
hint: 'Framework files are source code',
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
if (p.isCancel(installMode)) {
|
|
133
|
-
p.cancel('Installation cancelled');
|
|
134
|
-
process.exit(0);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Save installation config
|
|
138
|
-
const config = {
|
|
139
|
-
installation: {
|
|
140
|
-
mode: installMode,
|
|
141
|
-
detected_at: new Date().toISOString(),
|
|
142
|
-
},
|
|
143
|
-
repository: {
|
|
144
|
-
url: context.repositoryUrl,
|
|
145
|
-
auto_detect: true,
|
|
146
|
-
},
|
|
147
|
-
framework: {
|
|
148
|
-
source: installMode === 'framework-development' ? 'local' : 'npm',
|
|
149
|
-
version: context.packageVersion,
|
|
150
|
-
location: context.frameworkLocation,
|
|
151
|
-
},
|
|
152
|
-
git_ignore_rules: {
|
|
153
|
-
mode: installMode,
|
|
154
|
-
ignore_framework_files: installMode === 'project-development',
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const configPath = path.join(context.projectRoot, '.aios-installation-config.yaml');
|
|
159
|
-
fs.writeFileSync(configPath, yaml.stringify(config));
|
|
160
|
-
|
|
161
|
-
// Update .gitignore
|
|
162
|
-
updateGitIgnore(installMode, context.projectRoot);
|
|
163
|
-
|
|
164
|
-
// Step 2: PM Tool
|
|
165
|
-
const pmTool = await p.select({
|
|
166
|
-
message: 'Do you use a project management tool?',
|
|
167
|
-
options: [
|
|
168
|
-
{ value: 'local', label: 'None (local YAML files only)', hint: 'Recommended' },
|
|
169
|
-
{ value: 'clickup', label: 'ClickUp', hint: 'Requires API token' },
|
|
170
|
-
{ value: 'github-projects', label: 'GitHub Projects', hint: 'Uses gh auth' },
|
|
171
|
-
{ value: 'jira', label: 'Jira', hint: 'Requires API token' },
|
|
172
|
-
],
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
if (p.isCancel(pmTool)) {
|
|
176
|
-
p.cancel('Installation cancelled');
|
|
177
|
-
process.exit(0);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Save PM config
|
|
181
|
-
savePMConfig(pmTool, {}, context.projectRoot);
|
|
182
|
-
|
|
183
|
-
// Step 3: IDE Selection
|
|
184
|
-
const ide = await p.select({
|
|
185
|
-
message: 'Which IDE will you use?',
|
|
186
|
-
options: [
|
|
187
|
-
{ value: 'claude', label: 'Claude Code', hint: 'Recommended' },
|
|
188
|
-
{ value: 'windsurf', label: 'Windsurf' },
|
|
189
|
-
{ value: 'cursor', label: 'Cursor' },
|
|
190
|
-
{ value: 'none', label: 'Skip IDE setup' },
|
|
191
|
-
],
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
if (p.isCancel(ide)) {
|
|
195
|
-
p.cancel('Installation cancelled');
|
|
196
|
-
process.exit(0);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Step 4: Copy AIOS Core files
|
|
200
|
-
const s = p.spinner();
|
|
201
|
-
s.start('Installing AIOS Core files');
|
|
202
|
-
|
|
203
|
-
const sourceCoreDir = path.join(context.frameworkLocation, '.aios-core');
|
|
204
|
-
const targetCoreDir = path.join(context.projectRoot, '.aios-core');
|
|
205
|
-
|
|
206
|
-
if (fs.existsSync(sourceCoreDir)) {
|
|
207
|
-
await fse.copy(sourceCoreDir, targetCoreDir);
|
|
208
|
-
s.message('AIOS Core files installed (11 agents, 68 tasks, 23 templates)');
|
|
209
|
-
} else {
|
|
210
|
-
s.stop('AIOS Core files not found');
|
|
211
|
-
p.cancel('Installation failed');
|
|
212
|
-
process.exit(1);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Copy IDE rules if IDE was selected
|
|
216
|
-
if (ide !== 'none') {
|
|
217
|
-
const ideRulesMap = {
|
|
218
|
-
'claude': { source: 'claude-rules.md', target: '.claude/CLAUDE.md' },
|
|
219
|
-
'windsurf': { source: 'windsurf-rules.md', target: '.windsurf/rules.md' },
|
|
220
|
-
'cursor': { source: 'cursor-rules.md', target: '.cursor/rules.md' },
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
const ideConfig = ideRulesMap[ide];
|
|
224
|
-
if (ideConfig) {
|
|
225
|
-
const sourceRules = path.join(targetCoreDir, 'templates', 'ide-rules', ideConfig.source);
|
|
226
|
-
const targetRules = path.join(context.projectRoot, ideConfig.target);
|
|
227
|
-
|
|
228
|
-
if (fs.existsSync(sourceRules)) {
|
|
229
|
-
await fse.ensureDir(path.dirname(targetRules));
|
|
230
|
-
await fse.copy(sourceRules, targetRules);
|
|
231
|
-
s.message(`${ide.charAt(0).toUpperCase() + ide.slice(1)} rules installed`);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
s.stop('Core files installed');
|
|
237
|
-
|
|
238
|
-
// Step 5: Expansion Packs
|
|
239
|
-
const sourceExpansionDir = path.join(context.frameworkLocation, 'expansion-packs');
|
|
240
|
-
const availablePacks = [];
|
|
241
|
-
|
|
242
|
-
if (fs.existsSync(sourceExpansionDir)) {
|
|
243
|
-
const packs = fs.readdirSync(sourceExpansionDir).filter(f =>
|
|
244
|
-
fs.statSync(path.join(sourceExpansionDir, f)).isDirectory(),
|
|
245
|
-
);
|
|
246
|
-
availablePacks.push(...packs);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (availablePacks.length > 0) {
|
|
250
|
-
const expansionPacks = await p.multiselect({
|
|
251
|
-
message: 'Select expansion packs to install (optional)',
|
|
252
|
-
options: availablePacks.map(pack => ({
|
|
253
|
-
value: pack,
|
|
254
|
-
label: pack,
|
|
255
|
-
})),
|
|
256
|
-
required: false,
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
if (!p.isCancel(expansionPacks) && expansionPacks.length > 0) {
|
|
260
|
-
const s2 = p.spinner();
|
|
261
|
-
s2.start('Installing expansion packs');
|
|
262
|
-
|
|
263
|
-
const targetExpansionDir = path.join(context.projectRoot, 'expansion-packs');
|
|
264
|
-
|
|
265
|
-
for (const pack of expansionPacks) {
|
|
266
|
-
const sourcePack = path.join(sourceExpansionDir, pack);
|
|
267
|
-
const targetPack = path.join(targetExpansionDir, pack);
|
|
268
|
-
await fse.copy(sourcePack, targetPack);
|
|
269
|
-
s2.message(`Installed: ${pack}`);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
s2.stop(`${expansionPacks.length} expansion pack(s) installed`);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
p.outro(pc.green('✓ AIOS-FullStack installation complete!'));
|
|
277
|
-
|
|
278
|
-
console.log('');
|
|
279
|
-
p.note(
|
|
280
|
-
`Mode: ${installMode}\n` +
|
|
281
|
-
`Repository: ${context.repositoryUrl}\n` +
|
|
282
|
-
`IDE: ${ide !== 'none' ? ide : 'none'}\n` +
|
|
283
|
-
`PM Tool: ${pmTool}`,
|
|
284
|
-
'Configuration Summary',
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
console.log('');
|
|
288
|
-
console.log(pc.cyan('Next steps:'));
|
|
289
|
-
console.log(' • Activate agents using @agent-name (e.g., @dev, @github-devops)');
|
|
290
|
-
console.log(' • Run "aios --help" to see available commands');
|
|
291
|
-
console.log(' • Check documentation in docs/ directory');
|
|
292
|
-
console.log('');
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Updates .gitignore file based on installation mode
|
|
297
|
-
*/
|
|
298
|
-
function updateGitIgnore(mode, projectRoot) {
|
|
299
|
-
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
300
|
-
|
|
301
|
-
let gitignore = '';
|
|
302
|
-
if (fs.existsSync(gitignorePath)) {
|
|
303
|
-
gitignore = fs.readFileSync(gitignorePath, 'utf8');
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (mode === 'project-development') {
|
|
307
|
-
const frameworkRules = [
|
|
308
|
-
'',
|
|
309
|
-
'# AIOS-FullStack Framework Files (auto-managed - do not edit)',
|
|
310
|
-
'.aios-core/',
|
|
311
|
-
'node_modules/@aios/',
|
|
312
|
-
'outputs/minds/',
|
|
313
|
-
'.aios-installation-config.yaml',
|
|
314
|
-
'# End AIOS-FullStack auto-managed section',
|
|
315
|
-
'',
|
|
316
|
-
];
|
|
317
|
-
|
|
318
|
-
const hasFrameworkSection = gitignore.includes('# AIOS-FullStack Framework Files');
|
|
319
|
-
|
|
320
|
-
if (!hasFrameworkSection) {
|
|
321
|
-
gitignore += frameworkRules.join('\n');
|
|
322
|
-
fs.writeFileSync(gitignorePath, gitignore);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Save PM configuration
|
|
329
|
-
*/
|
|
330
|
-
function savePMConfig(pmTool, config, projectRoot) {
|
|
331
|
-
const pmConfigData = {
|
|
332
|
-
pm_tool: {
|
|
333
|
-
type: pmTool,
|
|
334
|
-
configured_at: new Date().toISOString(),
|
|
335
|
-
config: config,
|
|
336
|
-
},
|
|
337
|
-
sync_behavior: {
|
|
338
|
-
auto_sync_on_status_change: true,
|
|
339
|
-
create_tasks_on_story_creation: false,
|
|
340
|
-
bidirectional_sync: false,
|
|
341
|
-
},
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
const configPath = path.join(projectRoot, '.aios-pm-config.yaml');
|
|
345
|
-
fs.writeFileSync(configPath, yaml.stringify(pmConfigData));
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// Run installer with error handling
|
|
349
|
-
main().catch((error) => {
|
|
350
|
-
p.log.error('Installation failed: ' + error.message);
|
|
351
|
-
process.exit(1);
|
|
352
|
-
});
|