aios-core 3.2.0 → 3.4.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.
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Validator - Verifies IDE sync status
3
+ * @story 6.19 - IDE Command Auto-Sync System
4
+ */
5
+
6
+ const fs = require('fs-extra');
7
+ const path = require('path');
8
+ const crypto = require('crypto');
9
+ const { getRedirectFilenames } = require('./redirect-generator');
10
+
11
+ /**
12
+ * Calculate content hash for comparison
13
+ * @param {string} content - File content
14
+ * @returns {string} - SHA256 hash
15
+ */
16
+ function hashContent(content) {
17
+ // Normalize line endings for cross-platform consistency
18
+ const normalized = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
19
+ return crypto.createHash('sha256').update(normalized, 'utf8').digest('hex');
20
+ }
21
+
22
+ /**
23
+ * Check if a file exists at target path
24
+ * @param {string} filePath - Path to check
25
+ * @returns {boolean} - True if file exists
26
+ */
27
+ function fileExists(filePath) {
28
+ return fs.existsSync(filePath);
29
+ }
30
+
31
+ /**
32
+ * Read file content if it exists
33
+ * @param {string} filePath - Path to read
34
+ * @returns {string|null} - File content or null
35
+ */
36
+ function readFileIfExists(filePath) {
37
+ try {
38
+ if (fs.existsSync(filePath)) {
39
+ return fs.readFileSync(filePath, 'utf8');
40
+ }
41
+ } catch (error) {
42
+ // Ignore read errors
43
+ }
44
+ return null;
45
+ }
46
+
47
+ /**
48
+ * Validate sync status for a single IDE
49
+ * @param {object[]} expectedFiles - Array of {filename, content} expected
50
+ * @param {string} targetDir - Target directory to check
51
+ * @param {object} redirectsConfig - Redirects configuration
52
+ * @returns {object} - Validation result
53
+ */
54
+ function validateIdeSync(expectedFiles, targetDir, redirectsConfig) {
55
+ const result = {
56
+ targetDir,
57
+ missing: [],
58
+ drift: [],
59
+ orphaned: [],
60
+ synced: [],
61
+ total: {
62
+ expected: expectedFiles.length,
63
+ missing: 0,
64
+ drift: 0,
65
+ orphaned: 0,
66
+ synced: 0,
67
+ },
68
+ };
69
+
70
+ // Track expected filenames
71
+ const expectedFilenames = new Set(expectedFiles.map(f => f.filename));
72
+
73
+ // Add redirect filenames to expected
74
+ const redirectFilenames = getRedirectFilenames(redirectsConfig);
75
+ for (const rf of redirectFilenames) {
76
+ expectedFilenames.add(rf);
77
+ }
78
+
79
+ // Check each expected file
80
+ for (const expected of expectedFiles) {
81
+ const targetPath = path.join(targetDir, expected.filename);
82
+ const actualContent = readFileIfExists(targetPath);
83
+
84
+ if (actualContent === null) {
85
+ // File is missing
86
+ result.missing.push({
87
+ filename: expected.filename,
88
+ path: targetPath,
89
+ });
90
+ result.total.missing++;
91
+ } else {
92
+ // Compare content
93
+ const expectedHash = hashContent(expected.content);
94
+ const actualHash = hashContent(actualContent);
95
+
96
+ if (expectedHash !== actualHash) {
97
+ // Content differs (drift)
98
+ result.drift.push({
99
+ filename: expected.filename,
100
+ path: targetPath,
101
+ expectedHash,
102
+ actualHash,
103
+ });
104
+ result.total.drift++;
105
+ } else {
106
+ // File is synced
107
+ result.synced.push({
108
+ filename: expected.filename,
109
+ path: targetPath,
110
+ });
111
+ result.total.synced++;
112
+ }
113
+ }
114
+ }
115
+
116
+ // Check for orphaned files (files in target not in expected)
117
+ if (fs.existsSync(targetDir)) {
118
+ try {
119
+ const actualFiles = fs.readdirSync(targetDir).filter(f => f.endsWith('.md'));
120
+
121
+ for (const file of actualFiles) {
122
+ if (!expectedFilenames.has(file)) {
123
+ result.orphaned.push({
124
+ filename: file,
125
+ path: path.join(targetDir, file),
126
+ });
127
+ result.total.orphaned++;
128
+ }
129
+ }
130
+ } catch (error) {
131
+ // Ignore directory read errors
132
+ }
133
+ }
134
+
135
+ return result;
136
+ }
137
+
138
+ /**
139
+ * Validate sync status for all IDEs
140
+ * @param {object} ideConfigs - Map of IDE name to {expectedFiles, targetDir}
141
+ * @param {object} redirectsConfig - Redirects configuration
142
+ * @returns {object} - Full validation result
143
+ */
144
+ function validateAllIdes(ideConfigs, redirectsConfig) {
145
+ const results = {
146
+ ides: {},
147
+ summary: {
148
+ total: 0,
149
+ synced: 0,
150
+ missing: 0,
151
+ drift: 0,
152
+ orphaned: 0,
153
+ pass: true,
154
+ },
155
+ };
156
+
157
+ for (const [ideName, config] of Object.entries(ideConfigs)) {
158
+ const ideResult = validateIdeSync(
159
+ config.expectedFiles,
160
+ config.targetDir,
161
+ redirectsConfig
162
+ );
163
+
164
+ results.ides[ideName] = ideResult;
165
+
166
+ // Update summary
167
+ results.summary.total += ideResult.total.expected;
168
+ results.summary.synced += ideResult.total.synced;
169
+ results.summary.missing += ideResult.total.missing;
170
+ results.summary.drift += ideResult.total.drift;
171
+ results.summary.orphaned += ideResult.total.orphaned;
172
+ }
173
+
174
+ // Pass if no missing or drift
175
+ results.summary.pass =
176
+ results.summary.missing === 0 && results.summary.drift === 0;
177
+
178
+ return results;
179
+ }
180
+
181
+ /**
182
+ * Format validation result as report string
183
+ * @param {object} results - Validation results
184
+ * @param {boolean} verbose - Include detailed file lists
185
+ * @returns {string} - Formatted report
186
+ */
187
+ function formatValidationReport(results, verbose = false) {
188
+ const lines = [];
189
+
190
+ lines.push('# IDE Sync Validation Report');
191
+ lines.push('');
192
+
193
+ // Summary
194
+ lines.push('## Summary');
195
+ lines.push('');
196
+ lines.push(`| Metric | Count |`);
197
+ lines.push(`|--------|-------|`);
198
+ lines.push(`| Total Expected | ${results.summary.total} |`);
199
+ lines.push(`| Synced | ${results.summary.synced} |`);
200
+ lines.push(`| Missing | ${results.summary.missing} |`);
201
+ lines.push(`| Drift | ${results.summary.drift} |`);
202
+ lines.push(`| Orphaned | ${results.summary.orphaned} |`);
203
+ lines.push('');
204
+
205
+ const status = results.summary.pass ? '✅ PASS' : '❌ FAIL';
206
+ lines.push(`**Status:** ${status}`);
207
+ lines.push('');
208
+
209
+ // Per-IDE details
210
+ if (verbose) {
211
+ lines.push('## IDE Details');
212
+ lines.push('');
213
+
214
+ for (const [ideName, ideResult] of Object.entries(results.ides)) {
215
+ lines.push(`### ${ideName}`);
216
+ lines.push('');
217
+ lines.push(`- Target: \`${ideResult.targetDir}\``);
218
+ lines.push(`- Synced: ${ideResult.total.synced}`);
219
+ lines.push(`- Missing: ${ideResult.total.missing}`);
220
+ lines.push(`- Drift: ${ideResult.total.drift}`);
221
+ lines.push(`- Orphaned: ${ideResult.total.orphaned}`);
222
+ lines.push('');
223
+
224
+ if (ideResult.missing.length > 0) {
225
+ lines.push('**Missing Files:**');
226
+ for (const f of ideResult.missing) {
227
+ lines.push(`- ${f.filename}`);
228
+ }
229
+ lines.push('');
230
+ }
231
+
232
+ if (ideResult.drift.length > 0) {
233
+ lines.push('**Drifted Files:**');
234
+ for (const f of ideResult.drift) {
235
+ lines.push(`- ${f.filename}`);
236
+ }
237
+ lines.push('');
238
+ }
239
+
240
+ if (ideResult.orphaned.length > 0) {
241
+ lines.push('**Orphaned Files:**');
242
+ for (const f of ideResult.orphaned) {
243
+ lines.push(`- ${f.filename}`);
244
+ }
245
+ lines.push('');
246
+ }
247
+ }
248
+ }
249
+
250
+ // Fix instructions
251
+ if (!results.summary.pass) {
252
+ lines.push('## How to Fix');
253
+ lines.push('');
254
+ lines.push('Run the following command to sync IDE files:');
255
+ lines.push('');
256
+ lines.push('```bash');
257
+ lines.push('npm run sync:ide');
258
+ lines.push('```');
259
+ lines.push('');
260
+ lines.push('Then commit the generated files.');
261
+ }
262
+
263
+ return lines.join('\n');
264
+ }
265
+
266
+ module.exports = {
267
+ hashContent,
268
+ fileExists,
269
+ readFileIfExists,
270
+ validateIdeSync,
271
+ validateAllIdes,
272
+ formatValidationReport,
273
+ };
@@ -7,10 +7,10 @@
7
7
  # - SHA256 hashes for change detection
