@adityaaria/agent-os 1.0.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/AGENTS.md +41 -0
- package/AGENT_OS_BOOTSTRAP.md +29 -0
- package/ENTRYPOINT.md +118 -0
- package/LICENSE +21 -0
- package/README.md +230 -0
- package/adapters/antigravity/README.md +9 -0
- package/adapters/antigravity/plugin.json +13 -0
- package/adapters/claude/CLAUDE.md +16 -0
- package/adapters/claude/README.md +10 -0
- package/adapters/codex/README.md +20 -0
- package/adapters/cursor/README.md +9 -0
- package/adapters/cursor/agent-os.rules.md +18 -0
- package/bin/agent-os.mjs +98 -0
- package/core/AUTO_PROJECT_DETECTOR.md +99 -0
- package/core/COMPLIANCE_GATE.md +19 -0
- package/core/FRAMEWORK_AUDITOR.md +35 -0
- package/core/KNOWLEDGE_REGENERATOR.md +30 -0
- package/core/KNOWLEDGE_VALIDATOR.md +29 -0
- package/core/PROJECT_CONTEXT_STANDARD.md +19 -0
- package/core/QUALITY_GATES.md +42 -0
- package/core/REPORTING_STANDARD.md +47 -0
- package/core/SKILL_ORCHESTRATOR.md +63 -0
- package/core/TASK_ROUTER.md +33 -0
- package/core/TRACEABILITY_STANDARD.md +40 -0
- package/package.json +28 -0
- package/scripts/install.mjs +690 -0
- package/scripts/lib/cli-utils.mjs +148 -0
- package/scripts/lib/run-utils.mjs +185 -0
- package/scripts/lib/telegram-audit-log.mjs +50 -0
- package/scripts/lib/telegram-bot-utils.mjs +413 -0
- package/scripts/lib/telegram-utils.mjs +127 -0
- package/scripts/orchestrate.mjs +230 -0
- package/scripts/quality-static.mjs +19 -0
- package/scripts/report-export.mjs +86 -0
- package/scripts/report-notify.mjs +169 -0
- package/scripts/run-execution.mjs +83 -0
- package/scripts/run-list.mjs +44 -0
- package/scripts/run-status.mjs +38 -0
- package/scripts/run-step.mjs +173 -0
- package/scripts/setup-wizard.mjs +116 -0
- package/scripts/sync-runtime.mjs +87 -0
- package/scripts/telegram-bot.mjs +88 -0
- package/scripts/telegram-check.mjs +94 -0
- package/scripts/telegram-poll.mjs +176 -0
- package/scripts/validate-framework.mjs +290 -0
- package/skills/api-contract-audit/SKILL.md +26 -0
- package/skills/api-contract-audit/checklist.md +16 -0
- package/skills/api-contract-audit/examples.md +3 -0
- package/skills/api-contract-audit/report-template.md +39 -0
- package/skills/api-contract-audit/workflow.md +15 -0
- package/skills/audit/SKILL.md +28 -0
- package/skills/audit/checklist.md +18 -0
- package/skills/audit/examples.md +26 -0
- package/skills/audit/report-template.md +39 -0
- package/skills/audit/workflow.md +15 -0
- package/skills/bug-fix/SKILL.md +25 -0
- package/skills/bug-fix/checklist.md +18 -0
- package/skills/bug-fix/examples.md +26 -0
- package/skills/bug-fix/report-template.md +39 -0
- package/skills/bug-fix/workflow.md +10 -0
- package/skills/database-impact-analysis/SKILL.md +27 -0
- package/skills/database-impact-analysis/checklist.md +16 -0
- package/skills/database-impact-analysis/examples.md +3 -0
- package/skills/database-impact-analysis/report-template.md +39 -0
- package/skills/database-impact-analysis/workflow.md +14 -0
- package/skills/enhancement/SKILL.md +27 -0
- package/skills/enhancement/checklist.md +19 -0
- package/skills/enhancement/examples.md +26 -0
- package/skills/enhancement/report-template.md +39 -0
- package/skills/enhancement/workflow.md +10 -0
- package/skills/enterprise-certification/SKILL.md +19 -0
- package/skills/enterprise-certification/checklist.md +17 -0
- package/skills/enterprise-certification/report-template.md +39 -0
- package/skills/enterprise-certification/workflow.md +14 -0
- package/skills/knowledge-evolution/SKILL.md +23 -0
- package/skills/knowledge-evolution/checklist.md +17 -0
- package/skills/knowledge-evolution/report-template.md +39 -0
- package/skills/knowledge-evolution/workflow.md +14 -0
- package/skills/new-page/SKILL.md +26 -0
- package/skills/new-page/checklist.md +21 -0
- package/skills/new-page/examples.md +26 -0
- package/skills/new-page/report-template.md +39 -0
- package/skills/new-page/workflow.md +10 -0
- package/skills/project-onboarding/SKILL.md +27 -0
- package/skills/project-onboarding/checklist.md +18 -0
- package/skills/project-onboarding/examples.md +26 -0
- package/skills/project-onboarding/report-template.md +39 -0
- package/skills/project-onboarding/workflow.md +9 -0
- package/skills/release-readiness/SKILL.md +27 -0
- package/skills/release-readiness/checklist.md +16 -0
- package/skills/release-readiness/examples.md +3 -0
- package/skills/release-readiness/report-template.md +39 -0
- package/skills/release-readiness/workflow.md +14 -0
- package/skills/repository-health/SKILL.md +26 -0
- package/skills/repository-health/checklist.md +20 -0
- package/skills/repository-health/report-template.md +39 -0
- package/skills/repository-health/workflow.md +14 -0
- package/skills/selenium-e2e/SKILL.md +83 -0
- package/skills/selenium-e2e/checklist.md +29 -0
- package/skills/selenium-e2e/examples.md +26 -0
- package/skills/selenium-e2e/report-template.md +39 -0
- package/skills/selenium-e2e/workflow.md +9 -0
- package/skills/self-audit/SKILL.md +19 -0
- package/skills/self-audit/checklist.md +14 -0
- package/skills/self-audit/report-template.md +39 -0
- package/skills/self-audit/workflow.md +11 -0
- package/skills/traceability-analysis/SKILL.md +25 -0
- package/skills/traceability-analysis/checklist.md +17 -0
- package/skills/traceability-analysis/examples.md +3 -0
- package/skills/traceability-analysis/report-template.md +39 -0
- package/skills/traceability-analysis/workflow.md +17 -0
- package/templates/API_RULES.md +20 -0
- package/templates/ARCHITECTURE.md +20 -0
- package/templates/BUSINESS_FLOW.md +20 -0
- package/templates/COMMANDS.md +20 -0
- package/templates/DATABASE_RULES.md +20 -0
- package/templates/DEPENDENCY_MAP.md +20 -0
- package/templates/DEPLOYMENT_RULES.md +20 -0
- package/templates/DOMAIN_MODEL.md +20 -0
- package/templates/FE_BE_TRACEABILITY.md +20 -0
- package/templates/KNOWN_LIMITATIONS.md +20 -0
- package/templates/MODULE_CATALOG.md +20 -0
- package/templates/PROJECT_PROFILE.md +20 -0
- package/templates/RISK_REGISTER.md +20 -0
- package/templates/SECURITY_RULES.md +20 -0
- package/templates/TECHNICAL_DEBT.md +20 -0
- package/templates/TECH_STACK.md +20 -0
- package/templates/TESTING_RULES.md +47 -0
- package/templates/UI_UX_RULES.md +20 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { assertEnabledChannel, loadReportChannel } from './lib/run-utils.mjs';
|
|
5
|
+
import {
|
|
6
|
+
createTelegramAccessControl,
|
|
7
|
+
normalizeTelegramUpdates,
|
|
8
|
+
processTelegramUpdates,
|
|
9
|
+
readTelegramUpdatesFromFile,
|
|
10
|
+
writeTelegramBotOutput
|
|
11
|
+
} from './lib/telegram-bot-utils.mjs';
|
|
12
|
+
import { sendTelegramRequest, telegramEnv } from './lib/telegram-utils.mjs';
|
|
13
|
+
import { createCli, fail, failAll, resolveDefault, resolveDefaultPath, showHelp, wantsHelp } from './lib/cli-utils.mjs';
|
|
14
|
+
|
|
15
|
+
const { hasFlag, takeOption } = createCli(process.argv.slice(2));
|
|
16
|
+
|
|
17
|
+
if (wantsHelp(process.argv)) {
|
|
18
|
+
showHelp({
|
|
19
|
+
command: 'telegram-poll',
|
|
20
|
+
description: 'Poll Telegram for bot updates (one-shot)',
|
|
21
|
+
usage: [
|
|
22
|
+
'agent-os telegram-poll --send [options]',
|
|
23
|
+
'agent-os telegram-poll --dry-run [options]'
|
|
24
|
+
],
|
|
25
|
+
required: [
|
|
26
|
+
{ flag: '--send | --dry-run', desc: 'Send responses to Telegram, or write to file' },
|
|
27
|
+
{ flag: '--allowed-chat-id <ids>', desc: 'Comma-separated allowed Telegram chat IDs' }
|
|
28
|
+
],
|
|
29
|
+
options: [
|
|
30
|
+
{ flag: '--channel-config <file>', desc: 'Channel config file', default: '.agent-os/project/report-channels.json' },
|
|
31
|
+
{ flag: '--channel <name>', desc: 'Channel name', default: 'telegram' },
|
|
32
|
+
{ flag: '--run-root <dir>', desc: 'Run directory root', default: '.agent-os/runs' },
|
|
33
|
+
{ flag: '--state-file <file>', desc: 'Poll state file', default: '.agent-os/project/telegram-poll-state.json' },
|
|
34
|
+
{ flag: '--output <file>', desc: 'Override output path' },
|
|
35
|
+
{ flag: '--once', desc: 'Run once (default behavior)' }
|
|
36
|
+
],
|
|
37
|
+
examples: [
|
|
38
|
+
'agent-os telegram-poll --send --allowed-chat-id 12345',
|
|
39
|
+
'agent-os telegram-poll --dry-run --allowed-chat-id 12345,67890'
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const channelConfig = takeOption('--channel-config') ?? resolveDefault(null, '.agent-os/project/report-channels.json');
|
|
45
|
+
const channelName = takeOption('--channel') ?? 'telegram';
|
|
46
|
+
const allowedChatId = takeOption('--allowed-chat-id');
|
|
47
|
+
const runRoot = takeOption('--run-root') ?? resolveDefault(null, '.agent-os/runs');
|
|
48
|
+
const stateFile = takeOption('--state-file') ?? resolveDefaultPath(null, '.agent-os/project/telegram-poll-state.json');
|
|
49
|
+
const outputOverride = takeOption('--output');
|
|
50
|
+
const once = hasFlag('--once');
|
|
51
|
+
const dryRun = hasFlag('--dry-run');
|
|
52
|
+
const send = hasFlag('--send');
|
|
53
|
+
|
|
54
|
+
// Batched validation
|
|
55
|
+
const errors = [];
|
|
56
|
+
if (dryRun === send) errors.push('Use either --dry-run or --send (exactly one required).');
|
|
57
|
+
if (!channelConfig) errors.push('Missing --channel-config <file> (no default found at .agent-os/project/report-channels.json).');
|
|
58
|
+
if (!allowedChatId) errors.push('Missing --allowed-chat-id <id[,id]> (required, no default).');
|
|
59
|
+
if (!runRoot) errors.push('Missing --run-root <dir> (no default found at .agent-os/runs).');
|
|
60
|
+
if (!stateFile) errors.push('Missing --state-file <file>.');
|
|
61
|
+
failAll(errors, 'agent-os telegram-poll --send --allowed-chat-id 12345', 'telegram-poll');
|
|
62
|
+
|
|
63
|
+
let channelContext;
|
|
64
|
+
try {
|
|
65
|
+
channelContext = loadReportChannel(channelConfig, channelName);
|
|
66
|
+
assertEnabledChannel(channelContext);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
fail(err.message);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const channel = channelContext.channel;
|
|
72
|
+
if (channel.type !== 'telegram') {
|
|
73
|
+
fail(`Report channel is not a telegram channel: ${channelName}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const absoluteStateFile = path.resolve(process.cwd(), stateFile);
|
|
77
|
+
const { botTokenEnv, botToken } = telegramEnv(channel);
|
|
78
|
+
|
|
79
|
+
let updates;
|
|
80
|
+
const mockFile = channel.mockUpdatesFile;
|
|
81
|
+
|
|
82
|
+
let offset = null;
|
|
83
|
+
if (fs.existsSync(absoluteStateFile)) {
|
|
84
|
+
try {
|
|
85
|
+
const state = JSON.parse(fs.readFileSync(absoluteStateFile, 'utf8'));
|
|
86
|
+
offset = state.offset ?? null;
|
|
87
|
+
} catch {
|
|
88
|
+
offset = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (mockFile) {
|
|
93
|
+
updates = readTelegramUpdatesFromFile(mockFile, channelContext.outputBaseDir);
|
|
94
|
+
} else {
|
|
95
|
+
if (!botToken) {
|
|
96
|
+
fail(`Missing required environment variable: ${botTokenEnv}. Set it or add mockUpdatesFile to the channel config.`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const params = { timeout: 10, allowed_updates: ['message', 'callback_query'] };
|
|
100
|
+
if (offset !== null) params.offset = offset;
|
|
101
|
+
|
|
102
|
+
const result = await sendTelegramRequest({ channel, botToken, method: 'getUpdates', body: params });
|
|
103
|
+
updates = normalizeTelegramUpdates(result);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const pendingUpdates = offset !== null ? updates.filter((u) => u.update_id >= offset) : updates;
|
|
107
|
+
|
|
108
|
+
if (pendingUpdates.length > 0) {
|
|
109
|
+
const maxUpdateId = Math.max(...updates.map((u) => u.update_id));
|
|
110
|
+
fs.mkdirSync(path.dirname(absoluteStateFile), { recursive: true });
|
|
111
|
+
fs.writeFileSync(absoluteStateFile, JSON.stringify({ offset: maxUpdateId + 1 }) + '\n');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
const responses = processTelegramUpdates({
|
|
118
|
+
updates: pendingUpdates,
|
|
119
|
+
accessControl: createTelegramAccessControl({
|
|
120
|
+
allowedChatId,
|
|
121
|
+
roles: channel.roles
|
|
122
|
+
}),
|
|
123
|
+
runRoot,
|
|
124
|
+
channelConfig: channel,
|
|
125
|
+
auditRunRoot: runRoot
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
const outputPath = writeTelegramBotOutput({
|
|
130
|
+
channelContext,
|
|
131
|
+
channelName,
|
|
132
|
+
responses,
|
|
133
|
+
outputOverride,
|
|
134
|
+
mode: 'dry-run'
|
|
135
|
+
});
|
|
136
|
+
console.log(`Dry-run output: ${outputPath}`);
|
|
137
|
+
process.exit(0);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const { chatIdEnv, chatId } = telegramEnv(channel);
|
|
141
|
+
for (const response of responses) {
|
|
142
|
+
const targetChatId = response.chatId ?? chatId;
|
|
143
|
+
if (!targetChatId) {
|
|
144
|
+
console.error(`No chat ID for response. Set ${chatIdEnv} or ensure the update contains a chat ID.`);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const body = {
|
|
149
|
+
chat_id: targetChatId,
|
|
150
|
+
text: response.text,
|
|
151
|
+
parse_mode: 'MarkdownV2'
|
|
152
|
+
};
|
|
153
|
+
if (response.replyMarkup) body.reply_markup = response.replyMarkup;
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
await sendTelegramRequest({ channel, channelContext, botToken, method: 'sendMessage', body });
|
|
157
|
+
} catch (err) {
|
|
158
|
+
console.error(`Failed to send message to ${targetChatId}: ${err.message}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (response.callbackQueryId) {
|
|
162
|
+
try {
|
|
163
|
+
await sendTelegramRequest({
|
|
164
|
+
channel,
|
|
165
|
+
channelContext,
|
|
166
|
+
botToken,
|
|
167
|
+
method: 'answerCallbackQuery',
|
|
168
|
+
body: { callback_query_id: response.callbackQueryId }
|
|
169
|
+
});
|
|
170
|
+
} catch {
|
|
171
|
+
// Callback answer is best-effort
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
console.log(`Processed ${responses.length} response(s).`);
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { wantsHelp, showHelp } from './lib/cli-utils.mjs';
|
|
6
|
+
|
|
7
|
+
if (wantsHelp(process.argv)) {
|
|
8
|
+
showHelp({
|
|
9
|
+
command: 'validate',
|
|
10
|
+
description: 'Validate Agent OS framework structure and integrity',
|
|
11
|
+
usage: ['agent-os validate [--root <dir>]'],
|
|
12
|
+
options: [
|
|
13
|
+
{ flag: '--root <dir>', desc: 'Agent OS source root', default: '(auto-detected)' }
|
|
14
|
+
],
|
|
15
|
+
examples: [
|
|
16
|
+
'agent-os validate',
|
|
17
|
+
'agent-os validate --root /path/to/agent-os'
|
|
18
|
+
]
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
23
|
+
const defaultRepoRoot = path.resolve(path.dirname(__filename), '..');
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
const rootArgIndex = args.indexOf('--root');
|
|
26
|
+
const repoRoot = rootArgIndex === -1
|
|
27
|
+
? defaultRepoRoot
|
|
28
|
+
: path.resolve(process.cwd(), args[rootArgIndex + 1] ?? defaultRepoRoot);
|
|
29
|
+
|
|
30
|
+
const failures = [];
|
|
31
|
+
|
|
32
|
+
function exists(relativePath) {
|
|
33
|
+
return fs.existsSync(path.join(repoRoot, relativePath));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function fail(message) {
|
|
37
|
+
failures.push(message);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function requirePath(relativePath) {
|
|
41
|
+
if (!exists(relativePath)) fail(`Missing required path: ${relativePath}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function listDirs(relativePath) {
|
|
45
|
+
const absolutePath = path.join(repoRoot, relativePath);
|
|
46
|
+
if (!fs.existsSync(absolutePath)) return [];
|
|
47
|
+
return fs.readdirSync(absolutePath, { withFileTypes: true })
|
|
48
|
+
.filter((entry) => entry.isDirectory())
|
|
49
|
+
.map((entry) => entry.name)
|
|
50
|
+
.sort();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function listFilesRecursive(relativePath) {
|
|
54
|
+
const absolutePath = path.join(repoRoot, relativePath);
|
|
55
|
+
if (!fs.existsSync(absolutePath)) return [];
|
|
56
|
+
|
|
57
|
+
const entries = fs.readdirSync(absolutePath, { withFileTypes: true });
|
|
58
|
+
return entries.flatMap((entry) => {
|
|
59
|
+
const child = path.join(relativePath, entry.name);
|
|
60
|
+
if (entry.isDirectory()) return listFilesRecursive(child);
|
|
61
|
+
return child;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function validateCoreStructure() {
|
|
66
|
+
[
|
|
67
|
+
'AGENTS.md',
|
|
68
|
+
'ENTRYPOINT.md',
|
|
69
|
+
'AGENT_OS_BOOTSTRAP.md',
|
|
70
|
+
'plugin.json',
|
|
71
|
+
'core/TASK_ROUTER.md',
|
|
72
|
+
'core/QUALITY_GATES.md',
|
|
73
|
+
'core/SKILL_ORCHESTRATOR.md',
|
|
74
|
+
'.github/workflows/validate.yml',
|
|
75
|
+
'bin/agent-os.mjs',
|
|
76
|
+
'scripts/install.mjs',
|
|
77
|
+
'scripts/lib/run-utils.mjs',
|
|
78
|
+
'scripts/orchestrate.mjs',
|
|
79
|
+
'scripts/run-list.mjs',
|
|
80
|
+
'scripts/run-status.mjs',
|
|
81
|
+
'scripts/run-step.mjs',
|
|
82
|
+
'scripts/sync-runtime.mjs',
|
|
83
|
+
'scripts/validate-framework.mjs',
|
|
84
|
+
'templates/PROJECT_PROFILE.md',
|
|
85
|
+
'skills/enhancement/SKILL.md'
|
|
86
|
+
].forEach(requirePath);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function validateDeveloperWorkflow() {
|
|
90
|
+
const packageJsonPath = path.join(repoRoot, 'package.json');
|
|
91
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
92
|
+
fail('Missing package.json.');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
97
|
+
if (packageJson.bin?.['agent-os'] !== 'bin/agent-os.mjs') {
|
|
98
|
+
fail('package.json must expose bin.agent-os as bin/agent-os.mjs');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const script of ['test', 'validate', 'sync:runtime']) {
|
|
102
|
+
if (!packageJson.scripts?.[script]) fail(`package.json missing required script: ${script}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const workflowPath = path.join(repoRoot, '.github/workflows/validate.yml');
|
|
106
|
+
if (fs.existsSync(workflowPath)) {
|
|
107
|
+
const workflow = fs.readFileSync(workflowPath, 'utf8');
|
|
108
|
+
for (const command of ['npm run sync:runtime', 'npm test', 'npm run validate']) {
|
|
109
|
+
if (!workflow.includes(command)) fail(`CI workflow missing command: ${command}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const gitignorePath = path.join(repoRoot, '.gitignore');
|
|
114
|
+
if (fs.existsSync(gitignorePath)) {
|
|
115
|
+
const gitignore = fs.readFileSync(gitignorePath, 'utf8');
|
|
116
|
+
if (!/^\.DS_Store$/m.test(gitignore)) fail('.gitignore must ignore .DS_Store');
|
|
117
|
+
} else {
|
|
118
|
+
fail('Missing .gitignore');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function validateRuntimeStructure() {
|
|
123
|
+
[
|
|
124
|
+
'.agent-os/ENTRYPOINT.md',
|
|
125
|
+
'.agent-os/core/TASK_ROUTER.md',
|
|
126
|
+
'.agent-os/project',
|
|
127
|
+
'.agent-os/project/PROJECT_PROFILE.md',
|
|
128
|
+
'.agent-os/project/TECH_STACK.md',
|
|
129
|
+
'.agent-os/project/ARCHITECTURE.md',
|
|
130
|
+
'.agent-os/project/WORKSPACE_MAP.md',
|
|
131
|
+
'.agent-os/skills/enhancement/SKILL.md'
|
|
132
|
+
].forEach(requirePath);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function validateSkillAnatomy() {
|
|
136
|
+
const skills = listDirs('skills');
|
|
137
|
+
if (skills.length === 0) {
|
|
138
|
+
fail('No skills found in root skills directory.');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const skill of skills) {
|
|
143
|
+
for (const file of ['SKILL.md', 'workflow.md', 'checklist.md', 'report-template.md']) {
|
|
144
|
+
requirePath(`skills/${skill}/${file}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function validateRuntimeSkillSync() {
|
|
150
|
+
const sourceSkills = listDirs('skills');
|
|
151
|
+
const runtimeSkills = listDirs('.agent-os/skills');
|
|
152
|
+
|
|
153
|
+
const sourceOnly = sourceSkills.filter((skill) => !runtimeSkills.includes(skill));
|
|
154
|
+
const runtimeOnly = runtimeSkills.filter((skill) => !sourceSkills.includes(skill));
|
|
155
|
+
|
|
156
|
+
for (const skill of sourceOnly) fail(`Runtime skills missing source skill: ${skill}`);
|
|
157
|
+
for (const skill of runtimeOnly) fail(`Runtime skills contain unknown skill: ${skill}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function validateReportTemplates() {
|
|
161
|
+
const requiredSections = [
|
|
162
|
+
'Executive Summary',
|
|
163
|
+
'Scope',
|
|
164
|
+
'Knowledge Confidence',
|
|
165
|
+
'Knowledge Classification',
|
|
166
|
+
'Traceability Matrix',
|
|
167
|
+
'Evidence',
|
|
168
|
+
'Root Cause',
|
|
169
|
+
'Impact',
|
|
170
|
+
'Recommendation',
|
|
171
|
+
'Quality Gate',
|
|
172
|
+
'Enterprise Readiness',
|
|
173
|
+
'Final Decision'
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
const reportTemplates = [
|
|
177
|
+
...listFilesRecursive('skills'),
|
|
178
|
+
...listFilesRecursive('.agent-os/skills')
|
|
179
|
+
].filter((file) => file.endsWith('report-template.md'));
|
|
180
|
+
|
|
181
|
+
for (const file of reportTemplates) {
|
|
182
|
+
const content = fs.readFileSync(path.join(repoRoot, file), 'utf8');
|
|
183
|
+
for (const section of requiredSections) {
|
|
184
|
+
const sectionPattern = new RegExp(`^# ${section}$`, 'm');
|
|
185
|
+
if (!sectionPattern.test(content)) {
|
|
186
|
+
fail(`${file} missing required report section: ${section}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function validateNoForbiddenPlaceholders() {
|
|
193
|
+
const forbidden = [
|
|
194
|
+
'[TBD]',
|
|
195
|
+
'[Placeholder]',
|
|
196
|
+
'[List Here]',
|
|
197
|
+
'[Describe Here]',
|
|
198
|
+
'[0-100]',
|
|
199
|
+
'[Any Generic Text]',
|
|
200
|
+
'<Detail>'
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
const files = [
|
|
204
|
+
...listFilesRecursive('core'),
|
|
205
|
+
...listFilesRecursive('skills'),
|
|
206
|
+
...listFilesRecursive('templates'),
|
|
207
|
+
...listFilesRecursive('.agent-os/core')
|
|
208
|
+
].filter((file) => file.endsWith('.md'));
|
|
209
|
+
|
|
210
|
+
for (const file of files) {
|
|
211
|
+
const content = fs.readFileSync(path.join(repoRoot, file), 'utf8');
|
|
212
|
+
for (const token of forbidden) {
|
|
213
|
+
if (content.includes(token)) {
|
|
214
|
+
fail(`Forbidden placeholder ${token} found in ${file}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function validateEntrypointIntegrity() {
|
|
221
|
+
const coreFiles = [
|
|
222
|
+
'AGENTS.md',
|
|
223
|
+
'core/COMPLIANCE_GATE.md',
|
|
224
|
+
'core/AUTO_PROJECT_DETECTOR.md',
|
|
225
|
+
'core/KNOWLEDGE_VALIDATOR.md',
|
|
226
|
+
'core/KNOWLEDGE_REGENERATOR.md',
|
|
227
|
+
'core/SKILL_ORCHESTRATOR.md',
|
|
228
|
+
'core/TASK_ROUTER.md',
|
|
229
|
+
'core/QUALITY_GATES.md',
|
|
230
|
+
'core/TRACEABILITY_STANDARD.md',
|
|
231
|
+
'core/REPORTING_STANDARD.md'
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
let allPresent = true;
|
|
235
|
+
for (const file of coreFiles) {
|
|
236
|
+
if (!exists(file)) {
|
|
237
|
+
fail(`FAIL [entrypoint-integrity]: Missing core file: ${file}`);
|
|
238
|
+
allPresent = false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (allPresent) {
|
|
242
|
+
console.log('PASS [entrypoint-integrity]: All 10 core files present');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const warnings = [];
|
|
247
|
+
|
|
248
|
+
function warn(message) {
|
|
249
|
+
warnings.push(message);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function validateSkillComplianceCheck() {
|
|
253
|
+
const skills = listDirs('skills');
|
|
254
|
+
const requiredHeadings = ['Purpose', 'Responsibilities', 'Workflow'];
|
|
255
|
+
|
|
256
|
+
for (const skill of skills) {
|
|
257
|
+
const skillPath = `skills/${skill}/SKILL.md`;
|
|
258
|
+
if (!exists(skillPath)) continue;
|
|
259
|
+
|
|
260
|
+
const content = fs.readFileSync(path.join(repoRoot, skillPath), 'utf8');
|
|
261
|
+
const missing = requiredHeadings.filter((heading) => {
|
|
262
|
+
const pattern = new RegExp(`^#{1,2}\\s+${heading}`, 'im');
|
|
263
|
+
return !pattern.test(content);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
if (missing.length > 0) {
|
|
267
|
+
fail(`FAIL [skill-compliance]: skills/${skill}/SKILL.md missing required sections: ${missing.join(', ')}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
validateCoreStructure();
|
|
273
|
+
validateDeveloperWorkflow();
|
|
274
|
+
validateRuntimeStructure();
|
|
275
|
+
validateSkillAnatomy();
|
|
276
|
+
validateRuntimeSkillSync();
|
|
277
|
+
validateReportTemplates();
|
|
278
|
+
validateNoForbiddenPlaceholders();
|
|
279
|
+
validateEntrypointIntegrity();
|
|
280
|
+
validateSkillComplianceCheck();
|
|
281
|
+
|
|
282
|
+
for (const warning of warnings) console.warn(warning);
|
|
283
|
+
|
|
284
|
+
if (failures.length > 0) {
|
|
285
|
+
console.error('Framework validation failed:');
|
|
286
|
+
for (const failure of failures) console.error(`- ${failure}`);
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
console.log('Framework validation passed.');
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# API-CONTRACT-AUDIT SKILL
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
To audit the strict compliance between Frontend requests and Backend API Contracts, ensuring that payloads, responses, validations, and status codes are synchronized.
|
|
5
|
+
|
|
6
|
+
## Responsibilities
|
|
7
|
+
- Audit Frontend Request Payloads.
|
|
8
|
+
- Audit Backend Response Payloads.
|
|
9
|
+
- Validate DTOs and Swagger/OpenAPI documentation.
|
|
10
|
+
- Check validation rules and HTTP Status code handling.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
Follow the detailed workflow in `workflow.md` for this skill.
|
|
14
|
+
|
|
15
|
+
## Required Inputs
|
|
16
|
+
Minimal Prompting: `AUDIT: API Contract [Endpoint/Module]`
|
|
17
|
+
|
|
18
|
+
## Expected Outputs
|
|
19
|
+
API Contract Compliance Report.
|
|
20
|
+
|
|
21
|
+
## Execution Rules
|
|
22
|
+
- Never assume an API structure; verify against explicit DTOs or Swagger specs.
|
|
23
|
+
- Ensure Evidence Collection is populated (e.g., sample JSON payloads).
|
|
24
|
+
|
|
25
|
+
## Minimal Prompting Target
|
|
26
|
+
- Agent automatically infers the FE and BE code locations using onboarding knowledge.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# API-CONTRACT-AUDIT CHECKLIST
|
|
2
|
+
|
|
3
|
+
## Entry Criteria
|
|
4
|
+
- [ ] Target API or Module is clearly identified.
|
|
5
|
+
|
|
6
|
+
## Execution
|
|
7
|
+
- [ ] Frontend request payload validated.
|
|
8
|
+
- [ ] Backend response payload validated.
|
|
9
|
+
- [ ] DTO & Swagger specification validated.
|
|
10
|
+
- [ ] Validation rules (required, types, constraints) verified.
|
|
11
|
+
- [ ] HTTP Status handling verified.
|
|
12
|
+
|
|
13
|
+
## Exit Criteria / Definition of Done
|
|
14
|
+
- [ ] API Contract Compliance Report generated.
|
|
15
|
+
- [ ] Severity classified for all findings.
|
|
16
|
+
- [ ] Quality Gate set to PASS.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Executive Summary
|
|
2
|
+
* **Trigger Detected**: N/A. Reason: Populated during skill execution.
|
|
3
|
+
* **Purpose**: N/A. Reason: Populated during skill execution.
|
|
4
|
+
|
|
5
|
+
# Scope
|
|
6
|
+
* **Target**: N/A. Reason: Populated during skill execution.
|
|
7
|
+
|
|
8
|
+
# Knowledge Confidence
|
|
9
|
+
* **Score**: N/A. Reason: Populated during skill execution.
|
|
10
|
+
|
|
11
|
+
# Knowledge Classification
|
|
12
|
+
* **Classification**: N/A. Reason: Populated during skill execution.
|
|
13
|
+
|
|
14
|
+
# Traceability Matrix
|
|
15
|
+
| Layer | File | Function | Notes |
|
|
16
|
+
| ----- | ---- | -------- | ----- |
|
|
17
|
+
| Framework | N/A. Reason: Populated during skill execution. | N/A. Reason: Populated during skill execution. | N/A. Reason: Populated during skill execution. |
|
|
18
|
+
|
|
19
|
+
# Evidence
|
|
20
|
+
* N/A. Reason: Populated during skill execution.
|
|
21
|
+
|
|
22
|
+
# Root Cause
|
|
23
|
+
* N/A. Reason: Populated during skill execution.
|
|
24
|
+
|
|
25
|
+
# Impact
|
|
26
|
+
* N/A. Reason: Populated during skill execution.
|
|
27
|
+
|
|
28
|
+
# Recommendation
|
|
29
|
+
* **Quick Win**: N/A. Reason: Populated during skill execution.
|
|
30
|
+
* **Long Term Improvement**: N/A. Reason: Populated during skill execution.
|
|
31
|
+
|
|
32
|
+
# Quality Gate
|
|
33
|
+
* N/A. Reason: Populated during skill execution.
|
|
34
|
+
|
|
35
|
+
# Enterprise Readiness
|
|
36
|
+
* N/A. Reason: Populated during skill execution.
|
|
37
|
+
|
|
38
|
+
# Final Decision
|
|
39
|
+
N/A. Reason: Populated during skill execution.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# API-CONTRACT-AUDIT WORKFLOW
|
|
2
|
+
|
|
3
|
+
You MUST execute these explicit steps sequentially:
|
|
4
|
+
|
|
5
|
+
1. **Pre Validation** (Verify `traceability-analysis` coverage exists)
|
|
6
|
+
2. **Locate Frontend Request** (Identify payload generation in FE)
|
|
7
|
+
3. **Locate Backend Contract** (Identify Controller & DTO)
|
|
8
|
+
4. **Compare Payload Structure** (Match keys and types)
|
|
9
|
+
5. **Compare Response Structure** (Match BE response to FE expectations)
|
|
10
|
+
6. **Audit Swagger/Docs** (Check if docs match implementation)
|
|
11
|
+
7. **Audit Validation Rules** (Check class-validator constraints)
|
|
12
|
+
8. **Audit HTTP Statuses** (Ensure correct error/success codes)
|
|
13
|
+
9. **Execution Validation** (Ensure all mismatches are backed by Evidence)
|
|
14
|
+
10. **Generate Compliance Report**
|
|
15
|
+
11. **Post Validation** (Verify report conforms to Enterprise Standard)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# AUDIT SKILL
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
To execute a comprehensive Enterprise Architecture Audit across the repository, ensuring code adheres strictly to architectural, security, performance, maintainability, scalability, and traceability standards.
|
|
5
|
+
|
|
6
|
+
## Responsibilities
|
|
7
|
+
- Audit Architecture (Monolith/Microservice boundary leaks).
|
|
8
|
+
- Audit Security (Hardcoded secrets, exposed vulnerabilities).
|
|
9
|
+
- Audit Performance (N+1 queries, heavy bundles).
|
|
10
|
+
- Audit Maintainability (Code duplication, missing tests).
|
|
11
|
+
- Audit Scalability (Statelessness, caching).
|
|
12
|
+
- Audit Traceability (FE-BE links).
|
|
13
|
+
|
|
14
|
+
## Workflow
|
|
15
|
+
Follow the detailed workflow in `workflow.md` for this skill.
|
|
16
|
+
|
|
17
|
+
## Required Inputs
|
|
18
|
+
Minimal Prompting: `AUDIT: [Target component/module or whole project]`
|
|
19
|
+
|
|
20
|
+
## Expected Outputs
|
|
21
|
+
An Enterprise Architecture Audit Report with explicit severity assignments.
|
|
22
|
+
|
|
23
|
+
## Execution Rules
|
|
24
|
+
- Do not propose fixes blindly; categorize the severity (Critical, High, Medium, Low) and provide actionable recommendations.
|
|
25
|
+
- Collect explicit evidence (Snippets, Logs) for every finding.
|
|
26
|
+
|
|
27
|
+
## Minimal Prompting Target
|
|
28
|
+
- Agent autonomously parses "AUDIT: Order Module", analyzes the FE component, traces it to the BE service and DB, and audits all 6 vectors without further prompts.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# AUDIT CHECKLIST
|
|
2
|
+
|
|
3
|
+
## Entry Criteria
|
|
4
|
+
- [ ] Audit scope is clearly defined via minimal prompt.
|
|
5
|
+
|
|
6
|
+
## Execution
|
|
7
|
+
- [ ] Traceability established for the scope.
|
|
8
|
+
- [ ] Architecture audited.
|
|
9
|
+
- [ ] Security audited.
|
|
10
|
+
- [ ] Performance audited.
|
|
11
|
+
- [ ] Maintainability audited.
|
|
12
|
+
- [ ] Scalability audited.
|
|
13
|
+
- [ ] Evidence collected for all findings.
|
|
14
|
+
|
|
15
|
+
## Exit Criteria / Definition of Done
|
|
16
|
+
- [ ] Enterprise Architecture Audit Report generated.
|
|
17
|
+
- [ ] All findings categorized by Severity (Critical/High/Medium/Low).
|
|
18
|
+
- [ ] Quality Gate set to PASS.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# AUDIT EXAMPLES
|
|
2
|
+
|
|
3
|
+
### Example 1
|
|
4
|
+
```txt
|
|
5
|
+
AUDIT: Review the Auth module for token leaks.
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
### Example 2
|
|
9
|
+
```txt
|
|
10
|
+
AUDIT: Check DB queries for N+1 problems.
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Example 3
|
|
14
|
+
```txt
|
|
15
|
+
AUDIT: Verify FE components use Atomic Design.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Example 4
|
|
19
|
+
```txt
|
|
20
|
+
AUDIT: Audit dependencies for known CVEs.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Example 5
|
|
24
|
+
```txt
|
|
25
|
+
AUDIT: Review error handling in controllers.
|
|
26
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Executive Summary
|
|
2
|
+
* **Trigger Detected**: N/A. Reason: Populated during skill execution.
|
|
3
|
+
* **Purpose**: N/A. Reason: Populated during skill execution.
|
|
4
|
+
|
|
5
|
+
# Scope
|
|
6
|
+
* **Target**: N/A. Reason: Populated during skill execution.
|
|
7
|
+
|
|
8
|
+
# Knowledge Confidence
|
|
9
|
+
* **Score**: N/A. Reason: Populated during skill execution.
|
|
10
|
+
|
|
11
|
+
# Knowledge Classification
|
|
12
|
+
* **Classification**: N/A. Reason: Populated during skill execution.
|
|
13
|
+
|
|
14
|
+
# Traceability Matrix
|
|
15
|
+
| Layer | File | Function | Notes |
|
|
16
|
+
| ----- | ---- | -------- | ----- |
|
|
17
|
+
| Framework | N/A. Reason: Populated during skill execution. | N/A. Reason: Populated during skill execution. | N/A. Reason: Populated during skill execution. |
|
|
18
|
+
|
|
19
|
+
# Evidence
|
|
20
|
+
* N/A. Reason: Populated during skill execution.
|
|
21
|
+
|
|
22
|
+
# Root Cause
|
|
23
|
+
* N/A. Reason: Populated during skill execution.
|
|
24
|
+
|
|
25
|
+
# Impact
|
|
26
|
+
* N/A. Reason: Populated during skill execution.
|
|
27
|
+
|
|
28
|
+
# Recommendation
|
|
29
|
+
* **Quick Win**: N/A. Reason: Populated during skill execution.
|
|
30
|
+
* **Long Term Improvement**: N/A. Reason: Populated during skill execution.
|
|
31
|
+
|
|
32
|
+
# Quality Gate
|
|
33
|
+
* N/A. Reason: Populated during skill execution.
|
|
34
|
+
|
|
35
|
+
# Enterprise Readiness
|
|
36
|
+
* N/A. Reason: Populated during skill execution.
|
|
37
|
+
|
|
38
|
+
# Final Decision
|
|
39
|
+
N/A. Reason: Populated during skill execution.
|