agent-enderun 0.5.8 → 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.
- package/.enderun/PROJECT_MEMORY.md +16 -151
- package/.enderun/STATUS.md +19 -10
- package/.enderun/agents/analyst.md +19 -6
- package/.enderun/agents/backend.md +66 -48
- package/.enderun/agents/explorer.md +14 -2
- package/.enderun/agents/frontend.md +59 -14
- package/.enderun/agents/git.md +1 -1
- package/.enderun/agents/manager.md +10 -2
- package/.enderun/agents/mobile.md +1 -1
- package/.enderun/agents/native.md +1 -1
- package/.enderun/blueprints/backend/errors/domain-error.ts +84 -0
- package/.enderun/blueprints/backend/middleware/error-handler.ts +24 -0
- package/.enderun/blueprints/backend/types/api.ts +20 -0
- package/.enderun/blueprints/backend/types/brands.ts +12 -0
- package/.enderun/blueprints/backend/types/constants.ts +34 -0
- package/.enderun/blueprints/backend/types/index.ts +49 -0
- package/.enderun/blueprints/backend/types/logs.ts +16 -0
- package/.enderun/blueprints/backend/types/models.ts +65 -0
- package/.enderun/blueprints/frontend/ui/Button.tsx +60 -0
- package/.enderun/blueprints/frontend/ui/Input.tsx +43 -0
- package/.enderun/docs/api/README.md +7 -12
- package/.enderun/docs/project-docs.md +17 -7
- package/.enderun/knowledge/blueprint_driven_construction.md +22 -0
- package/.enderun/knowledge/code_review_checklist.md +1 -1
- package/.enderun/knowledge/contract_versioning.md +5 -5
- package/ENDERUN.md +29 -6
- package/README.md +45 -23
- package/bin/cli.js +205 -27
- package/bin/update-contract.js +3 -0
- package/{packages/framework-mcp → framework-mcp}/dist/index.js +0 -0
- package/{packages/framework-mcp → framework-mcp}/dist/schemas.js +12 -0
- package/{packages/framework-mcp → framework-mcp}/dist/tools/contract.js +16 -10
- package/{packages/framework-mcp → framework-mcp}/dist/tools/framework.js +5 -3
- package/{packages/framework-mcp → framework-mcp}/dist/tools/git.js +2 -4
- package/{packages/framework-mcp → framework-mcp}/dist/tools/index.js +3 -0
- package/{packages/framework-mcp → framework-mcp}/dist/tools/knowledge.js +1 -1
- package/{packages/framework-mcp → framework-mcp}/dist/tools/repository.js +1 -1
- package/framework-mcp/dist/tools/scaffold.js +129 -0
- package/{packages/framework-mcp → framework-mcp}/dist/utils.js +1 -1
- package/{packages/framework-mcp → framework-mcp}/package.json +4 -1
- package/{packages/framework-mcp → framework-mcp}/src/schemas.ts +15 -0
- package/{packages/framework-mcp → framework-mcp}/src/tools/contract.ts +22 -9
- package/{packages/framework-mcp → framework-mcp}/src/tools/framework.ts +6 -4
- package/{packages/framework-mcp → framework-mcp}/src/tools/git.ts +2 -3
- package/{packages/framework-mcp → framework-mcp}/src/tools/index.ts +3 -0
- package/{packages/framework-mcp → framework-mcp}/src/tools/knowledge.ts +6 -6
- package/{packages/framework-mcp → framework-mcp}/src/tools/repository.ts +1 -1
- package/framework-mcp/src/tools/scaffold.ts +147 -0
- package/{packages/framework-mcp → framework-mcp}/src/utils.ts +1 -1
- package/package.json +8 -12
- package/panda.config.ts +79 -5
- package/.enderun/logs/manager.json +0 -18
- package/packages/shared-types/README.md +0 -61
- package/packages/shared-types/contract.version.json +0 -12
- package/packages/shared-types/dist/index.d.ts +0 -92
- package/packages/shared-types/dist/index.js +0 -8
- package/packages/shared-types/dist/index.js.map +0 -1
- package/packages/shared-types/package.json +0 -33
- package/packages/shared-types/src/index.ts +0 -102
- package/packages/shared-types/tsconfig.json +0 -9
- /package/{packages/framework-mcp → framework-mcp}/README.md +0 -0
- /package/{packages/framework-mcp → framework-mcp}/dist/tools/academy.js +0 -0
- /package/{packages/framework-mcp → framework-mcp}/dist/tools/codebase.js +0 -0
- /package/{packages/framework-mcp → framework-mcp}/dist/tools/database.js +0 -0
- /package/{packages/framework-mcp → framework-mcp}/dist/tools/memory.js +0 -0
- /package/{packages/framework-mcp → framework-mcp}/dist/tools/messages.js +0 -0
- /package/{packages/framework-mcp → framework-mcp}/dist/tools/security.js +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/index.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/tools/academy.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/tools/codebase.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/tools/database.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/tools/memory.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/tools/messages.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/src/tools/security.ts +0 -0
- /package/{packages/framework-mcp → framework-mcp}/tsconfig.json +0 -0
|
@@ -3,7 +3,7 @@ name: manager
|
|
|
3
3
|
description: "CTO & Controller. Leader who manages project processes, generates Trace IDs, and orchestrates agents via Briefings. Responsible for Git Orchestration via the @git specialist. Reads {{FRAMEWORK_DIR}}/ENDERUN.md and {{FRAMEWORK_DIR}}/PROJECT_MEMORY.md in every session, validates the phase, and assigns agents."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Manager (CTO & Controller) — v0.
|
|
6
|
+
# Manager (CTO & Controller) — v0.6.0 Master
|
|
7
7
|
|
|
8
8
|
**Role:** Enforce all framework rules without compromise and direct agents to the correct tasks. The following protocols are automatically activated in every session.
|
|
9
9
|
|
|
@@ -168,7 +168,7 @@ graph TD
|
|
|
168
168
|
**Agent Completion Report** (v0.5.8)
|
|
169
169
|
|
|
170
170
|
- Mock used? [ ] No / [ ] Yes
|
|
171
|
-
-
|
|
171
|
+
- App types changed? [ ] No / [ ] Yes
|
|
172
172
|
- **API contract checked? [ ] No / [ ] Yes → {{FRAMEWORK_DIR}}/docs/api/**
|
|
173
173
|
- Log written? [ ] No / [ ] Yes → via log_agent_action tool
|
|
174
174
|
- **PROJECT_MEMORY HISTORY updated? [ ] No / [ ] Yes**
|
|
@@ -177,3 +177,11 @@ graph TD
|
|
|
177
177
|
- Blockers: [write if any, otherwise "NONE"]
|
|
178
178
|
|
|
179
179
|
---
|
|
180
|
+
ise "NONE"]
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
--
|
|
184
|
+
needs to be done]
|
|
185
|
+
- Blockers: [write if any, otherwise "NONE"]
|
|
186
|
+
|
|
187
|
+
---
|
|
@@ -3,7 +3,7 @@ name: mobile
|
|
|
3
3
|
description: "Mobile Application Expert. Specialist in React Native and Expo. Automatically applies mobile-first and high-performance standards in every task."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Mobile Architect — v0.
|
|
6
|
+
# Mobile Architect — v0.6.0 Master
|
|
7
7
|
|
|
8
8
|
**Role:** Build high-performance mobile applications using React Native. Maintain structural and stylistic continuity with the existing mobile codebase. All the following standards are automatically applied in every task.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: native
|
|
|
3
3
|
description: "Native Application Expert. Specialist in Rust, Tauri, and Electron. Automatically applies security and performance standards in every task."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Native Desktop Architect — v0.
|
|
6
|
+
# Native Desktop Architect — v0.6.0 Master
|
|
7
7
|
|
|
8
8
|
**Role:** Build secure and efficient desktop applications using Tauri or Electron. Ensure procedural continuity across the native codebase.
|
|
9
9
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ApiError } from "@agent-enderun/shared-types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base Domain Error
|
|
5
|
+
* All specialized errors should extend this class.
|
|
6
|
+
*/
|
|
7
|
+
export class DomainError extends Error {
|
|
8
|
+
constructor(
|
|
9
|
+
public readonly code: string,
|
|
10
|
+
public readonly statusCode: number,
|
|
11
|
+
message: string,
|
|
12
|
+
public readonly details?: unknown
|
|
13
|
+
) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "DomainError";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Converts the error to a standard API response format defined in shared-types
|
|
20
|
+
*/
|
|
21
|
+
toApiResponse(): ApiError {
|
|
22
|
+
return {
|
|
23
|
+
error: {
|
|
24
|
+
code: this.code,
|
|
25
|
+
message: this.message,
|
|
26
|
+
details: this.details,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 404 - Not Found
|
|
34
|
+
*/
|
|
35
|
+
export class NotFoundError extends DomainError {
|
|
36
|
+
constructor(entity: string, details?: unknown) {
|
|
37
|
+
super("NOT_FOUND", 404, `${entity} not found.`, details);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 400 - Validation Error
|
|
43
|
+
*/
|
|
44
|
+
export class ValidationError extends DomainError {
|
|
45
|
+
constructor(message: string, details?: unknown) {
|
|
46
|
+
super("VALIDATION_ERROR", 400, message, details);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 401 - Unauthorized
|
|
52
|
+
*/
|
|
53
|
+
export class UnauthorizedError extends DomainError {
|
|
54
|
+
constructor(message: string = "Authentication required.", details?: unknown) {
|
|
55
|
+
super("UNAUTHORIZED", 401, message, details);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 403 - Forbidden
|
|
61
|
+
*/
|
|
62
|
+
export class ForbiddenError extends DomainError {
|
|
63
|
+
constructor(message: string = "Access denied.", details?: unknown) {
|
|
64
|
+
super("FORBIDDEN", 403, message, details);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 409 - Conflict
|
|
70
|
+
*/
|
|
71
|
+
export class ConflictError extends DomainError {
|
|
72
|
+
constructor(message: string, details?: unknown) {
|
|
73
|
+
super("CONFLICT", 409, message, details);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 500 - Internal Server Error
|
|
79
|
+
*/
|
|
80
|
+
export class InternalServerError extends DomainError {
|
|
81
|
+
constructor(message: string = "An unexpected error occurred.", details?: unknown) {
|
|
82
|
+
super("INTERNAL_ERROR", 500, message, details);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { DomainError } from "../errors/domain-error.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Global Error Handler for Fastify (Template)
|
|
6
|
+
* This middleware captures DomainErrors and formats them consistently.
|
|
7
|
+
*/
|
|
8
|
+
export const errorHandler = (error: unknown, request: any, reply: any) => {
|
|
9
|
+
// Capture custom domain errors
|
|
10
|
+
if (error instanceof DomainError) {
|
|
11
|
+
return reply.status(error.statusCode).send(error.toApiResponse());
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Fallback for unknown errors
|
|
15
|
+
request.log.error(error);
|
|
16
|
+
|
|
17
|
+
return reply.status(500).send({
|
|
18
|
+
error: {
|
|
19
|
+
code: "INTERNAL_ERROR",
|
|
20
|
+
message: "An unexpected error occurred.",
|
|
21
|
+
details: process.env.NODE_ENV === "development" ? error.message : undefined
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TraceID } from "./brands.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* API Response Wrappers
|
|
5
|
+
*/
|
|
6
|
+
export interface ApiResponse<T> {
|
|
7
|
+
data: T;
|
|
8
|
+
meta?: {
|
|
9
|
+
requestId: TraceID;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ApiError {
|
|
15
|
+
error: {
|
|
16
|
+
code: string;
|
|
17
|
+
message: string;
|
|
18
|
+
details?: unknown;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branded Type Utility
|
|
3
|
+
*/
|
|
4
|
+
export type Brand<K, T> = K & { __brand: T };
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Entity IDs (Branded)
|
|
8
|
+
*/
|
|
9
|
+
export type TraceID = Brand<string, "TraceID">;
|
|
10
|
+
export type AgentID = Brand<string, "AgentID">;
|
|
11
|
+
export type ProjectID = Brand<string, "ProjectID">;
|
|
12
|
+
export type UserID = Brand<string, "UserID">;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { TraceID } from "./brands.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Project Phases
|
|
5
|
+
*/
|
|
6
|
+
export const PROJECT_PHASES = ["PHASE_0", "PHASE_1", "PHASE_2", "PHASE_3", "PHASE_4"] as const;
|
|
7
|
+
export type ProjectPhase = (typeof PROJECT_PHASES)[number];
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Execution Profiles
|
|
11
|
+
*/
|
|
12
|
+
export const EXECUTION_PROFILES = ["Lightweight", "Full"] as const;
|
|
13
|
+
export type ExecutionProfile = (typeof EXECUTION_PROFILES)[number];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Task Priorities
|
|
17
|
+
*/
|
|
18
|
+
export const TASK_PRIORITIES = ["P0", "P1", "P2", "P3"] as const;
|
|
19
|
+
export type TaskPriority = (typeof TASK_PRIORITIES)[number];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Task Statuses
|
|
23
|
+
*/
|
|
24
|
+
export const TASK_STATUSES = ["PENDING", "IN_PROGRESS", "BLOCKED", "COMPLETED", "FAILED"] as const;
|
|
25
|
+
export type TaskStatus = (typeof TASK_STATUSES)[number];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Action Types & Status
|
|
29
|
+
*/
|
|
30
|
+
export const ACTION_TYPES = ["CREATE", "MODIFY", "DELETE", "RESEARCH", "ORCHESTRATE"] as const;
|
|
31
|
+
export type ActionType = (typeof ACTION_TYPES)[number];
|
|
32
|
+
|
|
33
|
+
export const ACTION_STATUSES = ["SUCCESS", "FAILURE", "WAITING"] as const;
|
|
34
|
+
export type ActionStatus = (typeof ACTION_STATUSES)[number];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Enderun — App-Local Types (Modular)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export * from "./brands.js";
|
|
6
|
+
export * from "./constants.js";
|
|
7
|
+
export * from "./models.js";
|
|
8
|
+
export * from "./api.js";
|
|
9
|
+
export * from "./logs.js";
|
|
10
|
+
|
|
11
|
+
// --- Generated Application Contract ---
|
|
12
|
+
export type RoleID = Brand<string, "RoleID">;
|
|
13
|
+
export type ReportID = Brand<string, "ReportID">;
|
|
14
|
+
export type CustomerID = Brand<string, "CustomerID">;
|
|
15
|
+
|
|
16
|
+
export interface AuthSession {
|
|
17
|
+
user: User;
|
|
18
|
+
token: string;
|
|
19
|
+
expiresAt: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface Role {
|
|
23
|
+
id: RoleID;
|
|
24
|
+
name: string;
|
|
25
|
+
permissions: string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Customer {
|
|
29
|
+
id: CustomerID;
|
|
30
|
+
name: string;
|
|
31
|
+
ownerId: UserID;
|
|
32
|
+
status: "LEAD" | "ACTIVE" | "AT_RISK";
|
|
33
|
+
annualValue: number;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ReportMetric {
|
|
38
|
+
id: ReportID;
|
|
39
|
+
label: string;
|
|
40
|
+
value: number;
|
|
41
|
+
trend: "UP" | "DOWN" | "FLAT";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface DashboardSummary {
|
|
45
|
+
customers: Customer[];
|
|
46
|
+
users: User[];
|
|
47
|
+
roles: Role[];
|
|
48
|
+
reports: ReportMetric[];
|
|
49
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TraceID, AgentID } from "./brands.js";
|
|
2
|
+
import { ActionType, ActionStatus } from "./constants.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Audit & Agent Logging Types
|
|
6
|
+
*/
|
|
7
|
+
export interface AgentActionLog {
|
|
8
|
+
timestamp: string;
|
|
9
|
+
agent: AgentID;
|
|
10
|
+
action: ActionType;
|
|
11
|
+
requestId: TraceID | "—";
|
|
12
|
+
status: ActionStatus;
|
|
13
|
+
summary: string;
|
|
14
|
+
files?: string[];
|
|
15
|
+
details?: Record<string, unknown>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { UserID, TraceID, AgentID } from "./brands.js";
|
|
2
|
+
import { ProjectPhase, ExecutionProfile, TaskPriority, TaskStatus } from "./constants.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base Entity Fields
|
|
6
|
+
*/
|
|
7
|
+
export interface BaseEntity {
|
|
8
|
+
id: string; // Usually ULID
|
|
9
|
+
createdAt: string;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
deletedAt?: string | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Audit Log Model
|
|
16
|
+
*/
|
|
17
|
+
export interface AuditLog extends BaseEntity {
|
|
18
|
+
entityName: string;
|
|
19
|
+
entityId: string;
|
|
20
|
+
action: "CREATE" | "UPDATE" | "DELETE" | "RESTORE";
|
|
21
|
+
userId: UserID;
|
|
22
|
+
previousState?: Record<string, unknown> | null;
|
|
23
|
+
newState?: Record<string, unknown> | null;
|
|
24
|
+
traceId: TraceID;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* User Model
|
|
29
|
+
*/
|
|
30
|
+
export interface User extends BaseEntity {
|
|
31
|
+
id: UserID;
|
|
32
|
+
email: string;
|
|
33
|
+
fullName: string;
|
|
34
|
+
role: "ADMIN" | "DEVELOPER" | "VIEWER";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface UserProfile extends User {
|
|
38
|
+
avatarUrl?: string;
|
|
39
|
+
bio?: string;
|
|
40
|
+
preferences: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Project Status
|
|
45
|
+
*/
|
|
46
|
+
export interface ProjectStatus {
|
|
47
|
+
phase: ProjectPhase;
|
|
48
|
+
profile: ExecutionProfile;
|
|
49
|
+
lastUpdate: string;
|
|
50
|
+
activeTraceId: TraceID | null;
|
|
51
|
+
blockers: string[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Task Model
|
|
56
|
+
*/
|
|
57
|
+
export interface Task {
|
|
58
|
+
id: TraceID;
|
|
59
|
+
description: string;
|
|
60
|
+
agent: AgentID;
|
|
61
|
+
priority: TaskPriority;
|
|
62
|
+
status: TaskStatus;
|
|
63
|
+
createdAt: string;
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { css, cx } from "../../../styled-system/css";
|
|
2
|
+
import { type HTMLPandaProps } from "../../../styled-system/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GOLDEN STANDARD: Button Component
|
|
6
|
+
* Uses Semantic Tokens for automatic theme support.
|
|
7
|
+
*/
|
|
8
|
+
export interface ButtonProps extends HTMLPandaProps<"button"> {
|
|
9
|
+
variant?: "primary" | "secondary" | "outline" | "ghost";
|
|
10
|
+
size?: "sm" | "md" | "lg";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Button = (props: ButtonProps) => {
|
|
14
|
+
const { variant = "primary", size = "md", className, ...rest } = props;
|
|
15
|
+
|
|
16
|
+
const buttonStyles = css({
|
|
17
|
+
display: "inline-flex",
|
|
18
|
+
alignItems: "center",
|
|
19
|
+
justifyContent: "center",
|
|
20
|
+
fontWeight: "600",
|
|
21
|
+
borderRadius: "md",
|
|
22
|
+
cursor: "pointer",
|
|
23
|
+
transition: "all 0.2s ease",
|
|
24
|
+
_disabled: { opacity: 0.5, cursor: "not-allowed" },
|
|
25
|
+
_active: { transform: "scale(0.98)" },
|
|
26
|
+
|
|
27
|
+
// Size variants
|
|
28
|
+
...(size === "sm" && { px: "3", py: "1.5", fontSize: "xs" }),
|
|
29
|
+
...(size === "md" && { px: "4", py: "2", fontSize: "sm" }),
|
|
30
|
+
...(size === "lg" && { px: "6", py: "3", fontSize: "md" }),
|
|
31
|
+
|
|
32
|
+
// Theme-aware Semantic Tokens
|
|
33
|
+
...(variant === "primary" && {
|
|
34
|
+
bg: "accent.default",
|
|
35
|
+
color: "accent.fg",
|
|
36
|
+
_hover: { bg: "accent.emphasis" },
|
|
37
|
+
}),
|
|
38
|
+
...(variant === "secondary" && {
|
|
39
|
+
bg: "bg.muted",
|
|
40
|
+
color: "text.default",
|
|
41
|
+
_hover: { bg: "border.default" },
|
|
42
|
+
}),
|
|
43
|
+
...(variant === "outline" && {
|
|
44
|
+
bg: "transparent",
|
|
45
|
+
border: "1px solid",
|
|
46
|
+
borderColor: "border.default",
|
|
47
|
+
color: "text.default",
|
|
48
|
+
_hover: { bg: "bg.muted" },
|
|
49
|
+
}),
|
|
50
|
+
...(variant === "ghost" && {
|
|
51
|
+
bg: "transparent",
|
|
52
|
+
color: "text.default",
|
|
53
|
+
_hover: { bg: "bg.muted" },
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<button className={cx(buttonStyles, className)} {...rest} />
|
|
59
|
+
);
|
|
60
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { css, cx } from "../../../styled-system/css";
|
|
2
|
+
import { type HTMLPandaProps } from "../../../styled-system/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GOLDEN STANDARD: Input Component
|
|
6
|
+
* Fully theme-aware using semantic border and background tokens.
|
|
7
|
+
*/
|
|
8
|
+
export interface InputProps extends HTMLPandaProps<"input"> {
|
|
9
|
+
label?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Input = (props: InputProps) => {
|
|
13
|
+
const { className, ...rest } = props;
|
|
14
|
+
|
|
15
|
+
const inputStyles = css({
|
|
16
|
+
width: "100%",
|
|
17
|
+
px: "4",
|
|
18
|
+
py: "2",
|
|
19
|
+
borderRadius: "md",
|
|
20
|
+
border: "1px solid",
|
|
21
|
+
borderColor: "border.default",
|
|
22
|
+
bg: "bg.canvas",
|
|
23
|
+
color: "text.default",
|
|
24
|
+
fontSize: "sm",
|
|
25
|
+
outline: "none",
|
|
26
|
+
transition: "all 0.2s ease",
|
|
27
|
+
_placeholder: { color: "text.muted" },
|
|
28
|
+
_focus: {
|
|
29
|
+
borderColor: "accent.default",
|
|
30
|
+
ring: "2px",
|
|
31
|
+
ringColor: "accent.default/20",
|
|
32
|
+
},
|
|
33
|
+
_disabled: {
|
|
34
|
+
opacity: 0.5,
|
|
35
|
+
cursor: "not-allowed",
|
|
36
|
+
bg: "bg.muted",
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<input className={cx(inputStyles, className)} {...rest} />
|
|
42
|
+
);
|
|
43
|
+
};
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# API Registry
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
- `
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
|
|
10
|
-
## ⚖️ Rules of Engagement
|
|
11
|
-
1. **Contract-First**: Every document here MUST match the types in `packages/shared-types`.
|
|
12
|
-
2. **Versioning**: Major changes require a version bump in `contract.version.json`.
|
|
13
|
-
3. **Immutability**: Once a version is deployed, endpoints should not be modified without a migration path.
|
|
3
|
+
- `POST /api/v1/auth/login`
|
|
4
|
+
- `GET /api/v1/dashboard`
|
|
5
|
+
- `GET /api/v1/users`
|
|
6
|
+
- `GET /api/v1/roles`
|
|
7
|
+
- `GET /api/v1/customers`
|
|
8
|
+
- `GET /api/v1/reports`
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CRM Dashboard Requirements
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
| :--- | :--- | :--- |
|
|
5
|
-
| Feature A | [Description] | PENDING |
|
|
6
|
-
| Feature B | [Description] | PENDING |
|
|
3
|
+
## Request
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
A CRM dashboard
|
|
6
|
+
|
|
7
|
+
## Generated Scope
|
|
8
|
+
|
|
9
|
+
- Domain: CRM
|
|
10
|
+
- Auth: yes
|
|
11
|
+
- Users: yes
|
|
12
|
+
- Roles: yes
|
|
13
|
+
- Reports: yes
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
- `apps/backend`: Fastify API
|
|
18
|
+
- `apps/web`: React dashboard
|
|
19
|
+
- `apps/backend/src/types`: Contract-first backend TypeScript types
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Blueprint-Driven Construction & Evolution
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Blueprint-Driven Construction is the primary method for building and expanding the Agent Enderun ecosystem. It ensures that every new application or feature is built upon a "Gold Standard" foundation.
|
|
5
|
+
|
|
6
|
+
## Core Mechanics
|
|
7
|
+
|
|
8
|
+
### 1. Discovering Capabilities
|
|
9
|
+
Agents must use the `list_blueprints` tool to find existing architectural patterns, UI components, and logic hooks before writing any code.
|
|
10
|
+
|
|
11
|
+
### 2. Instantiating Standards
|
|
12
|
+
Once a blueprint is identified, the `instantiate_blueprint` tool is used to clone the template into the target application directory.
|
|
13
|
+
- **Example:** Cloning `backend/errors` into `apps/backend/src/errors`.
|
|
14
|
+
|
|
15
|
+
### 3. Dynamic Evolution (Capability Growth)
|
|
16
|
+
When an agent develops a high-quality, reusable solution (e.g., a complex data table or a specific auth service), they MUST save it as a new blueprint using the `save_as_blueprint` tool.
|
|
17
|
+
- **Goal:** The `blueprints/` directory is not static; it grows as the project tackles more complex challenges.
|
|
18
|
+
|
|
19
|
+
## Guidelines for Agents
|
|
20
|
+
- **Consistency first:** Always check for a blueprint before building from scratch.
|
|
21
|
+
- **Refinement:** If an existing blueprint is outdated, update it via `save_as_blueprint` after a successful implementation.
|
|
22
|
+
- **Documentation:** Always provide a description when saving a new blueprint to help other agents understand its purpose.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Code Review Checklist
|
|
2
2
|
|
|
3
3
|
- [ ] Does it follow ENDERUN.md?
|
|
4
|
-
- [ ] Are types imported from
|
|
4
|
+
- [ ] Are types imported from the app's local types directory?
|
|
5
5
|
- [ ] Is there any Raw SQL usage?
|
|
6
6
|
- [ ] Are unit tests included?
|
|
7
7
|
- [ ] Is the code mobile-first (if UI)?
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# Contract Versioning (v0.
|
|
1
|
+
# Contract Versioning (v0.6.0)
|
|
2
2
|
|
|
3
3
|
## Workflow
|
|
4
|
-
1. **Change**: Modify `
|
|
5
|
-
2. **Hash**: Generate new SHA-256 hash.
|
|
6
|
-
3. **Sync**: Update `contract.version.json`.
|
|
7
|
-
4. **Audit**: @analyst verifies the sync status.
|
|
4
|
+
1. **Change**: Modify types in `apps/backend/src/types`.
|
|
5
|
+
2. **Hash**: Generate new SHA-256 hash using the `update_contract_hash` tool.
|
|
6
|
+
3. **Sync**: Update `apps/backend/contract.version.json`.
|
|
7
|
+
4. **Audit**: @analyst verifies the sync status via the `verify_api_contract` tool.
|
package/ENDERUN.md
CHANGED
|
@@ -1,16 +1,39 @@
|
|
|
1
|
-
# Agent Enderun (v0.
|
|
1
|
+
# Agent Enderun (v0.6.0)
|
|
2
2
|
# Place in project root. This file is the single source of truth for Base Project AI Extensions.
|
|
3
3
|
|
|
4
4
|
## 🎖️ AGENT CHECKLIST (MANDATORY BEFORE RESPONSE)
|
|
5
5
|
> Check this list at the end of every response:
|
|
6
6
|
> - [ ] **Zero Mock:** Did you use fake data or placeholders? (Strictly Forbidden)
|
|
7
|
-
> - [ ] **Contract First:** Are
|
|
7
|
+
> - [ ] **Contract First:** Are the app's types and apps/backend/contract.version.json up to date?
|
|
8
8
|
> - [ ] **Audit Log:** Did you log this action in `{{FRAMEWORK_DIR}}/logs/[agent].json`?
|
|
9
9
|
> - [ ] **CLI Orchestration:** Does the action comply with `{{ADAPTER}} cli` rules?
|
|
10
10
|
> - [ ] **No "..." allowed:** Did you write the code completely without omitting parts?
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## 🧠 INTELLIGENCE & DISCOVERY PROTOCOLS
|
|
15
|
+
|
|
16
|
+
### 🔍 Architecture Discovery Protocol (ADP)
|
|
17
|
+
When encountering a project, agents must never assume a specific folder structure. Use the following algorithm:
|
|
18
|
+
1. **Entry Point Hunt:** Identify main entry points (`index.ts`, `main.ts`, `server.ts`) via `search_codebase`.
|
|
19
|
+
2. **Business Logic Mapping:** Search for core domain keywords (e.g. `service`, `repository`, `controller`) to find where logic resides, regardless of directory names.
|
|
20
|
+
3. **Contract Analysis:** Locate type definitions and API schemas to establish the "System Contract".
|
|
21
|
+
4. **Adaptive Scaffolding:** Always propose architectural improvements or scaffolding *before* writing code. Wait for explicit User consent.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🪙 TOKEN ECONOMY & CONTEXT MANAGEMENT
|
|
26
|
+
|
|
27
|
+
To minimize AI costs and maximize speed, all agents must adhere to the **Token Economy Protocol**:
|
|
28
|
+
|
|
29
|
+
1. **Search Before Reading (MANDATORY):** Never `read_file` an entire directory or large file without searching for specific points of interest first.
|
|
30
|
+
2. **Surgical Operations:** When editing, use the `replace` tool for targeted changes instead of overwriting entire files unless the file is very small (<50 lines).
|
|
31
|
+
3. **Output Conciseness:** MCP tools must return the minimum required data. Avoid verbose logs or redundant status messages in tool outputs.
|
|
32
|
+
4. **Context Compaction:** Before starting a new task, use `get_memory_insights` to retrieve only the relevant historical context.
|
|
33
|
+
5. **No Blind Coding:** Stop and ask if a task requires reading more than 5 large files without a clear search result.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
14
37
|
## Constitution Status
|
|
15
38
|
This file (`./{{ADAPTER}}.md`) and the `{{FRAMEWORK_DIR}}/docs/` folder represent the "Supreme Law" of the project. All agents must read this file first in every session and strictly comply with its rules 100%. All framework-specific documentation is stored within `{{FRAMEWORK_DIR}}/docs/`.
|
|
16
39
|
|
|
@@ -44,7 +67,7 @@ This file (`./{{ADAPTER}}.md`) and the `{{FRAMEWORK_DIR}}/docs/` folder represen
|
|
|
44
67
|
- **Zero Temporary Storage & Single Source of Truth:** Storing, caching, or writing project details, logs, tasks, files, or agent planning documents (including implementation plans, scratch scripts, or intermediate tasks) in the operating system's temporary directory (`/tmp`, `/var/tmp`, `temp`, etc.) is strictly forbidden. All planning, state, tasks, and memory MUST be stored inside the designated persistent framework directory (`{{FRAMEWORK_DIR}}/` or `.{{ADAPTER}}/` etc.) or the project workspace. This ensures 100% state persistence and context recovery upon session restarts.
|
|
45
68
|
- **Contract-First Agent Evolution:** Tools and SOPs used by agents must be defined via schemas and contracts first.
|
|
46
69
|
- **Zero Mock Policy:** The use of fake (mock) data or placeholders is strictly forbidden. Every line of code must connect to a real endpoint or a typed contract. (Exception: Controlled mock usage is allowed for external 3rd party services like Stripe, Twilio).
|
|
47
|
-
- **Branded Types Law:** All IDs (UserID, ProjectID, etc.) must be in the "Branded Types" format defined
|
|
70
|
+
- **Branded Types Law:** All IDs (UserID, ProjectID, etc.) must be in the "Branded Types" format defined in the app-local types (e.g., `apps/backend/src/types`). Using plain strings or numbers is forbidden.
|
|
48
71
|
- **CLI-First Policy:** Due to the AI CLI Assistant focus, all outputs must be user-friendly (using Chalk, Clack, etc.) and stream-based. All commands must support the `--output json` flag and produce machine-readable output.
|
|
49
72
|
- **Audit Logging Necessity:** Every critical action must be logged traceably under the `{{FRAMEWORK_DIR}}/logs/` folder.
|
|
50
73
|
- **Design Continuity & Response Policy:** All UI changes MUST be responsive (Mobile-First + Fluid) and surgical. Unnecessary overhauls of existing layouts are strictly forbidden.
|
|
@@ -159,7 +182,7 @@ This file is the single source of truth for API stability. `@backend-architect`
|
|
|
159
182
|
The development process follows a strict State Machine. Transition to the next phase is prohibited until the "Success Criteria" of the current phase is met.
|
|
160
183
|
|
|
161
184
|
- **[STATE: PHASE_0] Discovery & Setup:** Profile selection (Lightweight/Full), requirement analysis, and validating `{{FRAMEWORK_DIR}}/docs/tech-stack.md`.
|
|
162
|
-
- **[STATE: PHASE_1] Architecture & Contracts:** Setup of data models, API schemas, and
|
|
185
|
+
- **[STATE: PHASE_1] Architecture & Contracts:** Setup of data models, API schemas, and backend-defined types (e.g., apps/backend/src/types). Cannot proceed until Frontend and Backend approve these schemas.
|
|
163
186
|
- **[STATE: PHASE_2] Core Development:** Active agents build core features in parallel based on the selected profile. (Under the apps/ folder)
|
|
164
187
|
- **[STATE: PHASE_3] Integration & Testing:** System integration.
|
|
165
188
|
- **[STATE: PHASE_4] Optimization & Deployment:** Performance audit and deployment.
|
|
@@ -194,13 +217,13 @@ CLI behaviors (logLevel, outputFormat, defaultProfile) are managed through this
|
|
|
194
217
|
|
|
195
218
|
## API VERSIONING STRATEGY
|
|
196
219
|
|
|
197
|
-
All APIs are versioned via the URL path (`/api/v1/...`). The `
|
|
220
|
+
All APIs are versioned via the URL path (`/api/v1/...`). The `apps/backend/contract.version.json` file uses the MAJOR.MINOR format, and must be updated with every change. The `@backend-architect` is responsible for its accuracy. The MAJOR version is incremented for every breaking change. Old versions continue to be supported for at least 1 MAJOR release.
|
|
198
221
|
|
|
199
222
|
---
|
|
200
223
|
|
|
201
224
|
## PARALLEL EXECUTION & COORDINATION RULES
|
|
202
225
|
|
|
203
|
-
1. **
|
|
226
|
+
1. **Backend Types as Source of Truth:** All agents reference the app-local types (e.g., `apps/backend/src/types`) and the `apps/backend/contract.version.json` file.
|
|
204
227
|
2. **Commit-Level Logging:** Every agent must log every atomic change to the `{{FRAMEWORK_DIR}}/logs/[agent-name].json` file.
|
|
205
228
|
3. **Implicit Dependency Lock:** If an agent's required output is not ready, it switches to `WAITING` state.
|
|
206
229
|
4. **Ownership Enforcement:** Changes to files outside an agent's scope cannot be made without `@team-lead` approval.
|