8
8
  # - File types for categorization
9
9
  #
10
- version: 3.2.0
11
- generated_at: "2025-12-22T19:07:31.838Z"
10
+ version: 3.4.0
11
+ generated_at: "2025-12-23T02:05:10.189Z"
12
12
  generator: scripts/generate-install-manifest.js
13
- file_count: 555
13
+ file_count: 564
14
14
  files:
15
15
  - path: cli/commands/generate/index.js
16
16
  hash: sha256:36f8e38ab767fa5478d8dabac548c66dc2c0fc521c216e954ac33fcea0ba597b
@@ -165,9 +165,9 @@ files:
165
165
  type: cli
166
166
  size: 5907
167
167
  - path: core-config.yaml
168
- hash: sha256:5af2cf56303f66230e7fb1a106fcdaa10072b88fa3c9185a56d0b2e36c838839
168
+ hash: sha256:238af11d4bd06c600b65aec6bad627ecd87c1d4c037447bb5aa7befd474ad2f1
169
169
  type: config
170
- size: 14289
170
+ size: 15370
171
171
  - path: core/config/config-cache.js
172
172
  hash: sha256:527a788cbe650aa6b13d1101ebc16419489bfef20b2ee93042f6eb6a51e898e9
173
173
  type: core
@@ -1368,6 +1368,42 @@ files:
1368
1368
  hash: sha256:e4354cbceb1d3fe64f0a32b3b69e3f12e55f4a5770412b7cd31f92fe2cf3278c
