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
@@ -1,462 +1,462 @@
1
- const { exec } = require('child_process');
2
- const { promisify } = require('util');
3
- const execAsync = promisify(exec);
4
- const _path = require('path');
5
- const _fs = require('fs').promises;
6
- const chalk = require('chalk');
7
-
8
- /**
9
- * Git operations wrapper for AIOS framework modifications
10
- */
11
- class GitWrapper {
12
- constructor(options = {}) {
13
- this.rootPath = options.rootPath || process.cwd();
14
- this.gitPath = options.gitPath || 'git';
15
- this.defaultBranch = options.defaultBranch || 'main';
16
- this.metaAgentPrefix = options.metaAgentPrefix || 'meta-agent/';
17
- }
18
-
19
- /**
20
- * Execute a git command
21
- * @private
22
- */
23
- async execGit(command, options = {}) {
24
- try {
25
- const { stdout, stderr } = await execAsync(`${this.gitPath} ${command}`, {
26
- cwd: this.rootPath,
27
- ...options
28
- });
29
-
30
- if (stderr && !options.ignoreStderr) {
31
- console.warn(chalk.yellow(`Git warning: ${stderr}`));
32
- }
33
-
34
- return stdout.trim();
35
- } catch (_error) {
36
- throw new Error(`Git command failed: ${error.message}`);
37
- }
38
- }
39
-
40
- /**
41
- * Check if git is initialized
42
- * @returns {Promise<boolean>}
43
- */
44
- async isGitInitialized() {
45
- try {
46
- await this.execGit('status');
47
- return true;
48
- } catch (_error) {
49
- return false;
50
- }
51
- }
52
-
53
- /**
54
- * Initialize git repository if not already initialized
55
- * @returns {Promise<void>}
56
- */
57
- async initializeRepository() {
58
- const initialized = await this.isGitInitialized();
59
- if (!initialized) {
60
- await this.execGit('init');
61
- console.log(chalk.green('✅ Git repository initialized'));
62
- }
63
- }
64
-
65
- /**
66
- * Get current branch name
67
- * @returns {Promise<string>}
68
- */
69
- async getCurrentBranch() {
70
- return await this.execGit('rev-parse --abbrev-ref HEAD');
71
- }
72
-
73
- /**
74
- * Create a new branch
75
- * @param {string} branchName - Name of the branch to create
76
- * @param {boolean} checkout - Whether to checkout the branch
77
- * @returns {Promise<void>}
78
- */
79
- async createBranch(branchName, checkout = true) {
80
- try {
81
- if (checkout) {
82
- await this.execGit(`checkout -b ${branchName}`);
83
- } else {
84
- await this.execGit(`branch ${branchName}`);
85
- }
86
- console.log(chalk.green(`✅ Created branch: ${branchName}`));
87
- } catch (_error) {
88
- // Branch might already exist
89
- if (error.message.includes('already exists')) {
90
- console.log(chalk.yellow(`Branch already exists: ${branchName}`));
91
- if (checkout) {
92
- await this.checkoutBranch(branchName);
93
- }
94
- } else {
95
- throw error;
96
- }
97
- }
98
- }
99
-
100
- /**
101
- * Checkout an existing branch
102
- * @param {string} branchName - Name of the branch to checkout
103
- * @returns {Promise<void>}
104
- */
105
- async checkoutBranch(branchName) {
106
- await this.execGit(`checkout ${branchName}`);
107
- console.log(chalk.green(`✅ Checked out branch: ${branchName}`));
108
- }
109
-
110
- /**
111
- * Create a branch for meta-agent modifications
112
- * @param {string} modificationName - Name of the modification
113
- * @returns {Promise<string>} Branch name
114
- */
115
- async createModificationBranch(modificationName) {
116
- const timestamp = new Date().toISOString().substring(0, 10);
117
- const branchName = `${this.metaAgentPrefix}${modificationName}-${timestamp}`;
118
- await this.createBranch(branchName);
119
- return branchName;
120
- }
121
-
122
- /**
123
- * Stage files for commit
124
- * @param {Array<string>} files - Files to stage
125
- * @returns {Promise<void>}
126
- */
127
- async stageFiles(files) {
128
- if (!Array.isArray(files) || files.length === 0) {
129
- throw new Error('No files provided to stage');
130
- }
131
-
132
- for (const file of files) {
133
- await this.execGit(`add "${file}"`);
134
- }
135
-
136
- console.log(chalk.green(`✅ Staged ${files.length} files`));
137
- }
138
-
139
- /**
140
- * Commit changes with message
141
- * @param {string} message - Commit message
142
- * @param {Object} options - Commit options
143
- * @returns {Promise<string>} Commit hash
144
- */
145
- async commit(message, options = {}) {
146
- const {
147
- author = 'aios-developer <aios-developer@aios-fullstack.local>',
148
- signoff = true
149
- } = options;
150
-
151
- let command = `commit -m "${message.replace(/"/g, '\\"')}"`;
152
-
153
- if (author) {
154
- command += ` --author="${author}"`;
155
- }
156
-
157
- if (signoff) {
158
- command += ' --signoff';
159
- }
160
-
161
- const output = await this.execGit(command);
162
- const hashMatch = output.match(/\[[\w-]+ ([\w]+)\]/);
163
- const commitHash = hashMatch ? hashMatch[1] : 'unknown';
164
-
165
- console.log(chalk.green(`✅ Committed: ${commitHash}`));
166
- return commitHash;
167
- }
168
-
169
- /**
170
- * Create a commit for component modifications
171
- * @param {Array<string>} files - Files to commit
172
- * @param {string} message - Commit message
173
- * @param {Object} metadata - Additional metadata
174
- * @returns {Promise<string>} Commit hash
175
- */
176
- async commitModification(files, message, metadata = {}) {
177
- await this.stageFiles(files);
178
-
179
- // Add metadata to commit message
180
- let fullMessage = message;
181
- if (metadata.componentType && metadata.componentName) {
182
- fullMessage = `${metadata.componentType}(${metadata.componentName}): ${message}`;
183
- }
184
-
185
- if (metadata.breakingChange) {
186
- fullMessage += '\n\nBREAKING CHANGE: ' + metadata.breakingChange;
187
- }
188
-
189
- if (metadata.approvedBy) {
190
- fullMessage += `\n\nApproved-by: ${metadata.approvedBy}`;
191
- }
192
-
193
- fullMessage += '\n\nGenerated by: aios-developer meta-agent';
194
-
195
- return await this.commit(fullMessage);
196
- }
197
-
198
- /**
199
- * Get git status
200
- * @returns {Promise<Object>} Status information
201
- */
202
- async getStatus() {
203
- const porcelainStatus = await this.execGit('status --porcelain');
204
- const branch = await this.getCurrentBranch();
205
-
206
- const files = {
207
- modified: [],
208
- added: [],
209
- deleted: [],
210
- untracked: []
211
- };
212
-
213
- if (porcelainStatus) {
214
- const lines = porcelainStatus.split('\n');
215
- for (const line of lines) {
216
- if (!line) continue;
217
-
218
- const status = line.substring(0, 2);
219
- const filename = line.substring(3);
220
-
221
- if (status.includes('M')) files.modified.push(filename);
222
- else if (status.includes('A')) files.added.push(filename);
223
- else if (status.includes('D')) files.deleted.push(filename);
224
- else if (status === '??') files.untracked.push(filename);
225
- }
226
- }
227
-
228
- return {
229
- branch,
230
- clean: porcelainStatus === '',
231
- files
232
- };
233
- }
234
-
235
- /**
236
- * Get commit history
237
- * @param {number} limit - Number of commits to retrieve
238
- * @returns {Promise<Array>} Commit history
239
- */
240
- async getHistory(limit = 10) {
241
- const format = '%H|%an|%ae|%at|%s';
242
- const output = await this.execGit(`log -${limit} --format="${format}"`);
243
-
244
- if (!output) return [];
245
-
246
- return output.split('\n').map(line => {
247
- const [hash, author, email, timestamp, subject] = line.split('|');
248
- return {
249
- hash,
250
- author,
251
- email,
252
- date: new Date(parseInt(timestamp) * 1000),
253
- subject
254
- };
255
- });
256
- }
257
-
258
- /**
259
- * Check for conflicts
260
- * @returns {Promise<Array>} List of conflicted files
261
- */
262
- async getConflicts() {
263
- try {
264
- const output = await this.execGit('diff --name-only --diff-filter=U');
265
- return output ? output.split('\n').filter(Boolean) : [];
266
- } catch (_error) {
267
- return [];
268
- }
269
- }
270
-
271
- /**
272
- * Merge a branch
273
- * @param {string} branchName - Branch to merge
274
- * @param {Object} options - Merge options
275
- * @returns {Promise<Object>} Merge result
276
- */
277
- async mergeBranch(branchName, options = {}) {
278
- const {
279
- strategy = 'recursive',
280
- message = null,
281
- noFastForward = true
282
- } = options;
283
-
284
- let command = `merge ${branchName}`;
285
-
286
- if (strategy) {
287
- command += ` --strategy=${strategy}`;
288
- }
289
-
290
- if (noFastForward) {
291
- command += ' --no-ff';
292
- }
293
-
294
- if (message) {
295
- command += ` -m "${message.replace(/"/g, '\\"')}"`;
296
- }
297
-
298
- try {
299
- const output = await this.execGit(command);
300
- return {
301
- success: true,
302
- message: output
303
- };
304
- } catch (_error) {
305
- // Check for conflicts
306
- const conflicts = await this.getConflicts();
307
- if (conflicts.length > 0) {
308
- return {
309
- success: false,
310
- conflicts,
311
- error: 'Merge conflicts detected'
312
- };
313
- }
314
- throw error;
315
- }
316
- }
317
-
318
- /**
319
- * Create a tag
320
- * @param {string} tagName - Name of the tag
321
- * @param {string} message - Tag message
322
- * @returns {Promise<void>}
323
- */
324
- async createTag(tagName, message) {
325
- await this.execGit(`tag -a ${tagName} -m "${message.replace(/"/g, '\\"')}"`);
326
- console.log(chalk.green(`✅ Created tag: ${tagName}`));
327
- }
328
-
329
- /**
330
- * Push changes to remote
331
- * @param {string} remote - Remote name
332
- * @param {string} branch - Branch name
333
- * @param {Object} options - Push options
334
- * @returns {Promise<void>}
335
- */
336
- async push(remote = 'origin', branch = null, options = {}) {
337
- const currentBranch = branch || await this.getCurrentBranch();
338
- let command = `push ${remote} ${currentBranch}`;
339
-
340
- if (options.tags) {
341
- command += ' --tags';
342
- }
343
-
344
- if (options.force) {
345
- command += ' --force';
346
- }
347
-
348
- if (options.setUpstream) {
349
- command = `push -u ${remote} ${currentBranch}`;
350
- }
351
-
352
- await this.execGit(command);
353
- console.log(chalk.green(`✅ Pushed to ${remote}/${currentBranch}`));
354
- }
355
-
356
- /**
357
- * Get diff between commits or working tree
358
- * @param {Object} options - Diff options
359
- * @returns {Promise<string>} Diff output
360
- */
361
- async getDiff(options = {}) {
362
- const {
363
- from = 'HEAD',
364
- to = null,
365
- files = [],
366
- nameOnly = false
367
- } = options;
368
-
369
- let command = 'diff';
370
-
371
- if (nameOnly) {
372
- command += ' --name-only';
373
- }
374
-
375
- if (to) {
376
- command += ` ${from} ${to}`;
377
- } else {
378
- command += ` ${from}`;
379
- }
380
-
381
- if (files.length > 0) {
382
- command += ` -- ${files.join(' ')}`;
383
- }
384
-
385
- return await this.execGit(command);
386
- }
387
-
388
- /**
389
- * Stash changes
390
- * @param {string} message - Stash message
391
- * @returns {Promise<void>}
392
- */
393
- async stash(message = 'Meta-agent modifications') {
394
- await this.execGit(`stash push -m "${message}"`);
395
- console.log(chalk.green('✅ Changes stashed'));
396
- }
397
-
398
- /**
399
- * Apply stash
400
- * @param {string} stashRef - Stash reference
401
- * @returns {Promise<void>}
402
- */
403
- async stashApply(stashRef = 'stash@{0}') {
404
- await this.execGit(`stash apply ${stashRef}`);
405
- console.log(chalk.green('✅ Stash applied'));
406
- }
407
-
408
- /**
409
- * Get remote information
410
- * @returns {Promise<Array>} Remote information
411
- */
412
- async getRemotes() {
413
- const output = await this.execGit('remote -v');
414
- if (!output) return [];
415
-
416
- const remotes = {};
417
- output.split('\n').forEach(line => {
418
- const [name, url, type] = line.split(/\s+/);
419
- if (!remotes[name]) {
420
- remotes[name] = {};
421
- }
422
- remotes[name][type.replace(/[()]/g, '')] = url;
423
- });
424
-
425
- return Object.entries(remotes).map(([name, urls]) => ({
426
- name,
427
- fetchUrl: urls.fetch,
428
- pushUrl: urls.push
429
- }));
430
- }
431
-
432
- /**
433
- * Generate commit message for modifications
434
- * @param {Object} modification - Modification details
435
- * @returns {string} Generated commit message
436
- */
437
- generateCommitMessage(modification) {
438
- const {
439
- action,
440
- componentType,
441
- _componentName,
442
- summary,
443
- details = [],
444
- breakingChanges = []
445
- } = modification;
446
-
447
- let message = `${action}(${componentType}): ${summary}`;
448
-
449
- if (details.length > 0) {
450
- message += '\n\n' + details.map(d => `- ${d}`).join('\n');
451
- }
452
-
453
- if (breakingChanges.length > 0) {
454
- message += '\n\nBREAKING CHANGES:\n' +
455
- breakingChanges.map(bc => `- ${bc}`).join('\n');
456
- }
457
-
458
- return message;
459
- }
460
- }
461
-
1
+ const { exec } = require('child_process');
2
+ const { promisify } = require('util');
3
+ const execAsync = promisify(exec);
4
+ const _path = require('path');
5
+ const _fs = require('fs').promises;
6
+ const chalk = require('chalk');
7
+
8
+ /**
9
+ * Git operations wrapper for AIOS framework modifications
10
+ */
11
+ class GitWrapper {
12
+ constructor(options = {}) {
13
+ this.rootPath = options.rootPath || process.cwd();
14
+ this.gitPath = options.gitPath || 'git';
15
+ this.defaultBranch = options.defaultBranch || 'main';
16
+ this.metaAgentPrefix = options.metaAgentPrefix || 'meta-agent/';
17
+ }
18
+
19
+ /**
20
+ * Execute a git command
21
+ * @private
22
+ */
23
+ async execGit(command, options = {}) {
24
+ try {
25
+ const { stdout, stderr } = await execAsync(`${this.gitPath} ${command}`, {
26
+ cwd: this.rootPath,
27
+ ...options
28
+ });
29
+
30
+ if (stderr && !options.ignoreStderr) {
31
+ console.warn(chalk.yellow(`Git warning: ${stderr}`));
32
+ }
33
+
34
+ return stdout.trim();
35
+ } catch (_error) {
36
+ throw new Error(`Git command failed: ${error.message}`);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Check if git is initialized
42
+ * @returns {Promise<boolean>}
43
+ */
44
+ async isGitInitialized() {
45
+ try {
46
+ await this.execGit('status');
47
+ return true;
48
+ } catch (_error) {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Initialize git repository if not already initialized
55
+ * @returns {Promise<void>}
56
+ */
57
+ async initializeRepository() {
58
+ const initialized = await this.isGitInitialized();
59
+ if (!initialized) {
60
+ await this.execGit('init');
61
+ console.log(chalk.green('✅ Git repository initialized'));
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get current branch name
67
+ * @returns {Promise<string>}
68
+ */
69
+ async getCurrentBranch() {
70
+ return await this.execGit('rev-parse --abbrev-ref HEAD');
71
+ }
72
+
73
+ /**
74
+ * Create a new branch
75
+ * @param {string} branchName - Name of the branch to create
76
+ * @param {boolean} checkout - Whether to checkout the branch
77
+ * @returns {Promise<void>}
78
+ */
79
+ async createBranch(branchName, checkout = true) {
80
+ try {
81
+ if (checkout) {
82
+ await this.execGit(`checkout -b ${branchName}`);
83
+ } else {
84
+ await this.execGit(`branch ${branchName}`);
85
+ }
86
+ console.log(chalk.green(`✅ Created branch: ${branchName}`));
87
+ } catch (_error) {
88
+ // Branch might already exist
89
+ if (error.message.includes('already exists')) {
90
+ console.log(chalk.yellow(`Branch already exists: ${branchName}`));
91
+ if (checkout) {
92
+ await this.checkoutBranch(branchName);
93
+ }
94
+ } else {
95
+ throw error;
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Checkout an existing branch
102
+ * @param {string} branchName - Name of the branch to checkout
103
+ * @returns {Promise<void>}
104
+ */
105
+ async checkoutBranch(branchName) {
106
+ await this.execGit(`checkout ${branchName}`);
107
+ console.log(chalk.green(`✅ Checked out branch: ${branchName}`));
108
+ }
109
+
110
+ /**
111
+ * Create a branch for meta-agent modifications
112
+ * @param {string} modificationName - Name of the modification
113
+ * @returns {Promise<string>} Branch name
114
+ */
115
+ async createModificationBranch(modificationName) {
116
+ const timestamp = new Date().toISOString().substring(0, 10);
117
+ const branchName = `${this.metaAgentPrefix}${modificationName}-${timestamp}`;
118
+ await this.createBranch(branchName);
119
+ return branchName;
120
+ }
121
+
122
+ /**
123
+ * Stage files for commit
124
+ * @param {Array<string>} files - Files to stage
125
+ * @returns {Promise<void>}
126
+ */
127
+ async stageFiles(files) {
128
+ if (!Array.isArray(files) || files.length === 0) {
129
+ throw new Error('No files provided to stage');
130
+ }
131
+
132
+ for (const file of files) {
133
+ await this.execGit(`add "${file}"`);
134
+ }
135
+
136
+ console.log(chalk.green(`✅ Staged ${files.length} files`));
137
+ }
138
+
139
+ /**
140
+ * Commit changes with message
141
+ * @param {string} message - Commit message
142
+ * @param {Object} options - Commit options
143
+ * @returns {Promise<string>} Commit hash
144
+ */
145
+ async commit(message, options = {}) {
146
+ const {
147
+ author = 'aios-developer <aios-developer@aios-fullstack.local>',
148
+ signoff = true
149
+ } = options;
150
+
151
+ let command = `commit -m "${message.replace(/"/g, '\\"')}"`;
152
+
153
+ if (author) {
154
+ command += ` --author="${author}"`;
155
+ }
156
+
157
+ if (signoff) {
158
+ command += ' --signoff';
159
+ }
160
+
161
+ const output = await this.execGit(command);
162
+ const hashMatch = output.match(/\[[\w-]+ ([\w]+)\]/);
163
+ const commitHash = hashMatch ? hashMatch[1] : 'unknown';
164
+
165
+ console.log(chalk.green(`✅ Committed: ${commitHash}`));
166
+ return commitHash;
167
+ }
168
+
169
+ /**
170
+ * Create a commit for component modifications
171
+ * @param {Array<string>} files - Files to commit
172
+ * @param {string} message - Commit message
173
+ * @param {Object} metadata - Additional metadata
174
+ * @returns {Promise<string>} Commit hash
175
+ */
176
+ async commitModification(files, message, metadata = {}) {
177
+ await this.stageFiles(files);
178
+
179
+ // Add metadata to commit message
180
+ let fullMessage = message;
181
+ if (metadata.componentType && metadata.componentName) {
182
+ fullMessage = `${metadata.componentType}(${metadata.componentName}): ${message}`;
183
+ }
184
+
185
+ if (metadata.breakingChange) {
186
+ fullMessage += '\n\nBREAKING CHANGE: ' + metadata.breakingChange;
187
+ }
188
+
189
+ if (metadata.approvedBy) {
190
+ fullMessage += `\n\nApproved-by: ${metadata.approvedBy}`;
191
+ }
192
+
193
+ fullMessage += '\n\nGenerated by: aios-developer meta-agent';
194
+
195
+ return await this.commit(fullMessage);
196
+ }
197
+
198
+ /**
199
+ * Get git status
200
+ * @returns {Promise<Object>} Status information
201
+ */
202
+ async getStatus() {
203
+ const porcelainStatus = await this.execGit('status --porcelain');
204
+ const branch = await this.getCurrentBranch();
205
+
206
+ const files = {
207
+ modified: [],
208
+ added: [],
209
+ deleted: [],
210
+ untracked: []
211
+ };
212
+
213
+ if (porcelainStatus) {
214
+ const lines = porcelainStatus.split('\n');
215
+ for (const line of lines) {
216
+ if (!line) continue;
217
+
218
+ const status = line.substring(0, 2);
219
+ const filename = line.substring(3);
220
+
221
+ if (status.includes('M')) files.modified.push(filename);
222
+ else if (status.includes('A')) files.added.push(filename);
223
+ else if (status.includes('D')) files.deleted.push(filename);
224
+ else if (status === '??') files.untracked.push(filename);
225
+ }
226
+ }
227
+
228
+ return {
229
+ branch,
230
+ clean: porcelainStatus === '',
231
+ files
232
+ };
233
+ }
234
+
235
+ /**
236
+ * Get commit history
237
+ * @param {number} limit - Number of commits to retrieve
238
+ * @returns {Promise<Array>} Commit history
239
+ */
240
+ async getHistory(limit = 10) {
241
+ const format = '%H|%an|%ae|%at|%s';
242
+ const output = await this.execGit(`log -${limit} --format="${format}"`);
243
+
244
+ if (!output) return [];
245
+
246
+ return output.split('\n').map(line => {
247
+ const [hash, author, email, timestamp, subject] = line.split('|');
248
+ return {
249
+ hash,
250
+ author,
251
+ email,
252
+ date: new Date(parseInt(timestamp) * 1000),
253
+ subject
254
+ };
255
+ });
256
+ }
257
+
258
+ /**
259
+ * Check for conflicts
260
+ * @returns {Promise<Array>} List of conflicted files
261
+ */
262
+ async getConflicts() {
263
+ try {
264
+ const output = await this.execGit('diff --name-only --diff-filter=U');
265
+ return output ? output.split('\n').filter(Boolean) : [];
266
+ } catch (_error) {
267
+ return [];
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Merge a branch
273
+ * @param {string} branchName - Branch to merge
274
+ * @param {Object} options - Merge options
275
+ * @returns {Promise<Object>} Merge result
276
+ */
277
+ async mergeBranch(branchName, options = {}) {
278
+ const {
279
+ strategy = 'recursive',
280
+ message = null,
281
+ noFastForward = true
282
+ } = options;
283
+
284
+ let command = `merge ${branchName}`;
285
+
286
+ if (strategy) {
287
+ command += ` --strategy=${strategy}`;
288
+ }
289
+
290
+ if (noFastForward) {
291
+ command += ' --no-ff';
292
+ }
293
+
294
+ if (message) {
295
+ command += ` -m "${message.replace(/"/g, '\\"')}"`;
296
+ }
297
+
298
+ try {
299
+ const output = await this.execGit(command);
300
+ return {
301
+ success: true,
302
+ message: output
303
+ };
304
+ } catch (_error) {
305
+ // Check for conflicts
306
+ const conflicts = await this.getConflicts();
307
+ if (conflicts.length > 0) {
308
+ return {
309
+ success: false,
310
+ conflicts,
311
+ error: 'Merge conflicts detected'
312
+ };
313
+ }
314
+ throw error;
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Create a tag
320
+ * @param {string} tagName - Name of the tag
321
+ * @param {string} message - Tag message
322
+ * @returns {Promise<void>}
323
+ */
324
+ async createTag(tagName, message) {
325
+ await this.execGit(`tag -a ${tagName} -m "${message.replace(/"/g, '\\"')}"`);
326
+ console.log(chalk.green(`✅ Created tag: ${tagName}`));
327
+ }
328
+
329
+ /**
330
+ * Push changes to remote
331
+ * @param {string} remote - Remote name
332
+ * @param {string} branch - Branch name
333
+ * @param {Object} options - Push options
334
+ * @returns {Promise<void>}
335
+ */
336
+ async push(remote = 'origin', branch = null, options = {}) {
337
+ const currentBranch = branch || await this.getCurrentBranch();
338
+ let command = `push ${remote} ${currentBranch}`;
339
+
340
+ if (options.tags) {
341
+ command += ' --tags';
342
+ }
343
+
344
+ if (options.force) {
345
+ command += ' --force';
346
+ }
347
+
348
+ if (options.setUpstream) {
349
+ command = `push -u ${remote} ${currentBranch}`;
350
+ }
351
+
352
+ await this.execGit(command);
353
+ console.log(chalk.green(`✅ Pushed to ${remote}/${currentBranch}`));
354
+ }
355
+
356
+ /**
357
+ * Get diff between commits or working tree
358
+ * @param {Object} options - Diff options
359
+ * @returns {Promise<string>} Diff output
360
+ */
361
+ async getDiff(options = {}) {
362
+ const {
363
+ from = 'HEAD',
364
+ to = null,
365
+ files = [],
366
+ nameOnly = false
367
+ } = options;
368
+
369
+ let command = 'diff';
370
+
371
+ if (nameOnly) {
372
+ command += ' --name-only';
373
+ }
374
+
375
+ if (to) {
376
+ command += ` ${from} ${to}`;
377
+ } else {
378
+ command += ` ${from}`;
379
+ }
380
+
381
+ if (files.length > 0) {
382
+ command += ` -- ${files.join(' ')}`;
383
+ }
384
+
385
+ return await this.execGit(command);
386
+ }
387
+
388
+ /**
389
+ * Stash changes
390
+ * @param {string} message - Stash message
391
+ * @returns {Promise<void>}
392
+ */
393
+ async stash(message = 'Meta-agent modifications') {
394
+ await this.execGit(`stash push -m "${message}"`);
395
+ console.log(chalk.green('✅ Changes stashed'));
396
+ }
397
+
398
+ /**
399
+ * Apply stash
400
+ * @param {string} stashRef - Stash reference
401
+ * @returns {Promise<void>}
402
+ */
403
+ async stashApply(stashRef = 'stash@{0}') {
404
+ await this.execGit(`stash apply ${stashRef}`);
405
+ console.log(chalk.green('✅ Stash applied'));
406
+ }
407
+
408
+ /**
409
+ * Get remote information
410
+ * @returns {Promise<Array>} Remote information
411
+ */
412
+ async getRemotes() {
413
+ const output = await this.execGit('remote -v');
414
+ if (!output) return [];
415
+
416
+ const remotes = {};
417
+ output.split('\n').forEach(line => {
418
+ const [name, url, type] = line.split(/\s+/);
419
+ if (!remotes[name]) {
420
+ remotes[name] = {};
421
+ }
422
+ remotes[name][type.replace(/[()]/g, '')] = url;
423
+ });
424
+
425
+ return Object.entries(remotes).map(([name, urls]) => ({
426
+ name,
427
+ fetchUrl: urls.fetch,
428
+ pushUrl: urls.push
429
+ }));
430
+ }
431
+
432
+ /**
433
+ * Generate commit message for modifications
434
+ * @param {Object} modification - Modification details
435
+ * @returns {string} Generated commit message
436
+ */
437
+ generateCommitMessage(modification) {
438
+ const {
439
+ action,
440
+ componentType,
441
+ _componentName,
442
+ summary,
443
+ details = [],
444
+ breakingChanges = []
445
+ } = modification;
446
+
447
+ let message = `${action}(${componentType}): ${summary}`;
448
+
449
+ if (details.length > 0) {
450
+ message += '\n\n' + details.map(d => `- ${d}`).join('\n');
451
+ }
452
+
453
+ if (breakingChanges.length > 0) {
454
+ message += '\n\nBREAKING CHANGES:\n' +
455
+ breakingChanges.map(bc => `- ${bc}`).join('\n');
456
+ }
457
+
458
+ return message;
459
+ }
460
+ }
461
+
462
462
  module.exports = GitWrapper;