aios-core 3.2.0 → 3.3.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/core-config.yaml +44 -0
- package/.aios-core/infrastructure/scripts/ide-sync/agent-parser.js +251 -0
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +480 -0
- package/.aios-core/infrastructure/scripts/ide-sync/redirect-generator.js +200 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/antigravity.js +105 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/claude-code.js +84 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/cursor.js +93 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/trae.js +125 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/windsurf.js +106 -0
- package/.aios-core/infrastructure/scripts/ide-sync/validator.js +273 -0
- package/.aios-core/install-manifest.yaml +41 -5
- package/package.json +10 -1
|
@@ -454,3 +454,47 @@ utils:
|
|
|
454
454
|
- transaction-manager
|
|
455
455
|
- usage-analytics
|
|
456
456
|
- usage-tracker
|
|
457
|
+
|
|
458
|
+
# ============================================
|
|
459
|
+
# SECTION 12: IDE Sync System (Story 6.19)
|
|
460
|
+
# Automatically syncs agents to IDE command files
|
|
461
|
+
# ============================================
|
|
462
|
+
ideSync:
|
|
463
|
+
enabled: true
|
|
464
|
+
source: .aios-core/development/agents
|
|
465
|
+
|
|
466
|
+
# Target IDE configurations
|
|
467
|
+
targets:
|
|
468
|
+
claude-code:
|
|
469
|
+
enabled: true
|
|
470
|
+
path: .claude/commands/AIOS/agents
|
|
471
|
+
format: full-markdown-yaml
|
|
472
|
+
cursor:
|
|
473
|
+
enabled: true
|
|
474
|
+
path: .cursor/rules/agents
|
|
475
|
+
format: condensed-rules
|
|
476
|
+
windsurf:
|
|
477
|
+
enabled: true
|
|
478
|
+
path: .windsurf/rules/agents
|
|
479
|
+
format: xml-tagged-markdown
|
|
480
|
+
trae:
|
|
481
|
+
enabled: true
|
|
482
|
+
path: .trae/rules/agents
|
|
483
|
+
format: project-rules
|
|
484
|
+
antigravity:
|
|
485
|
+
enabled: true
|
|
486
|
+
path: .antigravity/rules/agents
|
|
487
|
+
format: cursor-style
|
|
488
|
+
|
|
489
|
+
# Redirects for deprecated/renamed agents
|
|
490
|
+
redirects:
|
|
491
|
+
aios-developer: aios-master
|
|
492
|
+
aios-orchestrator: aios-master
|
|
493
|
+
db-sage: data-engineer
|
|
494
|
+
github-devops: devops
|
|
495
|
+
|
|
496
|
+
# Validation settings
|
|
497
|
+
validation:
|
|
498
|
+
strictMode: true
|
|
499
|
+
failOnDrift: true
|
|
500
|
+
failOnOrphaned: false
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Parser - Extracts YAML and markdown sections from agent files
|
|
3
|
+
* @story 6.19 - IDE Command Auto-Sync System
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const yaml = require('js-yaml');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Extract YAML block from markdown content
|
|
12
|
+
* @param {string} content - Full markdown content
|
|
13
|
+
* @returns {string|null} - YAML content without fences, or null if not found
|
|
14
|
+
*/
|
|
15
|
+
function extractYamlBlock(content) {
|
|
16
|
+
// Match ```yaml ... ``` block
|
|
17
|
+
const yamlMatch = content.match(/```yaml\s*\n([\s\S]*?)\n```/);
|
|
18
|
+
if (yamlMatch && yamlMatch[1]) {
|
|
19
|
+
return yamlMatch[1].trim();
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parse YAML content safely with fallback for problematic patterns
|
|
26
|
+
* @param {string} yamlContent - YAML string to parse
|
|
27
|
+
* @returns {object|null} - Parsed object or null on error
|
|
28
|
+
*/
|
|
29
|
+
function parseYaml(yamlContent) {
|
|
30
|
+
try {
|
|
31
|
+
return yaml.load(yamlContent);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
// Try to fix common YAML issues before failing
|
|
34
|
+
try {
|
|
35
|
+
// Fix command format issues with {placeholders} in keys
|
|
36
|
+
// Convert "- key {param}: value" to "- name: key {param}\n description: value"
|
|
37
|
+
let fixed = yamlContent.replace(
|
|
38
|
+
/^(\s*)-\s+([a-z-]+)\s*(\{[^}]+\})?:\s*(.+)$/gm,
|
|
39
|
+
(match, indent, name, param, desc) => {
|
|
40
|
+
const fullName = param ? `${name} ${param}` : name;
|
|
41
|
+
return `${indent}- name: "${fullName}"\n${indent} description: "${desc.replace(/"/g, '\\"')}"`;
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Fix pipe patterns with invalid YAML
|
|
46
|
+
fixed = fixed.replace(/:\s*"[^"]*"\s*\|\s*"[^"]*"/g, (match) => {
|
|
47
|
+
// Convert "value1" | "value2" to list
|
|
48
|
+
return `: [${match.slice(2)}]`;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return yaml.load(fixed);
|
|
52
|
+
} catch (fixError) {
|
|
53
|
+
console.error(`YAML parse error: ${error.message}`);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Extract markdown section by heading
|
|
61
|
+
* @param {string} content - Full markdown content
|
|
62
|
+
* @param {string} heading - Heading to find (without #)
|
|
63
|
+
* @returns {string|null} - Section content or null if not found
|
|
64
|
+
*/
|
|
65
|
+
function extractSection(content, heading) {
|
|
66
|
+
// Escape special regex characters in heading
|
|
67
|
+
const escapedHeading = heading.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
68
|
+
|
|
69
|
+
// Match ## heading or ### heading
|
|
70
|
+
const regex = new RegExp(
|
|
71
|
+
`^#{2,3}\\s*${escapedHeading}\\s*$\\n([\\s\\S]*?)(?=^#{2,3}\\s|$)`,
|
|
72
|
+
'mi'
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const match = content.match(regex);
|
|
76
|
+
if (match && match[1]) {
|
|
77
|
+
return match[1].trim();
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Extract basic agent info using regex fallback
|
|
84
|
+
* @param {string} content - Raw markdown content
|
|
85
|
+
* @returns {object} - Extracted agent data
|
|
86
|
+
*/
|
|
87
|
+
function extractAgentInfoFallback(content) {
|
|
88
|
+
const agent = {};
|
|
89
|
+
|
|
90
|
+
// Try to extract agent name
|
|
91
|
+
const nameMatch = content.match(/name:\s*([^\n]+)/);
|
|
92
|
+
if (nameMatch) agent.name = nameMatch[1].trim();
|
|
93
|
+
|
|
94
|
+
// Try to extract id
|
|
95
|
+
const idMatch = content.match(/id:\s*([^\n]+)/);
|
|
96
|
+
if (idMatch) agent.id = idMatch[1].trim();
|
|
97
|
+
|
|
98
|
+
// Try to extract title
|
|
99
|
+
const titleMatch = content.match(/title:\s*([^\n]+)/);
|
|
100
|
+
if (titleMatch) agent.title = titleMatch[1].trim();
|
|
101
|
+
|
|
102
|
+
// Try to extract icon
|
|
103
|
+
const iconMatch = content.match(/icon:\s*([^\n]+)/);
|
|
104
|
+
if (iconMatch) agent.icon = iconMatch[1].trim();
|
|
105
|
+
|
|
106
|
+
// Try to extract whenToUse - handle apostrophes within text (e.g., "don't")
|
|
107
|
+
// First try quoted string, then unquoted to end of line
|
|
108
|
+
const whenMatchQuoted = content.match(/whenToUse:\s*["'](.+?)["'](?:\n|$)/);
|
|
109
|
+
const whenMatchUnquoted = content.match(/whenToUse:\s*([^\n]+)/);
|
|
110
|
+
const whenMatch = whenMatchQuoted || whenMatchUnquoted;
|
|
111
|
+
if (whenMatch) agent.whenToUse = whenMatch[1].trim();
|
|
112
|
+
|
|
113
|
+
return Object.keys(agent).length > 0 ? agent : null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Parse a single agent file
|
|
118
|
+
* @param {string} filePath - Path to agent markdown file
|
|
119
|
+
* @returns {object} - Parsed agent data
|
|
120
|
+
*/
|
|
121
|
+
function parseAgentFile(filePath) {
|
|
122
|
+
const result = {
|
|
123
|
+
path: filePath,
|
|
124
|
+
filename: path.basename(filePath),
|
|
125
|
+
id: path.basename(filePath, '.md'),
|
|
126
|
+
raw: null,
|
|
127
|
+
yaml: null,
|
|
128
|
+
agent: null,
|
|
129
|
+
persona_profile: null,
|
|
130
|
+
commands: [],
|
|
131
|
+
dependencies: null,
|
|
132
|
+
sections: {
|
|
133
|
+
quickCommands: null,
|
|
134
|
+
collaboration: null,
|
|
135
|
+
guide: null,
|
|
136
|
+
},
|
|
137
|
+
error: null,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
// Read file content
|
|
142
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
143
|
+
result.raw = content;
|
|
144
|
+
|
|
145
|
+
// Extract YAML block
|
|
146
|
+
const yamlContent = extractYamlBlock(content);
|
|
147
|
+
if (!yamlContent) {
|
|
148
|
+
result.error = 'No YAML block found';
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Parse YAML
|
|
153
|
+
const parsed = parseYaml(yamlContent);
|
|
154
|
+
if (!parsed) {
|
|
155
|
+
// Try fallback extraction for basic agent info
|
|
156
|
+
const fallbackAgent = extractAgentInfoFallback(content);
|
|
157
|
+
if (fallbackAgent) {
|
|
158
|
+
result.agent = fallbackAgent;
|
|
159
|
+
result.error = 'YAML parse failed, using fallback extraction';
|
|
160
|
+
// Don't return - allow processing with partial data
|
|
161
|
+
} else {
|
|
162
|
+
result.error = 'Failed to parse YAML';
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
result.yaml = parsed;
|
|
167
|
+
|
|
168
|
+
// Extract key sections
|
|
169
|
+
result.agent = parsed.agent || null;
|
|
170
|
+
result.persona_profile = parsed.persona_profile || null;
|
|
171
|
+
result.commands = parsed.commands || [];
|
|
172
|
+
result.dependencies = parsed.dependencies || null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Extract markdown sections (always try)
|
|
176
|
+
result.sections.quickCommands = extractSection(content, 'Quick Commands');
|
|
177
|
+
result.sections.collaboration = extractSection(content, 'Agent Collaboration');
|
|
178
|
+
result.sections.guide = extractSection(content, 'Developer Guide') ||
|
|
179
|
+
extractSection(content, '.*Guide \\(\\*guide command\\)');
|
|
180
|
+
|
|
181
|
+
} catch (error) {
|
|
182
|
+
result.error = error.message;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Parse all agent files in a directory
|
|
190
|
+
* @param {string} agentsDir - Path to agents directory
|
|
191
|
+
* @returns {object[]} - Array of parsed agent data
|
|
192
|
+
*/
|
|
193
|
+
function parseAllAgents(agentsDir) {
|
|
194
|
+
const agents = [];
|
|
195
|
+
|
|
196
|
+
if (!fs.existsSync(agentsDir)) {
|
|
197
|
+
console.error(`Agents directory not found: ${agentsDir}`);
|
|
198
|
+
return agents;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const files = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
|
|
202
|
+
|
|
203
|
+
for (const file of files) {
|
|
204
|
+
const filePath = path.join(agentsDir, file);
|
|
205
|
+
const agentData = parseAgentFile(filePath);
|
|
206
|
+
agents.push(agentData);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return agents;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get visibility-filtered commands
|
|
214
|
+
* @param {object[]} commands - Array of command objects
|
|
215
|
+
* @param {string} visibility - Visibility level (full, quick, key)
|
|
216
|
+
* @returns {object[]} - Filtered commands
|
|
217
|
+
*/
|
|
218
|
+
function getVisibleCommands(commands, visibility) {
|
|
219
|
+
if (!Array.isArray(commands)) return [];
|
|
220
|
+
|
|
221
|
+
return commands.filter(cmd => {
|
|
222
|
+
if (!cmd.visibility) return true; // Include if no visibility defined
|
|
223
|
+
return cmd.visibility.includes(visibility);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Format commands as bullet list
|
|
229
|
+
* @param {object[]} commands - Array of command objects
|
|
230
|
+
* @param {string} prefix - Prefix for command name (default: '*')
|
|
231
|
+
* @returns {string} - Formatted bullet list
|
|
232
|
+
*/
|
|
233
|
+
function formatCommandsList(commands, prefix = '*') {
|
|
234
|
+
if (!Array.isArray(commands) || commands.length === 0) {
|
|
235
|
+
return '- No commands available';
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return commands
|
|
239
|
+
.map(cmd => `- \`${prefix}${cmd.name}\` - ${cmd.description || 'No description'}`)
|
|
240
|
+
.join('\n');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
module.exports = {
|
|
244
|
+
extractYamlBlock,
|
|
245
|
+
parseYaml,
|
|
246
|
+
extractSection,
|
|
247
|
+
parseAgentFile,
|
|
248
|
+
parseAllAgents,
|
|
249
|
+
getVisibleCommands,
|
|
250
|
+
formatCommandsList,
|
|
251
|
+
};
|