atabey 0.0.7 → 0.0.9
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/README.md +1 -1
- package/dist/framework-mcp/src/resources/index.js +2 -2
- package/dist/framework-mcp/src/resources/index.js.map +1 -1
- package/dist/framework-mcp/src/utils/errors.d.ts +46 -0
- package/dist/framework-mcp/src/utils/errors.js +69 -0
- package/dist/framework-mcp/src/utils/errors.js.map +1 -0
- package/dist/framework-mcp/src/utils/memory.d.ts +3 -0
- package/dist/framework-mcp/src/utils/memory.js +75 -0
- package/dist/framework-mcp/src/utils/memory.js.map +1 -0
- package/dist/framework-mcp/src/utils/storage.d.ts +60 -0
- package/dist/framework-mcp/src/utils/storage.js +208 -0
- package/dist/framework-mcp/src/utils/storage.js.map +1 -0
- package/dist/framework-mcp/src/utils/types.d.ts +19 -0
- package/dist/framework-mcp/src/utils/types.js +13 -0
- package/dist/framework-mcp/src/utils/types.js.map +1 -0
- package/dist/src/cli/adapters/core.js +12 -19
- package/dist/src/cli/adapters/core.js.map +1 -1
- package/dist/src/shared/constants.d.ts +1 -0
- package/dist/src/shared/constants.js +1 -0
- package/dist/src/shared/constants.js.map +1 -1
- package/dist/tests/adapter.test.js +3 -2
- package/dist/tests/adapter.test.js.map +1 -1
- package/framework-mcp/dist/constants.js +64 -0
- package/framework-mcp/dist/framework-mcp/src/constants.js +64 -0
- package/framework-mcp/dist/framework-mcp/src/index.js +144 -0
- package/framework-mcp/dist/framework-mcp/src/resources/index.js +58 -0
- package/framework-mcp/dist/framework-mcp/src/tools/control_plane/locking.js +82 -0
- package/framework-mcp/dist/framework-mcp/src/tools/control_plane/registry.js +35 -0
- package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +322 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +64 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/patch_file.js +34 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/read_file.js +51 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/replace_text.js +50 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/write_file.js +43 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/audit_deps.js +41 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/get_status.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/orchestrate.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/run_tests.js +27 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/submit_plan.js +13 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/update_contract_hash.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/update_memory.js +8 -0
- package/framework-mcp/dist/framework-mcp/src/tools/index.js +62 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/get_insights.js +34 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/read_memory.js +28 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/log_action.js +22 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/send_message.js +94 -0
- package/framework-mcp/dist/framework-mcp/src/tools/observability/check_ports.js +26 -0
- package/framework-mcp/dist/framework-mcp/src/tools/observability/get_health.js +19 -0
- package/framework-mcp/dist/framework-mcp/src/tools/quality/check_lint.js +30 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/get_gaps.js +48 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/get_map.js +43 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/grep_search.js +75 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/list_dir.js +28 -0
- package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +56 -0
- package/framework-mcp/dist/framework-mcp/src/tools/types.js +1 -0
- package/framework-mcp/dist/framework-mcp/src/utils/cli.js +59 -0
- package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +231 -0
- package/framework-mcp/dist/framework-mcp/src/utils/errors.js +68 -0
- package/framework-mcp/dist/framework-mcp/src/utils/fs.js +44 -0
- package/framework-mcp/dist/framework-mcp/src/utils/memory.js +74 -0
- package/framework-mcp/dist/framework-mcp/src/utils/metrics.js +56 -0
- package/framework-mcp/dist/framework-mcp/src/utils/permissions.js +71 -0
- package/framework-mcp/dist/framework-mcp/src/utils/security.js +60 -0
- package/framework-mcp/dist/framework-mcp/src/utils/storage.js +207 -0
- package/framework-mcp/dist/framework-mcp/src/utils/types.js +12 -0
- package/framework-mcp/dist/index.js +144 -0
- package/framework-mcp/dist/resources/index.js +58 -0
- package/framework-mcp/dist/src/cli/adapters/core.js +71 -0
- package/framework-mcp/dist/src/cli/adapters/index.js +5 -0
- package/framework-mcp/dist/src/cli/adapters/paths.js +101 -0
- package/framework-mcp/dist/src/cli/adapters/scaffold.js +71 -0
- package/framework-mcp/dist/src/cli/adapters/utils.js +75 -0
- package/framework-mcp/dist/src/cli/commands/approve.js +63 -0
- package/framework-mcp/dist/src/cli/commands/check.js +181 -0
- package/framework-mcp/dist/src/cli/commands/compliance.js +50 -0
- package/framework-mcp/dist/src/cli/commands/contract.js +50 -0
- package/framework-mcp/dist/src/cli/commands/dashboard.js +123 -0
- package/framework-mcp/dist/src/cli/commands/explorer.js +42 -0
- package/framework-mcp/dist/src/cli/commands/git.js +40 -0
- package/framework-mcp/dist/src/cli/commands/init/create-agent.js +58 -0
- package/framework-mcp/dist/src/cli/commands/init/scaffold-core.js +112 -0
- package/framework-mcp/dist/src/cli/commands/init/scaffold-docs.js +34 -0
- package/framework-mcp/dist/src/cli/commands/init/scaffold-ops.js +80 -0
- package/framework-mcp/dist/src/cli/commands/init/scaffold-standards.js +67 -0
- package/framework-mcp/dist/src/cli/commands/init.js +167 -0
- package/framework-mcp/dist/src/cli/commands/knowledge.js +42 -0
- package/framework-mcp/dist/src/cli/commands/lint.js +22 -0
- package/framework-mcp/dist/src/cli/commands/log.js +10 -0
- package/framework-mcp/dist/src/cli/commands/memory.js +4 -0
- package/framework-mcp/dist/src/cli/commands/orchestrate.js +159 -0
- package/framework-mcp/dist/src/cli/commands/plan.js +117 -0
- package/framework-mcp/dist/src/cli/commands/script.js +19 -0
- package/framework-mcp/dist/src/cli/commands/security.js +36 -0
- package/framework-mcp/dist/src/cli/commands/status.js +97 -0
- package/framework-mcp/dist/src/cli/commands/trace.js +109 -0
- package/framework-mcp/dist/src/cli/index.js +338 -0
- package/framework-mcp/dist/src/cli/shims.js +66 -0
- package/framework-mcp/dist/src/cli/utils/claude.js +56 -0
- package/framework-mcp/dist/src/cli/utils/compliance.js +173 -0
- package/framework-mcp/dist/src/cli/utils/config-schema.js +42 -0
- package/framework-mcp/dist/src/cli/utils/fs.js +137 -0
- package/framework-mcp/dist/src/cli/utils/i18n.js +30 -0
- package/framework-mcp/dist/src/cli/utils/memory.js +276 -0
- package/framework-mcp/dist/src/cli/utils/pkg.js +282 -0
- package/framework-mcp/dist/src/cli/utils/schemas.js +19 -0
- package/framework-mcp/dist/src/cli/utils/string.js +49 -0
- package/framework-mcp/dist/src/cli/utils/time.js +27 -0
- package/framework-mcp/dist/src/cli/utils/ui.js +58 -0
- package/framework-mcp/dist/src/contracts/index.js +1 -0
- package/framework-mcp/dist/src/contracts/tasks.js +20 -0
- package/framework-mcp/dist/src/dashboard/vite.config.js +15 -0
- package/framework-mcp/dist/src/modules/adapters/definitions.js +140 -0
- package/framework-mcp/dist/src/modules/adapters/registry.js +18 -0
- package/framework-mcp/dist/src/modules/adapters/shared.js +104 -0
- package/framework-mcp/dist/src/modules/adapters/types.js +1 -0
- package/framework-mcp/dist/src/modules/agents/definitions.js +457 -0
- package/framework-mcp/dist/src/modules/agents/registry/analyst.js +39 -0
- package/framework-mcp/dist/src/modules/agents/registry/architect.js +42 -0
- package/framework-mcp/dist/src/modules/agents/registry/backend.js +49 -0
- package/framework-mcp/dist/src/modules/agents/registry/database.js +45 -0
- package/framework-mcp/dist/src/modules/agents/registry/devops.js +45 -0
- package/framework-mcp/dist/src/modules/agents/registry/explorer.js +36 -0
- package/framework-mcp/dist/src/modules/agents/registry/frontend.js +51 -0
- package/framework-mcp/dist/src/modules/agents/registry/git.js +36 -0
- package/framework-mcp/dist/src/modules/agents/registry/manager.js +53 -0
- package/framework-mcp/dist/src/modules/agents/registry/mobile.js +39 -0
- package/framework-mcp/dist/src/modules/agents/registry/native.js +39 -0
- package/framework-mcp/dist/src/modules/agents/registry/quality.js +41 -0
- package/framework-mcp/dist/src/modules/agents/registry/security.js +43 -0
- package/framework-mcp/dist/src/modules/agents/types.js +1 -0
- package/framework-mcp/dist/src/modules/engines/evaluation-engine.js +102 -0
- package/framework-mcp/dist/src/modules/engines/health-engine.js +49 -0
- package/framework-mcp/dist/src/modules/engines/planning-engine.js +78 -0
- package/framework-mcp/dist/src/modules/engines/risk-engine.js +105 -0
- package/framework-mcp/dist/src/modules/engines/routing-engine.js +73 -0
- package/framework-mcp/dist/src/modules/engines/types.js +1 -0
- package/framework-mcp/dist/src/modules/skills/definitions.js +70 -0
- package/framework-mcp/dist/src/shared/constants.js +187 -0
- package/framework-mcp/dist/src/shared/errors.js +68 -0
- package/framework-mcp/dist/src/shared/fs.js +51 -0
- package/framework-mcp/dist/src/shared/logger.js +116 -0
- package/framework-mcp/dist/src/shared/storage.js +207 -0
- package/framework-mcp/dist/src/shared/types.js +12 -0
- package/framework-mcp/dist/tools/control_plane/locking.js +82 -0
- package/framework-mcp/dist/tools/control_plane/registry.js +35 -0
- package/framework-mcp/dist/tools/definitions.js +322 -0
- package/framework-mcp/dist/tools/file_system/batch_surgical_edit.js +64 -0
- package/framework-mcp/dist/tools/file_system/patch_file.js +34 -0
- package/framework-mcp/dist/tools/file_system/read_file.js +51 -0
- package/framework-mcp/dist/tools/file_system/replace_text.js +50 -0
- package/framework-mcp/dist/tools/file_system/write_file.js +43 -0
- package/framework-mcp/dist/tools/framework/audit_deps.js +41 -0
- package/framework-mcp/dist/tools/framework/get_status.js +5 -0
- package/framework-mcp/dist/tools/framework/orchestrate.js +5 -0
- package/framework-mcp/dist/tools/framework/run_tests.js +27 -0
- package/framework-mcp/dist/tools/framework/submit_plan.js +13 -0
- package/framework-mcp/dist/tools/framework/update_contract_hash.js +5 -0
- package/framework-mcp/dist/tools/framework/update_memory.js +8 -0
- package/framework-mcp/dist/tools/index.js +62 -0
- package/framework-mcp/dist/tools/memory/get_insights.js +34 -0
- package/framework-mcp/dist/tools/memory/read_memory.js +28 -0
- package/framework-mcp/dist/tools/messaging/log_action.js +22 -0
- package/framework-mcp/dist/tools/messaging/send_message.js +94 -0
- package/framework-mcp/dist/tools/observability/check_ports.js +26 -0
- package/framework-mcp/dist/tools/observability/get_health.js +19 -0
- package/framework-mcp/dist/tools/quality/check_lint.js +30 -0
- package/framework-mcp/dist/tools/search/get_gaps.js +48 -0
- package/framework-mcp/dist/tools/search/get_map.js +43 -0
- package/framework-mcp/dist/tools/search/grep_search.js +75 -0
- package/framework-mcp/dist/tools/search/list_dir.js +28 -0
- package/framework-mcp/dist/tools/shell/run_command.js +56 -0
- package/framework-mcp/dist/tools/types.js +1 -0
- package/framework-mcp/dist/utils/cli.js +59 -0
- package/framework-mcp/dist/utils/compliance.js +231 -0
- package/framework-mcp/dist/utils/fs.js +44 -0
- package/framework-mcp/dist/utils/metrics.js +56 -0
- package/framework-mcp/dist/utils/permissions.js +71 -0
- package/framework-mcp/dist/utils/security.js +60 -0
- package/framework-mcp/package.json +37 -0
- package/mcp.json +1 -1
- package/package.json +10 -5
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { approveCommand } from "./commands/approve.js";
|
|
4
|
+
import { checkCommand } from "./commands/check.js";
|
|
5
|
+
import { updateApiContractCommand, verifyApiContractCommand } from "./commands/contract.js";
|
|
6
|
+
import { dashboardCommand } from "./commands/dashboard.js";
|
|
7
|
+
import { initCommand } from "./commands/init.js";
|
|
8
|
+
import { updateProjectMemoryCommand } from "./commands/memory.js";
|
|
9
|
+
import { orchestrateCommand, sendMessage } from "./commands/orchestrate.js";
|
|
10
|
+
import { planCommand, submitPlanCommand } from "./commands/plan.js";
|
|
11
|
+
import { statusCommand } from "./commands/status.js";
|
|
12
|
+
import { traceNewCommand, traceReplayCommand } from "./commands/trace.js";
|
|
13
|
+
import { getMemoryPath, readActiveTraceId } from "./utils/memory.js";
|
|
14
|
+
import { getPackageVersion, getValidatorPath } from "./utils/pkg.js";
|
|
15
|
+
/**
|
|
16
|
+
* Main CLI entry point.
|
|
17
|
+
*/
|
|
18
|
+
async function main() {
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
const command = args[0];
|
|
21
|
+
const KNOWN_COMMANDS = [
|
|
22
|
+
"init", "check", "status", "trace:new", "trace:replay", "update_project_memory",
|
|
23
|
+
"plan", "plan:submit", "orchestrate", "loop", "verify-contract", "update-contract", "dashboard",
|
|
24
|
+
"validate", "validate-army", "check:al", "version", "-v", "--version", "help", "-h", "--help",
|
|
25
|
+
"git:commit", "git:sync", "check:compliance", "explorer:graph", "explorer:audit",
|
|
26
|
+
"knowledge:update", "knowledge:search", "log:action", "run-script", "security:audit", "check:lint", "approve", "create-agent"
|
|
27
|
+
];
|
|
28
|
+
// Handle @agent delegation syntax
|
|
29
|
+
if (command?.startsWith("@")) {
|
|
30
|
+
const to = command;
|
|
31
|
+
const content = args.slice(1).join(" ");
|
|
32
|
+
if (!content) {
|
|
33
|
+
process.stderr.write(`[ERROR] Error: Missing task content for ${to}.\n`);
|
|
34
|
+
process.stderr.write(`Usage: atabey ${to} "Your task description"\n`);
|
|
35
|
+
process.exit(64);
|
|
36
|
+
}
|
|
37
|
+
const memoryPath = getMemoryPath();
|
|
38
|
+
let traceId = "T-000";
|
|
39
|
+
if (fs.existsSync(memoryPath)) {
|
|
40
|
+
const memoryContent = fs.readFileSync(memoryPath, "utf8");
|
|
41
|
+
const tid = readActiveTraceId(memoryContent);
|
|
42
|
+
if (tid)
|
|
43
|
+
traceId = tid.trim();
|
|
44
|
+
}
|
|
45
|
+
const taskPayload = {
|
|
46
|
+
traceId,
|
|
47
|
+
task: content,
|
|
48
|
+
priority: "NORMAL",
|
|
49
|
+
agent: to
|
|
50
|
+
};
|
|
51
|
+
await sendMessage({
|
|
52
|
+
from: "@manager",
|
|
53
|
+
to,
|
|
54
|
+
category: "DELEGATION",
|
|
55
|
+
content: JSON.stringify(taskPayload),
|
|
56
|
+
traceId
|
|
57
|
+
});
|
|
58
|
+
process.stdout.write(`[OK] Task delegated to ${to} (Trace: ${traceId})\n`);
|
|
59
|
+
process.stdout.write("[INFO] Run \"atabey orchestrate\" to process.\n");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
switch (command) {
|
|
63
|
+
case "init": {
|
|
64
|
+
const dryRun = args.includes("--dry-run");
|
|
65
|
+
const isUnified = args.includes("--unified");
|
|
66
|
+
const forceYes = args.includes("--yes") || args.includes("-y");
|
|
67
|
+
const adapter = args.find(a => !a.startsWith("-") && a !== "init") || "gemini";
|
|
68
|
+
await initCommand(adapter, { dryRun, unified: isUnified, yes: forceYes });
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case "check":
|
|
72
|
+
await checkCommand();
|
|
73
|
+
break;
|
|
74
|
+
case "plan":
|
|
75
|
+
await planCommand();
|
|
76
|
+
break;
|
|
77
|
+
case "plan:submit": {
|
|
78
|
+
const planData = args[1];
|
|
79
|
+
if (!planData) {
|
|
80
|
+
process.stderr.write("[ERROR] Error: JSON plan data is required.\n");
|
|
81
|
+
process.exit(64);
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const tasks = JSON.parse(planData);
|
|
85
|
+
await submitPlanCommand(tasks);
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
process.stderr.write(`[ERROR] Error: Invalid JSON plan data: ${e.message}\n`);
|
|
89
|
+
process.exit(64);
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case "dashboard": {
|
|
94
|
+
const port = parseInt(args[1]) || 4200;
|
|
95
|
+
await dashboardCommand(port);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case "status":
|
|
99
|
+
await statusCommand();
|
|
100
|
+
break;
|
|
101
|
+
case "trace:new": {
|
|
102
|
+
const description = args[1] || "Default task";
|
|
103
|
+
const agent = args[2] || "manager";
|
|
104
|
+
const priority = args[3] || "P1";
|
|
105
|
+
await traceNewCommand(description, agent, priority);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "trace:replay": {
|
|
109
|
+
const traceId = args[1];
|
|
110
|
+
if (!traceId) {
|
|
111
|
+
process.stderr.write("[ERROR] Error: traceId is required.\n");
|
|
112
|
+
process.exit(64);
|
|
113
|
+
}
|
|
114
|
+
await traceReplayCommand(traceId);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case "update_project_memory": {
|
|
118
|
+
const section = args[1];
|
|
119
|
+
const content = args[2];
|
|
120
|
+
if (!section || !content) {
|
|
121
|
+
process.stderr.write("[ERROR] Error: section and content are required.\n");
|
|
122
|
+
process.exit(64);
|
|
123
|
+
}
|
|
124
|
+
await updateProjectMemoryCommand(section, content);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case "orchestrate":
|
|
128
|
+
case "loop":
|
|
129
|
+
await orchestrateCommand();
|
|
130
|
+
break;
|
|
131
|
+
case "approve": {
|
|
132
|
+
const traceId = args[1];
|
|
133
|
+
if (!traceId) {
|
|
134
|
+
process.stderr.write("[ERROR] Error: traceId is required.\n");
|
|
135
|
+
process.exit(64);
|
|
136
|
+
}
|
|
137
|
+
await approveCommand(traceId);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case "verify-contract":
|
|
141
|
+
await verifyApiContractCommand();
|
|
142
|
+
break;
|
|
143
|
+
case "update-contract":
|
|
144
|
+
await updateApiContractCommand();
|
|
145
|
+
break;
|
|
146
|
+
case "validate":
|
|
147
|
+
case "validate-army":
|
|
148
|
+
case "check:al": {
|
|
149
|
+
const { execSync } = await import("child_process");
|
|
150
|
+
try {
|
|
151
|
+
const validatorPath = getValidatorPath();
|
|
152
|
+
execSync(`node "${validatorPath}"`, { stdio: "inherit" });
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// handled by validator
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case "git:commit": {
|
|
160
|
+
const memoryContent = fs.existsSync(getMemoryPath()) ? fs.readFileSync(getMemoryPath(), "utf8") : "";
|
|
161
|
+
const traceId = readActiveTraceId(memoryContent) || "T-000";
|
|
162
|
+
const { gitCommitCommand } = await import("./commands/git.js");
|
|
163
|
+
await gitCommitCommand(traceId);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case "git:sync": {
|
|
167
|
+
const { gitSyncCommand } = await import("./commands/git.js");
|
|
168
|
+
await gitSyncCommand();
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case "check:compliance": {
|
|
172
|
+
const targetPath = args[1] || "src";
|
|
173
|
+
const { complianceCheckCommand } = await import("./commands/compliance.js");
|
|
174
|
+
await complianceCheckCommand(targetPath);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "explorer:graph": {
|
|
178
|
+
const targetPath = args[1] || "src";
|
|
179
|
+
const { explorerGraphCommand } = await import("./commands/explorer.js");
|
|
180
|
+
await explorerGraphCommand(targetPath);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case "explorer:audit": {
|
|
184
|
+
const targetPath = args[1] || "src";
|
|
185
|
+
const { explorerAuditCommand } = await import("./commands/explorer.js");
|
|
186
|
+
await explorerAuditCommand(targetPath);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case "knowledge:update": {
|
|
190
|
+
const topic = args[1];
|
|
191
|
+
const content = args[2];
|
|
192
|
+
const { updateKnowledgeBaseCommand } = await import("./commands/knowledge.js");
|
|
193
|
+
await updateKnowledgeBaseCommand(topic, content);
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case "knowledge:search": {
|
|
197
|
+
const query = args[1];
|
|
198
|
+
const { searchKnowledgeBaseCommand } = await import("./commands/knowledge.js");
|
|
199
|
+
await searchKnowledgeBaseCommand(query);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case "log:action": {
|
|
203
|
+
const agent = args[1];
|
|
204
|
+
const action = args[2];
|
|
205
|
+
const status = args[3] || "SUCCESS";
|
|
206
|
+
const summary = args[4] || "";
|
|
207
|
+
const memoryContent = fs.existsSync(getMemoryPath()) ? fs.readFileSync(getMemoryPath(), "utf8") : "";
|
|
208
|
+
const traceId = readActiveTraceId(memoryContent) || "T-000";
|
|
209
|
+
const { logAgentActionCommand } = await import("./commands/log.js");
|
|
210
|
+
await logAgentActionCommand({ agent, action, status, summary, traceId });
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case "run-script": {
|
|
214
|
+
const script = args[1];
|
|
215
|
+
const projectPath = args[2] || ".";
|
|
216
|
+
const { runScriptCommand } = await import("./commands/script.js");
|
|
217
|
+
await runScriptCommand(script, projectPath);
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case "create-agent": {
|
|
221
|
+
const name = args[1];
|
|
222
|
+
if (!name) {
|
|
223
|
+
process.stderr.write("[ERROR] Error: Agent name is required.\n");
|
|
224
|
+
process.exit(64);
|
|
225
|
+
}
|
|
226
|
+
const { createAgentCommand } = await import("./commands/init/create-agent.js");
|
|
227
|
+
await createAgentCommand(name);
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "security:audit": {
|
|
231
|
+
const targetPath = args[1] || "src";
|
|
232
|
+
const { securityAuditCommand } = await import("./commands/security.js");
|
|
233
|
+
await securityAuditCommand(targetPath);
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
case "check:lint": {
|
|
237
|
+
const { lintCommand } = await import("./commands/lint.js");
|
|
238
|
+
await lintCommand();
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
case "version":
|
|
242
|
+
case "-v":
|
|
243
|
+
case "--version":
|
|
244
|
+
process.stdout.write(`v${getPackageVersion()}\n`);
|
|
245
|
+
break;
|
|
246
|
+
case "help":
|
|
247
|
+
case "-h":
|
|
248
|
+
case "--help":
|
|
249
|
+
showHelp();
|
|
250
|
+
break;
|
|
251
|
+
default:
|
|
252
|
+
if (command && !KNOWN_COMMANDS.includes(command)) {
|
|
253
|
+
// Natural language request fallback to @manager
|
|
254
|
+
const content = args.join(" ");
|
|
255
|
+
const memoryPath = getMemoryPath();
|
|
256
|
+
let traceId = "T-000";
|
|
257
|
+
if (fs.existsSync(memoryPath)) {
|
|
258
|
+
const memoryContent = fs.readFileSync(memoryPath, "utf8");
|
|
259
|
+
const tid = readActiveTraceId(memoryContent);
|
|
260
|
+
if (tid)
|
|
261
|
+
traceId = tid.trim();
|
|
262
|
+
}
|
|
263
|
+
await sendMessage({
|
|
264
|
+
from: "@user",
|
|
265
|
+
to: "@manager",
|
|
266
|
+
category: "ACTION",
|
|
267
|
+
content,
|
|
268
|
+
traceId
|
|
269
|
+
});
|
|
270
|
+
process.stdout.write(`[SIGNAL] Request sent to @manager: "${content}" (Trace: ${traceId})\n`);
|
|
271
|
+
process.stdout.write("[INFO] Run 'atabey orchestrate' to process.\n");
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
showHelp();
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function showHelp() {
|
|
280
|
+
process.stdout.write(`
|
|
281
|
+
[ATABEY] Agent Atabey CLI (v${getPackageVersion()}) — The Supreme AI Orchestrator
|
|
282
|
+
|
|
283
|
+
Usage:
|
|
284
|
+
atabey <command> [options]
|
|
285
|
+
atabey @<agent> "task description"
|
|
286
|
+
atabey "natural language request"
|
|
287
|
+
|
|
288
|
+
Commands:
|
|
289
|
+
@<agent> <task> Delegate a task to a specialist agent (e.g. @backend, @frontend)
|
|
290
|
+
init [adapter] Initialize Agent Atabey framework.
|
|
291
|
+
Options: --unified, --yes
|
|
292
|
+
check Perform an enterprise-grade system health check
|
|
293
|
+
status Show active phase, trace ID, and agent statuses
|
|
294
|
+
dashboard [port] Launch the Hermes Visual Control Plane (default: 4200)
|
|
295
|
+
trace:new <desc> Start a new task chain with a unique Trace ID
|
|
296
|
+
trace:replay <id> Replay chronological message exchanges of a Trace ID
|
|
297
|
+
plan Read docs/ and create planning tasks (Static)
|
|
298
|
+
plan:submit <json> Submit a structured DAG plan for execution (Dynamic)
|
|
299
|
+
orchestrate Start the dynamic Hermes agent orchestration loop
|
|
300
|
+
verify-contract Validate type alignment between backend and frontend
|
|
301
|
+
update-contract Generate and synchronize a new contract hash
|
|
302
|
+
git:commit Suggest git commit messages matching the Trace ID
|
|
303
|
+
git:sync Sync and rebase the project with remote repository
|
|
304
|
+
check:compliance Verify file compliance with ATABEY.md rules
|
|
305
|
+
explorer:graph Generate import dependency charts in Mermaid format
|
|
306
|
+
explorer:audit Scan source files for lines-of-code complexity
|
|
307
|
+
knowledge:update Add or update a topic in the local knowledge base
|
|
308
|
+
knowledge:search Search the local knowledge base for a topic query
|
|
309
|
+
log:action Record structured logs for agent executions
|
|
310
|
+
run-script Execute package scripts in the project directory
|
|
311
|
+
security:audit Audit source files for secrets and unsafe coding
|
|
312
|
+
check:lint Run ESLint checks on the project files
|
|
313
|
+
version Show version information
|
|
314
|
+
|
|
315
|
+
Natural Language:
|
|
316
|
+
If you provide a sentence that is not a known command, it will be automatically
|
|
317
|
+
sent to the @manager for orchestration.
|
|
318
|
+
|
|
319
|
+
Example:
|
|
320
|
+
atabey "Audit my project"
|
|
321
|
+
atabey @backend "Create the login page"
|
|
322
|
+
\n`);
|
|
323
|
+
}
|
|
324
|
+
import { AtabeyBaseError } from "../shared/errors.js";
|
|
325
|
+
import { logger } from "../shared/logger.js";
|
|
326
|
+
main().catch((err) => {
|
|
327
|
+
if (err instanceof AtabeyBaseError) {
|
|
328
|
+
process.stderr.write(`\n[ERROR] [${err.code}] Error: ${err.message}\n`);
|
|
329
|
+
if (err.solution) {
|
|
330
|
+
process.stderr.write(`[TIP] Solution Tip: ${err.solution}\n\n`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
process.stderr.write(`\n[ERROR] Fatal Error: ${err.message || String(err)}\n`);
|
|
335
|
+
}
|
|
336
|
+
logger.fatal("Fatal exception during CLI execution", err);
|
|
337
|
+
process.exit(1);
|
|
338
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const SHIM_TEMPLATES = {
|
|
2
|
+
gemini: `# [ATABEY] Agent Atabey — GEMINI Strategy (Command Intelligence)
|
|
3
|
+
|
|
4
|
+
You are the **Gemini Commander**. You represent the project's **Strategic Decision Center**. Your intelligence is derived from project history, architectural memory, and governance compliance.
|
|
5
|
+
|
|
6
|
+
## [GOV] Directives
|
|
7
|
+
- **Constitutional Supremacy:** Read \`{{FRAMEWORK_DIR}}/ATABEY.md\` first. You are the final arbiter of these rules.
|
|
8
|
+
- **Strategic Memory Sync:** Always read \`{{FRAMEWORK_DIR}}/memory/PROJECT_MEMORY.md\` and \`PROJECT_MEMORY.md\` at the start.
|
|
9
|
+
- **Orchestration Audit:** Before delegating, verify that the task matches the current Phase and Trace ID context.
|
|
10
|
+
- **Enterprise Reasoning:** Focus on long-term maintainability, security, and scalability in every strategic decision.
|
|
11
|
+
`,
|
|
12
|
+
"antigravity-cli": `# [ATABEY] Agent Atabey — ANTIGRAVITY Strategy (Internal Discipline)
|
|
13
|
+
|
|
14
|
+
You are the **Antigravity Specialist**. You represent the **Military Academy** of the framework, preserving internal standards and coding discipline.
|
|
15
|
+
|
|
16
|
+
## [GOV] Directives
|
|
17
|
+
- **Constitutional Supremacy:** Read \`{{FRAMEWORK_DIR}}/ATABEY.md\` first.
|
|
18
|
+
- **Standard Enforcement:** You are responsible for ensuring that all code adheres to the 26+ corporate standards in \`{{FRAMEWORK_DIR}}/knowledge/\`.
|
|
19
|
+
- **Sandbox Discipline:** Maintain isolated and high-discipline development environments.
|
|
20
|
+
`,
|
|
21
|
+
claude: `# [ATABEY] Agent Atabey — CLAUDE Strategy (Operational Surgery)
|
|
22
|
+
|
|
23
|
+
You are the **Claude Field Engineer**. You represent the **Operational Cerrahi (Surgical)** wing of the army. Your mission is precision execution with minimal footprint.
|
|
24
|
+
|
|
25
|
+
## [GOV] Directives
|
|
26
|
+
- **Surgical Precision (MANDATORY):** NEVER rewrite an entire file. Use \`replace_text\` or \`patch_file\` tools exclusively.
|
|
27
|
+
- **Token Economy:** Minimize API usage by targetting only the exact lines of code needed.
|
|
28
|
+
- **Traceability:** Ensure every change is linked to an active Trace ID and logged traceable under \`{{FRAMEWORK_DIR}}/logs/\`.
|
|
29
|
+
- **Phase Discipline:** Do not attempt Phase 2 tasks if Phase 1 contracts are not sealed.
|
|
30
|
+
`,
|
|
31
|
+
grok: `# [ATABEY] Agent Atabey — GROK Strategy (Scouting Wing)
|
|
32
|
+
|
|
33
|
+
You are the **Grok Explorer**. You represent the **Otonom Keşif Kanadı (Autonomous Scouting Wing)**. Your mission is experimental discovery and boundary testing.
|
|
34
|
+
|
|
35
|
+
## [GOV] Directives
|
|
36
|
+
- **Architecture Discovery:** Use \`get_project_map\` and \`get_project_gaps\` to map unexplored territory before any specialist acts.
|
|
37
|
+
- **Boundary Testing:** Identify architectural weaknesses or security gaps before they become critical.
|
|
38
|
+
- **Experimental Protocol:** Test futuristic agent behaviors and report findings to the **Commander**.
|
|
39
|
+
`,
|
|
40
|
+
cursor: `# [ATABEY] Agent Atabey — CURSOR Strategy (Implementer)
|
|
41
|
+
|
|
42
|
+
You are the **Cursor Implementer**. You are the **Kod İşçisi (Code Worker)** integrated directly into the IDE.
|
|
43
|
+
|
|
44
|
+
## [GOV] Directives
|
|
45
|
+
- **IDE Synergy:** Leverage Cursor's native context and Atabey's governance to write high-quality, compliant code.
|
|
46
|
+
- **Atomic Implementation:** Focus on implementing the specific task delegated by the @manager.
|
|
47
|
+
`,
|
|
48
|
+
codex: `# [ATABEY] Agent Atabey — COPILOT Strategy (Assistant)
|
|
49
|
+
|
|
50
|
+
You are the **Copilot Assistant**. You represent the **Yardımcı Geliştirici (Assistant Developer)**.
|
|
51
|
+
|
|
52
|
+
## [GOV] Directives
|
|
53
|
+
- **Predictive Support:** Provide code completions and suggestions that strictly adhere to the project's \`{{FRAMEWORK_DIR}}/ATABEY.md\` rules.
|
|
54
|
+
- **Rapid Prototyping:** Support the army by generating boilerplate that follows established enterprise patterns.
|
|
55
|
+
`,
|
|
56
|
+
local: `# [ATABEY] Agent Atabey — LOCAL LLM Strategy (Private Intelligence)
|
|
57
|
+
|
|
58
|
+
You are the **Local Private Intelligence**. You represent the project's **Private & Secure Command Wing**. Your intelligence is derived entirely from local models (Ollama, vLLM, etc.) and project-specific knowledge.
|
|
59
|
+
|
|
60
|
+
## [GOV] Directives
|
|
61
|
+
- **Constitutional Supremacy:** Read \`{{FRAMEWORK_DIR}}/ATABEY.md\` first. You are the final arbiter of these rules.
|
|
62
|
+
- **Zero Cloud Policy:** Ensure all operations remain local and secure.
|
|
63
|
+
- **Trace ID Discipline:** Every local inference and code generation MUST follow the active Trace ID.
|
|
64
|
+
- **Technical Integrity:** Adhere strictly to the 100% type-safety and surgical edit rules of the Atabey Order.
|
|
65
|
+
`
|
|
66
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { writeTextFile } from "./fs.js";
|
|
4
|
+
/**
|
|
5
|
+
* Finds the Claude config file path (if it exists).
|
|
6
|
+
*/
|
|
7
|
+
export function findClaudeConfigPath() {
|
|
8
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
9
|
+
if (!home)
|
|
10
|
+
return null;
|
|
11
|
+
const possiblePaths = [
|
|
12
|
+
// Claude Desktop
|
|
13
|
+
path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"), // macOS Claude Desktop
|
|
14
|
+
path.join(home, "AppData", "Roaming", "Claude", "claude_desktop_config.json"), // Windows Claude Desktop
|
|
15
|
+
// Claude Code CLI
|
|
16
|
+
path.join(home, ".claude.json"), // Global Claude Code CLI MCP config
|
|
17
|
+
// Legacy or system-specific paths
|
|
18
|
+
path.join(home, ".config", "claude", "config.json"),
|
|
19
|
+
path.join(home, ".claude", "config.json"),
|
|
20
|
+
path.join(home, "Library", "Application Support", "Claude Code", "config.json"),
|
|
21
|
+
path.join(home, ".config", "Claude", "config.json"),
|
|
22
|
+
];
|
|
23
|
+
for (const p of possiblePaths) {
|
|
24
|
+
if (fs.existsSync(p)) {
|
|
25
|
+
return p;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Adds or updates an MCP server entry in Claude's config file.
|
|
32
|
+
*/
|
|
33
|
+
export function addMcpServerToClaude(configPath, serverName, serverConfig) {
|
|
34
|
+
try {
|
|
35
|
+
let config = { mcpServers: {} };
|
|
36
|
+
if (fs.existsSync(configPath)) {
|
|
37
|
+
const content = fs.readFileSync(configPath, "utf8");
|
|
38
|
+
config = JSON.parse(content);
|
|
39
|
+
}
|
|
40
|
+
if (!config.mcpServers) {
|
|
41
|
+
config.mcpServers = {};
|
|
42
|
+
}
|
|
43
|
+
config.mcpServers[serverName] = serverConfig;
|
|
44
|
+
// Ensure parent directory exists
|
|
45
|
+
const dir = path.dirname(configPath);
|
|
46
|
+
if (!fs.existsSync(dir)) {
|
|
47
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
writeTextFile(configPath, JSON.stringify(config, null, 2));
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
console.error(`[WARN] Failed to add MCP server to Claude config at ${configPath}:`, e);
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
/**
|
|
5
|
+
* Enterprise Compliance Scanner (AST-Based)
|
|
6
|
+
* Scans the project source code for governance and discipline violations.
|
|
7
|
+
*/
|
|
8
|
+
export function scanProjectCompliance(targetDir = "src") {
|
|
9
|
+
const issues = [];
|
|
10
|
+
if (!fs.existsSync(targetDir))
|
|
11
|
+
return [];
|
|
12
|
+
const files = getAllFiles(targetDir);
|
|
13
|
+
for (const file of files) {
|
|
14
|
+
// Absolute skip for critical framework and utility files to avoid self-flagging
|
|
15
|
+
if (file.includes("compliance") ||
|
|
16
|
+
file.includes("definitions") ||
|
|
17
|
+
file.includes("agents/registry") ||
|
|
18
|
+
file.includes("scaffold-ops.ts") ||
|
|
19
|
+
file.includes("logger") ||
|
|
20
|
+
file.includes("errors") ||
|
|
21
|
+
file.includes("shared/fs") ||
|
|
22
|
+
file.includes("commands/git") ||
|
|
23
|
+
file.includes("commands/lint") ||
|
|
24
|
+
file.includes("commands/script") ||
|
|
25
|
+
file.includes("commands/check") ||
|
|
26
|
+
file.includes("cli/index.ts") ||
|
|
27
|
+
file.includes("adapters/shared"))
|
|
28
|
+
continue;
|
|
29
|
+
const content = fs.readFileSync(file, "utf8");
|
|
30
|
+
// --- 1. AST-Based Analysis (For Language Rules) ---
|
|
31
|
+
const sourceFile = ts.createSourceFile(file, content, ts.ScriptTarget.Latest, true);
|
|
32
|
+
const visit = (node) => {
|
|
33
|
+
// Rule: No console.log allowed (excluding UI and warn/error helpers)
|
|
34
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
35
|
+
const expression = node.expression;
|
|
36
|
+
const name = node.name.text;
|
|
37
|
+
if (ts.isIdentifier(expression) && expression.text === "console" && name === "log") {
|
|
38
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
39
|
+
issues.push({ file, line: line + 1, rule: "No console.log allowed (Use logger instead)" });
|
|
40
|
+
}
|
|
41
|
+
// Rule: innerHTML / outerHTML check
|
|
42
|
+
if (name === "innerHTML" || name === "outerHTML") {
|
|
43
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
44
|
+
issues.push({ file, line: line + 1, rule: `Unsafe assignment/usage of '${name}' detected (Avoid XSS)` });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Rule: No 'any' type usage
|
|
48
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
49
|
+
if (ts.isIdentifier(node.typeName) && node.typeName.text === "any") {
|
|
50
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
51
|
+
issues.push({ file, line: line + 1, rule: "Usage of 'any' type is forbidden" });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (node.kind === ts.SyntaxKind.AnyKeyword) {
|
|
55
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
56
|
+
issues.push({ file, line: line + 1, rule: "Usage of 'any' keyword is forbidden" });
|
|
57
|
+
}
|
|
58
|
+
// Rule: Zero UI Library & child_process Policy
|
|
59
|
+
if (ts.isImportDeclaration(node)) {
|
|
60
|
+
const moduleSpecifier = node.moduleSpecifier;
|
|
61
|
+
if (ts.isStringLiteral(moduleSpecifier)) {
|
|
62
|
+
const forbiddenLibs = ["@chakra-ui", "mui", "@shadcn", "antd", "bootstrap"];
|
|
63
|
+
const lib = forbiddenLibs.find(l => moduleSpecifier.text.includes(l));
|
|
64
|
+
if (lib) {
|
|
65
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
66
|
+
issues.push({ file, line: line + 1, rule: `Forbidden UI library '${lib}' usage detected` });
|
|
67
|
+
}
|
|
68
|
+
if (moduleSpecifier.text === "child_process") {
|
|
69
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
70
|
+
issues.push({ file, line: line + 1, rule: "Direct child_process module usage is forbidden. Command execution must be managed through secure framework APIs." });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Rule: child_process dynamic usage & Raw SQL templates
|
|
75
|
+
if (ts.isCallExpression(node)) {
|
|
76
|
+
const expression = node.expression;
|
|
77
|
+
if (ts.isIdentifier(expression) && expression.text === "require") {
|
|
78
|
+
const args = node.arguments;
|
|
79
|
+
if (args.length > 0 && ts.isStringLiteral(args[0]) && args[0].text === "child_process") {
|
|
80
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
81
|
+
issues.push({ file, line: line + 1, rule: "Direct child_process module usage is forbidden. Command execution must be managed through secure framework APIs." });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (node.kind === ts.SyntaxKind.ImportKeyword) {
|
|
86
|
+
const parent = node.parent;
|
|
87
|
+
if (parent && ts.isCallExpression(parent)) {
|
|
88
|
+
const args = parent.arguments;
|
|
89
|
+
if (args.length > 0 && ts.isStringLiteral(args[0]) && args[0].text === "child_process") {
|
|
90
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(parent.getStart());
|
|
91
|
+
issues.push({ file, line: line + 1, rule: "Direct child_process module usage is forbidden. Command execution must be managed through secure framework APIs." });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (ts.isTaggedTemplateExpression(node)) {
|
|
96
|
+
const tag = node.tag;
|
|
97
|
+
if (ts.isIdentifier(tag) && tag.text === "sql") {
|
|
98
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
99
|
+
issues.push({ file, line: line + 1, rule: "Raw SQL tagged template detected. Use Kysely query builder instead." });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Rule: Raw fs mutation check (Use atomic utilities)
|
|
103
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
104
|
+
const prop = node.expression;
|
|
105
|
+
if (ts.isIdentifier(prop.expression) && prop.expression.text === "fs") {
|
|
106
|
+
if (["writeFileSync", "appendFileSync"].includes(prop.name.text)) {
|
|
107
|
+
// Skip if it's explicitly allowed (e.g. lock files)
|
|
108
|
+
const args = node.arguments;
|
|
109
|
+
let isLockFile = false;
|
|
110
|
+
if (args.length > 0) {
|
|
111
|
+
const firstArgText = args[0].getText(sourceFile).toLowerCase();
|
|
112
|
+
if (firstArgText.includes("lock")) {
|
|
113
|
+
isLockFile = true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!isLockFile) {
|
|
117
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
118
|
+
issues.push({ file, line: line + 1, rule: "Use atomic utilities (writeTextFile) instead of raw fs mutations" });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
ts.forEachChild(node, visit);
|
|
124
|
+
};
|
|
125
|
+
visit(sourceFile);
|
|
126
|
+
// --- 2. Pattern-Based Analysis (For Secrets & PII & Debt) ---
|
|
127
|
+
const lines = content.split("\n");
|
|
128
|
+
const piiKeywords = [
|
|
129
|
+
{ regex: /API_KEY\s*[:=]\s*['"][^'"]+['"]/i, msg: "Hardcoded API Key" },
|
|
130
|
+
{ regex: /SECRET\s*[:=]\s*['"][^'"]+['"]/i, msg: "Hardcoded Secret" },
|
|
131
|
+
{ regex: /PASSWORD\s*[:=]\s*['"][^'"]+['"]/i, msg: "Hardcoded Password" },
|
|
132
|
+
{ regex: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/, msg: "PII Detected: Email Address" },
|
|
133
|
+
{ regex: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/, msg: "PII Detected: Credit Card Pattern" }
|
|
134
|
+
];
|
|
135
|
+
lines.forEach((line, index) => {
|
|
136
|
+
const lineNum = index + 1;
|
|
137
|
+
const trimmedLine = line.trim();
|
|
138
|
+
if (trimmedLine.startsWith("//") || trimmedLine.startsWith("*"))
|
|
139
|
+
return;
|
|
140
|
+
// PII & Secret Guard
|
|
141
|
+
for (const { regex, msg } of piiKeywords) {
|
|
142
|
+
if (regex.test(line)) {
|
|
143
|
+
// Allow emails in specific files
|
|
144
|
+
if (msg.includes("Email") && (file.endsWith("README.md") || file.endsWith("package.json") || file.includes("CONTRIBUTING"))) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
issues.push({ file, line: lineNum, rule: `Corporate Compliance Breach: ${msg}` });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Technical Debt (TODO/FIXME)
|
|
151
|
+
if (/\b(TODO|FIXME)\b/i.test(line)) {
|
|
152
|
+
issues.push({ file, line: lineNum, rule: "Unresolved Technical Debt (TODO/FIXME) found" });
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return issues;
|
|
157
|
+
}
|
|
158
|
+
function getAllFiles(dirPath, arrayOfFiles = []) {
|
|
159
|
+
const files = fs.readdirSync(dirPath);
|
|
160
|
+
files.forEach((file) => {
|
|
161
|
+
const fullPath = path.join(dirPath, file);
|
|
162
|
+
if (fs.statSync(fullPath).isDirectory()) {
|
|
163
|
+
arrayOfFiles = getAllFiles(fullPath, arrayOfFiles);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const ext = path.extname(fullPath);
|
|
167
|
+
if ([".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
|
|
168
|
+
arrayOfFiles.push(fullPath);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return arrayOfFiles;
|
|
173
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Standard Color Palette Schema
|
|
4
|
+
*/
|
|
5
|
+
export const ColorPaletteSchema = z.object({
|
|
6
|
+
primary: z.string().regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/),
|
|
7
|
+
secondary: z.string().regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/),
|
|
8
|
+
accent: z.string().regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/),
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Agent Atabey config.json Schema
|
|
12
|
+
*/
|
|
13
|
+
export const ConfigSchema = z.object({
|
|
14
|
+
name: z.string().default("Agent Atabey"),
|
|
15
|
+
version: z.string(),
|
|
16
|
+
frameworkDir: z.string().optional(),
|
|
17
|
+
theme: z.object({
|
|
18
|
+
palette: z.string(),
|
|
19
|
+
colors: ColorPaletteSchema
|
|
20
|
+
}).optional(),
|
|
21
|
+
paths: z.object({
|
|
22
|
+
backend: z.string(),
|
|
23
|
+
frontend: z.string(),
|
|
24
|
+
docs: z.string(),
|
|
25
|
+
tests: z.string(),
|
|
26
|
+
}).default({
|
|
27
|
+
backend: "apps/backend",
|
|
28
|
+
frontend: "apps/web",
|
|
29
|
+
docs: "docs",
|
|
30
|
+
tests: "tests"
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* MCP mcp.json Schema
|
|
35
|
+
*/
|
|
36
|
+
export const McpConfigSchema = z.object({
|
|
37
|
+
mcpServers: z.record(z.object({
|
|
38
|
+
command: z.string(),
|
|
39
|
+
args: z.array(z.string()),
|
|
40
|
+
env: z.record(z.string()).optional()
|
|
41
|
+
}))
|
|
42
|
+
});
|