agent-enderun 0.5.9 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/.enderun/PROJECT_MEMORY.md +17 -32
  2. package/.enderun/STATUS.md +19 -10
  3. package/.enderun/agents/analyst.md +9 -2
  4. package/.enderun/agents/backend.md +23 -12
  5. package/.enderun/agents/explorer.md +2 -2
  6. package/.enderun/agents/frontend.md +21 -10
  7. package/.enderun/agents/git.md +1 -1
  8. package/.enderun/agents/manager.md +10 -2
  9. package/.enderun/agents/mobile.md +1 -1
  10. package/.enderun/agents/native.md +1 -1
  11. package/.enderun/blueprints/backend/types/index.ts +49 -0
  12. package/{packages/shared-types/src → .enderun/blueprints/backend/types}/models.ts +0 -1
  13. package/.enderun/docs/api/README.md +7 -12
  14. package/.enderun/docs/project-docs.md +17 -7
  15. package/.enderun/knowledge/blueprint_driven_construction.md +22 -0
  16. package/.enderun/knowledge/code_review_checklist.md +1 -1
  17. package/.enderun/knowledge/contract_versioning.md +5 -5
  18. package/ENDERUN.md +6 -6
  19. package/README.md +39 -22
  20. package/bin/cli.js +205 -27
  21. package/{packages/framework-mcp → framework-mcp}/dist/index.js +0 -0
  22. package/{packages/framework-mcp → framework-mcp}/dist/schemas.js +12 -0
  23. package/{packages/framework-mcp → framework-mcp}/dist/tools/contract.js +5 -5
  24. package/{packages/framework-mcp → framework-mcp}/dist/tools/framework.js +3 -2
  25. package/{packages/framework-mcp → framework-mcp}/dist/tools/git.js +2 -4
  26. package/{packages/framework-mcp → framework-mcp}/dist/tools/index.js +3 -0
  27. package/{packages/framework-mcp → framework-mcp}/dist/tools/repository.js +1 -1
  28. package/framework-mcp/dist/tools/scaffold.js +129 -0
  29. package/{packages/framework-mcp → framework-mcp}/dist/utils.js +1 -1
  30. package/{packages/framework-mcp → framework-mcp}/package.json +1 -1
  31. package/{packages/framework-mcp → framework-mcp}/src/schemas.ts +15 -0
  32. package/{packages/framework-mcp → framework-mcp}/src/tools/contract.ts +5 -5
  33. package/{packages/framework-mcp → framework-mcp}/src/tools/framework.ts +3 -2
  34. package/{packages/framework-mcp → framework-mcp}/src/tools/git.ts +2 -3
  35. package/{packages/framework-mcp → framework-mcp}/src/tools/index.ts +3 -0
  36. package/{packages/framework-mcp → framework-mcp}/src/tools/repository.ts +1 -1
  37. package/framework-mcp/src/tools/scaffold.ts +147 -0
  38. package/{packages/framework-mcp → framework-mcp}/src/utils.ts +1 -1
  39. package/package.json +7 -11
  40. package/.enderun/logs/manager.json +0 -1
  41. package/packages/shared-types/README.md +0 -61
  42. package/packages/shared-types/contract.version.json +0 -12
  43. package/packages/shared-types/dist/api.d.ts +0 -18
  44. package/packages/shared-types/dist/api.js +0 -2
  45. package/packages/shared-types/dist/api.js.map +0 -1
  46. package/packages/shared-types/dist/brands.d.ts +0 -13
  47. package/packages/shared-types/dist/brands.js +0 -2
  48. package/packages/shared-types/dist/brands.js.map +0 -1
  49. package/packages/shared-types/dist/constants.d.ts +0 -27
  50. package/packages/shared-types/dist/constants.js +0 -22
  51. package/packages/shared-types/dist/constants.js.map +0 -1
  52. package/packages/shared-types/dist/index.d.ts +0 -11
  53. package/packages/shared-types/dist/index.js +0 -12
  54. package/packages/shared-types/dist/index.js.map +0 -1
  55. package/packages/shared-types/dist/logs.d.ts +0 -15
  56. package/packages/shared-types/dist/logs.js +0 -2
  57. package/packages/shared-types/dist/logs.js.map +0 -1
  58. package/packages/shared-types/dist/models.d.ts +0 -60
  59. package/packages/shared-types/dist/models.js +0 -2
  60. package/packages/shared-types/dist/models.js.map +0 -1
  61. package/packages/shared-types/package.json +0 -36
  62. package/packages/shared-types/src/index.ts +0 -12
  63. package/packages/shared-types/tsconfig.json +0 -9
  64. /package/{packages/shared-types/src → .enderun/blueprints/backend/types}/api.ts +0 -0
  65. /package/{packages/shared-types/src → .enderun/blueprints/backend/types}/brands.ts +0 -0
  66. /package/{packages/shared-types/src → .enderun/blueprints/backend/types}/constants.ts +0 -0
  67. /package/{packages/shared-types/src → .enderun/blueprints/backend/types}/logs.ts +0 -0
  68. /package/{packages/framework-mcp → framework-mcp}/README.md +0 -0
  69. /package/{packages/framework-mcp → framework-mcp}/dist/tools/academy.js +0 -0
  70. /package/{packages/framework-mcp → framework-mcp}/dist/tools/codebase.js +0 -0
  71. /package/{packages/framework-mcp → framework-mcp}/dist/tools/database.js +0 -0
  72. /package/{packages/framework-mcp → framework-mcp}/dist/tools/knowledge.js +0 -0
  73. /package/{packages/framework-mcp → framework-mcp}/dist/tools/memory.js +0 -0
  74. /package/{packages/framework-mcp → framework-mcp}/dist/tools/messages.js +0 -0
  75. /package/{packages/framework-mcp → framework-mcp}/dist/tools/security.js +0 -0
  76. /package/{packages/framework-mcp → framework-mcp}/src/index.ts +0 -0
  77. /package/{packages/framework-mcp → framework-mcp}/src/tools/academy.ts +0 -0
  78. /package/{packages/framework-mcp → framework-mcp}/src/tools/codebase.ts +0 -0
  79. /package/{packages/framework-mcp → framework-mcp}/src/tools/database.ts +0 -0
  80. /package/{packages/framework-mcp → framework-mcp}/src/tools/knowledge.ts +0 -0
  81. /package/{packages/framework-mcp → framework-mcp}/src/tools/memory.ts +0 -0
  82. /package/{packages/framework-mcp → framework-mcp}/src/tools/messages.ts +0 -0
  83. /package/{packages/framework-mcp → framework-mcp}/src/tools/security.ts +0 -0
  84. /package/{packages/framework-mcp → framework-mcp}/tsconfig.json +0 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # 🏛️ Agent Enderun (v0.5.9) — The Supreme AI Governance Framework
