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.
Files changed (181) hide show
  1. package/README.md +1 -1
  2. package/dist/framework-mcp/src/resources/index.js +2 -2
  3. package/dist/framework-mcp/src/resources/index.js.map +1 -1
  4. package/dist/framework-mcp/src/utils/errors.d.ts +46 -0
  5. package/dist/framework-mcp/src/utils/errors.js +69 -0
  6. package/dist/framework-mcp/src/utils/errors.js.map +1 -0
  7. package/dist/framework-mcp/src/utils/memory.d.ts +3 -0
  8. package/dist/framework-mcp/src/utils/memory.js +75 -0
  9. package/dist/framework-mcp/src/utils/memory.js.map +1 -0
  10. package/dist/framework-mcp/src/utils/storage.d.ts +60 -0
  11. package/dist/framework-mcp/src/utils/storage.js +208 -0
  12. package/dist/framework-mcp/src/utils/storage.js.map +1 -0
  13. package/dist/framework-mcp/src/utils/types.d.ts +19 -0
  14. package/dist/framework-mcp/src/utils/types.js +13 -0
  15. package/dist/framework-mcp/src/utils/types.js.map +1 -0
  16. package/dist/src/cli/adapters/core.js +12 -19
  17. package/dist/src/cli/adapters/core.js.map +1 -1
  18. package/dist/src/shared/constants.d.ts +1 -0
  19. package/dist/src/shared/constants.js +1 -0
  20. package/dist/src/shared/constants.js.map +1 -1
  21. package/dist/tests/adapter.test.js +3 -2
  22. package/dist/tests/adapter.test.js.map +1 -1
  23. package/framework-mcp/dist/constants.js +64 -0
  24. package/framework-mcp/dist/framework-mcp/src/constants.js +64 -0
  25. package/framework-mcp/dist/framework-mcp/src/index.js +144 -0
  26. package/framework-mcp/dist/framework-mcp/src/resources/index.js +58 -0
  27. package/framework-mcp/dist/framework-mcp/src/tools/control_plane/locking.js +82 -0
  28. package/framework-mcp/dist/framework-mcp/src/tools/control_plane/registry.js +35 -0
  29. package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +322 -0
  30. package/framework-mcp/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +64 -0
  31. package/framework-mcp/dist/framework-mcp/src/tools/file_system/patch_file.js +34 -0
  32. package/framework-mcp/dist/framework-mcp/src/tools/file_system/read_file.js +51 -0
  33. package/framework-mcp/dist/framework-mcp/src/tools/file_system/replace_text.js +50 -0
  34. package/framework-mcp/dist/framework-mcp/src/tools/file_system/write_file.js +43 -0
  35. package/framework-mcp/dist/framework-mcp/src/tools/framework/audit_deps.js +41 -0
  36. package/framework-mcp/dist/framework-mcp/src/tools/framework/get_status.js +5 -0
  37. package/framework-mcp/dist/framework-mcp/src/tools/framework/orchestrate.js +5 -0
  38. package/framework-mcp/dist/framework-mcp/src/tools/framework/run_tests.js +27 -0
  39. package/framework-mcp/dist/framework-mcp/src/tools/framework/submit_plan.js +13 -0
  40. package/framework-mcp/dist/framework-mcp/src/tools/framework/update_contract_hash.js +5 -0
  41. package/framework-mcp/dist/framework-mcp/src/tools/framework/update_memory.js +8 -0
  42. package/framework-mcp/dist/framework-mcp/src/tools/index.js +62 -0
  43. package/framework-mcp/dist/framework-mcp/src/tools/memory/get_insights.js +34 -0
  44. package/framework-mcp/dist/framework-mcp/src/tools/memory/read_memory.js +28 -0
  45. package/framework-mcp/dist/framework-mcp/src/tools/messaging/log_action.js +22 -0
  46. package/framework-mcp/dist/framework-mcp/src/tools/messaging/send_message.js +94 -0
  47. package/framework-mcp/dist/framework-mcp/src/tools/observability/check_ports.js +26 -0
  48. package/framework-mcp/dist/framework-mcp/src/tools/observability/get_health.js +19 -0
  49. package/framework-mcp/dist/framework-mcp/src/tools/quality/check_lint.js +30 -0
  50. package/framework-mcp/dist/framework-mcp/src/tools/search/get_gaps.js +48 -0
  51. package/framework-mcp/dist/framework-mcp/src/tools/search/get_map.js +43 -0
  52. package/framework-mcp/dist/framework-mcp/src/tools/search/grep_search.js +75 -0
  53. package/framework-mcp/dist/framework-mcp/src/tools/search/list_dir.js +28 -0
  54. package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +56 -0
  55. package/framework-mcp/dist/framework-mcp/src/tools/types.js +1 -0
  56. package/framework-mcp/dist/framework-mcp/src/utils/cli.js +59 -0
  57. package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +231 -0
  58. package/framework-mcp/dist/framework-mcp/src/utils/errors.js +68 -0
  59. package/framework-mcp/dist/framework-mcp/src/utils/fs.js +44 -0
  60. package/framework-mcp/dist/framework-mcp/src/utils/memory.js +74 -0
  61. package/framework-mcp/dist/framework-mcp/src/utils/metrics.js +56 -0
  62. package/framework-mcp/dist/framework-mcp/src/utils/permissions.js +71 -0
  63. package/framework-mcp/dist/framework-mcp/src/utils/security.js +60 -0
  64. package/framework-mcp/dist/framework-mcp/src/utils/storage.js +207 -0
  65. package/framework-mcp/dist/framework-mcp/src/utils/types.js +12 -0
  66. package/framework-mcp/dist/index.js +144 -0
  67. package/framework-mcp/dist/resources/index.js +58 -0
  68. package/framework-mcp/dist/src/cli/adapters/core.js +71 -0
  69. package/framework-mcp/dist/src/cli/adapters/index.js +5 -0
  70. package/framework-mcp/dist/src/cli/adapters/paths.js +101 -0
  71. package/framework-mcp/dist/src/cli/adapters/scaffold.js +71 -0
  72. package/framework-mcp/dist/src/cli/adapters/utils.js +75 -0
  73. package/framework-mcp/dist/src/cli/commands/approve.js +63 -0
  74. package/framework-mcp/dist/src/cli/commands/check.js +181 -0
  75. package/framework-mcp/dist/src/cli/commands/compliance.js +50 -0
  76. package/framework-mcp/dist/src/cli/commands/contract.js +50 -0
  77. package/framework-mcp/dist/src/cli/commands/dashboard.js +123 -0
  78. package/framework-mcp/dist/src/cli/commands/explorer.js +42 -0
  79. package/framework-mcp/dist/src/cli/commands/git.js +40 -0
  80. package/framework-mcp/dist/src/cli/commands/init/create-agent.js +58 -0
  81. package/framework-mcp/dist/src/cli/commands/init/scaffold-core.js +112 -0
  82. package/framework-mcp/dist/src/cli/commands/init/scaffold-docs.js +34 -0
  83. package/framework-mcp/dist/src/cli/commands/init/scaffold-ops.js +80 -0
  84. package/framework-mcp/dist/src/cli/commands/init/scaffold-standards.js +67 -0
  85. package/framework-mcp/dist/src/cli/commands/init.js +167 -0
  86. package/framework-mcp/dist/src/cli/commands/knowledge.js +42 -0
  87. package/framework-mcp/dist/src/cli/commands/lint.js +22 -0
  88. package/framework-mcp/dist/src/cli/commands/log.js +10 -0
  89. package/framework-mcp/dist/src/cli/commands/memory.js +4 -0
  90. package/framework-mcp/dist/src/cli/commands/orchestrate.js +159 -0
  91. package/framework-mcp/dist/src/cli/commands/plan.js +117 -0
  92. package/framework-mcp/dist/src/cli/commands/script.js +19 -0
  93. package/framework-mcp/dist/src/cli/commands/security.js +36 -0
  94. package/framework-mcp/dist/src/cli/commands/status.js +97 -0
  95. package/framework-mcp/dist/src/cli/commands/trace.js +109 -0
  96. package/framework-mcp/dist/src/cli/index.js +338 -0
  97. package/framework-mcp/dist/src/cli/shims.js +66 -0
  98. package/framework-mcp/dist/src/cli/utils/claude.js +56 -0
  99. package/framework-mcp/dist/src/cli/utils/compliance.js +173 -0
  100. package/framework-mcp/dist/src/cli/utils/config-schema.js +42 -0
  101. package/framework-mcp/dist/src/cli/utils/fs.js +137 -0
  102. package/framework-mcp/dist/src/cli/utils/i18n.js +30 -0
  103. package/framework-mcp/dist/src/cli/utils/memory.js +276 -0
  104. package/framework-mcp/dist/src/cli/utils/pkg.js +282 -0
  105. package/framework-mcp/dist/src/cli/utils/schemas.js +19 -0
  106. package/framework-mcp/dist/src/cli/utils/string.js +49 -0
  107. package/framework-mcp/dist/src/cli/utils/time.js +27 -0
  108. package/framework-mcp/dist/src/cli/utils/ui.js +58 -0
  109. package/framework-mcp/dist/src/contracts/index.js +1 -0
  110. package/framework-mcp/dist/src/contracts/tasks.js +20 -0
  111. package/framework-mcp/dist/src/dashboard/vite.config.js +15 -0
  112. package/framework-mcp/dist/src/modules/adapters/definitions.js +140 -0
  113. package/framework-mcp/dist/src/modules/adapters/registry.js +18 -0
  114. package/framework-mcp/dist/src/modules/adapters/shared.js +104 -0
  115. package/framework-mcp/dist/src/modules/adapters/types.js +1 -0
  116. package/framework-mcp/dist/src/modules/agents/definitions.js +457 -0
  117. package/framework-mcp/dist/src/modules/agents/registry/analyst.js +39 -0
  118. package/framework-mcp/dist/src/modules/agents/registry/architect.js +42 -0
  119. package/framework-mcp/dist/src/modules/agents/registry/backend.js +49 -0
  120. package/framework-mcp/dist/src/modules/agents/registry/database.js +45 -0
  121. package/framework-mcp/dist/src/modules/agents/registry/devops.js +45 -0
  122. package/framework-mcp/dist/src/modules/agents/registry/explorer.js +36 -0
  123. package/framework-mcp/dist/src/modules/agents/registry/frontend.js +51 -0
  124. package/framework-mcp/dist/src/modules/agents/registry/git.js +36 -0
  125. package/framework-mcp/dist/src/modules/agents/registry/manager.js +53 -0
  126. package/framework-mcp/dist/src/modules/agents/registry/mobile.js +39 -0
  127. package/framework-mcp/dist/src/modules/agents/registry/native.js +39 -0
  128. package/framework-mcp/dist/src/modules/agents/registry/quality.js +41 -0
  129. package/framework-mcp/dist/src/modules/agents/registry/security.js +43 -0
  130. package/framework-mcp/dist/src/modules/agents/types.js +1 -0
  131. package/framework-mcp/dist/src/modules/engines/evaluation-engine.js +102 -0
  132. package/framework-mcp/dist/src/modules/engines/health-engine.js +49 -0
  133. package/framework-mcp/dist/src/modules/engines/planning-engine.js +78 -0
  134. package/framework-mcp/dist/src/modules/engines/risk-engine.js +105 -0
  135. package/framework-mcp/dist/src/modules/engines/routing-engine.js +73 -0
  136. package/framework-mcp/dist/src/modules/engines/types.js +1 -0
  137. package/framework-mcp/dist/src/modules/skills/definitions.js +70 -0
  138. package/framework-mcp/dist/src/shared/constants.js +187 -0
  139. package/framework-mcp/dist/src/shared/errors.js +68 -0
  140. package/framework-mcp/dist/src/shared/fs.js +51 -0
  141. package/framework-mcp/dist/src/shared/logger.js +116 -0
  142. package/framework-mcp/dist/src/shared/storage.js +207 -0
  143. package/framework-mcp/dist/src/shared/types.js +12 -0
  144. package/framework-mcp/dist/tools/control_plane/locking.js +82 -0
  145. package/framework-mcp/dist/tools/control_plane/registry.js +35 -0
  146. package/framework-mcp/dist/tools/definitions.js +322 -0
  147. package/framework-mcp/dist/tools/file_system/batch_surgical_edit.js +64 -0
  148. package/framework-mcp/dist/tools/file_system/patch_file.js +34 -0
  149. package/framework-mcp/dist/tools/file_system/read_file.js +51 -0
  150. package/framework-mcp/dist/tools/file_system/replace_text.js +50 -0
  151. package/framework-mcp/dist/tools/file_system/write_file.js +43 -0
  152. package/framework-mcp/dist/tools/framework/audit_deps.js +41 -0
  153. package/framework-mcp/dist/tools/framework/get_status.js +5 -0
  154. package/framework-mcp/dist/tools/framework/orchestrate.js +5 -0
  155. package/framework-mcp/dist/tools/framework/run_tests.js +27 -0
  156. package/framework-mcp/dist/tools/framework/submit_plan.js +13 -0
  157. package/framework-mcp/dist/tools/framework/update_contract_hash.js +5 -0
  158. package/framework-mcp/dist/tools/framework/update_memory.js +8 -0
  159. package/framework-mcp/dist/tools/index.js +62 -0
  160. package/framework-mcp/dist/tools/memory/get_insights.js +34 -0
  161. package/framework-mcp/dist/tools/memory/read_memory.js +28 -0
  162. package/framework-mcp/dist/tools/messaging/log_action.js +22 -0
  163. package/framework-mcp/dist/tools/messaging/send_message.js +94 -0
  164. package/framework-mcp/dist/tools/observability/check_ports.js +26 -0
  165. package/framework-mcp/dist/tools/observability/get_health.js +19 -0
  166. package/framework-mcp/dist/tools/quality/check_lint.js +30 -0
  167. package/framework-mcp/dist/tools/search/get_gaps.js +48 -0
  168. package/framework-mcp/dist/tools/search/get_map.js +43 -0
  169. package/framework-mcp/dist/tools/search/grep_search.js +75 -0
  170. package/framework-mcp/dist/tools/search/list_dir.js +28 -0
  171. package/framework-mcp/dist/tools/shell/run_command.js +56 -0
  172. package/framework-mcp/dist/tools/types.js +1 -0
  173. package/framework-mcp/dist/utils/cli.js +59 -0
  174. package/framework-mcp/dist/utils/compliance.js +231 -0
  175. package/framework-mcp/dist/utils/fs.js +44 -0
  176. package/framework-mcp/dist/utils/metrics.js +56 -0
  177. package/framework-mcp/dist/utils/permissions.js +71 -0
  178. package/framework-mcp/dist/utils/security.js +60 -0
  179. package/framework-mcp/package.json +37 -0
  180. package/mcp.json +1 -1
  181. package/package.json +10 -5