1369
1369
  type: script
1370
1370
  size: 9735
1371
+ - path: infrastructure/scripts/ide-sync/agent-parser.js
1372
+ hash: sha256:f18531d68ffec3f661b81c528bff0929bac6fa26213f28affbfebb2faca091db
1373
+ type: script
1374
+ size: 7428
1375
+ - path: infrastructure/scripts/ide-sync/index.js
1376
+ hash: sha256:9e792b680a1ed19893d10fe27aa14f2ccf2235004d62f83bd052d2dde75c1aeb
1377
+ type: script
1378
+ size: 12879
1379
+ - path: infrastructure/scripts/ide-sync/redirect-generator.js
1380
+ hash: sha256:658725f2832d331ee83350e620e5a79a499492172fc8f44174749e3471feb77f
1381
+ type: script
1382
+ size: 4518
1383
+ - path: infrastructure/scripts/ide-sync/transformers/antigravity.js
1384
+ hash: sha256:f78399acdc7557f496abcffcd252e722e91f06afe16859b5066882954d9cd23e
1385
+ type: script
1386
+ size: 2687
1387
+ - path: infrastructure/scripts/ide-sync/transformers/claude-code.js
1388
+ hash: sha256:f028bdef022e54a5f70c92fa6d6b0dc0877c2fc87a9f8d2f477b29d09248dab7
1389
+ type: script
1390
+ size: 2225
1391
+ - path: infrastructure/scripts/ide-sync/transformers/cursor.js
1392
+ hash: sha256:957eb51c7c516f2a73ade0be38d25f97b5508f9816067bfe94ed23e7f17be265
1393
+ type: script
1394
+ size: 2321
1395
+ - path: infrastructure/scripts/ide-sync/transformers/trae.js
1396
+ hash: sha256:c3609987ed07d1c4959ef803548cbd224797db117affb8655c30c04ed524967a
1397
+ type: script
1398
+ size: 2895
1399
+ - path: infrastructure/scripts/ide-sync/transformers/windsurf.js
1400
+ hash: sha256:f0c6ad1cbab8618ea41572a4c667e13d471b49794f5508bc4f9184106f260342
1401
+ type: script
1402
+ size: 2636
1403
+ - path: infrastructure/scripts/ide-sync/validator.js
1404
+ hash: sha256:356c78125db7f88d14f4e521808e96593d729291c3d7a1c36cb02f78b4aef8fc
1405
+ type: script
1406
+ size: 7316
1371
1407
  - path: infrastructure/scripts/improvement-engine.js
1372
1408
  hash: sha256:2a132e285295fa9455f94c3b3cc2abf0c38a1dc2faa1197bdbe36d80dc69430c
1373
1409
  type: script
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aios-core",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework",
5
5
  "main": "index.js",
6
6
  "module": "index.esm.js",
@@ -80,6 +80,12 @@
80
80
  "release:test": "semantic-release --dry-run --no-ci || echo 'Config test complete - authentication errors are expected locally'",
81
81
  "generate:manifest": "node scripts/generate-install-manifest.js",
82
82
  "validate:manifest": "node scripts/validate-manifest.js",
83
+ "sync:ide": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync",
84
+ "sync:ide:validate": "node .aios-core/infrastructure/scripts/ide-sync/index.js validate",
85
+ "sync:ide:check": "node .aios-core/infrastructure/scripts/ide-sync/index.js validate --strict",
86
+ "sync:ide:cursor": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide cursor",
87
+ "sync:ide:windsurf": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide windsurf",
88
+ "sync:ide:trae": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide trae",
83
89
  "prepublishOnly": "npm run generate:manifest && npm run validate:manifest",
84
90
  "prepare": "echo 'Skipping husky - not needed for NPM publish'"
85
91
  },
@@ -156,6 +162,9 @@
156
162
  ],
157
163
  "*.md": [
158
164
  "prettier --write"
165
+ ],
166
+ ".aios-core/development/agents/*.md": [
167
+ "npm run sync:ide"
159
168
  ]
160
169
  }
161
170
  }