1
+ # 🏛️ Agent Enderun (v0.6.0) — The Supreme AI Governance Framework
2
2
 
3
3
  **The Supreme AI Governance & Orchestration Framework for Enterprise Development**
4
4
 
@@ -317,28 +317,18 @@ agent-enderun/
317
317
  ├── bin/
318
318
  │ └── cli.js ← CLI entry point
319
319
  ├── docs/ ← Your project docs (agents read these)
320
- ├── tech-stack.md
321
- │ └── project-docs.md
322
- ├── packages/
323
- ├── shared-types/ ← Branded types (contract)
324
- ├── src/index.ts
325
- └── contract.version.json ← SHA-256 integrity hash
326
- │ └── framework-mcp/ ← MCP server (40+ tools)
327
- │ └── src/tools/
328
- │ ├── academy.ts
329
- │ ├── codebase.ts
330
- │ ├── security.ts
331
- │ ├── contract.ts
332
- │ ├── git.ts
333
- │ ├── knowledge.ts
334
- │ ├── database.ts
335
- │ ├── memory.ts
336
- │ ├── messages.ts
337
- │ ├── repository.ts
338
- │ └── framework.ts
320
+ ├── framework-mcp/ ← MCP server (40+ tools)
321
+ │ └── src/tools/
322
+ ├── scaffold.ts ← Blueprint construction
323
+ ├── academy.ts
324
+ ├── codebase.ts
325
+ └── [10 more...]
339
326
  ├── apps/ ← Your applications (start here)
340
- │ ├── backend/ ← (you create this)
341
- └── web/ (you create this)
327
+ │ ├── backend/
328
+ │ ├── src/types/ App-local contract types
329
+ │ │ └── contract.version.json ← SHA-256 integrity hash
330
+ │ └── web/
331
+ │ └── src/types/ ← Frontend mirrors of backend types
342
332
  └── {{FRAMEWORK_DIR}}/ ← Framework governance
343
333
  ├── ENDERUN.md ← Constitution (MANDATORY READ)
344
334
  ├── PROJECT_MEMORY.md ← State machine
@@ -748,3 +738,30 @@ All governance and engineering assets are consolidated under the framework direc
748
738
 
749
739
  ## 📜 License
750
740
  MIT © 2026 Yusuf BEKAR — **Agent Enderun: The Future of AI Governance.**
