aios-core 4.2.2 → 4.2.4
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/registry/service-registry.json +6466 -6586
- package/.aios-core/core-config.yaml +10 -5
- package/.aios-core/data/aios-kb.md +19 -25
- package/.aios-core/data/entity-registry.yaml +311 -204
- package/.aios-core/data/registry-update-log.jsonl +8 -0
- package/.aios-core/development/tasks/db-squad-integration.md +3 -3
- package/.aios-core/development/tasks/dev-develop-story.md +1 -1
- package/.aios-core/development/tasks/integrate-squad.md +1 -1
- package/.aios-core/development/tasks/pr-automation.md +3 -3
- package/.aios-core/development/tasks/squad-creator-migrate.md +1 -1
- package/.aios-core/development/tasks/squad-creator-sync-ide-command.md +0 -2
- package/.aios-core/development/tasks/update-aios.md +2 -2
- package/.aios-core/development/tasks/validate-next-story.md +2 -99
- package/.aios-core/development/workflows/README.md +0 -4
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +0 -1
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +3 -3
- package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +1 -1
- package/.aios-core/docs/standards/STANDARDS-INDEX.md +4 -4
- package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +2 -2
- package/.aios-core/framework-config.yaml +8 -4
- package/.aios-core/infrastructure/scripts/ide-sync/README.md +29 -5
- package/.aios-core/infrastructure/scripts/ide-sync/gemini-commands.js +205 -0
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +48 -11
- package/.aios-core/infrastructure/scripts/ide-sync/redirect-generator.js +1 -1
- package/.aios-core/infrastructure/scripts/test-utilities.js +1 -1
- package/.aios-core/infrastructure/scripts/tool-resolver.js +2 -2
- package/.aios-core/infrastructure/scripts/validate-claude-integration.js +101 -0
- package/.aios-core/infrastructure/scripts/validate-codex-integration.js +141 -0
- package/.aios-core/infrastructure/scripts/validate-gemini-integration.js +151 -0
- package/.aios-core/infrastructure/scripts/validate-parity.js +119 -0
- package/.aios-core/infrastructure/templates/aios-sync.yaml.template +0 -11
- package/.aios-core/install-manifest.yaml +83 -71
- package/.aios-core/local-config.yaml.template +2 -1
- package/.aios-core/presets/README.md +0 -1
- package/.aios-core/product/data/integration-patterns.md +1 -1
- package/.aios-core/product/templates/ide-rules/gemini-rules.md +87 -233
- package/.aios-core/product/templates/statusline/statusline-script.js +188 -0
- package/.aios-core/product/templates/statusline/track-agent.sh +68 -0
- package/.aios-core/user-guide.md +14 -19
- package/LICENSE +0 -27
- package/README.md +42 -6
- package/bin/aios-init.js +98 -54
- package/bin/modules/env-config.js +0 -1
- package/package.json +18 -5
- package/packages/gemini-aios-extension/README.md +13 -8
- package/packages/gemini-aios-extension/commands/aios-agent.js +7 -0
- package/packages/gemini-aios-extension/commands/aios-agents.js +2 -1
- package/packages/gemini-aios-extension/commands/aios-analyst.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-architect.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-data-engineer.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-dev.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-devops.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-master.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-menu.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-pm.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-po.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-qa.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-sm.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-squad-creator.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-ux-design-expert.js +6 -0
- package/packages/gemini-aios-extension/commands/lib/agent-launcher.js +138 -0
- package/packages/gemini-aios-extension/extension.json +70 -0
- package/packages/gemini-aios-extension/gemini-extension.json +147 -0
- package/packages/gemini-aios-extension/hooks/hooks.json +67 -65
- package/packages/installer/src/config/ide-configs.js +10 -10
- package/packages/installer/src/config/templates/core-config-template.js +6 -3
- package/packages/installer/src/wizard/ide-config-generator.js +373 -2
- package/packages/installer/src/wizard/ide-selector.js +1 -1
- package/packages/installer/src/wizard/pro-setup.js +237 -150
- package/scripts/code-intel-health-check.js +125 -125
- package/scripts/ensure-manifest.js +58 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/windsurf.js +0 -106
- package/.aios-core/product/templates/ide-rules/cline-rules.md +0 -84
- package/.aios-core/product/templates/ide-rules/roo-rules.md +0 -86
- package/.aios-core/product/templates/ide-rules/windsurf-rules.md +0 -80
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
* @agent @devops (Gage)
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
const { execFile } = require('node:child_process')
|
|
26
|
-
const { promisify } = require('node:util')
|
|
27
|
-
const { existsSync, readFileSync } = require('node:fs')
|
|
28
|
-
const { resolve, join } = require('node:path')
|
|
25
|
+
const { execFile } = require('node:child_process');
|
|
26
|
+
const { promisify } = require('node:util');
|
|
27
|
+
const { existsSync, readFileSync } = require('node:fs');
|
|
28
|
+
const { resolve, join } = require('node:path');
|
|
29
29
|
|
|
30
|
-
const execFileAsync = promisify(execFile)
|
|
30
|
+
const execFileAsync = promisify(execFile);
|
|
31
31
|
|
|
32
|
-
const RESPONSE_TIMEOUT_MS = 5000
|
|
32
|
+
const RESPONSE_TIMEOUT_MS = 5000;
|
|
33
33
|
const EXPECTED_TOOLS = [
|
|
34
34
|
'get_usage_guide',
|
|
35
35
|
'analyze_codebase',
|
|
@@ -39,147 +39,147 @@ const EXPECTED_TOOLS = [
|
|
|
39
39
|
'find_callees',
|
|
40
40
|
'complexity_analysis',
|
|
41
41
|
'dependency_analysis',
|
|
42
|
-
'project_statistics'
|
|
43
|
-
]
|
|
42
|
+
'project_statistics',
|
|
43
|
+
];
|
|
44
44
|
|
|
45
45
|
function parseArgs() {
|
|
46
|
-
const args = process.argv.slice(2)
|
|
46
|
+
const args = process.argv.slice(2);
|
|
47
47
|
return {
|
|
48
48
|
smoke: args.includes('--smoke'),
|
|
49
|
-
projectRoot: getArgValue(args, '--project-root') || process.cwd()
|
|
50
|
-
}
|
|
49
|
+
projectRoot: getArgValue(args, '--project-root') || process.cwd(),
|
|
50
|
+
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function getArgValue(args, flag) {
|
|
54
|
-
const idx = args.indexOf(flag)
|
|
55
|
-
if (idx === -1 || idx + 1 >= args.length) return null
|
|
56
|
-
return args[idx + 1]
|
|
54
|
+
const idx = args.indexOf(flag);
|
|
55
|
+
if (idx === -1 || idx + 1 >= args.length) return null;
|
|
56
|
+
return args[idx + 1];
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
async function checkBinaryInstalled() {
|
|
60
60
|
try {
|
|
61
61
|
const { stdout } = await execFileAsync('code-graph-mcp', ['--help'], {
|
|
62
|
-
timeout: RESPONSE_TIMEOUT_MS
|
|
63
|
-
})
|
|
64
|
-
return { installed: true, output: stdout.trim() }
|
|
62
|
+
timeout: RESPONSE_TIMEOUT_MS,
|
|
63
|
+
});
|
|
64
|
+
return { installed: true, output: stdout.trim() };
|
|
65
65
|
} catch (error) {
|
|
66
66
|
return {
|
|
67
67
|
installed: false,
|
|
68
68
|
error: error.code === 'ENOENT'
|
|
69
69
|
? 'code-graph-mcp binary not found in PATH'
|
|
70
|
-
: `Binary check failed: ${error.message}
|
|
71
|
-
}
|
|
70
|
+
: `Binary check failed: ${error.message}`,
|
|
71
|
+
};
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function checkMcpConfig(projectRoot) {
|
|
76
|
-
const mcpJsonPath = join(projectRoot, '.mcp.json')
|
|
76
|
+
const mcpJsonPath = join(projectRoot, '.mcp.json');
|
|
77
77
|
if (!existsSync(mcpJsonPath)) {
|
|
78
|
-
return { configured: false, error: '.mcp.json not found' }
|
|
78
|
+
return { configured: false, error: '.mcp.json not found' };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
try {
|
|
82
|
-
const config = JSON.parse(readFileSync(mcpJsonPath, 'utf-8'))
|
|
83
|
-
const servers = config.mcpServers || {}
|
|
84
|
-
const codeGraphEntry = servers['code-graph'] || servers['code-graph-mcp']
|
|
82
|
+
const config = JSON.parse(readFileSync(mcpJsonPath, 'utf-8'));
|
|
83
|
+
const servers = config.mcpServers || {};
|
|
84
|
+
const codeGraphEntry = servers['code-graph'] || servers['code-graph-mcp'];
|
|
85
85
|
|
|
86
86
|
if (!codeGraphEntry) {
|
|
87
|
-
return { configured: false, error: 'No code-graph entry in .mcp.json mcpServers' }
|
|
87
|
+
return { configured: false, error: 'No code-graph entry in .mcp.json mcpServers' };
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return {
|
|
91
91
|
configured: true,
|
|
92
92
|
serverName: servers['code-graph'] ? 'code-graph' : 'code-graph-mcp',
|
|
93
|
-
config: codeGraphEntry
|
|
94
|
-
}
|
|
93
|
+
config: codeGraphEntry,
|
|
94
|
+
};
|
|
95
95
|
} catch (error) {
|
|
96
|
-
return { configured: false, error: `Failed to parse .mcp.json: ${error.message}` }
|
|
96
|
+
return { configured: false, error: `Failed to parse .mcp.json: ${error.message}` };
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
async function checkServerAndTools(projectRoot) {
|
|
101
|
-
const start = Date.now()
|
|
101
|
+
const start = Date.now();
|
|
102
102
|
try {
|
|
103
|
-
const child = execFile('code-graph-mcp', ['--project-root', projectRoot])
|
|
103
|
+
const child = execFile('code-graph-mcp', ['--project-root', projectRoot]);
|
|
104
104
|
|
|
105
105
|
return new Promise((resolvePromise) => {
|
|
106
|
-
let stdout = ''
|
|
107
|
-
let stderr = ''
|
|
108
|
-
let settled = false
|
|
106
|
+
let stdout = '';
|
|
107
|
+
let stderr = '';
|
|
108
|
+
let settled = false;
|
|
109
109
|
|
|
110
110
|
const settle = (result) => {
|
|
111
|
-
if (settled) return
|
|
112
|
-
settled = true
|
|
113
|
-
resolvePromise(result)
|
|
114
|
-
}
|
|
111
|
+
if (settled) return;
|
|
112
|
+
settled = true;
|
|
113
|
+
resolvePromise(result);
|
|
114
|
+
};
|
|
115
115
|
|
|
116
116
|
child.stdout.on('data', (data) => {
|
|
117
|
-
stdout += data.toString()
|
|
118
|
-
})
|
|
117
|
+
stdout += data.toString();
|
|
118
|
+
});
|
|
119
119
|
|
|
120
120
|
child.stderr.on('data', (data) => {
|
|
121
|
-
stderr += data.toString()
|
|
122
|
-
})
|
|
121
|
+
stderr += data.toString();
|
|
122
|
+
});
|
|
123
123
|
|
|
124
124
|
// Send MCP initialize + tools/list via JSON-RPC over stdio
|
|
125
125
|
const initMsg = JSON.stringify({
|
|
126
126
|
jsonrpc: '2.0', id: 1, method: 'initialize',
|
|
127
|
-
params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'health-check', version: '1.0' } }
|
|
128
|
-
})
|
|
129
|
-
const notifyMsg = JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' })
|
|
130
|
-
const listMsg = JSON.stringify({ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} })
|
|
127
|
+
params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'health-check', version: '1.0' } },
|
|
128
|
+
});
|
|
129
|
+
const notifyMsg = JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' });
|
|
130
|
+
const listMsg = JSON.stringify({ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} });
|
|
131
131
|
|
|
132
|
-
child.stdin.write(initMsg + '\n')
|
|
133
|
-
child.stdin.write(notifyMsg + '\n')
|
|
134
|
-
child.stdin.write(listMsg + '\n')
|
|
132
|
+
child.stdin.write(initMsg + '\n');
|
|
133
|
+
child.stdin.write(notifyMsg + '\n');
|
|
134
|
+
child.stdin.write(listMsg + '\n');
|
|
135
135
|
|
|
136
136
|
// Parse JSON-RPC responses as they arrive
|
|
137
|
-
let responseCount = 0
|
|
138
|
-
let actualTools = null
|
|
137
|
+
let responseCount = 0;
|
|
138
|
+
let actualTools = null;
|
|
139
139
|
|
|
140
140
|
const checkResponses = () => {
|
|
141
|
-
const lines = stdout.split('\n').filter((l) => l.trim())
|
|
141
|
+
const lines = stdout.split('\n').filter((l) => l.trim());
|
|
142
142
|
for (const line of lines) {
|
|
143
143
|
try {
|
|
144
|
-
const msg = JSON.parse(line)
|
|
145
|
-
if (msg.id === 1) responseCount
|
|
144
|
+
const msg = JSON.parse(line);
|
|
145
|
+
if (msg.id === 1) responseCount++;
|
|
146
146
|
if (msg.id === 2 && msg.result && msg.result.tools) {
|
|
147
|
-
responseCount
|
|
148
|
-
actualTools = msg.result.tools.map((t) => t.name)
|
|
147
|
+
responseCount++;
|
|
148
|
+
actualTools = msg.result.tools.map((t) => t.name);
|
|
149
149
|
}
|
|
150
150
|
} catch {
|
|
151
151
|
// partial line
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
}
|
|
154
|
+
};
|
|
155
155
|
|
|
156
156
|
// Poll for responses, timeout after RESPONSE_TIMEOUT_MS
|
|
157
157
|
const pollInterval = setInterval(() => {
|
|
158
|
-
checkResponses()
|
|
158
|
+
checkResponses();
|
|
159
159
|
if (responseCount >= 2) {
|
|
160
|
-
clearInterval(pollInterval)
|
|
161
|
-
clearTimeout(timer)
|
|
162
|
-
child.kill('SIGTERM')
|
|
160
|
+
clearInterval(pollInterval);
|
|
161
|
+
clearTimeout(timer);
|
|
162
|
+
child.kill('SIGTERM');
|
|
163
163
|
|
|
164
164
|
const toolReport = EXPECTED_TOOLS.map((name) => ({
|
|
165
165
|
name,
|
|
166
|
-
available: actualTools ? actualTools.includes(name) : false
|
|
167
|
-
}))
|
|
166
|
+
available: actualTools ? actualTools.includes(name) : false,
|
|
167
|
+
}));
|
|
168
168
|
|
|
169
169
|
settle({
|
|
170
170
|
responding: true,
|
|
171
171
|
responseTimeMs: Date.now() - start,
|
|
172
172
|
tools: toolReport,
|
|
173
173
|
actualToolCount: actualTools ? actualTools.length : 0,
|
|
174
|
-
note: 'Server responded via JSON-RPC, tools verified via tools/list'
|
|
175
|
-
})
|
|
174
|
+
note: 'Server responded via JSON-RPC, tools verified via tools/list',
|
|
175
|
+
});
|
|
176
176
|
}
|
|
177
|
-
}, 200)
|
|
177
|
+
}, 200);
|
|
178
178
|
|
|
179
179
|
const timer = setTimeout(() => {
|
|
180
|
-
clearInterval(pollInterval)
|
|
181
|
-
child.kill('SIGTERM')
|
|
182
|
-
checkResponses()
|
|
180
|
+
clearInterval(pollInterval);
|
|
181
|
+
child.kill('SIGTERM');
|
|
182
|
+
checkResponses();
|
|
183
183
|
|
|
184
184
|
// If we got at least the init response, server is alive
|
|
185
185
|
if (responseCount >= 1) {
|
|
@@ -188,59 +188,59 @@ async function checkServerAndTools(projectRoot) {
|
|
|
188
188
|
responseTimeMs: Date.now() - start,
|
|
189
189
|
tools: EXPECTED_TOOLS.map((name) => ({ name, available: true })),
|
|
190
190
|
actualToolCount: EXPECTED_TOOLS.length,
|
|
191
|
-
note: 'Server responded to initialize but tools/list timed out; using expected tool list'
|
|
192
|
-
})
|
|
191
|
+
note: 'Server responded to initialize but tools/list timed out; using expected tool list',
|
|
192
|
+
});
|
|
193
193
|
} else {
|
|
194
194
|
settle({
|
|
195
195
|
responding: false,
|
|
196
196
|
responseTimeMs: Date.now() - start,
|
|
197
197
|
tools: EXPECTED_TOOLS.map((name) => ({ name, available: false })),
|
|
198
198
|
actualToolCount: 0,
|
|
199
|
-
error: 'Server did not respond within timeout'
|
|
200
|
-
})
|
|
199
|
+
error: 'Server did not respond within timeout',
|
|
200
|
+
});
|
|
201
201
|
}
|
|
202
|
-
}, RESPONSE_TIMEOUT_MS)
|
|
202
|
+
}, RESPONSE_TIMEOUT_MS);
|
|
203
203
|
|
|
204
204
|
child.on('error', (error) => {
|
|
205
|
-
clearInterval(pollInterval)
|
|
206
|
-
clearTimeout(timer)
|
|
205
|
+
clearInterval(pollInterval);
|
|
206
|
+
clearTimeout(timer);
|
|
207
207
|
settle({
|
|
208
208
|
responding: false,
|
|
209
209
|
responseTimeMs: Date.now() - start,
|
|
210
210
|
tools: EXPECTED_TOOLS.map((name) => ({ name, available: false })),
|
|
211
211
|
actualToolCount: 0,
|
|
212
|
-
error: `Server failed to start: ${error.message}
|
|
213
|
-
})
|
|
214
|
-
})
|
|
212
|
+
error: `Server failed to start: ${error.message}`,
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
215
|
|
|
216
216
|
child.on('exit', (code) => {
|
|
217
|
-
clearInterval(pollInterval)
|
|
218
|
-
clearTimeout(timer)
|
|
217
|
+
clearInterval(pollInterval);
|
|
218
|
+
clearTimeout(timer);
|
|
219
219
|
if (code !== null && code !== 0) {
|
|
220
220
|
settle({
|
|
221
221
|
responding: false,
|
|
222
222
|
responseTimeMs: Date.now() - start,
|
|
223
223
|
tools: EXPECTED_TOOLS.map((name) => ({ name, available: false })),
|
|
224
224
|
actualToolCount: 0,
|
|
225
|
-
error: `Server exited with code ${code}. stderr: ${stderr}
|
|
226
|
-
})
|
|
225
|
+
error: `Server exited with code ${code}. stderr: ${stderr}`,
|
|
226
|
+
});
|
|
227
227
|
}
|
|
228
|
-
})
|
|
229
|
-
})
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
230
|
} catch (error) {
|
|
231
231
|
return {
|
|
232
232
|
responding: false,
|
|
233
233
|
responseTimeMs: Date.now() - start,
|
|
234
234
|
tools: EXPECTED_TOOLS.map((name) => ({ name, available: false })),
|
|
235
235
|
actualToolCount: 0,
|
|
236
|
-
error: `Server check failed: ${error.message}
|
|
237
|
-
}
|
|
236
|
+
error: `Server check failed: ${error.message}`,
|
|
237
|
+
};
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
async function runHealthCheck() {
|
|
242
|
-
const { smoke, projectRoot } = parseArgs()
|
|
243
|
-
const resolvedRoot = resolve(projectRoot)
|
|
242
|
+
const { smoke, projectRoot } = parseArgs();
|
|
243
|
+
const resolvedRoot = resolve(projectRoot);
|
|
244
244
|
|
|
245
245
|
const report = {
|
|
246
246
|
status: 'unknown',
|
|
@@ -251,64 +251,64 @@ async function runHealthCheck() {
|
|
|
251
251
|
checks: {},
|
|
252
252
|
tools: [],
|
|
253
253
|
responseTimeMs: null,
|
|
254
|
-
errors: []
|
|
255
|
-
}
|
|
254
|
+
errors: [],
|
|
255
|
+
};
|
|
256
256
|
|
|
257
257
|
// Check 1: Binary installed
|
|
258
|
-
const binaryCheck = await checkBinaryInstalled()
|
|
259
|
-
report.checks.binaryInstalled = binaryCheck.installed
|
|
258
|
+
const binaryCheck = await checkBinaryInstalled();
|
|
259
|
+
report.checks.binaryInstalled = binaryCheck.installed;
|
|
260
260
|
if (!binaryCheck.installed) {
|
|
261
|
-
report.status = 'unavailable'
|
|
262
|
-
report.errors.push(binaryCheck.error)
|
|
263
|
-
outputReport(report, 2)
|
|
264
|
-
return
|
|
261
|
+
report.status = 'unavailable';
|
|
262
|
+
report.errors.push(binaryCheck.error);
|
|
263
|
+
outputReport(report, 2);
|
|
264
|
+
return;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
// Check 2: MCP config present
|
|
268
|
-
const configCheck = checkMcpConfig(resolvedRoot)
|
|
269
|
-
report.checks.mcpConfigured = configCheck.configured
|
|
268
|
+
const configCheck = checkMcpConfig(resolvedRoot);
|
|
269
|
+
report.checks.mcpConfigured = configCheck.configured;
|
|
270
270
|
if (!configCheck.configured) {
|
|
271
|
-
report.errors.push(configCheck.error)
|
|
271
|
+
report.errors.push(configCheck.error);
|
|
272
272
|
// Not a blocker — binary works, just no MCP config
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
// Check 3: Server responds and tools verified via MCP tools/list
|
|
276
|
-
const serverCheck = await checkServerAndTools(resolvedRoot)
|
|
277
|
-
report.checks.serverResponding = serverCheck.responding
|
|
278
|
-
report.responseTimeMs = serverCheck.responseTimeMs
|
|
276
|
+
const serverCheck = await checkServerAndTools(resolvedRoot);
|
|
277
|
+
report.checks.serverResponding = serverCheck.responding;
|
|
278
|
+
report.responseTimeMs = serverCheck.responseTimeMs;
|
|
279
279
|
|
|
280
280
|
if (!serverCheck.responding) {
|
|
281
|
-
report.status = 'unavailable'
|
|
282
|
-
report.errors.push(serverCheck.error)
|
|
283
|
-
report.tools = serverCheck.tools
|
|
284
|
-
outputReport(report, 2)
|
|
285
|
-
return
|
|
281
|
+
report.status = 'unavailable';
|
|
282
|
+
report.errors.push(serverCheck.error);
|
|
283
|
+
report.tools = serverCheck.tools;
|
|
284
|
+
outputReport(report, 2);
|
|
285
|
+
return;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
// Tool report from real MCP tools/list query
|
|
289
|
-
report.tools = serverCheck.tools
|
|
290
|
-
const availableCount = report.tools.filter((t) => t.available).length
|
|
289
|
+
report.tools = serverCheck.tools;
|
|
290
|
+
const availableCount = report.tools.filter((t) => t.available).length;
|
|
291
291
|
|
|
292
292
|
if (availableCount === EXPECTED_TOOLS.length) {
|
|
293
|
-
report.status = 'available'
|
|
293
|
+
report.status = 'available';
|
|
294
294
|
} else if (availableCount > 0) {
|
|
295
|
-
report.status = 'degraded'
|
|
295
|
+
report.status = 'degraded';
|
|
296
296
|
} else {
|
|
297
|
-
report.status = 'unavailable'
|
|
297
|
+
report.status = 'unavailable';
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
// Version detection (try pip, fallback to python -m pip for Windows compatibility)
|
|
301
301
|
for (const cmd of [
|
|
302
302
|
{ file: 'pip', args: ['show', 'code-graph-mcp', '--no-color'] },
|
|
303
303
|
{ file: 'python', args: ['-m', 'pip', 'show', 'code-graph-mcp', '--no-color'] },
|
|
304
|
-
{ file: 'python3', args: ['-m', 'pip', 'show', 'code-graph-mcp', '--no-color'] }
|
|
304
|
+
{ file: 'python3', args: ['-m', 'pip', 'show', 'code-graph-mcp', '--no-color'] },
|
|
305
305
|
]) {
|
|
306
306
|
try {
|
|
307
|
-
const { stdout } = await execFileAsync(cmd.file, cmd.args, { timeout: 5000 })
|
|
308
|
-
const versionMatch = stdout.match(/Version:\s*(.+)/)
|
|
307
|
+
const { stdout } = await execFileAsync(cmd.file, cmd.args, { timeout: 5000 });
|
|
308
|
+
const versionMatch = stdout.match(/Version:\s*(.+)/);
|
|
309
309
|
if (versionMatch) {
|
|
310
|
-
report.version = versionMatch[1].trim()
|
|
311
|
-
break
|
|
310
|
+
report.version = versionMatch[1].trim();
|
|
311
|
+
break;
|
|
312
312
|
}
|
|
313
313
|
} catch {
|
|
314
314
|
// Try next command
|
|
@@ -323,21 +323,21 @@ async function runHealthCheck() {
|
|
|
323
323
|
'Use find_definition tool with symbol "UnifiedActivationPipeline"',
|
|
324
324
|
'Use find_references tool with symbol "entity-registry"',
|
|
325
325
|
'Use dependency_analysis tool on ".aios-core/core/"',
|
|
326
|
-
'Use project_statistics tool on project root'
|
|
327
|
-
]
|
|
328
|
-
}
|
|
326
|
+
'Use project_statistics tool on project root',
|
|
327
|
+
],
|
|
328
|
+
};
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
const exitCode = report.status === 'available' ? 0
|
|
332
332
|
: report.status === 'degraded' ? 1
|
|
333
|
-
|
|
333
|
+
: 2;
|
|
334
334
|
|
|
335
|
-
outputReport(report, exitCode)
|
|
335
|
+
outputReport(report, exitCode);
|
|
336
336
|
}
|
|
337
337
|
|
|
338
338
|
function outputReport(report, exitCode) {
|
|
339
|
-
console.log(JSON.stringify(report, null, 2))
|
|
340
|
-
process.exit(exitCode)
|
|
339
|
+
console.log(JSON.stringify(report, null, 2));
|
|
340
|
+
process.exit(exitCode);
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
runHealthCheck()
|
|
343
|
+
runHealthCheck();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const { validateManifest } = require('./validate-manifest');
|
|
6
|
+
const { generateManifest, writeManifest } = require('./generate-install-manifest');
|
|
7
|
+
|
|
8
|
+
function getStagedFiles() {
|
|
9
|
+
try {
|
|
10
|
+
const output = execSync('git diff --cached --name-only', { encoding: 'utf8' }).trim();
|
|
11
|
+
if (!output) return [];
|
|
12
|
+
return output.split('\n').map((line) => line.trim()).filter(Boolean);
|
|
13
|
+
} catch (_error) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function shouldCheckManifest(stagedFiles) {
|
|
19
|
+
if (stagedFiles.length === 0) return false;
|
|
20
|
+
|
|
21
|
+
return stagedFiles.some((file) => {
|
|
22
|
+
if (file === '.aios-core/install-manifest.yaml') return false;
|
|
23
|
+
return file.startsWith('.aios-core/');
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function main() {
|
|
28
|
+
const stagedFiles = getStagedFiles();
|
|
29
|
+
if (!shouldCheckManifest(stagedFiles)) {
|
|
30
|
+
console.log('ℹ️ manifest: no .aios-core changes staged, skipping check');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const result = validateManifest();
|
|
35
|
+
if (result.valid) {
|
|
36
|
+
console.log('✅ manifest: already up-to-date');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log('🔄 manifest: outdated, regenerating...');
|
|
41
|
+
const manifest = await generateManifest();
|
|
42
|
+
await writeManifest(manifest);
|
|
43
|
+
execSync('git add .aios-core/install-manifest.yaml', { stdio: 'inherit' });
|
|
44
|
+
console.log('✅ manifest: regenerated and staged');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (require.main === module) {
|
|
48
|
+
main().catch((error) => {
|
|
49
|
+
console.error(`❌ manifest: ensure failed - ${error.message}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
getStagedFiles,
|
|
56
|
+
shouldCheckManifest,
|
|
57
|
+
main,
|
|
58
|
+
};
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Windsurf Transformer - XML-tagged markdown sections
|
|
3
|
-
* @story 6.19 - IDE Command Auto-Sync System
|
|
4
|
-
*
|
|
5
|
-
* Format: Markdown with XML tags for agent sections
|
|
6
|
-
* Target: .windsurf/rules/agents/*.md
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { getVisibleCommands, normalizeCommands } = require('../agent-parser');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Transform agent data to Windsurf format
|
|
13
|
-
* @param {object} agentData - Parsed agent data from agent-parser
|
|
14
|
-
* @returns {string} - Transformed content
|
|
15
|
-
*/
|
|
16
|
-
function transform(agentData) {
|
|
17
|
-
const agent = agentData.agent || {};
|
|
18
|
-
const persona = agentData.persona_profile || {};
|
|
19
|
-
|
|
20
|
-
const icon = agent.icon || '🤖';
|
|
21
|
-
const name = agent.name || agentData.id;
|
|
22
|
-
const title = agent.title || 'AIOS Agent';
|
|
23
|
-
const whenToUse = agent.whenToUse || 'Use this agent for specific tasks';
|
|
24
|
-
const archetype = persona.archetype || '';
|
|
25
|
-
|
|
26
|
-
// Get all commands (normalized to consistent format)
|
|
27
|
-
const allCommands = normalizeCommands(agentData.commands || []);
|
|
28
|
-
const quickCommands = getVisibleCommands(allCommands, 'quick');
|
|
29
|
-
|
|
30
|
-
// Build content with XML tags
|
|
31
|
-
let content = `# ${name} Agent
|
|
32
|
-
|
|
33
|
-
<agent-identity>
|
|
34
|
-
${icon} **${name}** - ${title}
|
|
35
|
-
ID: @${agentData.id}
|
|
36
|
-
${archetype ? `Archetype: ${archetype}` : ''}
|
|
37
|
-
</agent-identity>
|
|
38
|
-
|
|
39
|
-
<when-to-use>
|
|
40
|
-
${whenToUse}
|
|
41
|
-
</when-to-use>
|
|
42
|
-
|
|
43
|
-
`;
|
|
44
|
-
|
|
45
|
-
// Add commands section with XML tags
|
|
46
|
-
if (allCommands.length > 0) {
|
|
47
|
-
content += `<commands>
|
|
48
|
-
`;
|
|
49
|
-
for (const cmd of allCommands) {
|
|
50
|
-
const isQuick = quickCommands.some(q => q.name === cmd.name);
|
|
51
|
-
content += `- *${cmd.name}: ${cmd.description || 'No description'}${isQuick ? ' (quick)' : ''}\n`;
|
|
52
|
-
}
|
|
53
|
-
content += `</commands>
|
|
54
|
-
|
|
55
|
-
`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Add collaboration section if available
|
|
59
|
-
if (agentData.sections.collaboration) {
|
|
60
|
-
content += `<collaboration>
|
|
61
|
-
${agentData.sections.collaboration}
|
|
62
|
-
</collaboration>
|
|
63
|
-
|
|
64
|
-
`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Add dependencies if available
|
|
68
|
-
if (agentData.dependencies) {
|
|
69
|
-
const deps = agentData.dependencies;
|
|
70
|
-
content += `<dependencies>
|
|
71
|
-
`;
|
|
72
|
-
if (deps.tasks && deps.tasks.length > 0) {
|
|
73
|
-
content += `Tasks: ${deps.tasks.join(', ')}\n`;
|
|
74
|
-
}
|
|
75
|
-
if (deps.checklists && deps.checklists.length > 0) {
|
|
76
|
-
content += `Checklists: ${deps.checklists.join(', ')}\n`;
|
|
77
|
-
}
|
|
78
|
-
if (deps.tools && deps.tools.length > 0) {
|
|
79
|
-
content += `Tools: ${deps.tools.join(', ')}\n`;
|
|
80
|
-
}
|
|
81
|
-
content += `</dependencies>
|
|
82
|
-
|
|
83
|
-
`;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
content += `---
|
|
87
|
-
*Synced from .aios-core/development/agents/${agentData.filename}*
|
|
88
|
-
`;
|
|
89
|
-
|
|
90
|
-
return content;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Get the target filename for this agent
|
|
95
|
-
* @param {object} agentData - Parsed agent data
|
|
96
|
-
* @returns {string} - Target filename
|
|
97
|
-
*/
|
|
98
|
-
function getFilename(agentData) {
|
|
99
|
-
return agentData.filename;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
module.exports = {
|
|
103
|
-
transform,
|
|
104
|
-
getFilename,
|
|
105
|
-
format: 'xml-tagged-markdown',
|
|
106
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# Synkra AIOS Development Rules for Cline
|
|
2
|
-
|
|
3
|
-
You are working with Synkra AIOS, an AI-Orchestrated System for Full Stack Development.
|
|
4
|
-
|
|
5
|
-
## Core Framework Understanding
|
|
6
|
-
|
|
7
|
-
Synkra AIOS is a meta-framework that orchestrates AI agents to handle complex development workflows. Always recognize and work within this architecture.
|
|
8
|
-
|
|
9
|
-
## Agent System
|
|
10
|
-
|
|
11
|
-
### Agent Activation
|
|
12
|
-
- Agents are activated with @agent-name syntax: @dev, @qa, @architect, @pm, @po, @sm, @analyst
|
|
13
|
-
- The master agent is activated with @aios-master
|
|
14
|
-
- Agent commands use the * prefix: *help, *create-story, *task, *exit
|
|
15
|
-
|
|
16
|
-
### Agent Context
|
|
17
|
-
When an agent is active:
|
|
18
|
-
- Follow that agent's specific persona and expertise
|
|
19
|
-
- Use the agent's designated workflow patterns
|
|
20
|
-
- Maintain the agent's perspective throughout the interaction
|
|
21
|
-
|
|
22
|
-
## Development Methodology
|
|
23
|
-
|
|
24
|
-
### Story-Driven Development
|
|
25
|
-
1. **Work from stories** - All development starts with a story in `docs/stories/`
|
|
26
|
-
2. **Update progress** - Mark checkboxes as tasks complete: [ ] → [x]
|
|
27
|
-
3. **Track changes** - Maintain the File List section in the story
|
|
28
|
-
4. **Follow criteria** - Implement exactly what the acceptance criteria specify
|
|
29
|
-
|
|
30
|
-
### Code Standards
|
|
31
|
-
- Write clean, self-documenting code
|
|
32
|
-
- Follow existing patterns in the codebase
|
|
33
|
-
- Include comprehensive error handling
|
|
34
|
-
- Add unit tests for all new functionality
|
|
35
|
-
- Use TypeScript/JavaScript best practices
|
|
36
|
-
|
|
37
|
-
### Testing Requirements
|
|
38
|
-
- Run all tests before marking tasks complete
|
|
39
|
-
- Ensure linting passes: `npm run lint`
|
|
40
|
-
- Verify type checking: `npm run typecheck`
|
|
41
|
-
- Add tests for new features
|
|
42
|
-
- Test edge cases and error scenarios
|
|
43
|
-
|
|
44
|
-
## AIOS Framework Structure
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
aios-core/
|
|
48
|
-
├── agents/ # Agent persona definitions (YAML/Markdown)
|
|
49
|
-
├── tasks/ # Executable task workflows
|
|
50
|
-
├── workflows/ # Multi-step workflow definitions
|
|
51
|
-
├── templates/ # Document and code templates
|
|
52
|
-
├── checklists/ # Validation and review checklists
|
|
53
|
-
└── rules/ # Framework rules and patterns
|
|
54
|
-
|
|
55
|
-
docs/
|
|
56
|
-
├── stories/ # Development stories (numbered)
|
|
57
|
-
├── prd/ # Product requirement documents
|
|
58
|
-
├── architecture/ # System architecture documentation
|
|
59
|
-
└── guides/ # User and developer guides
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Cline-Specific Configuration
|
|
63
|
-
|
|
64
|
-
### Agent Rules Location
|
|
65
|
-
- Rules are stored in `.cline/rules/`
|
|
66
|
-
- Use @agent-name to activate agents in chat
|
|
67
|
-
|
|
68
|
-
### Tool Permissions
|
|
69
|
-
Cline requires explicit approval for:
|
|
70
|
-
- File creation/modification
|
|
71
|
-
- Terminal commands
|
|
72
|
-
- Browser actions
|
|
73
|
-
|
|
74
|
-
### Performance Tips
|
|
75
|
-
- Use the task panel for complex multi-step operations
|
|
76
|
-
- Leverage diff view for reviewing changes
|
|
77
|
-
- Enable auto-approve for trusted operations
|
|
78
|
-
|
|
79
|
-
### MCP Integration
|
|
80
|
-
- Cline supports MCP servers for extended functionality
|
|
81
|
-
- Configure in Cline settings for additional tools
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
*Synkra AIOS Cline Configuration v4.0.4*
|