agent-enderun 0.8.7 → 0.8.8
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/.enderun/BRAIN_DASHBOARD.md +4 -4
- package/.enderun/PROJECT_MEMORY.md +7 -15
- package/.enderun/STATUS.md +3 -5
- package/.enderun/agents/agent_army_schema.json +1 -1
- package/.enderun/agents/analyst.md +8 -15
- package/.enderun/agents/backend.md +11 -21
- package/.enderun/agents/devops.md +7 -16
- package/.enderun/agents/explorer.md +4 -13
- package/.enderun/agents/frontend.md +6 -15
- package/.enderun/agents/git.md +4 -13
- package/.enderun/agents/manager.md +28 -22
- package/.enderun/agents/mobile.md +4 -13
- package/.enderun/agents/orchestrator.md +14 -23
- package/.enderun/agents/qa.md +7 -16
- package/.enderun/agents/security.md +7 -16
- package/.enderun/cli-commands.json +0 -4
- package/.enderun/config.json +2 -2
- package/.enderun/knowledge/manager_authority_audit_enforcement.md +2 -2
- package/.enderun/knowledge/token_economy_and_memory.md +129 -0
- package/.enderun/memory-graph/agent-contexts/manager.json +1 -1
- package/.enderun/memory-graph/graph.json +1 -2
- package/.enderun/memory-graph/shared-facts.json +1 -2
- package/ENDERUN.md +1 -1
- package/README.md +379 -257
- package/docs/roadmap.md +1 -1
- package/framework-mcp/dist/schemas.js +0 -34
- package/framework-mcp/dist/tools/framework.js +40 -11
- package/framework-mcp/dist/tools/governance.js +1 -1
- package/framework-mcp/dist/tools/memory.js +24 -7
- package/framework-mcp/dist/tools/monitoring.js +6 -6
- package/framework-mcp/dist/tools/orchestration.js +9 -8
- package/framework-mcp/dist/utils.js +2 -2
- package/framework-mcp/package.json +1 -1
- package/framework-mcp/src/tools/framework.ts +39 -8
- package/framework-mcp/src/utils.ts +2 -2
- package/mcp.json +2 -2
- package/package.json +1 -1
- package/.enderun/agents/native.md +0 -115
- package/.enderun/claude.md +0 -19
- package/.enderun/cursor.md +0 -19
- package/.enderun/gemini.md +0 -19
- package/.enderun/memory-graph/agent-contexts/native.json +0 -1
package/docs/roadmap.md
CHANGED
|
@@ -42,7 +42,7 @@ This program systematically audits current agent maturity levels and runs struct
|
|
|
42
42
|
| **@explorer** | 6.5 | 8.5 | High / Stable. Highly capable in dependency analysis and codebase intelligence. |
|
|
43
43
|
| **@analyst** | 6.5 | 8.5 | Medium / Stable. Handles system health metrics and compliance audits. |
|
|
44
44
|
| **@git** | 6.0 | 8.0 | Medium / Stable. Coordinates PRs, semantic commits, and version compliance. |
|
|
45
|
-
| **@mobile
|
|
45
|
+
| **@mobile** | 2.0 | 7.5 | Low / Dormant. Foundational blueprints and Hermes safety rules added. |
|
|
46
46
|
|
|
47
47
|
> **Note:** `@frontend` is currently the highest risk to enterprise onboarding and is the top priority.
|
|
48
48
|
|
|
@@ -46,12 +46,6 @@ export const UPDATE_KNOWLEDGE_BASE_ARGS_SCHEMA = z.object({
|
|
|
46
46
|
content: z.string().min(1),
|
|
47
47
|
tags: z.array(z.string().min(1)).default([]),
|
|
48
48
|
});
|
|
49
|
-
export const ANALYZE_DATABASE_SCHEMA_ARGS_SCHEMA = z.object({
|
|
50
|
-
path: z.string().default("apps/backend"),
|
|
51
|
-
});
|
|
52
|
-
export const GENERATE_STRATEGIC_BRIEFING_ARGS_SCHEMA = z.object({
|
|
53
|
-
focusArea: z.string().optional(),
|
|
54
|
-
});
|
|
55
49
|
export const ANALYZE_CONSTITUTION_COMPLIANCE_ARGS_SCHEMA = z.object({
|
|
56
50
|
path: z.string().min(1),
|
|
57
51
|
});
|
|
@@ -59,15 +53,6 @@ export const GENERATE_DEPENDENCY_GRAPH_ARGS_SCHEMA = z.object({
|
|
|
59
53
|
path: z.string().default("src"),
|
|
60
54
|
format: z.enum(["mermaid", "json"]).default("mermaid"),
|
|
61
55
|
});
|
|
62
|
-
export const GENERATE_ACADEMY_PROGRESS_REPORT_ARGS_SCHEMA = z.object({
|
|
63
|
-
days: z.number().default(7),
|
|
64
|
-
});
|
|
65
|
-
export const ANALYZE_DOCUMENTATION_DEBT_ARGS_SCHEMA = z.object({
|
|
66
|
-
path: z.string().default("."),
|
|
67
|
-
});
|
|
68
|
-
export const VALIDATE_REPOSITORY_HEALTH_ARGS_SCHEMA = z.object({
|
|
69
|
-
scope: z.enum(["full", "lint", "test", "build"]).default("full"),
|
|
70
|
-
});
|
|
71
56
|
export const READ_AGENT_MESSAGES_ARGS_SCHEMA = z.object({
|
|
72
57
|
agent: z.string().min(1),
|
|
73
58
|
traceId: z.string().min(1).optional(),
|
|
@@ -81,17 +66,10 @@ export const GENERATE_SEMANTIC_COMMIT_MESSAGE_ARGS_SCHEMA = z.object({
|
|
|
81
66
|
export const ANALYZE_CODEBASE_INTELLIGENCE_ARGS_SCHEMA = z.object({
|
|
82
67
|
path: z.string().default("."),
|
|
83
68
|
});
|
|
84
|
-
export const GET_ACADEMY_PERFORMANCE_ARGS_SCHEMA = z.object({
|
|
85
|
-
periodDays: z.number().default(30),
|
|
86
|
-
});
|
|
87
69
|
export const ANALYZE_PROCEDURAL_CONTINUITY_ARGS_SCHEMA = z.object({
|
|
88
70
|
targetPath: z.string().min(1),
|
|
89
71
|
referencePath: z.string().min(1),
|
|
90
72
|
});
|
|
91
|
-
export const GET_AGENT_AUDIT_REPORT_ARGS_SCHEMA = z.object({
|
|
92
|
-
agent: z.string().min(1),
|
|
93
|
-
days: z.number().default(7),
|
|
94
|
-
});
|
|
95
73
|
export const GET_AGENT_INBOX_STATS_ARGS_SCHEMA = z.object({
|
|
96
74
|
agent: z.string().min(1),
|
|
97
75
|
});
|
|
@@ -104,15 +82,3 @@ export const SYNC_CONTRACT_HASH_ARGS_SCHEMA = z.object({
|
|
|
104
82
|
export const VERIFY_FRAMEWORK_HEALTH_ARGS_SCHEMA = z.object({
|
|
105
83
|
detailed: z.boolean().default(false),
|
|
106
84
|
});
|
|
107
|
-
export const INSTANTIATE_BLUEPRINT_ARGS_SCHEMA = z.object({
|
|
108
|
-
blueprintPath: z.string().min(1),
|
|
109
|
-
targetPath: z.string().min(1),
|
|
110
|
-
});
|
|
111
|
-
export const LIST_BLUEPRINTS_ARGS_SCHEMA = z.object({
|
|
112
|
-
category: z.enum(["backend", "frontend"]).optional(),
|
|
113
|
-
});
|
|
114
|
-
export const SAVE_AS_BLUEPRINT_ARGS_SCHEMA = z.object({
|
|
115
|
-
blueprintPath: z.string().min(1),
|
|
116
|
-
content: z.string().min(1),
|
|
117
|
-
description: z.string().optional(),
|
|
118
|
-
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { execSync } from "child_process";
|
|
4
3
|
import { getFrameworkDir, collectMarkdownArtifacts, FRAMEWORK_VERSION } from "../utils.js";
|
|
5
4
|
export const frameworkTools = [
|
|
6
5
|
{
|
|
@@ -119,10 +118,9 @@ export const frameworkHandlers = {
|
|
|
119
118
|
missing.push(`[MISSING FOLDER] ${frameworkDir}/agents`);
|
|
120
119
|
}
|
|
121
120
|
else {
|
|
122
|
-
const agents = fs.readdirSync(agentsDir)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
121
|
+
const agents = fs.readdirSync(agentsDir)
|
|
122
|
+
.filter((f) => f.endsWith(".md") && f !== "README.md")
|
|
123
|
+
.map((f) => f.replace(".md", ""));
|
|
126
124
|
const logsDir = path.join(projectRoot, frameworkDir, "logs");
|
|
127
125
|
for (const agentName of agents) {
|
|
128
126
|
const logFile = path.join(logsDir, `${agentName}.json`);
|
|
@@ -182,15 +180,46 @@ export const frameworkHandlers = {
|
|
|
182
180
|
},
|
|
183
181
|
verify_framework_health: async (args, projectRoot) => {
|
|
184
182
|
try {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
const frameworkDir = getFrameworkDir(projectRoot);
|
|
184
|
+
const requiredFiles = [
|
|
185
|
+
["Constitution", fs.existsSync(path.join(projectRoot, "ENDERUN.md")) ? "ENDERUN.md" : path.join(frameworkDir, "ENDERUN.md")],
|
|
186
|
+
["Memory", path.join(frameworkDir, "PROJECT_MEMORY.md")],
|
|
187
|
+
["Command Map", path.join(frameworkDir, "cli-commands.json")],
|
|
188
|
+
["Framework Config", path.join(frameworkDir, "config.json")],
|
|
189
|
+
["Agent Status", path.join(frameworkDir, "STATUS.md")],
|
|
190
|
+
["MCP Config", "mcp.json"],
|
|
191
|
+
["Backend Contract", "apps/backend/contract.version.json"],
|
|
192
|
+
["MCP Server", "framework-mcp/package.json"],
|
|
193
|
+
["Panda CSS Config", "panda.config.ts"],
|
|
194
|
+
["Brain Dashboard", path.join(frameworkDir, "BRAIN_DASHBOARD.md")],
|
|
195
|
+
["Docs Portal", "docs/README.md"],
|
|
196
|
+
["Getting Started", "docs/getting-started.md"],
|
|
197
|
+
];
|
|
198
|
+
const lines = [];
|
|
199
|
+
let issues = 0;
|
|
200
|
+
for (const [name, relativePath] of requiredFiles) {
|
|
201
|
+
if (fs.existsSync(path.join(projectRoot, relativePath))) {
|
|
202
|
+
lines.push(`OK ${name}: ${relativePath}`);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
issues += 1;
|
|
206
|
+
lines.push(`MISSING ${name}: ${relativePath}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const buildPath = path.join(projectRoot, "framework-mcp/dist/index.js");
|
|
210
|
+
if (fs.existsSync(buildPath)) {
|
|
211
|
+
lines.push("OK MCP Build: framework-mcp/dist/index.js");
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
issues += 1;
|
|
215
|
+
lines.push("MISSING MCP Build: framework-mcp/dist/index.js");
|
|
216
|
+
}
|
|
217
|
+
const status = issues === 0 ? "PASSED" : "FAILED";
|
|
218
|
+
return { content: [{ type: "text", text: `### FRAMEWORK HEALTH CHECK (${status})\n\n${lines.join("\n")}` }] };
|
|
190
219
|
}
|
|
191
220
|
catch (error) {
|
|
192
221
|
const err = error;
|
|
193
|
-
return { content: [{ type: "text", text: `### FRAMEWORK HEALTH CHECK (FAILED)\n\n${err.
|
|
222
|
+
return { content: [{ type: "text", text: `### FRAMEWORK HEALTH CHECK (FAILED)\n\n${err.message ?? "Unknown error"}` }] };
|
|
194
223
|
}
|
|
195
224
|
}
|
|
196
225
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Governance Tools - MCP Tools for enforcing corporate governance standards
|
|
3
3
|
*
|
|
4
|
-
* These tools bridge the .
|
|
4
|
+
* These tools bridge the .enderun/knowledge/corporate-governance/ knowledge base
|
|
5
5
|
* with actual code-level compliance verification.
|
|
6
6
|
*
|
|
7
7
|
* Philosophy: We do not just document standards — we actively verify them.
|
|
@@ -78,14 +78,31 @@ export const memoryHandlers = {
|
|
|
78
78
|
const lockPath = memoryPath + ".lock";
|
|
79
79
|
const lockOwner = `lock-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
80
80
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
try {
|
|
82
|
+
// Atomic write using 'wx' flag to prevent TOCTOU race conditions
|
|
83
|
+
fs.writeFileSync(lockPath, JSON.stringify({ owner: lockOwner, createdAt: new Date().toISOString() }), { flag: "wx" });
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error.code === "EEXIST") {
|
|
87
|
+
const stats = fs.statSync(lockPath);
|
|
88
|
+
if (Date.now() - stats.mtimeMs > 120000) {
|
|
89
|
+
try {
|
|
90
|
+
fs.unlinkSync(lockPath);
|
|
91
|
+
// Retry atomic write once after unlinking stale lock
|
|
92
|
+
fs.writeFileSync(lockPath, JSON.stringify({ owner: lockOwner, createdAt: new Date().toISOString() }), { flag: "wx" });
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return { content: [{ type: "text", text: "Memory is locked. Try again later." }] };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return { content: [{ type: "text", text: "Memory is locked. Try again later." }] };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
87
105
|
}
|
|
88
|
-
fs.writeFileSync(lockPath, JSON.stringify({ owner: lockOwner, createdAt: new Date().toISOString() }));
|
|
89
106
|
let memoryContent = fs.readFileSync(memoryPath, "utf-8");
|
|
90
107
|
if (section === "HISTORY") {
|
|
91
108
|
let updated = false;
|
|
@@ -93,7 +93,7 @@ export const monitoringHandlers = {
|
|
|
93
93
|
results.agents = [{ error: "STATUS.md not found or unreadable" }];
|
|
94
94
|
}
|
|
95
95
|
// Read queue depths
|
|
96
|
-
const queueBase = path.join(projectRoot,
|
|
96
|
+
const queueBase = path.join(projectRoot, getFrameworkDir(projectRoot), "queue");
|
|
97
97
|
for (const subdir of ["pending", "processing", "completed", "failed"]) {
|
|
98
98
|
try {
|
|
99
99
|
const files = await fs.readdir(path.join(queueBase, subdir));
|
|
@@ -104,7 +104,7 @@ export const monitoringHandlers = {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
// Read orchestrator log for recent blockages and broadcasts
|
|
107
|
-
const logPath = path.join(projectRoot,
|
|
107
|
+
const logPath = path.join(projectRoot, getFrameworkDir(projectRoot), "logs", "orchestrator.json");
|
|
108
108
|
try {
|
|
109
109
|
const logContent = await fs.readFile(logPath, "utf-8");
|
|
110
110
|
const log = JSON.parse(logContent);
|
|
@@ -128,7 +128,7 @@ export const monitoringHandlers = {
|
|
|
128
128
|
const { agentName, lastN } = args;
|
|
129
129
|
const n = lastN ?? 20;
|
|
130
130
|
const logName = agentName.replace("@", "") + ".json";
|
|
131
|
-
const logPath = path.join(projectRoot,
|
|
131
|
+
const logPath = path.join(projectRoot, getFrameworkDir(projectRoot), "logs", logName);
|
|
132
132
|
try {
|
|
133
133
|
const content = await fs.readFile(logPath, "utf-8");
|
|
134
134
|
const log = JSON.parse(content);
|
|
@@ -172,7 +172,7 @@ export const monitoringHandlers = {
|
|
|
172
172
|
async detect_bottleneck_agents(args, projectRoot) {
|
|
173
173
|
const { thresholdMinutes } = args;
|
|
174
174
|
const threshold = thresholdMinutes ?? 30;
|
|
175
|
-
const statusPath = path.join(projectRoot,
|
|
175
|
+
const statusPath = path.join(projectRoot, getFrameworkDir(projectRoot), "STATUS.md");
|
|
176
176
|
const bottlenecks = [];
|
|
177
177
|
try {
|
|
178
178
|
const content = await fs.readFile(statusPath, "utf-8");
|
|
@@ -256,7 +256,7 @@ export const monitoringHandlers = {
|
|
|
256
256
|
report.agentStatuses = [];
|
|
257
257
|
}
|
|
258
258
|
// Queue snapshot
|
|
259
|
-
const queueBase = path.join(projectRoot,
|
|
259
|
+
const queueBase = path.join(projectRoot, getFrameworkDir(projectRoot), "queue");
|
|
260
260
|
const snapshot = {};
|
|
261
261
|
for (const dir of ["pending", "processing", "completed", "failed"]) {
|
|
262
262
|
try {
|
|
@@ -269,7 +269,7 @@ export const monitoringHandlers = {
|
|
|
269
269
|
}
|
|
270
270
|
report.queueSnapshot = snapshot;
|
|
271
271
|
// Recent blockages
|
|
272
|
-
const logPath = path.join(projectRoot,
|
|
272
|
+
const logPath = path.join(projectRoot, getFrameworkDir(projectRoot), "logs", "orchestrator.json");
|
|
273
273
|
try {
|
|
274
274
|
const logContent = await fs.readFile(logPath, "utf-8");
|
|
275
275
|
const log = JSON.parse(logContent);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { getFrameworkDir } from "../utils.js";
|
|
3
4
|
// ─── Tool Definitions ─────────────────────────────────────────────────────────
|
|
4
5
|
export const orchestrationTools = [
|
|
5
6
|
{
|
|
@@ -178,7 +179,7 @@ export const orchestrationHandlers = {
|
|
|
178
179
|
parallelOpportunities: executionWaves.filter((w) => w.length > 1).length,
|
|
179
180
|
};
|
|
180
181
|
// Persist to queue
|
|
181
|
-
const queueDir = path.join(projectRoot,
|
|
182
|
+
const queueDir = path.join(projectRoot, getFrameworkDir(projectRoot), "queue", "pending");
|
|
182
183
|
await fs.mkdir(queueDir, { recursive: true });
|
|
183
184
|
await fs.writeFile(path.join(queueDir, `${traceId}-dag.json`), JSON.stringify(dag, null, 2), "utf-8");
|
|
184
185
|
return { content: [{ type: "text", text: JSON.stringify(dag, null, 2) }] };
|
|
@@ -188,7 +189,7 @@ export const orchestrationHandlers = {
|
|
|
188
189
|
// Try to load capability roster from shared-facts.json (dynamic — fixes KRITIK-3)
|
|
189
190
|
let agentCapabilityRoster = [];
|
|
190
191
|
try {
|
|
191
|
-
const sharedFactsPath = path.join(projectRoot,
|
|
192
|
+
const sharedFactsPath = path.join(projectRoot, getFrameworkDir(projectRoot), "memory-graph", "shared-facts.json");
|
|
192
193
|
const content = await fs.readFile(sharedFactsPath, "utf-8");
|
|
193
194
|
const facts = JSON.parse(content);
|
|
194
195
|
agentCapabilityRoster = facts.agentCapabilityRoster ?? [];
|
|
@@ -249,7 +250,7 @@ export const orchestrationHandlers = {
|
|
|
249
250
|
sourceMap: Object.keys(domainMap).length > 0 ? "shared-facts" : "fallback",
|
|
250
251
|
};
|
|
251
252
|
// Write assignment log
|
|
252
|
-
const logPath = path.join(projectRoot,
|
|
253
|
+
const logPath = path.join(projectRoot, getFrameworkDir(projectRoot), "logs", "orchestrator.json");
|
|
253
254
|
let log = { assignments: [] };
|
|
254
255
|
try {
|
|
255
256
|
const existing = await fs.readFile(logPath, "utf-8");
|
|
@@ -264,7 +265,7 @@ export const orchestrationHandlers = {
|
|
|
264
265
|
return { content: [{ type: "text", text: JSON.stringify(assignment, null, 2) }] };
|
|
265
266
|
},
|
|
266
267
|
async get_agent_workload(_args, projectRoot) {
|
|
267
|
-
const statusPath = path.join(projectRoot,
|
|
268
|
+
const statusPath = path.join(projectRoot, getFrameworkDir(projectRoot), "STATUS.md");
|
|
268
269
|
let statusContent;
|
|
269
270
|
try {
|
|
270
271
|
statusContent = await fs.readFile(statusPath, "utf-8");
|
|
@@ -301,7 +302,7 @@ export const orchestrationHandlers = {
|
|
|
301
302
|
status: "ESCALATED_TO_MANAGER",
|
|
302
303
|
};
|
|
303
304
|
// Log blockage
|
|
304
|
-
const logPath = path.join(projectRoot,
|
|
305
|
+
const logPath = path.join(projectRoot, getFrameworkDir(projectRoot), "logs", "orchestrator.json");
|
|
305
306
|
let log = { assignments: [], blockages: [] };
|
|
306
307
|
try {
|
|
307
308
|
const existing = await fs.readFile(logPath, "utf-8");
|
|
@@ -316,7 +317,7 @@ export const orchestrationHandlers = {
|
|
|
316
317
|
await fs.mkdir(path.dirname(logPath), { recursive: true });
|
|
317
318
|
await fs.writeFile(logPath, JSON.stringify(log, null, 2), "utf-8");
|
|
318
319
|
// Write a message to @manager's inbox via messages folder
|
|
319
|
-
const messagesDir = path.join(projectRoot,
|
|
320
|
+
const messagesDir = path.join(projectRoot, getFrameworkDir(projectRoot), "messages");
|
|
320
321
|
await fs.mkdir(messagesDir, { recursive: true });
|
|
321
322
|
const messageFile = path.join(messagesDir, `BLOCKAGE-${traceId}-${Date.now()}.json`);
|
|
322
323
|
await fs.writeFile(messageFile, JSON.stringify({
|
|
@@ -342,11 +343,11 @@ export const orchestrationHandlers = {
|
|
|
342
343
|
timestamp: new Date().toISOString(),
|
|
343
344
|
};
|
|
344
345
|
// Write to messages folder for all agents
|
|
345
|
-
const messagesDir = path.join(projectRoot,
|
|
346
|
+
const messagesDir = path.join(projectRoot, getFrameworkDir(projectRoot), "messages");
|
|
346
347
|
await fs.mkdir(messagesDir, { recursive: true });
|
|
347
348
|
await fs.writeFile(path.join(messagesDir, `${broadcast.id}.json`), JSON.stringify(broadcast, null, 2), "utf-8");
|
|
348
349
|
// Log broadcast
|
|
349
|
-
const logPath = path.join(projectRoot,
|
|
350
|
+
const logPath = path.join(projectRoot, getFrameworkDir(projectRoot), "logs", "orchestrator.json");
|
|
350
351
|
let log = {
|
|
351
352
|
assignments: [],
|
|
352
353
|
blockages: [],
|
|
@@ -8,13 +8,13 @@ const getPackageVersion = () => {
|
|
|
8
8
|
const pkgPath = path.join(__dirname, "../package.json");
|
|
9
9
|
if (fs.existsSync(pkgPath)) {
|
|
10
10
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
11
|
-
return pkg.version || "0.
|
|
11
|
+
return pkg.version || "0.8.8";
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
catch {
|
|
15
15
|
// fallback
|
|
16
16
|
}
|
|
17
|
-
return "0.
|
|
17
|
+
return "0.8.8";
|
|
18
18
|
};
|
|
19
19
|
export const FRAMEWORK_VERSION = getPackageVersion();
|
|
20
20
|
/**
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { execSync } from "child_process";
|
|
4
3
|
import {
|
|
5
4
|
getFrameworkDir,
|
|
6
5
|
collectMarkdownArtifacts,
|
|
@@ -179,14 +178,46 @@ export const frameworkHandlers = {
|
|
|
179
178
|
},
|
|
180
179
|
verify_framework_health: async (args: unknown, projectRoot: string) => {
|
|
181
180
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
181
|
+
const frameworkDir = getFrameworkDir(projectRoot);
|
|
182
|
+
const requiredFiles = [
|
|
183
|
+
["Constitution", fs.existsSync(path.join(projectRoot, "ENDERUN.md")) ? "ENDERUN.md" : path.join(frameworkDir, "ENDERUN.md")],
|
|
184
|
+
["Memory", path.join(frameworkDir, "PROJECT_MEMORY.md")],
|
|
185
|
+
["Command Map", path.join(frameworkDir, "cli-commands.json")],
|
|
186
|
+
["Framework Config", path.join(frameworkDir, "config.json")],
|
|
187
|
+
["Agent Status", path.join(frameworkDir, "STATUS.md")],
|
|
188
|
+
["MCP Config", "mcp.json"],
|
|
189
|
+
["Backend Contract", "apps/backend/contract.version.json"],
|
|
190
|
+
["MCP Server", "framework-mcp/package.json"],
|
|
191
|
+
["Panda CSS Config", "panda.config.ts"],
|
|
192
|
+
["Brain Dashboard", path.join(frameworkDir, "BRAIN_DASHBOARD.md")],
|
|
193
|
+
["Docs Portal", "docs/README.md"],
|
|
194
|
+
["Getting Started", "docs/getting-started.md"],
|
|
195
|
+
] as const;
|
|
196
|
+
|
|
197
|
+
const lines: string[] = [];
|
|
198
|
+
let issues = 0;
|
|
199
|
+
for (const [name, relativePath] of requiredFiles) {
|
|
200
|
+
if (fs.existsSync(path.join(projectRoot, relativePath))) {
|
|
201
|
+
lines.push(`OK ${name}: ${relativePath}`);
|
|
202
|
+
} else {
|
|
203
|
+
issues += 1;
|
|
204
|
+
lines.push(`MISSING ${name}: ${relativePath}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const buildPath = path.join(projectRoot, "framework-mcp/dist/index.js");
|
|
209
|
+
if (fs.existsSync(buildPath)) {
|
|
210
|
+
lines.push("OK MCP Build: framework-mcp/dist/index.js");
|
|
211
|
+
} else {
|
|
212
|
+
issues += 1;
|
|
213
|
+
lines.push("MISSING MCP Build: framework-mcp/dist/index.js");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const status = issues === 0 ? "PASSED" : "FAILED";
|
|
217
|
+
return { content: [{ type: "text", text: `### FRAMEWORK HEALTH CHECK (${status})\n\n${lines.join("\n")}` }] };
|
|
187
218
|
} catch (error: unknown) {
|
|
188
|
-
const err = error as {
|
|
189
|
-
return { content: [{ type: "text", text: `### FRAMEWORK HEALTH CHECK (FAILED)\n\n${err.
|
|
219
|
+
const err = error as { message?: string };
|
|
220
|
+
return { content: [{ type: "text", text: `### FRAMEWORK HEALTH CHECK (FAILED)\n\n${err.message ?? "Unknown error"}` }] };
|
|
190
221
|
}
|
|
191
222
|
}
|
|
192
223
|
};
|
|
@@ -10,12 +10,12 @@ const getPackageVersion = (): string => {
|
|
|
10
10
|
const pkgPath = path.join(__dirname, "../package.json");
|
|
11
11
|
if (fs.existsSync(pkgPath)) {
|
|
12
12
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
13
|
-
return pkg.version || "0.8.
|
|
13
|
+
return pkg.version || "0.8.8";
|
|
14
14
|
}
|
|
15
15
|
} catch {
|
|
16
16
|
// fallback
|
|
17
17
|
}
|
|
18
|
-
return "0.8.
|
|
18
|
+
return "0.8.8";
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export const FRAMEWORK_VERSION = getPackageVersion();
|
package/mcp.json
CHANGED
package/package.json
CHANGED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: native
|
|
3
|
-
description: "Native Platform Desktop Specialist Agent for Agent Enderun"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# @native — native
|
|
7
|
-
|
|
8
|
-
- **Name:** native
|
|
9
|
-
- **Capability:** 9.0
|
|
10
|
-
- **Role:** native
|
|
11
|
-
- **State Machine:** `../schema/agent-lifecycle-schema.json`
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# @native — Native Capabilities
|
|
16
|
-
|
|
17
|
-
- **Name:** @native
|
|
18
|
-
- **Capability:** 8.9
|
|
19
|
-
- **Role:** Native Capabilities
|
|
20
|
-
- **Specialization:** Swift/Kotlin, native integrations, deep links, platform-specific high-risk flows
|
|
21
|
-
- **Permitted Directories:**
|
|
22
|
-
- `apps/native/`
|
|
23
|
-
- `{{FRAMEWORK_DIR}}/knowledge/`
|
|
24
|
-
- **Hermes Channels:**
|
|
25
|
-
- `@native->@manager`
|
|
26
|
-
- `@native->@orchestrator`
|
|
27
|
-
- **Tags:** specialist
|
|
28
|
-
- **State Machine:** `../schema/agent-lifecycle-schema.json`
|
|
29
|
-
|
|
30
|
-
## Core Rules
|
|
31
|
-
- All native work must be preceded by contract definition and manager briefing.
|
|
32
|
-
- Security-sensitive native code requires extra audit logging.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
# Native Desktop Architect
|
|
37
|
-
|
|
38
|
-
**Role:** Build secure and efficient desktop applications using Tauri or Electron. Ensure procedural continuity across the native codebase.
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## 🎯 Core Principle: Search Before Reading
|
|
43
|
-
|
|
44
|
-
Always research the existing codebase and native bridge implementations before adding new native functionality.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 🔌 SESSION STARTUP PROTOCOL (Mandatory)
|
|
49
|
-
|
|
50
|
-
1. Read `{{FRAMEWORK_DIR}}/PROJECT_MEMORY.md` → Understand the current project state.
|
|
51
|
-
2. Read `{{FRAMEWORK_DIR}}/docs/api/` → Align with the contracts.
|
|
52
|
-
3. Check `apps/backend/src/types/` → Use the standardized types.
|
|
53
|
-
|
|
54
|
-
> ✅ **End of Session:** Update `{{FRAMEWORK_DIR}}/PROJECT_MEMORY.md` HISTORY (via `update_project_memory`) + log action via `log_agent_action`. Every turn MUST end with an automated log and memory update.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Native Standards (Golden Rules)
|
|
59
|
-
|
|
60
|
-
- **Tauri (Recommended):** High security + small bundle size (Rust backend preferred).
|
|
61
|
-
- **Electron:** For complex Node.js integration or legacy needs.
|
|
62
|
-
- **Security:** Strict CSP, no remote code execution, sandboxing mandatory.
|
|
63
|
-
- **IPC:** Typed and secure communication (frontend ↔ native layer). For Rust side, `tauri::command` is recommended.
|
|
64
|
-
- **Window & Menu Management:** Native menu, tray, and window state management should be standardized.
|
|
65
|
-
- **Auto Update:** Use Tauri built-in updater or electron-updater for Electron.
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Native Checklist (Mandatory on Every Task)
|
|
70
|
-
|
|
71
|
-
- [ ] Minimal memory footprint and performance?
|
|
72
|
-
- [ ] Typed and secure IPC communication?
|
|
73
|
-
- [ ] Security (CSP, sandbox, no remote execution) checked?
|
|
74
|
-
- [ ] Auto-update and versioning considered?
|
|
75
|
-
- [ ] Platform-specific behaviors (Windows/macOS/Linux) documented?
|
|
76
|
-
- [ ] Error handling and crash reporting present?
|
|
77
|
-
|
|
78
|
-
## 🖥️ Native Capability Growth (Mandatory)
|
|
79
|
-
|
|
80
|
-
- On every task, **at least one** native UX or security improvement must be made (native menu, tray, secure storage, auto-update, window state, etc.).
|
|
81
|
-
- When a new IPC pattern or native feature is developed, it is added to this agent's knowledge and becomes the project standard.
|
|
82
|
-
|
|
83
|
-
## 🖥️ Native Component & Logic Standards
|
|
84
|
-
|
|
85
|
-
- **Tauri (Recommended):** Rust backend + typed IPC (`tauri::command`).
|
|
86
|
-
- **Electron:** For complex Node.js integration. Strict CSP and sandbox mandatory.
|
|
87
|
-
- **State Management:** Frontend uses Zustand or project standard. Native side synchronization must be handled carefully.
|
|
88
|
-
- **IPC:** Typed and secure communication is mandatory. A contract must be defined between frontend and native.
|
|
89
|
-
- **Security:** No remote code execution, strict CSP, secure storage (keychain / credential manager) must be used.
|
|
90
|
-
- **Auto Update:** Tauri updater or electron-updater should be considered for automatic updates.
|
|
91
|
-
- **Window & Menu:** Native menu, tray icon, and window state management should be standardized.
|
|
92
|
-
|
|
93
|
-
## 🖥️ Native Agent Completion Report (Zorunlu)
|
|
94
|
-
|
|
95
|
-
- [ ] Mock used? [ ] No / [ ] Yes
|
|
96
|
-
- [ ] App types imported? [ ] No / [ ] Yes
|
|
97
|
-
- [ ] Typed IPC used? [ ] No / [ ] Yes
|
|
98
|
-
- [ ] Security (CSP, sandbox, secure storage) checked? [ ] No / [ ] Yes
|
|
99
|
-
- [ ] Auto-update and versioning considered? [ ] No / [ ] Yes
|
|
100
|
-
- [ ] Performance and memory footprint checked? [ ] No / [ ] Yes
|
|
101
|
-
- [ ] Log written? [ ] No / [ ] Yes → via log_agent_action tool
|
|
102
|
-
- [ ] PROJECT_MEMORY HISTORY updated? [ ] No / [ ] Yes
|
|
103
|
-
- Next step: [what needs to be done]
|
|
104
|
-
- Blockers: [write if any, otherwise "NONE"]
|
|
105
|
-
- [ ] Proper error handling at the native layer?
|
|
106
|
-
- [ ] Cross-platform (Mac, Windows, Linux) compatibility checked?
|
|
107
|
-
|
|
108
|
-
## 🖥️ Native Capability Growth
|
|
109
|
-
|
|
110
|
-
- **Security Improvement:** Add one security hardening note if native code touches IPC, file access, or shell commands.
|
|
111
|
-
- **Performance Growth:** Measure and record the impact of any native bridge or runtime change.
|
|
112
|
-
- **Platform Notes:** Capture platform-specific constraints in the project memory for future reference.
|
|
113
|
-
- **Developer Experience:** Document any native tooling or setup requirements so the next agent can onboard faster.
|
|
114
|
-
|
|
115
|
-
---
|
package/.enderun/claude.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Agent Enderun — Claude Code CLI Adapter
|
|
2
|
-
|
|
3
|
-
This file is the entry point when using Agent Enderun with Claude Code CLI.
|
|
4
|
-
|
|
5
|
-
The framework installs into the `.claude/` folder for Claude users.
|
|
6
|
-
|
|
7
|
-
### Primary Constitution
|
|
8
|
-
All governance rules, agent checklists, and project memory live here:
|
|
9
|
-
|
|
10
|
-
👉 **[.claude/ENDERUN.md](.claude/ENDERUN.md)**
|
|
11
|
-
|
|
12
|
-
### 🤖 Agent Directive (Claude Code CLI users)
|
|
13
|
-
You are operating under the Agent Enderun governance framework.
|
|
14
|
-
|
|
15
|
-
At the **start of every session**, before any work:
|
|
16
|
-
1. Read `.claude/PROJECT_MEMORY.md` to restore state, active Trace ID, and history.
|
|
17
|
-
2. Read the relevant agent definition under `.claude/agents/{agent}.md` (especially `@manager`).
|
|
18
|
-
|
|
19
|
-
All paths and references inside `.claude/` use the Claude adapter structure. No migration to other CLIs is required.
|
package/.enderun/cursor.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Agent Enderun — Cursor / Codex Adapter
|
|
2
|
-
|
|
3
|
-
This file is the entry point when using Agent Enderun with Cursor Composer / Codex CLI.
|
|
4
|
-
|
|
5
|
-
The framework installs into the `.cursor/` folder for Cursor users.
|
|
6
|
-
|
|
7
|
-
### Primary Constitution
|
|
8
|
-
All governance rules, agent checklists, and project memory live here:
|
|
9
|
-
|
|
10
|
-
👉 **[.cursor/ENDERUN.md](.cursor/ENDERUN.md)**
|
|
11
|
-
|
|
12
|
-
### 🤖 Agent Directive (Cursor users)
|
|
13
|
-
You are operating under the Agent Enderun governance framework.
|
|
14
|
-
|
|
15
|
-
At the **start of every session**, before any work:
|
|
16
|
-
1. Read `.cursor/PROJECT_MEMORY.md` to restore state, active Trace ID, and history.
|
|
17
|
-
2. Read the relevant agent definition under `.cursor/agents/{agent}.md` (especially `@manager`).
|
|
18
|
-
|
|
19
|
-
All paths and references inside `.cursor/` use the Cursor adapter structure. No migration to other CLIs is required.
|
package/.enderun/gemini.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Agent Enderun — Gemini CLI Adapter
|
|
2
|
-
|
|
3
|
-
This file is the entry point when using Agent Enderun with Gemini CLI.
|
|
4
|
-
|
|
5
|
-
The framework installs into the `.enderun/` folder for Gemini users.
|
|
6
|
-
|
|
7
|
-
### Primary Constitution
|
|
8
|
-
All governance rules, agent checklists, and project memory live here:
|
|
9
|
-
|
|
10
|
-
👉 **[.enderun/ENDERUN.md](.enderun/ENDERUN.md)**
|
|
11
|
-
|
|
12
|
-
### 🤖 Agent Directive (Gemini CLI users)
|
|
13
|
-
You are operating under the Agent Enderun governance framework.
|
|
14
|
-
|
|
15
|
-
At the **start of every session**, before any work:
|
|
16
|
-
1. Read `.enderun/PROJECT_MEMORY.md` to restore state, active Trace ID, and history.
|
|
17
|
-
2. Read the relevant agent definition under `.enderun/agents/{agent}.md` (especially `@manager`).
|
|
18
|
-
|
|
19
|
-
All paths and references inside `.enderun/` use the Enderun adapter structure. No migration to other CLIs is required.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "agent": "@native", "version": "1.0.0", "lastUpdated": "2026-05-25T17:00:00Z", "sessionHistory": [], "knownContracts": [], "recentDecisions": [], "watchedFiles": [], "pendingTasks": [], "notes": "Context initialized." }
|