741
+ unctional.
742
+ - **Branded Types:** IDs must be type-safe (e.g., `UserID` vs `string`).
743
+ - **Panda CSS Only:** Zero-runtime CSS-in-JS for high-performance UI.
744
+ - **Contract-First:** Schemas are defined in `shared-types` BEFORE implementation.
745
+
746
+ ---
747
+
748
+ ## 📜 License
749
+ MIT © 2026 Yusuf BEKAR — **Agent Enderun: The Future of AI Governance.**
750
+ / # CLI Entry Point
751
+ ├── packages/ # Shared Types & MCP Engine
752
+ └── apps/ # Production Modules (Backend, Web, Mobile)
753
+ ```
754
+
755
+ ---
756
+
757
+ ## 🛡️ Engineering Standards
758
+
759
+ - **Zero Mock Policy:** Placeholders are forbidden. Every line of code must be functional.
760
+ - **Branded Types:** IDs must be type-safe (e.g., `UserID` vs `string`).
761
+ - **Panda CSS Only:** Zero-runtime CSS-in-JS for high-performance UI.
762
+ - **Contract-First:** Schemas are defined in `shared-types` BEFORE implementation.
763
+
764
+ ---
765
+
766
+ ## 📜 License
767
+ MIT © 2026 Yusuf BEKAR — **Agent Enderun: The Future of AI Governance.**
package/bin/cli.js CHANGED
@@ -159,7 +159,7 @@ function mergePackageJson(targetPath, sourcePath) {
159
159
  "enderun:check": "agent-enderun check",
160
160
  "enderun:test": "vitest run",
161
161
  "enderun:test:watch": "vitest",
162
- "enderun:build": `${runCmd} build --prefix packages/shared-types && ${runCmd} build --prefix packages/framework-mcp`,
162
+ "enderun:build": `${runCmd} build --prefix packages/shared-types && ${runCmd} build --prefix framework-mcp`,
163
163
  };
164
164
 
165
165
  const sourceDevDeps = sourcePkg.devDependencies || {};
@@ -337,8 +337,7 @@ async function initCommand(selectedAdapter) {
337
337
  "package.json",
338
338
  "tsconfig.json",
339
339
  "panda.config.ts",
340
- "packages/framework-mcp",
341
- "packages/shared-types",
340
+ "framework-mcp",
342
341
  ];
343
342
 
344
343
  const DIRS_TO_CREATE = [
@@ -353,8 +352,7 @@ async function initCommand(selectedAdapter) {
353
352
  "apps/web",
354
353
  "apps/backend",
355
354
  "docs",
356
- "packages/shared-types",
357
- "packages/framework-mcp",
355
+ "framework-mcp",
358
356
  ];
359
357
 
360
358
  console.log(`🚀 Installing Agent Enderun (Adapter: ${selectedAdapter || "all"})...`);
@@ -407,7 +405,7 @@ async function initCommand(selectedAdapter) {
407
405
  let dest = path.join(targetDir, item);
408
406
 
409
407
  // FORCED CLEANUP: Delete existing framework engine directory to ensure clean update
410
- if (["packages/framework-mcp"].includes(item)) {
408
+ if (["framework-mcp"].includes(item)) {
411
409
  if (fs.existsSync(dest)) {
412
410
  try {
413
411
  fs.rmSync(dest, { recursive: true, force: true });
@@ -432,7 +430,7 @@ async function initCommand(selectedAdapter) {
432
430
  if (fs.existsSync(src)) {
433
431
  if (fs.lstatSync(src).isDirectory()) {
434
432
  const skipFiles = (item === ".enderun") ? ["logs", "PROJECT_MEMORY.md", "PROJECT_MEMORY.lock"] : [];
435
- const nonDestructive = ["packages/shared-types", "docs", ".enderun"].includes(item);
433
+ const nonDestructive = ["docs", ".enderun"].includes(item);
436
434
  copyDir(src, dest, new Set(skipFiles), nonDestructive, targetBase, targetScope);
437
435
  } else {
438
436
  if (item === "package.json") continue; // We merge it later
@@ -507,7 +505,7 @@ async function initCommand(selectedAdapter) {
507
505
  ext.mcpServers = {
508
506
  "agent-enderun": {
509
507
  command: "node",
510
- args: ["packages/framework-mcp/dist/index.js"]
508
+ args: ["framework-mcp/dist/index.js"]
511
509
  }
512
510
  };
513
511
  fs.writeFileSync(geminiExtPath, JSON.stringify(ext, null, 2) + "\n");
@@ -519,7 +517,7 @@ async function initCommand(selectedAdapter) {
519
517
  }
520
518
 
521
519
  if (selectedAdapter === "claude") {
522
- const mcpPath = path.join(targetDir, "packages/framework-mcp/src/index.ts");
520
+ const mcpPath = path.join(targetDir, "framework-mcp/src/index.ts");
523
521
  console.log("\n📝 Claude Code Setup:");
524
522
  console.log("To enable Agent Enderun tools in Claude Code, run this command:");
525
523
  console.log(`\x1b[36mclaude config add framework-mcp npx tsx ${mcpPath}\x1b[0m`);
@@ -612,8 +610,8 @@ function checkCommand() {
612
610
  { name: "Framework Config (config.json)", path: path.join(frameworkDir, "config.json") },
613
611
  { name: "Agent Status (STATUS.md)", path: path.join(frameworkDir, "STATUS.md") },
614
612
  { name: "MCP Config (mcp.json)", path: "mcp.json" },
615
- { name: "Shared Types", path: "packages/shared-types/package.json" },
616
- { name: "MCP Server", path: "packages/framework-mcp/package.json" },
613
+ { name: "Backend Contract", path: "apps/backend/contract.version.json" },
614
+ { name: "MCP Server", path: "framework-mcp/package.json" },
617
615
  { name: "Tech Stack", path: path.join(frameworkDir, "docs/tech-stack.md") },
618
616
  { name: "Panda CSS Config", path: "panda.config.ts" },
619
617
  { name: "Requirements", path: path.join(frameworkDir, "docs/project-docs.md") },
@@ -633,7 +631,7 @@ function checkCommand() {
633
631
  }
634
632
 
635
633
  // Dependency Check
636
- const mcpNodeModules = path.join(process.cwd(), "packages/framework-mcp/node_modules");
634
+ const mcpNodeModules = path.join(process.cwd(), "framework-mcp/node_modules");
637
635
  const rootNodeModules = path.join(process.cwd(), "node_modules");
638
636
  if (!fs.existsSync(mcpNodeModules) && !fs.existsSync(rootNodeModules)) {
639
637
  console.log("❌ Dependencies MISSING! (Run 'npm install')");
@@ -643,7 +641,7 @@ function checkCommand() {
643
641
  }
644
642
 
645
643
  // MCP Build Check
646
- const mcpPath = path.join(process.cwd(), "packages/framework-mcp/dist/index.js");
644
+ const mcpPath = path.join(process.cwd(), "framework-mcp/dist/index.js");
647
645
  if (!fs.existsSync(mcpPath)) {
648
646
  console.log("❌ MCP Build MISSING! (Run 'npm run enderun:build')");
649
647
  issues++;
@@ -857,11 +855,11 @@ function traceNewCommand(description, agent = "manager", priority = "P2") {
857
855
  * Verify the shared-types contract hash.
858
856
  */
859
857
  function verifyContractCommand() {
860
- const sharedDir = path.join(targetDir, "packages/shared-types/src");
861
- const contractPath = path.join(targetDir, "packages/shared-types/contract.version.json");
858
+ const sharedDir = path.join(targetDir, "apps/backend/src/types");
859
+ const contractPath = path.join(targetDir, "apps/backend/contract.version.json");
862
860
 
863
861
  if (!fs.existsSync(sharedDir) || !fs.existsSync(contractPath)) {
864
- console.error("❌ Error: Shared types or contract.version.json not found.");
862
+ console.error("❌ Error: Backend types or contract.version.json not found.");
865
863
  return;
866
864
  }
867
865
 
@@ -953,7 +951,7 @@ function gitCommitCommand(traceId) {
953
951
  const files = cp.execSync("git diff --staged --name-only", { encoding: "utf8" }).split("\n").filter(Boolean);
954
952
  let type = "feat", scope = "code";
955
953
  if (files.some(f => f.includes(".md"))) type = "docs";
956
- else if (files.some(f => f.includes("shared-types"))) type = "arch";
954
+ else if (files.some(f => f.includes("apps/backend/src/types"))) type = "arch";
957
955
  else if (files.some(f => f.includes("bin/cli.js"))) type = "fix";
958
956
 
959
957
  const summary = files.length === 1 ? `update ${path.basename(files[0])}` : `update ${files.length} files`;
@@ -1227,8 +1225,8 @@ function buildSharedTypesContent(existingContent) {
1227
1225
  }
1228
1226
 
1229
1227
  function updateContractHashFile() {
1230
- const sharedDir = path.join(targetDir, "packages/shared-types/src");
1231
- const contractPath = path.join(targetDir, "packages/shared-types/contract.version.json");
1228
+ const sharedDir = path.join(targetDir, "apps/backend/src/types");
1229
+ const contractPath = path.join(targetDir, "apps/backend/contract.version.json");
1232
1230
  if (!fs.existsSync(sharedDir) || !fs.existsSync(contractPath)) return;
1233
1231
 
1234
1232
  const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
@@ -1250,7 +1248,186 @@ function updateContractHashFile() {
1250
1248
  fs.writeFileSync(contractPath, JSON.stringify(contract, null, 2));
1251
1249
  }
1252
1250
 
1251
+ function createBaseTypeFiles(baseDir) {
1252
+ const typesDir = path.join(baseDir, "types");
1253
+ ensureDir(typesDir);
1254
+
1255
+ writeTextFile(path.join(typesDir, "api.ts"), `import { TraceID } from "./brands.js";
1256
+
1257
+ /**
1258
+ * API Response Wrappers
1259
+ */
1260
+ export interface ApiResponse<T> {
1261
+ data: T;
1262
+ meta?: {
1263
+ requestId: TraceID;
1264
+ timestamp: string;
1265
+ };
1266
+ }
1267
+
1268
+ export interface ApiError {
1269
+ error: {
1270
+ code: string;
1271
+ message: string;
1272
+ details?: unknown;
1273
+ };
1274
+ }
1275
+ `);
1276
+
1277
+ writeTextFile(path.join(typesDir, "brands.ts"), `/**
1278
+ * Branded Type Utility
1279
+ */
1280
+ export type Brand<K, T> = K & { __brand: T };
1281
+
1282
+ /**
1283
+ * Entity IDs (Branded)
1284
+ */
1285
+ export type TraceID = Brand<string, "TraceID">;
1286
+ export type AgentID = Brand<string, "AgentID">;
1287
+ export type ProjectID = Brand<string, "ProjectID">;
1288
+ export type UserID = Brand<string, "UserID">;
1289
+ `);
1290
+
1291
+ writeTextFile(path.join(typesDir, "constants.ts"), `import { TraceID } from "./brands.js";
1292
+
1293
+ /**
1294
+ * Project Phases
1295
+ */
1296
+ export const PROJECT_PHASES = ["PHASE_0", "PHASE_1", "PHASE_2", "PHASE_3", "PHASE_4"] as const;
1297
+ export type ProjectPhase = (typeof PROJECT_PHASES)[number];
1298
+
1299
+ /**
1300
+ * Execution Profiles
1301
+ */
1302
+ export const EXECUTION_PROFILES = ["Lightweight", "Full"] as const;
1303
+ export type ExecutionProfile = (typeof EXECUTION_PROFILES)[number];
1304
+
1305
+ /**
1306
+ * Task Priorities
1307
+ */
1308
+ export const TASK_PRIORITIES = ["P0", "P1", "P2", "P3"] as const;
1309
+ export type TaskPriority = (typeof TASK_PRIORITIES)[number];
1310
+
1311
+ /**
1312
+ * Task Statuses
1313
+ */
1314
+ export const TASK_STATUSES = ["PENDING", "IN_PROGRESS", "BLOCKED", "COMPLETED", "FAILED"] as const;
1315
+ export type TaskStatus = (typeof TASK_STATUSES)[number];
1316
+
1317
+ /**
1318
+ * Action Types & Status
1319
+ */
1320
+ export const ACTION_TYPES = ["CREATE", "MODIFY", "DELETE", "RESEARCH", "ORCHESTRATE"] as const;
1321
+ export type ActionType = (typeof ACTION_TYPES)[number];
1322
+
1323
+ export const ACTION_STATUSES = ["SUCCESS", "FAILURE", "WAITING"] as const;
1324
+ export type ActionStatus = (typeof ACTION_STATUSES)[number];
1325
+ `);
1326
+
1327
+ writeTextFile(path.join(typesDir, "index.ts"), `/**
1328
+ * Agent Enderun — App-Local Types (Modular)
1329
+ */
1330
+
1331
+ export * from "./brands.js";
1332
+ export * from "./constants.js";
1333
+ export * from "./models.js";
1334
+ export * from "./api.js";
1335
+ export * from "./logs.js";
1336
+ `);
1337
+
1338
+ writeTextFile(path.join(typesDir, "logs.ts"), `import { TraceID, AgentID } from "./brands.js";
1339
+ import { ActionType, ActionStatus } from "./constants.js";
1340
+
1341
+ /**
1342
+ * Audit & Agent Logging Types
1343
+ */
1344
+ export interface AgentActionLog {
1345
+ timestamp: string;
1346
+ agent: AgentID;
1347
+ action: ActionType;
1348
+ requestId: TraceID | "—";
1349
+ status: ActionStatus;
1350
+ summary: string;
1351
+ files?: string[];
1352
+ details?: Record<string, unknown>;
1353
+ }
1354
+ `);
1355
+
1356
+ writeTextFile(path.join(typesDir, "models.ts"), `import { UserID, TraceID, AgentID } from "./brands.js";
1357
+ import { ProjectPhase, ExecutionProfile, TaskPriority, TaskStatus } from "./constants.js";
1358
+
1359
+ /**
1360
+ * Base Entity Fields
1361
+ */
1362
+ export interface BaseEntity {
1363
+ id: string; // Usually ULID
1364
+ createdAt: string;
1365
+ updatedAt: string;
1366
+ deletedAt?: string | null;
1367
+ }
1368
+
1369
+ /**
1370
+ * Audit Log Model
1371
+ */
1372
+ export interface AuditLog extends BaseEntity {
1373
+ entityName: string;
1374
+ entityId: string;
1375
+ action: "CREATE" | "UPDATE" | "DELETE" | "RESTORE";
1376
+ userId: UserID;
1377
+ previousState?: Record<string, unknown> | null;
1378
+ newState?: Record<string, unknown> | null;
1379
+ traceId: TraceID;
1380
+ }
1381
+
1382
+ /**
1383
+ * User Model
1384
+ */
1385
+ export interface User extends BaseEntity {
1386
+ id: UserID;
1387
+ email: string;
1388
+ fullName: string;
1389
+ role: "ADMIN" | "DEVELOPER" | "VIEWER";
1390
+ }
1391
+
1392
+ export interface UserProfile extends User {
1393
+ avatarUrl?: string;
1394
+ bio?: string;
1395
+ preferences: Record<string, unknown>;
1396
+ }
1397
+
1398
+ /**
1399
+ * Project Status
1400
+ */
1401
+ export interface ProjectStatus {
1402
+ phase: ProjectPhase;
1403
+ profile: ExecutionProfile;
1404
+ lastUpdate: string;
1405
+ activeTraceId: TraceID | null;
1406
+ blockers: string[];
1407
+ }
1408
+
1409
+ /**
1410
+ * Task Model
1411
+ */
1412
+ export interface Task {
1413
+ id: TraceID;
1414
+ description: string;
1415
+ agent: AgentID;
1416
+ priority: TaskPriority;
1417
+ status: TaskStatus;
1418
+ createdAt: string;
1419
+ updatedAt: string;
1420
+ }
1421
+ `);
1422
+ console.log(`✅ Base types created in ${path.relative(targetDir, typesDir)}`);
1423
+ }
1424
+
1253
1425
  function createBackendFiles(spec) {
1426
+ createBaseTypeFiles(path.join(targetDir, "apps/backend/src"));
1427
+ writeJsonFile(path.join(targetDir, "apps/backend/contract.version.json"), {
1428
+ "contract_hash": "initial_hash_placeholder",
1429
+ "last_updated": new Date().toISOString()
1430
+ });
1254
1431
  writeJsonFile(path.join(targetDir, "apps/backend/package.json"), {
1255
1432
  name: "@agent-enderun/backend",
1256
1433
  version: "0.1.0",
@@ -1290,7 +1467,7 @@ function createBackendFiles(spec) {
1290
1467
  });
1291
1468
 
1292
1469
  writeTextFile(path.join(targetDir, "apps/backend/src/data.ts"), [
1293
- 'import type { Customer, DashboardSummary, ReportMetric, Role, User } from "../../../packages/shared-types/src/index.js";',
1470
+ 'import type { Customer, DashboardSummary, ReportMetric, Role, User } from "./types/index.js";',
1294
1471
  "",
1295
1472
  'const now = new Date().toISOString();',
1296
1473
  "",
@@ -1364,6 +1541,7 @@ function createBackendFiles(spec) {
1364
1541
  }
1365
1542
 
1366
1543
  function createWebFiles(spec) {
1544
+ createBaseTypeFiles(path.join(targetDir, "apps/web/src"));
1367
1545
  writeJsonFile(path.join(targetDir, "apps/web/package.json"), {
1368
1546
  name: "@agent-enderun/web",
1369
1547
  version: "0.1.0",
@@ -1632,7 +1810,7 @@ function updateProjectDocs(spec) {
1632
1810
  "",
1633
1811
  "- `apps/backend`: Fastify API",
1634
1812
  "- `apps/web`: React dashboard",
1635
- "- `packages/shared-types`: Contract-first shared TypeScript types",
1813
+ "- `apps/backend/src/types`: Contract-first backend TypeScript types",
1636
1814
  ].join("\n"));
1637
1815
 
1638
1816
  writeTextFile(path.join(apiDir, "README.md"), [
@@ -1658,7 +1836,7 @@ function updateMemoryForGeneratedApp(spec, traceId) {
1658
1836
  "- **Agent:** @manager",
1659
1837
  `- **Trace ID:** ${traceId}`,
1660
1838
  "- **Action:** Created full-stack starter from natural language request.",
1661
- "- **Files:** apps/backend, apps/web, shared-types, project docs",
1839
+ "- **Files:** apps/backend, apps/web, project docs",
1662
1840
  ].join("\n");
1663
1841
 
1664
1842
  updateProjectMemoryCommand("HISTORY", history);
@@ -1693,10 +1871,10 @@ async function createAppCommand(args) {
1693
1871
  createWebFiles(spec);
1694
1872
  updateProjectDocs(spec);
1695
1873
 
1696
- const sharedTypesPath = path.join(targetDir, "packages/shared-types/src/index.ts");
1697
- if (fs.existsSync(sharedTypesPath)) {
1698
- const existing = fs.readFileSync(sharedTypesPath, "utf8");
1699
- fs.writeFileSync(sharedTypesPath, buildSharedTypesContent(existing));
1874
+ const backendTypesPath = path.join(targetDir, "apps/backend/src/types/index.ts");
1875
+ if (fs.existsSync(backendTypesPath)) {
1876
+ const existing = fs.readFileSync(backendTypesPath, "utf8");
1877
+ fs.writeFileSync(backendTypesPath, buildSharedTypesContent(existing));
1700
1878
  updateContractHashFile();
1701
1879
  }
1702
1880
 
@@ -1746,7 +1924,7 @@ async function main() {
1746
1924
  verifyContractCommand();
1747
1925
  break;
1748
1926
  case "mcp": {
1749
- const mcpServerPath = path.join(sourceDir, "packages/framework-mcp/dist/index.js");
1927
+ const mcpServerPath = path.join(sourceDir, "framework-mcp/dist/index.js");
1750
1928
  if (fs.existsSync(mcpServerPath)) {
1751
1929
  const { spawn } = await import("child_process");
1752
1930
  // Use node to execute the built MCP server
@@ -98,3 +98,15 @@ export const SYNC_CONTRACT_HASH_ARGS_SCHEMA = z.object({
98
98
  export const VERIFY_FRAMEWORK_HEALTH_ARGS_SCHEMA = z.object({
99
99
  detailed: z.boolean().default(false),
100
100
  });
101
+ export const INSTANTIATE_BLUEPRINT_ARGS_SCHEMA = z.object({
102
+ blueprintPath: z.string().min(1),
103
+ targetPath: z.string().min(1),
104
+ });
105
+ export const LIST_BLUEPRINTS_ARGS_SCHEMA = z.object({
106
+ category: z.enum(["backend", "frontend"]).optional(),
107
+ });
108
+ export const SAVE_AS_BLUEPRINT_ARGS_SCHEMA = z.object({
109
+ blueprintPath: z.string().min(1),
110
+ content: z.string().min(1),
111
+ description: z.string().optional(),
112
+ });
@@ -44,8 +44,8 @@ export const contractTools = [
44
44
  export const contractHandlers = {
45
45
  verify_api_contract: async (args, projectRoot) => {
46
46
  try {
47
- const sharedTypesDir = path.join(projectRoot, "packages/shared-types/src");
48
- const contractJsonPath = path.join(projectRoot, "packages/shared-types/contract.version.json");
47
+ const sharedTypesDir = path.join(projectRoot, "apps/backend/src/types");
48
+ const contractJsonPath = path.join(projectRoot, "apps/backend/contract.version.json");
49
49
  if (!fs.existsSync(sharedTypesDir) || !fs.existsSync(contractJsonPath))
50
50
  return { content: [{ type: "text", text: "Missing shared-types directory or contract.version.json" }] };
51
51
  const currentHash = calculateContractHash(sharedTypesDir, projectRoot);
@@ -58,8 +58,8 @@ export const contractHandlers = {
58
58
  },
59
59
  update_contract_hash: async (args, projectRoot) => {
60
60
  try {
61
- const sharedTypesDir = path.join(projectRoot, "packages/shared-types/src");
62
- const contractJsonPath = path.join(projectRoot, "packages/shared-types/contract.version.json");
61
+ const sharedTypesDir = path.join(projectRoot, "apps/backend/src/types");
62
+ const contractJsonPath = path.join(projectRoot, "apps/backend/contract.version.json");
63
63
  if (!fs.existsSync(sharedTypesDir))
64
64
  return { content: [{ type: "text", text: "Missing shared-types directory" }] };
65
65
  const files = collectFilesRecursively(sharedTypesDir, new Set(["ts"])).sort();
@@ -83,7 +83,7 @@ export const contractHandlers = {
83
83
  try {
84
84
  const frameworkDir = getFrameworkDir(projectRoot);
85
85
  const apiDocPath = path.join(projectRoot, frameworkDir, "docs/api", `${parsed.data.domain}.md`);
86
- const sharedTypesDir = path.join(projectRoot, "packages/shared-types/src");
86
+ const sharedTypesDir = path.join(projectRoot, "apps/backend/src/types");
87
87
  if (!fs.existsSync(apiDocPath))
88
88
  return { content: [{ type: "text", text: `API documentation not found for domain: ${parsed.data.domain}` }] };
89
89
  if (!fs.existsSync(sharedTypesDir))
@@ -103,8 +103,9 @@ export const frameworkHandlers = {
103
103
  const missing = [];
104
104
  const frameworkDir = getFrameworkDir(projectRoot);
105
105
  const checkPaths = [
106
- { path: "apps", type: "folder", optional: true },
107
- { path: "packages/shared-types/src", type: "folder" },
106
+ { path: "apps/backend/src/types", type: "folder" },
107
+ { path: "apps/web/src/types", type: "folder" },
108
+ { path: "framework-mcp/src", type: "folder" },
108
109
  { path: path.join(frameworkDir, "docs/api"), type: "folder", optional: true },
109
110
  { path: ".env", type: "file", optional: true },
110
111
  { path: ".env.example", type: "file" },
@@ -27,7 +27,7 @@ export const gitHandlers = {
27
27
  let type = "feat", scope = "code";
28
28
  if (files.some(f => f.includes(".md")))
29
29
  type = "docs";
30
- else if (files.some(f => f.includes("shared-types")))
30
+ else if (files.some(f => f.includes("apps/backend/src/types")))
31
31
  type = "arch";
32
32
  else if (files.some(f => f.includes("framework-mcp")))
33
33
  type = "chore";
@@ -39,9 +39,7 @@ export const gitHandlers = {
39
39
  scope = "web";
40
40
  else if (files.some(f => f.includes("apps/backend")))
41
41
  scope = "backend";
42
- else if (files.some(f => f.includes("packages/shared-types")))
43
- scope = "contract";
44
- else if (files.some(f => f.includes("packages/framework-mcp")))
42
+ else if (files.some(f => f.includes("framework-mcp")))
45
43
  scope = "mcp";
46
44
  const summary = files.length === 1 ? `update ${path.basename(files[0])}` : `update ${files.length} files`;
47
45
  return { content: [{ type: "text", text: `### SUGGESTED SEMANTIC COMMIT MESSAGE\n\n\`[${parsed.data.traceId}] ${type}(${scope}): ${summary}\`\n\n**Files Analyzed:**\n${files.map(f => `- ${f}`).join("\n")}` }] };
@@ -9,6 +9,7 @@ import { gitTools, gitHandlers } from "./git.js";
9
9
  import { databaseTools, databaseHandlers } from "./database.js";
10
10
  import { knowledgeTools, knowledgeHandlers } from "./knowledge.js";
11
11
  import { repositoryTools, repositoryHandlers } from "./repository.js";
12
+ import { scaffoldTools, scaffoldHandlers } from "./scaffold.js";
12
13
  export const allTools = [
13
14
  ...codebaseTools,
14
15
  ...frameworkTools,
@@ -21,6 +22,7 @@ export const allTools = [
21
22
  ...databaseTools,
22
23
  ...knowledgeTools,
23
24
  ...repositoryTools,
25
+ ...scaffoldTools,
24
26
  ];
25
27
  export const allHandlers = {
26
28
  ...codebaseHandlers,
@@ -34,6 +36,7 @@ export const allHandlers = {
34
36
  ...databaseHandlers,
35
37
  ...knowledgeHandlers,
36
38
  ...repositoryHandlers,
39
+ ...scaffoldHandlers,
37
40
  };
38
41
  // Add compatibility aliases
39
42
  allHandlers.codebase_search = allHandlers.search_codebase;
@@ -91,7 +91,7 @@ export const repositoryHandlers = {
91
91
  });
92
92
  });
93
93
  }
94
- const majorDirs = ["apps/backend", "apps/web", "packages/shared-types", "packages/framework-mcp"], missingREADME = majorDirs.filter(dir => fs.existsSync(path.join(projectRoot, dir)) && !fs.existsSync(path.join(projectRoot, dir, "README.md")));
94
+ const majorDirs = ["apps/backend", "apps/web", "framework-mcp"], missingREADME = majorDirs.filter(dir => fs.existsSync(path.join(projectRoot, dir)) && !fs.existsSync(path.join(projectRoot, dir, "README.md")));
95
95
  return { content: [{ type: "text", text: `### DOCUMENTATION DEBT REPORT\n\n**Missing JSDoc:**\n${missingJSDoc.slice(0, 10).join("\n")}\n\n**Missing README.md:**\n${missingREADME.join("\n")}` }] };
96
96
  }
97
97
  catch (error) {