@@ -0,0 +1,207 @@
1
+ import Database from "better-sqlite3";
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { getFrameworkDir } from "./memory.js";
5
+ /**
6
+ * [DB] Atabey Storage Engine
7
+ * Central SQLite database for enterprise-scale agent state management.
8
+ */
9
+ export class Storage {
10
+ static db = null;
11
+ static getDB() {
12
+ if (!this.db) {
13
+ const frameworkDir = getFrameworkDir();
14
+ if (!fs.existsSync(frameworkDir)) {
15
+ fs.mkdirSync(frameworkDir, { recursive: true });
16
+ }
17
+ const dbPath = path.join(frameworkDir, "atabey.db");
18
+ this.db = new Database(dbPath);
19
+ this.initializeSchema();
20
+ }
21
+ return this.db;
22
+ }
23
+ static initializeSchema() {
24
+ const db = this.db;
25
+ // Agents Table
26
+ db.exec(`
27
+ CREATE TABLE IF NOT EXISTS agents (
28
+ name TEXT PRIMARY KEY,
29
+ state TEXT DEFAULT 'READY',
30
+ task TEXT DEFAULT 'Idle',
31
+ last_updated DATETIME DEFAULT CURRENT_TIMESTAMP
32
+ )
33
+ `);
34
+ // Messages (Hermes) Table
35
+ db.exec(`
36
+ CREATE TABLE IF NOT EXISTS messages (
37
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
38
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
39
+ sender TEXT,
40
+ receiver TEXT,
41
+ category TEXT,
42
+ content TEXT,
43
+ trace_id TEXT,
44
+ parent_id TEXT,
45
+ status TEXT DEFAULT 'PENDING',
46
+ priority TEXT DEFAULT 'NORMAL',
47
+ requires_approval BOOLEAN DEFAULT 0
48
+ )
49
+ `);
50
+ // Tasks Table
51
+ db.exec(`
52
+ CREATE TABLE IF NOT EXISTS tasks (
53
+ id TEXT PRIMARY KEY,
54
+ trace_id TEXT,
55
+ description TEXT,
56
+ agent TEXT,
57
+ status TEXT DEFAULT 'PENDING',
58
+ priority TEXT DEFAULT 'NORMAL',
59
+ dependencies TEXT, -- JSON Array
60
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
61
+ )
62
+ `);
63
+ // Logs Table
64
+ db.exec(`
65
+ CREATE TABLE IF NOT EXISTS logs (
66
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
67
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
68
+ agent TEXT,
69
+ action TEXT,
70
+ trace_id TEXT,
71
+ status TEXT,
72
+ summary TEXT,
73
+ findings TEXT
74
+ )
75
+ `);
76
+ // Metadata (State) Table
77
+ db.exec(`
78
+ CREATE TABLE IF NOT EXISTS metadata (
79
+ key TEXT PRIMARY KEY,
80
+ value TEXT
81
+ )
82
+ `);
83
+ }
84
+ // --- Agent Operations ---
85
+ static updateAgentStatus(name, state, task, lastUpdated) {
86
+ const db = this.getDB();
87
+ const cleanName = name.replace("@", "");
88
+ const timestamp = lastUpdated || new Date().toISOString();
89
+ db.prepare(`
90
+ INSERT INTO agents (name, state, task, last_updated)
91
+ VALUES (?, ?, ?, ?)
92
+ ON CONFLICT(name) DO UPDATE SET
93
+ state = excluded.state,
94
+ task = excluded.task,
95
+ last_updated = excluded.last_updated
96
+ `).run(cleanName, state, task, timestamp);
97
+ }
98
+ static getAllAgents() {
99
+ return this.getDB().prepare("SELECT * FROM agents").all();
100
+ }
101
+ // --- Message Operations ---
102
+ static saveMessage(msg) {
103
+ const db = this.getDB();
104
+ db.prepare(`
105
+ INSERT INTO messages (sender, receiver, category, content, trace_id, parent_id, status, priority, requires_approval)
106
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
107
+ `).run(msg.from, msg.to, msg.category, msg.content, msg.traceId, msg.parentId || null, msg.status || "PENDING", msg.priority || "NORMAL", msg.requiresApproval ? 1 : 0);
108
+ }
109
+ static getPendingMessages() {
110
+ const rows = this.getDB().prepare("SELECT * FROM messages WHERE status IN ('PENDING', 'APPROVED') ORDER BY priority DESC, timestamp ASC").all();
111
+ return rows.map(r => ({
112
+ id: r.id,
113
+ timestamp: r.timestamp,
114
+ from: r.sender,
115
+ to: r.receiver,
116
+ category: r.category,
117
+ content: r.content,
118
+ traceId: r.trace_id,
119
+ parentId: r.parent_id || undefined,
120
+ status: r.status,
121
+ priority: r.priority,
122
+ requiresApproval: r.requires_approval === 1
123
+ }));
124
+ }
125
+ static updateMessageStatus(id, status) {
126
+ this.getDB().prepare("UPDATE messages SET status = ? WHERE id = ?").run(status, id);
127
+ }
128
+ // --- Task Operations ---
129
+ static saveTask(task) {
130
+ const db = this.getDB();
131
+ db.prepare(`
132
+ INSERT INTO tasks (id, trace_id, description, agent, status, priority, dependencies)
133
+ VALUES (?, ?, ?, ?, ?, ?, ?)
134
+ ON CONFLICT(id) DO UPDATE SET
135
+ status = excluded.status,
136
+ description = excluded.description
137
+ `).run(task.id, task.traceId, task.description, task.agent, task.status, task.priority, JSON.stringify(task.dependencies || []));
138
+ }
139
+ static getTasks(traceId) {
140
+ const db = this.getDB();
141
+ let rows;
142
+ if (traceId) {
143
+ rows = db.prepare("SELECT * FROM tasks WHERE trace_id = ?").all(traceId);
144
+ }
145
+ else {
146
+ rows = db.prepare("SELECT * FROM tasks").all();
147
+ }
148
+ return rows.map(r => {
149
+ let deps = [];
150
+ try {
151
+ const parsed = JSON.parse(r.dependencies || "[]");
152
+ // Handle cases where dependencies might be double-stringified or are raw JSON strings
153
+ deps = Array.isArray(parsed) ? parsed : JSON.parse(parsed);
154
+ }
155
+ catch {
156
+ // Keep empty array
157
+ }
158
+ return {
159
+ id: r.id,
160
+ traceId: r.trace_id,
161
+ description: r.description,
162
+ agent: r.agent,
163
+ status: r.status,
164
+ priority: r.priority,
165
+ dependencies: deps
166
+ };
167
+ });
168
+ }
169
+ static getLogs(agentName) {
170
+ const db = this.getDB();
171
+ let rows;
172
+ const cleanName = agentName ? agentName.replace("@", "") : undefined;
173
+ if (cleanName) {
174
+ rows = db.prepare("SELECT * FROM logs WHERE agent = ? ORDER BY timestamp DESC").all(cleanName);
175
+ }
176
+ else {
177
+ rows = db.prepare("SELECT * FROM logs ORDER BY timestamp DESC").all();
178
+ }
179
+ return rows.map(r => ({
180
+ id: r.id,
181
+ timestamp: r.timestamp,
182
+ agent: r.agent,
183
+ action: r.action,
184
+ trace_id: r.trace_id || undefined,
185
+ status: r.status,
186
+ summary: r.summary,
187
+ findings: r.findings || undefined
188
+ }));
189
+ }
190
+ // --- Metadata Operations ---
191
+ static setMetadata(key, value) {
192
+ this.getDB().prepare(`
193
+ INSERT INTO metadata (key, value) VALUES (?, ?)
194
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value
195
+ `).run(key, value);
196
+ }
197
+ static getMetadata(key) {
198
+ const row = this.getDB().prepare("SELECT value FROM metadata WHERE key = ?").get(key);
199
+ return row ? row.value : null;
200
+ }
201
+ static reset() {
202
+ if (this.db) {
203
+ this.db.close();
204
+ this.db = null;
205
+ }
206
+ }
207
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Agent Atabey Framework — Internal Branded Types
3
+ * Used to enforce absolute type safety within the core orchestration logic.
4
+ */
5
+ /**
6
+ * Casts a raw string to a Branded Type.
7
+ * Use this only at the boundaries of the system.
8
+ */
9
+ export function asTraceID(val) { return val; }
10
+ export function asAgentID(val) { return val; }
11
+ export function asPhaseID(val) { return val; }
12
+ export function asProjectPath(val) { return val; }
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
8
+ import { TOOLS, toolHandlers } from "./tools/index.js";
9
+ import { RESOURCES, handleReadResource } from "./resources/index.js";
10
+ // ─── Server Setup ─────────────────────────────────────────────────
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+ // Robustly find package.json by walking up from __dirname
13
+ function findPackageJson(startDir) {
14
+ let currentDir = startDir;
15
+ while (currentDir !== path.parse(currentDir).root) {
16
+ const pkgPath = path.join(currentDir, "package.json");
17
+ if (fs.existsSync(pkgPath))
18
+ return pkgPath;
19
+ currentDir = path.dirname(currentDir);
20
+ }
21
+ throw new Error("Could not find package.json for atabey-mcp");
22
+ }
23
+ const pkgPath = findPackageJson(__dirname);
24
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
25
+ const serverVersion = pkg.version;
26
+ const server = new Server({
27
+ name: "atabey-mcp",
28
+ version: serverVersion,
29
+ }, {
30
+ capabilities: {
31
+ tools: {},
32
+ resources: {},
33
+ },
34
+ });
35
+ // Basic Schema Validator for Required Fields
36
+ function validateArgs(toolName, args) {
37
+ const definition = TOOLS.find(t => t.name === toolName);
38
+ if (!definition)
39
+ return `Unknown tool: ${toolName}`;
40
+ const required = definition.inputSchema.required || [];
41
+ for (const field of required) {
42
+ if (args[field] === undefined || args[field] === null || args[field] === "") {
43
+ return `Missing required argument: '${field}' for tool '${toolName}'`;
44
+ }
45
+ }
46
+ return null;
47
+ }
48
+ server.setRequestHandler(ListToolsRequestSchema, async (request) => {
49
+ // 2026 Stateless Spec: Log client info from metadata if available
50
+ const meta = request._meta;
51
+ if (meta) {
52
+ process.stderr.write(`[MCP] Stateless ListTools from ${meta.client?.name || "unknown"} v${meta.client?.version || "?.?"}\n`);
53
+ }
54
+ return { tools: TOOLS };
55
+ });
56
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
57
+ return { resources: RESOURCES };
58
+ });
59
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
60
+ const uri = request.params.uri;
61
+ try {
62
+ const content = await handleReadResource(uri);
63
+ return {
64
+ contents: [
65
+ {
66
+ uri,
67
+ mimeType: "text/markdown",
68
+ text: content,
69
+ },
70
+ ],
71
+ };
72
+ }
73
+ catch (error) {
74
+ const message = error instanceof Error ? error.message : String(error);
75
+ throw new Error(`Failed to read resource: ${message}`, { cause: error });
76
+ }
77
+ });
78
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
79
+ const req = request;
80
+ const { name, arguments: args } = req.params;
81
+ const meta = request._meta;
82
+ // 2026 Stateless Spec: Prioritize metadata-driven context
83
+ if (meta) {
84
+ process.stderr.write(`[MCP] Stateless CallTool: ${name} (Client: ${meta.client?.name || "unknown"})\n`);
85
+ }
86
+ const projectRoot = process.env.ATABEY_PROJECT_ROOT || process.cwd();
87
+ try {
88
+ const handler = toolHandlers[name];
89
+ if (!handler) {
90
+ return {
91
+ isError: true,
92
+ content: [{ type: "text", text: `[ERROR] Unknown tool: ${name}` }],
93
+ };
94
+ }
95
+ // [SECURITY] Runtime Validation
96
+ const validationError = validateArgs(name, args || {});
97
+ if (validationError) {
98
+ return {
99
+ isError: true,
100
+ content: [{ type: "text", text: `[ERROR] Validation Error: ${validationError}` }],
101
+ };
102
+ }
103
+ return await handler(projectRoot, args || {});
104
+ }
105
+ catch (error) {
106
+ const message = error instanceof Error ? error.message : "Unknown error occurred";
107
+ return {
108
+ isError: true,
109
+ content: [{ type: "text", text: `[ERROR] Execution failed: ${message}` }],
110
+ };
111
+ }
112
+ });
113
+ // ─── Graceful Startup & Shutdown ──────────────────────────────────
114
+ async function run() {
115
+ const transport = new StdioServerTransport();
116
+ // Prevent unhandled errors from crashing the MCP stream
117
+ process.on("uncaughtException", (error) => {
118
+ process.stderr.write(`[atabey-mcp] Uncaught exception: ${error.message}
119
+ `);
120
+ });
121
+ process.on("unhandledRejection", (reason) => {
122
+ const message = reason instanceof Error ? reason.message : String(reason);
123
+ process.stderr.write(`[atabey-mcp] Unhandled rejection: ${message}
124
+ `);
125
+ });
126
+ // Graceful shutdown on SIGINT/SIGTERM
127
+ const shutdown = async () => {
128
+ try {
129
+ await server.close();
130
+ }
131
+ catch {
132
+ // Already closed or failed — safe to ignore
133
+ }
134
+ process.exit(0);
135
+ };
136
+ process.on("SIGINT", shutdown);
137
+ process.on("SIGTERM", shutdown);
138
+ await server.connect(transport);
139
+ }
140
+ run().catch((error) => {
141
+ process.stderr.write(`[atabey-mcp] Fatal startup error: ${error.message}
142
+ `);
143
+ process.exit(1);
144
+ });
@@ -0,0 +1,58 @@
1
+ import { Storage } from "../../../src/shared/storage.js";
2
+ /**
3
+ * [DATA] MCP Resource Definitions
4
+ */
5
+ export const RESOURCES = [
6
+ {
7
+ uri: "atabey://army/status",
8
+ name: "Agent Army Status",
9
+ description: "Real-time state and active tasks of all specialized agents.",
10
+ mimeType: "text/markdown"
11
+ },
12
+ {
13
+ uri: "atabey://plan/active",
14
+ name: "Active Execution Plan",
15
+ description: "The current DAG of tasks and their completion status.",
16
+ mimeType: "text/markdown"
17
+ },
18
+ {
19
+ uri: "atabey://memory/project",
20
+ name: "Project Memory",
21
+ description: "The central source of truth for project context (PROJECT_MEMORY.md).",
22
+ mimeType: "text/markdown"
23
+ }
24
+ ];
25
+ export async function handleReadResource(uri) {
26
+ if (uri === "atabey://army/status") {
27
+ const agents = Storage.getAllAgents();
28
+ let md = "# [AI] Agent Army Status\n\n| Agent | State | Active Task | Last Updated |\n| :--- | :--- | :--- | :--- |\n";
29
+ agents.forEach((a) => {
30
+ md += `| @${a.name} | ${a.state} | ${a.task} | ${a.last_updated} |\n`;
31
+ });
32
+ return md;
33
+ }
34
+ if (uri === "atabey://plan/active") {
35
+ const tasks = Storage.getTasks();
36
+ let md = "# 📋 Active Execution Plan\n\n| ID | Task | Agent | Status | Dependencies |\n| :--- | :--- | :--- | :--- | :--- |\n";
37
+ tasks.forEach((t) => {
38
+ const deps = t.dependencies.join(", ") || "-";
39
+ md += `| ${t.id} | ${t.description} | ${t.agent} | ${t.status} | ${deps} |\n`;
40
+ });
41
+ return md;
42
+ }
43
+ if (uri === "atabey://memory/project") {
44
+ const fs = await import("fs");
45
+ const path = await import("path");
46
+ const { getFrameworkDir } = await import("../../../src/cli/utils/memory.js");
47
+ const projectRoot = process.env.ATABEY_PROJECT_ROOT || process.cwd();
48
+ const fwDir = getFrameworkDir();
49
+ const p = path.isAbsolute(fwDir)
50
+ ? path.join(fwDir, "memory", "PROJECT_MEMORY.md")
51
+ : path.join(projectRoot, fwDir, "memory", "PROJECT_MEMORY.md");
52
+ if (fs.existsSync(p)) {
53
+ return fs.readFileSync(p, "utf8");
54
+ }
55
+ return "Project memory not found. Run 'atabey init' first.";
56
+ }
57
+ throw new Error(`Unknown resource URI: ${uri}`);
58
+ }
@@ -0,0 +1,71 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { writeJsonFile } from "../utils/fs.js";
4
+ import { getPackageRoot } from "../utils/pkg.js";
5
+ import { MCP } from "../../shared/constants.js";
6
+ import { ADAPTER_CONFIGS, POST_INIT_HANDLERS } from "../../modules/adapters/definitions.js";
7
+ export const ADAPTERS = ADAPTER_CONFIGS;
8
+ export const SHIM_FILES = Object.keys(ADAPTERS).map((id) => ADAPTERS[id].shimFile);
9
+ export const FRAMEWORK_DIR_CANDIDATES = [
10
+ ".atabey",
11
+ ".cursor",
12
+ ".claude",
13
+ ".github",
14
+ ".grok",
15
+ ".antigravity",
16
+ ".agent",
17
+ ".gemini/antigravity-cli",
18
+ ".gemini",
19
+ ".agents",
20
+ "antigravity-cli"
21
+ ];
22
+ export function buildMcpServerEntry(projectRoot) {
23
+ const packageRoot = getPackageRoot();
24
+ // Check if we are running in the framework local development repository itself
25
+ const isLocalFrameworkDev = path.resolve(packageRoot) === path.resolve(projectRoot);
26
+ let relativePath;
27
+ if (isLocalFrameworkDev) {
28
+ // In local framework dev, always use the build path directly relative to project root
29
+ let mcpServerPath = path.join(packageRoot, MCP.SERVER_DIST_PATH);
30
+ if (!fs.existsSync(mcpServerPath)) {
31
+ mcpServerPath = path.join(packageRoot, "../atabey-mcp/dist/index.js");
32
+ }
33
+ if (!fs.existsSync(mcpServerPath)) {
34
+ mcpServerPath = path.join(projectRoot, "node_modules/atabey-mcp/dist/index.js");
35
+ }
36
+ if (!fs.existsSync(mcpServerPath)) {
37
+ console.warn("[WARN] MCP Server not found. Did you run 'npm run build' inside atabey-mcp?");
38
+ }
39
+ relativePath = path.relative(projectRoot, mcpServerPath) || mcpServerPath;
40
+ }
41
+ else {
42
+ // If we are initializing in a user's project:
43
+ // We target the atabey-mcp package which is a dependency of atabey.
44
+ // This ensures a stable path across different npm/pnpm/yarn setups.
45
+ relativePath = "node_modules/atabey-mcp/dist/index.js";
46
+ // Fallback check if it actually exists in a different location during init
47
+ const localAtabeyPath = path.join(projectRoot, "node_modules/atabey", MCP.SERVER_DIST_PATH);
48
+ if (!fs.existsSync(path.join(projectRoot, relativePath)) && fs.existsSync(localAtabeyPath)) {
49
+ relativePath = path.join("node_modules/atabey", MCP.SERVER_DIST_PATH);
50
+ }
51
+ }
52
+ return {
53
+ command: "node",
54
+ args: [relativePath],
55
+ env: {
56
+ [MCP.PROJECT_ROOT_ENV]: projectRoot,
57
+ },
58
+ };
59
+ }
60
+ export function runAdapterPostInit(adapter, projectRoot) {
61
+ const mcpEntry = buildMcpServerEntry(projectRoot);
62
+ const mcpBlock = { mcpServers: { [MCP.SERVER_NAME]: mcpEntry } };
63
+ const postInitFn = POST_INIT_HANDLERS[adapter.id];
64
+ if (postInitFn) {
65
+ postInitFn(projectRoot, mcpBlock);
66
+ }
67
+ const rootMcpPath = path.join(projectRoot, MCP.ROOT_CONFIG_FILE);
68
+ if (!fs.existsSync(rootMcpPath)) {
69
+ writeJsonFile(rootMcpPath, mcpBlock);
70
+ }
71
+ }
@@ -0,0 +1,5 @@
1
+ export { ADAPTER_IDS } from "../../modules/adapters/types.js";
2
+ export { ADAPTERS, FRAMEWORK_DIR_CANDIDATES, runAdapterPostInit, buildMcpServerEntry } from "./core.js";
3
+ export { resolveAdapter, isAdapterShimFile, remapFrameworkContent } from "./utils.js";
4
+ export { scaffoldAgents } from "./scaffold.js";
5
+ export { resolveAgentsDir, mirrorUnifiedAgentsToNative } from "./paths.js";
@@ -0,0 +1,101 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { ADAPTER_IDS } from "../../modules/adapters/types.js";
4
+ import { LEGACY_AGENT_LAYOUT_BASES, UNIFIED_ADAPTER_SLUG, UNIFIED_HUB_DIR, pathJoin, unifiedAdapterPath, } from "../../shared/constants.js";
5
+ import { ADAPTERS } from "./core.js";
6
+ export { CORE_FRAMEWORK_DIR, UNIFIED_HUB_DIR, UNIFIED_ADAPTER_SLUG, } from "../../shared/constants.js";
7
+ export function unifiedAdapterRoot(aiToolDir, adapterId) {
8
+ return pathJoin(aiToolDir, UNIFIED_ADAPTER_SLUG[adapterId]);
9
+ }
10
+ export function resolveAgentsDir(adapterId, isUnified, aiToolDir = UNIFIED_HUB_DIR) {
11
+ const adapter = ADAPTERS[adapterId];
12
+ if (!isUnified) {
13
+ return {
14
+ agentsDir: adapter.agentsDir ?? pathJoin(adapter.frameworkDir, "agents"),
15
+ agentsExt: adapter.agentsExt ?? ".md",
16
+ nestedAntigravity: adapterId === "antigravity-cli",
17
+ };
18
+ }
19
+ const base = unifiedAdapterRoot(aiToolDir, adapterId);
20
+ switch (adapterId) {
21
+ case "cursor":
22
+ return { agentsDir: pathJoin(base, "rules"), agentsExt: ".mdc", nestedAntigravity: false };
23
+ case "codex":
24
+ return { agentsDir: pathJoin(base, "instructions"), agentsExt: ".md", nestedAntigravity: false };
25
+ case "antigravity-cli":
26
+ // Antigravity CLI expects workspace agents at .agents/agents/{agent_name}/agent.json
27
+ return { agentsDir: pathJoin(aiToolDir, "agents"), agentsExt: ".json", nestedAntigravity: true };
28
+ default:
29
+ return { agentsDir: pathJoin(base, "agents"), agentsExt: ".md", nestedAntigravity: false };
30
+ }
31
+ }
32
+ export function getUnifiedAgentLayoutBases(aiToolDir = UNIFIED_HUB_DIR) {
33
+ return ADAPTER_IDS.map((id) => resolveAgentsDir(id, true, aiToolDir).agentsDir);
34
+ }
35
+ const AGENT_INSTRUCTION_CANDIDATES = [
36
+ (n) => ADAPTER_IDS.flatMap((id) => {
37
+ const { agentsDir, nestedAntigravity, agentsExt } = resolveAgentsDir(id, true);
38
+ if (nestedAntigravity) {
39
+ return [pathJoin(agentsDir, n, "agent.json"), pathJoin(agentsDir, n, "agent.md")];
40
+ }
41
+ return [pathJoin(agentsDir, `${n}${agentsExt}`)];
42
+ }),
43
+ (n) => LEGACY_AGENT_LAYOUT_BASES.flatMap((base) => {
44
+ if (base.includes("antigravity")) {
45
+ return [pathJoin(base, n, "agent.json"), pathJoin(base, n, "agent.md")];
46
+ }
47
+ const ext = base.includes("rules") ? ".mdc" : ".md";
48
+ return [pathJoin(base, `${n}${ext}`)];
49
+ }),
50
+ ];
51
+ export function findAgentInstruction(projectRoot, agentName) {
52
+ for (const buildPaths of AGENT_INSTRUCTION_CANDIDATES) {
53
+ for (const rel of buildPaths(agentName)) {
54
+ const full = path.join(projectRoot, rel);
55
+ if (fs.existsSync(full))
56
+ return rel;
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+ export function detectActiveAgentLayouts(projectRoot) {
62
+ const unified = getUnifiedAgentLayoutBases()
63
+ .filter((b) => fs.existsSync(path.join(projectRoot, b)));
64
+ const legacy = LEGACY_AGENT_LAYOUT_BASES
65
+ .filter((b) => fs.existsSync(path.join(projectRoot, b)));
66
+ return [...new Set([...unified, ...legacy])];
67
+ }
68
+ function copyDirectoryRecursive(src, dest) {
69
+ fs.mkdirSync(dest, { recursive: true });
70
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
71
+ const srcPath = path.join(src, entry.name);
72
+ const destPath = path.join(dest, entry.name);
73
+ if (entry.isDirectory()) {
74
+ copyDirectoryRecursive(srcPath, destPath);
75
+ }
76
+ else {
77
+ fs.copyFileSync(srcPath, destPath);
78
+ }
79
+ }
80
+ }
81
+ export function mirrorUnifiedAgentsToNative(projectRoot, adapterId) {
82
+ const { agentsDir: unifiedDir } = resolveAgentsDir(adapterId, true);
83
+ const nativeRel = ADAPTERS[adapterId].agentsDir;
84
+ if (!nativeRel)
85
+ return;
86
+ const src = path.join(projectRoot, unifiedDir);
87
+ const dest = path.join(projectRoot, nativeRel);
88
+ if (!fs.existsSync(src) || path.resolve(src) === path.resolve(dest))
89
+ return;
90
+ if (fs.existsSync(dest)) {
91
+ fs.rmSync(dest, { recursive: true, force: true });
92
+ }
93
+ copyDirectoryRecursive(src, dest);
94
+ }
95
+ /** Cursor global rule destinations (native + unified hub). */
96
+ export function getCursorGlobalRulePaths(projectRoot) {
97
+ return [
98
+ path.join(projectRoot, ADAPTERS.cursor.frameworkDir, "rules", "global.mdc"),
99
+ path.join(projectRoot, unifiedAdapterPath(UNIFIED_ADAPTER_SLUG.cursor, "rules", "global.mdc")),
100
+ ];
101
+ }
@@ -0,0 +1,71 @@
1
+ import { writeTextFile } from "../utils/fs.js";
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { getPackageRoot } from "../utils/pkg.js";
5
+ import { ALL_AGENTS, toClaudeCodeMd, toGeminiCliMd, toCodexMd, toAntigravityJson, toCursorMdc } from "../../modules/agents/definitions.js";
6
+ import { ADAPTERS } from "./core.js";
7
+ export function scaffoldAgents(projectRoot, adapterId, dryRun, agentsToScaffold, explicitDestDir, explicitExt, paths, backendLanguage, _language) {
8
+ const adapter = ADAPTERS[adapterId];
9
+ if (!adapter)
10
+ return;
11
+ const allowedAgents = agentsToScaffold ? new Set(agentsToScaffold) : undefined;
12
+ const destAgentsDir = explicitDestDir ? path.join(projectRoot, explicitDestDir) : (adapter.agentsDir ? path.join(projectRoot, adapter.agentsDir) : null);
13
+ const extension = explicitExt || adapter.agentsExt || ".md";
14
+ if (!destAgentsDir)
15
+ return;
16
+ const baseKnowledgeDir = path.join(getPackageRoot(), "templates/standards");
17
+ try {
18
+ if (!dryRun)
19
+ fs.mkdirSync(destAgentsDir, { recursive: true });
20
+ for (const agent of ALL_AGENTS) {
21
+ if (allowedAgents && !allowedAgents.has(agent.name))
22
+ continue;
23
+ let content = "";
24
+ let fileName = `${agent.name}${extension}`;
25
+ let secondaryContent = null;
26
+ let secondaryFileName = null;
27
+ switch (adapterId) {
28
+ case "gemini":
29
+ content = toGeminiCliMd(agent, baseKnowledgeDir, paths, backendLanguage);
30
+ break;
31
+ case "grok":
32
+ // Grok uses same Gemini-compatible YAML format
33
+ content = toGeminiCliMd(agent, baseKnowledgeDir, paths, backendLanguage);
34
+ break;
35
+ case "claude":
36
+ content = toClaudeCodeMd(agent, baseKnowledgeDir, paths, backendLanguage);
37
+ break;
38
+ case "cursor":
39
+ content = toCursorMdc(agent, baseKnowledgeDir, paths, backendLanguage);
40
+ break;
41
+ case "codex":
42
+ content = toCodexMd(agent, baseKnowledgeDir, paths, backendLanguage);
43
+ break;
44
+ case "antigravity-cli": {
45
+ // Antigravity uses nested folders: agents/{name}/agent.json and agents/{name}/agent.md
46
+ const agentDir = path.join(destAgentsDir, agent.name);
47
+ if (!dryRun)
48
+ fs.mkdirSync(agentDir, { recursive: true });
49
+ content = toAntigravityJson(agent, baseKnowledgeDir, paths, backendLanguage);
50
+ fileName = path.join(agent.name, "agent.json");
51
+ secondaryContent = `# [ATABEY] Agent Atabey — @${agent.name}\n\n${agent.instructions.identity}\n\n${agent.instructions.mission}`;
52
+ secondaryFileName = path.join(agent.name, "agent.md");
53
+ break;
54
+ }
55
+ default:
56
+ // Fallback to Gemini format
57
+ content = toGeminiCliMd(agent, baseKnowledgeDir, paths, backendLanguage);
58
+ break;
59
+ }
60
+ if (!dryRun) {
61
+ writeTextFile(path.join(destAgentsDir, fileName), content, dryRun);
62
+ if (secondaryContent && secondaryFileName) {
63
+ writeTextFile(path.join(destAgentsDir, secondaryFileName), secondaryContent, dryRun);
64
+ }
65
+ }
66
+ }
67
+ }
68
+ catch (e) {
69
+ console.warn(`[WARN] Failed to scaffold agents for ${adapterId}: ${e}`);
70
+ }
71
+ }