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
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pro Content Scaffolder
|
|
3
|
+
*
|
|
4
|
+
* Copies premium content (squads, configs, feature registry) from
|
|
5
|
+
* node_modules/@aios-fullstack/pro/ into the user's project after
|
|
6
|
+
* license activation.
|
|
7
|
+
*
|
|
8
|
+
* @module packages/installer/src/pro/pro-scaffolder
|
|
9
|
+
* @story INS-3.1 — Implement Pro Content Scaffolder
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const fs = require('fs-extra');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const yaml = require('js-yaml');
|
|
17
|
+
const { hashFileAsync, hashFilesMatchAsync } = require('../installer/file-hasher');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Items to scaffold from pro package into user project.
|
|
21
|
+
* Each entry defines source (relative to proSourceDir) and dest (relative to targetDir).
|
|
22
|
+
*/
|
|
23
|
+
const SCAFFOLD_ITEMS = [
|
|
24
|
+
{
|
|
25
|
+
type: 'directory',
|
|
26
|
+
source: 'squads',
|
|
27
|
+
dest: 'squads',
|
|
28
|
+
description: 'Pro squads',
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: 'file',
|
|
33
|
+
source: 'pro-config.yaml',
|
|
34
|
+
dest: path.join('.aios-core', 'pro-config.yaml'),
|
|
35
|
+
description: 'Pro configuration',
|
|
36
|
+
required: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: 'file',
|
|
40
|
+
source: 'feature-registry.yaml',
|
|
41
|
+
dest: path.join('.aios-core', 'feature-registry.yaml'),
|
|
42
|
+
description: 'Feature registry',
|
|
43
|
+
required: false,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Scaffold pro content into user project.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} targetDir - Project root directory
|
|
51
|
+
* @param {string} proSourceDir - Path to pro package content (node_modules/@aios-fullstack/pro)
|
|
52
|
+
* @param {Object} [options={}] - Scaffold options
|
|
53
|
+
* @param {Function} [options.onProgress] - Progress callback ({item, status, message})
|
|
54
|
+
* @param {boolean} [options.force=false] - Force overwrite even if content exists
|
|
55
|
+
* @returns {Promise<Object>} Scaffold result with copiedFiles, warnings, manifest
|
|
56
|
+
*/
|
|
57
|
+
async function scaffoldProContent(targetDir, proSourceDir, options = {}) {
|
|
58
|
+
const { onProgress = null, force = false } = options;
|
|
59
|
+
|
|
60
|
+
const result = {
|
|
61
|
+
success: false,
|
|
62
|
+
copiedFiles: [],
|
|
63
|
+
skippedFiles: [],
|
|
64
|
+
warnings: [],
|
|
65
|
+
errors: [],
|
|
66
|
+
manifest: null,
|
|
67
|
+
versionInfo: null,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Track files for rollback on partial failure
|
|
71
|
+
const rollbackFiles = [];
|
|
72
|
+
|
|
73
|
+
// Validate pro source exists
|
|
74
|
+
if (!await fs.pathExists(proSourceDir)) {
|
|
75
|
+
result.errors.push(
|
|
76
|
+
`Pro package not found at ${proSourceDir}. Run "npm install @aios-fullstack/pro" first.`
|
|
77
|
+
);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
for (const item of SCAFFOLD_ITEMS) {
|
|
83
|
+
const sourcePath = path.join(proSourceDir, item.source);
|
|
84
|
+
const destPath = path.join(targetDir, item.dest);
|
|
85
|
+
|
|
86
|
+
// Check source exists
|
|
87
|
+
if (!await fs.pathExists(sourcePath)) {
|
|
88
|
+
if (item.required) {
|
|
89
|
+
throw new Error(`Required pro content not found: ${item.source}`);
|
|
90
|
+
}
|
|
91
|
+
const warning = `${item.description} (${item.source}) not found in pro package — skipping`;
|
|
92
|
+
result.warnings.push(warning);
|
|
93
|
+
if (onProgress) {
|
|
94
|
+
onProgress({ item: item.source, status: 'warning', message: warning });
|
|
95
|
+
}
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (item.type === 'directory') {
|
|
100
|
+
const copied = await scaffoldDirectory(sourcePath, destPath, { force, rollbackFiles, baseDir: targetDir });
|
|
101
|
+
result.copiedFiles.push(...copied.copiedFiles);
|
|
102
|
+
result.skippedFiles.push(...copied.skippedFiles);
|
|
103
|
+
} else {
|
|
104
|
+
const copied = await scaffoldFile(sourcePath, destPath, { force, rollbackFiles, baseDir: targetDir });
|
|
105
|
+
if (copied.skipped) {
|
|
106
|
+
result.skippedFiles.push(copied.relativePath);
|
|
107
|
+
} else {
|
|
108
|
+
result.copiedFiles.push(copied.relativePath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (onProgress) {
|
|
113
|
+
onProgress({ item: item.source, status: 'done', message: `${item.description} scaffolded` });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Generate pro-version.json (AC4)
|
|
118
|
+
const versionInfo = await generateProVersionJson(targetDir, proSourceDir, result.copiedFiles);
|
|
119
|
+
result.versionInfo = versionInfo;
|
|
120
|
+
result.copiedFiles.push('pro-version.json');
|
|
121
|
+
rollbackFiles.push(path.join(targetDir, 'pro-version.json'));
|
|
122
|
+
|
|
123
|
+
// Generate pro-installed-manifest.yaml (AC8)
|
|
124
|
+
const manifest = await generateInstalledManifest(targetDir, result.copiedFiles);
|
|
125
|
+
result.manifest = manifest;
|
|
126
|
+
result.copiedFiles.push('pro-installed-manifest.yaml');
|
|
127
|
+
rollbackFiles.push(path.join(targetDir, 'pro-installed-manifest.yaml'));
|
|
128
|
+
|
|
129
|
+
result.success = true;
|
|
130
|
+
|
|
131
|
+
} catch (error) {
|
|
132
|
+
result.errors.push(error.message);
|
|
133
|
+
|
|
134
|
+
// Rollback partially copied files (AC6)
|
|
135
|
+
const rollbackResult = await rollbackScaffold(rollbackFiles);
|
|
136
|
+
if (rollbackResult.errors.length > 0) {
|
|
137
|
+
result.errors.push(`Rollback errors: ${rollbackResult.errors.join(', ')}`);
|
|
138
|
+
}
|
|
139
|
+
result.warnings.push(
|
|
140
|
+
`Scaffolding failed: ${error.message}. ${rollbackResult.removed} files cleaned up.`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Scaffold a directory recursively with idempotency checks.
|
|
149
|
+
*
|
|
150
|
+
* @param {string} sourceDir - Source directory
|
|
151
|
+
* @param {string} destDir - Destination directory
|
|
152
|
+
* @param {Object} options - Options
|
|
153
|
+
* @returns {Promise<Object>} Result with copiedFiles and skippedFiles
|
|
154
|
+
*/
|
|
155
|
+
async function scaffoldDirectory(sourceDir, destDir, options = {}) {
|
|
156
|
+
const { force = false, rollbackFiles = [], baseDir } = options;
|
|
157
|
+
const copiedFiles = [];
|
|
158
|
+
const skippedFiles = [];
|
|
159
|
+
|
|
160
|
+
await fs.ensureDir(destDir);
|
|
161
|
+
|
|
162
|
+
const items = await fs.readdir(sourceDir, { withFileTypes: true });
|
|
163
|
+
|
|
164
|
+
for (const item of items) {
|
|
165
|
+
const sourcePath = path.join(sourceDir, item.name);
|
|
166
|
+
const destPath = path.join(destDir, item.name);
|
|
167
|
+
|
|
168
|
+
if (item.isDirectory()) {
|
|
169
|
+
const sub = await scaffoldDirectory(sourcePath, destPath, options);
|
|
170
|
+
copiedFiles.push(...sub.copiedFiles);
|
|
171
|
+
skippedFiles.push(...sub.skippedFiles);
|
|
172
|
+
} else {
|
|
173
|
+
const result = await scaffoldFile(sourcePath, destPath, { force, rollbackFiles, baseDir });
|
|
174
|
+
if (result.skipped) {
|
|
175
|
+
skippedFiles.push(result.relativePath);
|
|
176
|
+
} else {
|
|
177
|
+
copiedFiles.push(result.relativePath);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { copiedFiles, skippedFiles };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Scaffold a single file with idempotency (AC5).
|
|
187
|
+
* If dest exists and has identical hash, skip. If user modified, skip (preserve).
|
|
188
|
+
*
|
|
189
|
+
* @param {string} sourcePath - Source file path
|
|
190
|
+
* @param {string} destPath - Destination file path
|
|
191
|
+
* @param {Object} options - Options
|
|
192
|
+
* @returns {Promise<Object>} Result with relativePath and skipped flag
|
|
193
|
+
*/
|
|
194
|
+
async function scaffoldFile(sourcePath, destPath, options = {}) {
|
|
195
|
+
const { force = false, rollbackFiles = [], baseDir } = options;
|
|
196
|
+
const base = baseDir || path.resolve(destPath, '..', '..');
|
|
197
|
+
const relativePath = path.relative(base, destPath).replace(/\\/g, '/');
|
|
198
|
+
|
|
199
|
+
// Idempotency check (AC5) — async to avoid blocking event loop
|
|
200
|
+
if (!force && await fs.pathExists(destPath)) {
|
|
201
|
+
try {
|
|
202
|
+
if (await hashFilesMatchAsync(sourcePath, destPath)) {
|
|
203
|
+
// Identical — skip
|
|
204
|
+
return { relativePath, skipped: true };
|
|
205
|
+
}
|
|
206
|
+
} catch {
|
|
207
|
+
// Hash comparison failed — overwrite to be safe
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
await fs.ensureDir(path.dirname(destPath));
|
|
212
|
+
await fs.copy(sourcePath, destPath);
|
|
213
|
+
rollbackFiles.push(destPath);
|
|
214
|
+
|
|
215
|
+
return { relativePath, skipped: false };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Generate pro-version.json with SHA256 hashes for version tracking (AC4).
|
|
220
|
+
*
|
|
221
|
+
* @param {string} targetDir - Project root
|
|
222
|
+
* @param {string} proSourceDir - Pro package directory
|
|
223
|
+
* @param {string[]} copiedFiles - List of copied file relative paths
|
|
224
|
+
* @returns {Promise<Object>} Version info object
|
|
225
|
+
*/
|
|
226
|
+
async function generateProVersionJson(targetDir, proSourceDir, copiedFiles) {
|
|
227
|
+
// Read pro package version
|
|
228
|
+
let proVersion = 'unknown';
|
|
229
|
+
const proPkgPath = path.join(proSourceDir, 'package.json');
|
|
230
|
+
if (await fs.pathExists(proPkgPath)) {
|
|
231
|
+
try {
|
|
232
|
+
const proPkg = await fs.readJson(proPkgPath);
|
|
233
|
+
proVersion = proPkg.version || 'unknown';
|
|
234
|
+
} catch {
|
|
235
|
+
// Keep 'unknown'
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Generate hashes for all copied files
|
|
240
|
+
const fileHashes = {};
|
|
241
|
+
for (const relativePath of copiedFiles) {
|
|
242
|
+
const absolutePath = path.join(targetDir, relativePath);
|
|
243
|
+
try {
|
|
244
|
+
if (await fs.pathExists(absolutePath)) {
|
|
245
|
+
const stats = await fs.stat(absolutePath);
|
|
246
|
+
if (stats.isFile()) {
|
|
247
|
+
fileHashes[relativePath] = `sha256:${await hashFileAsync(absolutePath)}`;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} catch {
|
|
251
|
+
// Skip unhashable files
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const versionInfo = {
|
|
256
|
+
proVersion,
|
|
257
|
+
installedAt: new Date().toISOString(),
|
|
258
|
+
fileCount: copiedFiles.length,
|
|
259
|
+
fileHashes,
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const versionPath = path.join(targetDir, 'pro-version.json');
|
|
263
|
+
await fs.writeJson(versionPath, versionInfo, { spaces: 2 });
|
|
264
|
+
|
|
265
|
+
return versionInfo;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Generate pro-installed-manifest.yaml listing all scaffolded files (AC8).
|
|
270
|
+
*
|
|
271
|
+
* @param {string} targetDir - Project root
|
|
272
|
+
* @param {string[]} copiedFiles - List of copied file relative paths
|
|
273
|
+
* @returns {Promise<Object>} Manifest object
|
|
274
|
+
*/
|
|
275
|
+
async function generateInstalledManifest(targetDir, copiedFiles) {
|
|
276
|
+
const files = [];
|
|
277
|
+
for (const relativePath of copiedFiles) {
|
|
278
|
+
const absolutePath = path.join(targetDir, relativePath);
|
|
279
|
+
let timestamp = new Date().toISOString();
|
|
280
|
+
try {
|
|
281
|
+
if (await fs.pathExists(absolutePath)) {
|
|
282
|
+
const stats = await fs.stat(absolutePath);
|
|
283
|
+
timestamp = stats.mtime.toISOString();
|
|
284
|
+
}
|
|
285
|
+
} catch {
|
|
286
|
+
// Use current time
|
|
287
|
+
}
|
|
288
|
+
files.push({ path: relativePath, timestamp });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const manifest = {
|
|
292
|
+
generatedAt: new Date().toISOString(),
|
|
293
|
+
totalFiles: files.length,
|
|
294
|
+
files,
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const manifestPath = path.join(targetDir, 'pro-installed-manifest.yaml');
|
|
298
|
+
await fs.writeFile(manifestPath, yaml.dump(manifest), 'utf8');
|
|
299
|
+
|
|
300
|
+
return manifest;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Rollback partially scaffolded files on error (AC6).
|
|
305
|
+
*
|
|
306
|
+
* @param {string[]} rollbackFiles - Absolute paths to remove
|
|
307
|
+
* @returns {Promise<Object>} Rollback result with removed count and errors
|
|
308
|
+
*/
|
|
309
|
+
async function rollbackScaffold(rollbackFiles) {
|
|
310
|
+
let removed = 0;
|
|
311
|
+
const errors = [];
|
|
312
|
+
|
|
313
|
+
for (const filePath of rollbackFiles) {
|
|
314
|
+
try {
|
|
315
|
+
if (await fs.pathExists(filePath)) {
|
|
316
|
+
await fs.remove(filePath);
|
|
317
|
+
removed++;
|
|
318
|
+
}
|
|
319
|
+
} catch (error) {
|
|
320
|
+
errors.push(`Failed to remove ${filePath}: ${error.message}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return { removed, errors };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
module.exports = {
|
|
328
|
+
scaffoldProContent,
|
|
329
|
+
scaffoldDirectory,
|
|
330
|
+
scaffoldFile,
|
|
331
|
+
generateProVersionJson,
|
|
332
|
+
generateInstalledManifest,
|
|
333
|
+
rollbackScaffold,
|
|
334
|
+
SCAFFOLD_ITEMS,
|
|
335
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AIOS Color Palette
|
|
2
|
+
* AIOS Color Palette v4.0.4
|
|
3
3
|
*
|
|
4
4
|
* Brand-inspired color system for CLI tools and terminal output.
|
|
5
5
|
* Colors derived from AIOS logo gradient (magenta → orange → purple → blue)
|
|
@@ -189,7 +189,7 @@ const lists = {
|
|
|
189
189
|
*/
|
|
190
190
|
const examples = {
|
|
191
191
|
welcome: () => {
|
|
192
|
-
console.log(headings.h1('🎉 Welcome to AIOS
|
|
192
|
+
console.log(headings.h1('🎉 Welcome to AIOS v4 Installer!'));
|
|
193
193
|
console.log(colors.info('Let\'s configure your project in just a few steps...\n'));
|
|
194
194
|
},
|
|
195
195
|
|
|
@@ -206,14 +206,14 @@ function generateTemplateVariables(wizardState) {
|
|
|
206
206
|
|
|
207
207
|
/**
|
|
208
208
|
* Copy agent files from .aios-core/development/agents to IDE-specific agent folder
|
|
209
|
-
*
|
|
209
|
+
* v4 modular structure: agents are now in development/ module
|
|
210
210
|
* @param {string} projectRoot - Project root directory
|
|
211
211
|
* @param {string} agentFolder - Target folder for agent files (IDE-specific)
|
|
212
212
|
* @param {Object} ideConfig - IDE configuration object (optional, for special handling)
|
|
213
213
|
* @returns {Promise<string[]>} List of copied files
|
|
214
214
|
*/
|
|
215
215
|
async function copyAgentFiles(projectRoot, agentFolder, ideConfig = null) {
|
|
216
|
-
//
|
|
216
|
+
// v4: Agents are in development/agents/ (not root agents/)
|
|
217
217
|
const sourceDir = path.join(__dirname, '..', '..', '..', '..', '.aios-core', 'development', 'agents');
|
|
218
218
|
const targetDir = path.join(projectRoot, agentFolder);
|
|
219
219
|
const copiedFiles = [];
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
const inquirer = require('inquirer');
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const fse = require('fs-extra');
|
|
13
|
+
const { colors } = require('../utils/aios-colors');
|
|
13
14
|
const {
|
|
14
15
|
getLanguageQuestion,
|
|
15
16
|
getUserProfileQuestion,
|
|
@@ -41,11 +42,11 @@ const {
|
|
|
41
42
|
isLLMRoutingInstalled,
|
|
42
43
|
} = require('../../../../.aios-core/infrastructure/scripts/llm-routing/install-llm-routing');
|
|
43
44
|
|
|
44
|
-
// DISABLED:
|
|
45
|
+
// DISABLED: Legacy installation block superseded by squads flow (OSR-8)
|
|
45
46
|
// /**
|
|
46
|
-
// * Generate AntiGravity workflow content for
|
|
47
|
+
// * Generate AntiGravity workflow content for squad agents
|
|
47
48
|
// * @param {string} agentName - Agent name (e.g., 'data-collector')
|
|
48
|
-
// * @param {string} packName -
|
|
49
|
+
// * @param {string} packName - Starter squad name (e.g., 'etl')
|
|
49
50
|
// * @returns {string} Workflow file content
|
|
50
51
|
// */
|
|
51
52
|
// function generateExpansionPackWorkflow(agentName, packName) {
|
|
@@ -57,7 +58,7 @@ const {
|
|
|
57
58
|
//
|
|
58
59
|
// # Ativação do Agente ${displayName}
|
|
59
60
|
//
|
|
60
|
-
// **
|
|
61
|
+
// **Squad:** ${packName}
|
|
61
62
|
//
|
|
62
63
|
// **INSTRUÇÕES CRÍTICAS PARA O ANTIGRAVITY:**
|
|
63
64
|
//
|
|
@@ -118,7 +119,7 @@ const LANGUAGE_MAP = {
|
|
|
118
119
|
/**
|
|
119
120
|
* Write language preference to Claude Code's native settings.json (Story ACT-12)
|
|
120
121
|
* Replaces the old approach of storing language in core-config.yaml.
|
|
121
|
-
* Claude Code
|
|
122
|
+
* Claude Code v4.0.4+ natively supports a `language` field in settings.json
|
|
122
123
|
* that is automatically injected into the system prompt.
|
|
123
124
|
*
|
|
124
125
|
* @param {string} language - Language code from wizard (en|pt|es)
|
|
@@ -460,16 +461,16 @@ async function runWizard(options = {}) {
|
|
|
460
461
|
answers.techPresetResult = { preset: 'none', success: true };
|
|
461
462
|
}
|
|
462
463
|
|
|
463
|
-
// DISABLED:
|
|
464
|
-
// Install
|
|
464
|
+
// DISABLED: Legacy installation block superseded by squads flow (OSR-8)
|
|
465
|
+
// Install Squads if selected
|
|
465
466
|
// if (answers.selectedExpansionPacks && answers.selectedExpansionPacks.length > 0) {
|
|
466
|
-
// console.log('\n🎁 Installing
|
|
467
|
+
// console.log('\n🎁 Installing Squads...');
|
|
467
468
|
//
|
|
468
|
-
// // Detect source
|
|
469
|
+
// // Detect source squads directory (npm package location)
|
|
469
470
|
// const possibleSourceDirs = [
|
|
470
|
-
// path.join(__dirname, '..', '..', '
|
|
471
|
-
// path.join(__dirname, '..', '..', '..', '
|
|
472
|
-
// path.join(process.cwd(), 'node_modules', '@synkra/aios-core', '
|
|
471
|
+
// path.join(__dirname, '..', '..', 'squads'),
|
|
472
|
+
// path.join(__dirname, '..', '..', '..', 'squads'),
|
|
473
|
+
// path.join(process.cwd(), 'node_modules', '@synkra/aios-core', 'squads'),
|
|
473
474
|
// ];
|
|
474
475
|
//
|
|
475
476
|
// let sourceExpansionDir = null;
|
|
@@ -481,7 +482,7 @@ async function runWizard(options = {}) {
|
|
|
481
482
|
// }
|
|
482
483
|
//
|
|
483
484
|
// if (sourceExpansionDir) {
|
|
484
|
-
// const targetExpansionDir = path.join(process.cwd(), '
|
|
485
|
+
// const targetExpansionDir = path.join(process.cwd(), 'squads');
|
|
485
486
|
// await fse.ensureDir(targetExpansionDir);
|
|
486
487
|
//
|
|
487
488
|
// const installedPacks = [];
|
|
@@ -514,10 +515,10 @@ async function runWizard(options = {}) {
|
|
|
514
515
|
// };
|
|
515
516
|
//
|
|
516
517
|
// if (installedPacks.length > 0) {
|
|
517
|
-
// console.log(`\n✅
|
|
518
|
+
// console.log(`\n✅ Squads installed (${installedPacks.length}/${answers.selectedExpansionPacks.length})`);
|
|
518
519
|
// }
|
|
519
520
|
// } else {
|
|
520
|
-
// console.log(' ⚠️
|
|
521
|
+
// console.log(' ⚠️ Squads source directory not found');
|
|
521
522
|
// answers.expansionPacksInstalled = false;
|
|
522
523
|
// }
|
|
523
524
|
// }
|
|
@@ -544,10 +545,10 @@ async function runWizard(options = {}) {
|
|
|
544
545
|
}
|
|
545
546
|
}
|
|
546
547
|
|
|
547
|
-
// DISABLED:
|
|
548
|
-
// Install
|
|
548
|
+
// DISABLED: Legacy installation block superseded by squads flow (OSR-8)
|
|
549
|
+
// Install squad agents to each selected IDE
|
|
549
550
|
// if (answers.expansionPacksResult && answers.expansionPacksResult.installed.length > 0) {
|
|
550
|
-
// console.log('\n📦 Installing
|
|
551
|
+
// console.log('\n📦 Installing squad agents to IDEs...');
|
|
551
552
|
//
|
|
552
553
|
// for (const packName of answers.expansionPacksResult.installed) {
|
|
553
554
|
// const packAgentsDir = path.join(answers.expansionPacksResult.targetDir, packName, 'agents');
|
|
@@ -562,7 +563,7 @@ async function runWizard(options = {}) {
|
|
|
562
563
|
//
|
|
563
564
|
// const isAntiGravity = ideConfig.specialConfig && ideConfig.specialConfig.type === 'antigravity';
|
|
564
565
|
//
|
|
565
|
-
// // Determine target folder for this
|
|
566
|
+
// // Determine target folder for this squad
|
|
566
567
|
// let targetFolder;
|
|
567
568
|
// if (isAntiGravity) {
|
|
568
569
|
// // AntiGravity: workflows go to .agent/workflows/{packName}/
|
|
@@ -818,6 +819,44 @@ async function runWizard(options = {}) {
|
|
|
818
819
|
answers.llmRoutingInstalled = false;
|
|
819
820
|
}
|
|
820
821
|
|
|
822
|
+
// Story INS-3.2: Pro Installation Wizard (optional phase)
|
|
823
|
+
if (!options.skipPro) {
|
|
824
|
+
try {
|
|
825
|
+
const { runProWizard } = require('./pro-setup');
|
|
826
|
+
const isCI = process.env.CI === 'true' || !process.stdout.isTTY;
|
|
827
|
+
const hasProKey = !!process.env.AIOS_PRO_KEY;
|
|
828
|
+
|
|
829
|
+
if (isCI && hasProKey) {
|
|
830
|
+
// CI mode: auto-run if AIOS_PRO_KEY is set
|
|
831
|
+
console.log('\n🔑 Pro license key detected, running Pro setup...');
|
|
832
|
+
const proResult = await runProWizard({ quiet: true });
|
|
833
|
+
answers.proInstalled = proResult.success;
|
|
834
|
+
answers.proResult = proResult;
|
|
835
|
+
} else if (!isCI && !options.quiet) {
|
|
836
|
+
// Interactive mode: ask if user has a Pro license
|
|
837
|
+
const { hasPro } = await inquirer.prompt([
|
|
838
|
+
{
|
|
839
|
+
type: 'confirm',
|
|
840
|
+
name: 'hasPro',
|
|
841
|
+
message: colors.primary('Do you have an AIOS Pro license key?'),
|
|
842
|
+
default: false,
|
|
843
|
+
},
|
|
844
|
+
]);
|
|
845
|
+
|
|
846
|
+
if (hasPro) {
|
|
847
|
+
const proResult = await runProWizard();
|
|
848
|
+
answers.proInstalled = proResult.success;
|
|
849
|
+
answers.proResult = proResult;
|
|
850
|
+
} else {
|
|
851
|
+
answers.proInstalled = false;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
} catch {
|
|
855
|
+
// Pro module not available — skip silently
|
|
856
|
+
answers.proInstalled = false;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
821
860
|
// Story 1.8: Installation Validation
|
|
822
861
|
console.log('\n🔍 Validating installation...\n');
|
|
823
862
|
|