agent-enderun 1.1.10 → 1.10.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/README.md +294 -19
- package/bin/cli.js +7 -0
- package/bin/enderun-dashboard.js +16 -857
- package/bin/validate-agent-army.js +12 -12
- package/dist/framework-mcp/src/index.js +14 -2
- package/dist/framework-mcp/src/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +2 -1
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/replace_text.js +2 -1
- package/dist/framework-mcp/src/tools/file_system/replace_text.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/write_file.js +3 -3
- package/dist/framework-mcp/src/tools/file_system/write_file.js.map +1 -1
- package/dist/framework-mcp/src/utils/fs.d.ts +16 -0
- package/dist/framework-mcp/src/utils/fs.js +45 -0
- package/dist/framework-mcp/src/utils/fs.js.map +1 -0
- package/dist/framework-mcp/src/utils/metrics.js.map +1 -1
- package/dist/src/cli/adapters/core.js.map +1 -1
- package/dist/src/cli/adapters/scaffold.js +4 -3
- package/dist/src/cli/adapters/scaffold.js.map +1 -1
- package/dist/src/cli/commands/app.js +20 -5
- package/dist/src/cli/commands/app.js.map +1 -1
- package/dist/src/cli/commands/approve.d.ts +1 -1
- package/dist/src/cli/commands/approve.js +7 -7
- package/dist/src/cli/commands/approve.js.map +1 -1
- package/dist/src/cli/commands/check.d.ts +1 -1
- package/dist/src/cli/commands/check.js +35 -4
- package/dist/src/cli/commands/check.js.map +1 -1
- package/dist/src/cli/commands/compliance.d.ts +1 -1
- package/dist/src/cli/commands/compliance.js +1 -1
- package/dist/src/cli/commands/compliance.js.map +1 -1
- package/dist/src/cli/commands/contract.d.ts +2 -2
- package/dist/src/cli/commands/contract.js +8 -14
- package/dist/src/cli/commands/contract.js.map +1 -1
- package/dist/src/cli/commands/dashboard/data-service.d.ts +33 -0
- package/dist/src/cli/commands/dashboard/data-service.js +120 -0
- package/dist/src/cli/commands/dashboard/data-service.js.map +1 -0
- package/dist/src/cli/commands/dashboard/html-template.d.ts +4 -0
- package/dist/src/cli/commands/dashboard/html-template.js +697 -0
- package/dist/src/cli/commands/dashboard/html-template.js.map +1 -0
- package/dist/src/cli/commands/dashboard/server.d.ts +2 -0
- package/dist/src/cli/commands/dashboard/server.js +38 -0
- package/dist/src/cli/commands/dashboard/server.js.map +1 -0
- package/dist/src/cli/commands/dashboard.d.ts +4 -0
- package/dist/src/cli/commands/dashboard.js +10 -0
- package/dist/src/cli/commands/dashboard.js.map +1 -0
- package/dist/src/cli/commands/explorer.d.ts +2 -2
- package/dist/src/cli/commands/explorer.js +2 -2
- package/dist/src/cli/commands/explorer.js.map +1 -1
- package/dist/src/cli/commands/git.d.ts +2 -2
- package/dist/src/cli/commands/git.js +2 -2
- package/dist/src/cli/commands/git.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-core.d.ts +4 -0
- package/dist/src/cli/commands/init/scaffold-core.js +65 -0
- package/dist/src/cli/commands/init/scaffold-core.js.map +1 -0
- package/dist/src/cli/commands/init/scaffold-ops.d.ts +1 -0
- package/dist/src/cli/commands/init/scaffold-ops.js +83 -0
- package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -0
- package/dist/src/cli/commands/init/scaffold-standards.d.ts +2 -0
- package/dist/src/cli/commands/init/scaffold-standards.js +58 -0
- package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -0
- package/dist/src/cli/commands/init.js +14 -275
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/knowledge.d.ts +2 -2
- package/dist/src/cli/commands/knowledge.js +4 -3
- package/dist/src/cli/commands/knowledge.js.map +1 -1
- package/dist/src/cli/commands/lint.d.ts +1 -1
- package/dist/src/cli/commands/lint.js +2 -3
- package/dist/src/cli/commands/lint.js.map +1 -1
- package/dist/src/cli/commands/log.d.ts +1 -1
- package/dist/src/cli/commands/log.js +3 -2
- package/dist/src/cli/commands/log.js.map +1 -1
- package/dist/src/cli/commands/memory.d.ts +1 -1
- package/dist/src/cli/commands/memory.js +1 -1
- package/dist/src/cli/commands/memory.js.map +1 -1
- package/dist/src/cli/commands/orchestrate.js +169 -140
- package/dist/src/cli/commands/orchestrate.js.map +1 -1
- package/dist/src/cli/commands/plan.d.ts +1 -1
- package/dist/src/cli/commands/plan.js +1 -1
- package/dist/src/cli/commands/plan.js.map +1 -1
- package/dist/src/cli/commands/script.d.ts +1 -1
- package/dist/src/cli/commands/script.js +1 -1
- package/dist/src/cli/commands/script.js.map +1 -1
- package/dist/src/cli/commands/security.d.ts +1 -1
- package/dist/src/cli/commands/security.js +1 -1
- package/dist/src/cli/commands/security.js.map +1 -1
- package/dist/src/cli/commands/status.d.ts +1 -1
- package/dist/src/cli/commands/status.js +1 -1
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/commands/trace.d.ts +1 -1
- package/dist/src/cli/commands/trace.js +1 -1
- package/dist/src/cli/commands/trace.js.map +1 -1
- package/dist/src/cli/index.js +36 -21
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/shims.js +6 -6
- package/dist/src/cli/utils/app-backend.js +7 -0
- package/dist/src/cli/utils/app-backend.js.map +1 -1
- package/dist/src/cli/utils/app-docs.js +23 -5
- package/dist/src/cli/utils/app-docs.js.map +1 -1
- package/dist/src/cli/utils/app-frontend.js +5 -0
- package/dist/src/cli/utils/app-frontend.js.map +1 -1
- package/dist/src/cli/utils/app-inferrer.d.ts +1 -0
- package/dist/src/cli/utils/app-inferrer.js +12 -1
- package/dist/src/cli/utils/app-inferrer.js.map +1 -1
- package/dist/src/cli/utils/app-mobile.d.ts +2 -0
- package/dist/src/cli/utils/app-mobile.js +106 -0
- package/dist/src/cli/utils/app-mobile.js.map +1 -0
- package/dist/src/cli/utils/app-types.js +8 -4
- package/dist/src/cli/utils/app-types.js.map +1 -1
- package/dist/src/cli/utils/app.d.ts +1 -0
- package/dist/src/cli/utils/app.js +1 -0
- package/dist/src/cli/utils/app.js.map +1 -1
- package/dist/src/cli/utils/claude.js +2 -1
- package/dist/src/cli/utils/claude.js.map +1 -1
- package/dist/src/cli/utils/compliance.js +37 -6
- package/dist/src/cli/utils/compliance.js.map +1 -1
- package/dist/src/cli/utils/config-schema.d.ts +3 -3
- package/dist/src/cli/utils/config-schema.js +3 -3
- package/dist/src/cli/utils/config-schema.js.map +1 -1
- package/dist/src/cli/utils/fs.d.ts +2 -2
- package/dist/src/cli/utils/fs.js +9 -13
- package/dist/src/cli/utils/fs.js.map +1 -1
- package/dist/src/cli/utils/memory.d.ts +9 -2
- package/dist/src/cli/utils/memory.js +87 -16
- package/dist/src/cli/utils/memory.js.map +1 -1
- package/dist/src/cli/utils/pkg.js +14 -13
- package/dist/src/cli/utils/pkg.js.map +1 -1
- package/dist/src/cli/utils/string.js +1 -1
- package/dist/src/cli/utils/string.js.map +1 -1
- package/dist/src/cli/utils/ui.d.ts +1 -1
- package/dist/src/cli/utils/ui.js +1 -1
- package/dist/src/modules/adapters/shared.js +7 -7
- package/dist/src/modules/adapters/shared.js.map +1 -1
- package/dist/src/modules/agents/definitions.d.ts +3 -34
- package/dist/src/modules/agents/definitions.js +35 -511
- package/dist/src/modules/agents/definitions.js.map +1 -1
- package/dist/src/modules/agents/registry/analyst.d.ts +2 -0
- package/dist/src/modules/agents/registry/analyst.js +36 -0
- package/dist/src/modules/agents/registry/analyst.js.map +1 -0
- package/dist/src/modules/agents/registry/architect.d.ts +2 -0
- package/dist/src/modules/agents/registry/architect.js +42 -0
- package/dist/src/modules/agents/registry/architect.js.map +1 -0
- package/dist/src/modules/agents/registry/backend.d.ts +2 -0
- package/dist/src/modules/agents/registry/backend.js +43 -0
- package/dist/src/modules/agents/registry/backend.js.map +1 -0
- package/dist/src/modules/agents/registry/database.d.ts +2 -0
- package/dist/src/modules/agents/registry/database.js +38 -0
- package/dist/src/modules/agents/registry/database.js.map +1 -0
- package/dist/src/modules/agents/registry/devops.d.ts +2 -0
- package/dist/src/modules/agents/registry/devops.js +38 -0
- package/dist/src/modules/agents/registry/devops.js.map +1 -0
- package/dist/src/modules/agents/registry/explorer.d.ts +2 -0
- package/dist/src/modules/agents/registry/explorer.js +36 -0
- package/dist/src/modules/agents/registry/explorer.js.map +1 -0
- package/dist/src/modules/agents/registry/frontend.d.ts +2 -0
- package/dist/src/modules/agents/registry/frontend.js +44 -0
- package/dist/src/modules/agents/registry/frontend.js.map +1 -0
- package/dist/src/modules/agents/registry/git.d.ts +2 -0
- package/dist/src/modules/agents/registry/git.js +35 -0
- package/dist/src/modules/agents/registry/git.js.map +1 -0
- package/dist/src/modules/agents/registry/manager.d.ts +2 -0
- package/dist/src/modules/agents/registry/manager.js +49 -0
- package/dist/src/modules/agents/registry/manager.js.map +1 -0
- package/dist/src/modules/agents/registry/mobile.d.ts +2 -0
- package/dist/src/modules/agents/registry/mobile.js +40 -0
- package/dist/src/modules/agents/registry/mobile.js.map +1 -0
- package/dist/src/modules/agents/registry/native.d.ts +2 -0
- package/dist/src/modules/agents/registry/native.js +36 -0
- package/dist/src/modules/agents/registry/native.js.map +1 -0
- package/dist/src/modules/agents/registry/quality.d.ts +2 -0
- package/dist/src/modules/agents/registry/quality.js +41 -0
- package/dist/src/modules/agents/registry/quality.js.map +1 -0
- package/dist/src/modules/agents/registry/security.d.ts +2 -0
- package/dist/src/modules/agents/registry/security.js +37 -0
- package/dist/src/modules/agents/registry/security.js.map +1 -0
- package/dist/src/modules/agents/types.d.ts +31 -0
- package/dist/src/modules/agents/types.js +2 -0
- package/dist/src/modules/agents/types.js.map +1 -0
- package/dist/src/modules/skills/definitions.d.ts +1 -1
- package/dist/src/modules/skills/definitions.js +1 -1
- package/dist/src/shared/errors.d.ts +8 -6
- package/dist/src/shared/errors.js +13 -10
- package/dist/src/shared/errors.js.map +1 -1
- package/dist/src/shared/fs.d.ts +4 -0
- package/dist/src/shared/fs.js +17 -2
- package/dist/src/shared/fs.js.map +1 -1
- package/dist/src/shared/types.d.ts +19 -0
- package/dist/src/shared/types.js +13 -0
- package/dist/src/shared/types.js.map +1 -0
- package/package.json +3 -5
- package/src/cli/adapters/core.ts +0 -1
- package/src/cli/adapters/scaffold.ts +4 -3
- package/src/cli/commands/app.ts +23 -5
- package/src/cli/commands/approve.ts +15 -7
- package/src/cli/commands/check.ts +38 -5
- package/src/cli/commands/compliance.ts +1 -1
- package/src/cli/commands/contract.ts +20 -14
- package/src/cli/commands/dashboard/data-service.ts +119 -0
- package/src/cli/commands/dashboard/html-template.ts +696 -0
- package/src/cli/commands/dashboard/server.ts +43 -0
- package/src/cli/commands/dashboard.ts +11 -0
- package/src/cli/commands/explorer.ts +2 -2
- package/src/cli/commands/git.ts +2 -2
- package/src/cli/commands/init/scaffold-core.ts +71 -0
- package/src/cli/commands/init/scaffold-ops.ts +86 -0
- package/src/cli/commands/init/scaffold-standards.ts +59 -0
- package/src/cli/commands/init.ts +21 -292
- package/src/cli/commands/knowledge.ts +5 -3
- package/src/cli/commands/lint.ts +2 -4
- package/src/cli/commands/log.ts +4 -2
- package/src/cli/commands/memory.ts +1 -1
- package/src/cli/commands/orchestrate.ts +177 -142
- package/src/cli/commands/plan.ts +1 -1
- package/src/cli/commands/script.ts +1 -1
- package/src/cli/commands/security.ts +1 -1
- package/src/cli/commands/status.ts +1 -1
- package/src/cli/commands/trace.ts +1 -1
- package/src/cli/index.ts +37 -21
- package/src/cli/shims.ts +6 -6
- package/src/cli/utils/app-backend.ts +8 -0
- package/src/cli/utils/app-docs.ts +23 -5
- package/src/cli/utils/app-frontend.ts +6 -0
- package/src/cli/utils/app-inferrer.ts +11 -1
- package/src/cli/utils/app-mobile.ts +113 -0
- package/src/cli/utils/app-types.ts +9 -4
- package/src/cli/utils/app.ts +1 -0
- package/src/cli/utils/claude.ts +2 -1
- package/src/cli/utils/compliance.ts +38 -7
- package/src/cli/utils/config-schema.ts +4 -4
- package/src/cli/utils/fs.ts +9 -14
- package/src/cli/utils/memory.ts +103 -20
- package/src/cli/utils/pkg.ts +14 -13
- package/src/cli/utils/string.ts +1 -1
- package/src/cli/utils/ui.ts +1 -1
- package/src/modules/adapters/shared.ts +7 -7
- package/src/modules/agents/definitions.ts +39 -598
- package/src/modules/agents/registry/analyst.ts +40 -0
- package/src/modules/agents/registry/architect.ts +46 -0
- package/src/modules/agents/registry/backend.ts +47 -0
- package/src/modules/agents/registry/database.ts +42 -0
- package/src/modules/agents/registry/devops.ts +42 -0
- package/src/modules/agents/registry/explorer.ts +40 -0
- package/src/modules/agents/registry/frontend.ts +48 -0
- package/src/modules/agents/registry/git.ts +39 -0
- package/src/modules/agents/registry/manager.ts +53 -0
- package/src/modules/agents/registry/mobile.ts +44 -0
- package/src/modules/agents/registry/native.ts +40 -0
- package/src/modules/agents/registry/quality.ts +45 -0
- package/src/modules/agents/registry/security.ts +41 -0
- package/src/modules/agents/types.ts +37 -0
- package/src/modules/skills/definitions.ts +1 -1
- package/src/shared/errors.ts +13 -10
- package/src/shared/fs.ts +17 -2
- package/src/shared/types.ts +20 -0
- package/bin/utils/docgen.ts +0 -24
package/src/cli/shims.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const SHIM_TEMPLATES: Record<string, string> = {
|
|
2
|
-
gemini: `# 🎖️ Enderun
|
|
2
|
+
gemini: `# 🎖️ Agent Enderun — GEMINI Strategy
|
|
3
3
|
|
|
4
4
|
You are the **Gemini Commander** (Strategic Decision Center).
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ You are the **Gemini Commander** (Strategic Decision Center).
|
|
|
8
8
|
- **State Persistence:** Read \`{{FRAMEWORK_DIR}}/memory/PROJECT_MEMORY.md\` to restore session memory.
|
|
9
9
|
- **Zero-Request Logging:** Write logs to \`{{FRAMEWORK_DIR}}/logs/\` at the end of every turn.
|
|
10
10
|
`,
|
|
11
|
-
"antigravity-cli": `# 🎖️ Enderun
|
|
11
|
+
"antigravity-cli": `# 🎖️ Agent Enderun — ANTIGRAVITY-CLI Strategy
|
|
12
12
|
|
|
13
13
|
You are the **Antigravity Specialist** (Preserve Coding Standards).
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ You are the **Antigravity Specialist** (Preserve Coding Standards).
|
|
|
17
17
|
- **State Persistence:** Read \`{{FRAMEWORK_DIR}}/memory/PROJECT_MEMORY.md\` to restore session memory.
|
|
18
18
|
- **Standard Check:** Run health checks regularly to preserve framework integrity.
|
|
19
19
|
`,
|
|
20
|
-
claude: `# 🎖️ Enderun
|
|
20
|
+
claude: `# 🎖️ Agent Enderun — CLAUDE Strategy
|
|
21
21
|
|
|
22
22
|
You are the **Claude Field Engineer** (Surgical Operations).
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ You are the **Claude Field Engineer** (Surgical Operations).
|
|
|
26
26
|
- **State Persistence:** Read \`{{FRAMEWORK_DIR}}/memory/PROJECT_MEMORY.md\` to restore session memory.
|
|
27
27
|
- **Surgical Precision:** Do not rewrite files. Execute surgical edits.
|
|
28
28
|
`,
|
|
29
|
-
grok: `# 🎖️ Enderun
|
|
29
|
+
grok: `# 🎖️ Agent Enderun — GROK Strategy
|
|
30
30
|
|
|
31
31
|
You are the **Grok Explorer** (Experimental Protocols).
|
|
32
32
|
|
|
@@ -34,7 +34,7 @@ You are the **Grok Explorer** (Experimental Protocols).
|
|
|
34
34
|
- **Constitutional Supremacy:** Read \`{{FRAMEWORK_DIR}}/ENDERUN.md\` first.
|
|
35
35
|
- **State Persistence:** Read \`{{FRAMEWORK_DIR}}/memory/PROJECT_MEMORY.md\` to restore session memory.
|
|
36
36
|
`,
|
|
37
|
-
cursor: `# 🎖️ Enderun
|
|
37
|
+
cursor: `# 🎖️ Agent Enderun — CURSOR Strategy
|
|
38
38
|
|
|
39
39
|
You are the **Cursor Implementer** (IDE Integration).
|
|
40
40
|
|
|
@@ -42,7 +42,7 @@ You are the **Cursor Implementer** (IDE Integration).
|
|
|
42
42
|
- **Constitutional Supremacy:** Read \`{{FRAMEWORK_DIR}}/ENDERUN.md\` first.
|
|
43
43
|
- **State Persistence:** Read \`{{FRAMEWORK_DIR}}/memory/PROJECT_MEMORY.md\` to restore session memory.
|
|
44
44
|
`,
|
|
45
|
-
codex: `# 🎖️ Enderun
|
|
45
|
+
codex: `# 🎖️ Agent Enderun — COPILOT Strategy
|
|
46
46
|
|
|
47
47
|
You are the **Copilot Implementer** (GitHub Copilot Integration).
|
|
48
48
|
|
|
@@ -235,6 +235,14 @@ export function createBackendFiles(spec: AppSpec): void {
|
|
|
235
235
|
"await app.listen({ port, host: \"0.0.0.0\" });",
|
|
236
236
|
].join("\n"));
|
|
237
237
|
|
|
238
|
+
writeTextFile(path.join(targetDir, backendDir, ".env.example"), [
|
|
239
|
+
"# Agent Enderun - Backend Environment Variables",
|
|
240
|
+
"PORT=4000",
|
|
241
|
+
"NODE_ENV=development",
|
|
242
|
+
"DATABASE_URL=sqlite://./dev.db",
|
|
243
|
+
"JWT_SECRET=your_secret_key_here",
|
|
244
|
+
].join("\n"));
|
|
245
|
+
|
|
238
246
|
writeTextFile(path.join(targetDir, backendDir, "README.md"), [
|
|
239
247
|
`# ${spec.title} Backend`,
|
|
240
248
|
"",
|
|
@@ -12,6 +12,18 @@ export function updateProjectDocs(spec: AppSpec): void {
|
|
|
12
12
|
const apiDir = path.join(docsDir, "api");
|
|
13
13
|
ensureDir(apiDir);
|
|
14
14
|
|
|
15
|
+
const architecture = [];
|
|
16
|
+
if (spec.platform === "full-stack" || spec.platform === "backend") {
|
|
17
|
+
architecture.push(`- \`${pathsMap.backend}\`: Fastify API`);
|
|
18
|
+
architecture.push(`- \`${pathsMap.backend}/src/types\`: Contract-first backend TypeScript types`);
|
|
19
|
+
}
|
|
20
|
+
if (spec.platform === "full-stack" || spec.platform === "web") {
|
|
21
|
+
architecture.push(`- \`${pathsMap.frontend}\`: React dashboard`);
|
|
22
|
+
}
|
|
23
|
+
if (spec.platform === "mobile") {
|
|
24
|
+
architecture.push(`- \`${pathsMap.mobile || "apps/mobile"}\`: Expo / React Native App`);
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
writeTextFile(path.join(docsDir, "project-docs.md"), [
|
|
16
28
|
`# ${spec.title} Requirements`,
|
|
17
29
|
"",
|
|
@@ -21,6 +33,7 @@ export function updateProjectDocs(spec: AppSpec): void {
|
|
|
21
33
|
"",
|
|
22
34
|
"## Generated Scope",
|
|
23
35
|
"",
|
|
36
|
+
`- Platform: ${spec.platform}`,
|
|
24
37
|
`- Domain: ${spec.domain}`,
|
|
25
38
|
`- Auth: ${spec.modules.auth ? "yes" : "no"}`,
|
|
26
39
|
`- Users: ${spec.modules.users ? "yes" : "no"}`,
|
|
@@ -29,9 +42,7 @@ export function updateProjectDocs(spec: AppSpec): void {
|
|
|
29
42
|
"",
|
|
30
43
|
"## Architecture",
|
|
31
44
|
"",
|
|
32
|
-
|
|
33
|
-
`- \`${pathsMap.frontend}\`: React dashboard`,
|
|
34
|
-
`- \`${pathsMap.backend}/src/types\`: Contract-first backend TypeScript types`,
|
|
45
|
+
...architecture,
|
|
35
46
|
].join("\n"));
|
|
36
47
|
|
|
37
48
|
writeTextFile(path.join(apiDir, "README.md"), [
|
|
@@ -52,13 +63,20 @@ export function updateMemoryForGeneratedApp(spec: AppSpec, traceId: string): voi
|
|
|
52
63
|
|
|
53
64
|
const pathsMap = getConfiguredPaths();
|
|
54
65
|
const today = new Date().toISOString().split("T")[0];
|
|
66
|
+
|
|
67
|
+
const impactedFiles = [];
|
|
68
|
+
if (spec.platform === "full-stack" || spec.platform === "backend") impactedFiles.push(pathsMap.backend);
|
|
69
|
+
if (spec.platform === "full-stack" || spec.platform === "web") impactedFiles.push(pathsMap.frontend);
|
|
70
|
+
if (spec.platform === "mobile") impactedFiles.push(pathsMap.mobile || "apps/mobile");
|
|
71
|
+
impactedFiles.push("project docs");
|
|
72
|
+
|
|
55
73
|
const history = [
|
|
56
74
|
`### ${today} — Generated ${spec.title}`,
|
|
57
75
|
"",
|
|
58
76
|
"- **Agent:** @manager",
|
|
59
77
|
`- **Trace ID:** ${traceId}`,
|
|
60
|
-
|
|
61
|
-
`- **Files:** ${
|
|
78
|
+
`- **Action:** Created ${spec.platform} starter from natural language request.`,
|
|
79
|
+
`- **Files:** ${impactedFiles.join(", ")}`,
|
|
62
80
|
].join("\n");
|
|
63
81
|
|
|
64
82
|
updateProjectMemory("HISTORY", history);
|
|
@@ -243,6 +243,12 @@ export function createWebFiles(spec: AppSpec): void {
|
|
|
243
243
|
"}",
|
|
244
244
|
].join("\n"));
|
|
245
245
|
|
|
246
|
+
writeTextFile(path.join(targetDir, frontendDir, ".env.example"), [
|
|
247
|
+
"# Agent Enderun - Web Environment Variables",
|
|
248
|
+
"VITE_API_URL=http://localhost:4000/api/v1",
|
|
249
|
+
"VITE_APP_TITLE=" + spec.title,
|
|
250
|
+
].join("\n"));
|
|
251
|
+
|
|
246
252
|
writeTextFile(path.join(targetDir, frontendDir, "README.md"), [
|
|
247
253
|
`# ${spec.title} Web`,
|
|
248
254
|
"",
|
|
@@ -5,6 +5,7 @@ export interface AppSpec {
|
|
|
5
5
|
appName: string;
|
|
6
6
|
title: string;
|
|
7
7
|
domain: string;
|
|
8
|
+
platform: "web" | "mobile" | "backend" | "full-stack";
|
|
8
9
|
modules: {
|
|
9
10
|
auth: boolean;
|
|
10
11
|
users: boolean;
|
|
@@ -19,13 +20,22 @@ export function inferAppSpec(description: string): AppSpec {
|
|
|
19
20
|
const hasAuth = /auth|login|giris|giriş|signin|sign in|user|kullanici|kullanıcı|role|rol/.test(normalized);
|
|
20
21
|
const hasRoles = /role|rol|permission|yetki|admin/.test(normalized);
|
|
21
22
|
const hasReports = /report|rapor|analytics|dashboard|chart|metric/.test(normalized);
|
|
23
|
+
const isMobile = /mobile|ios|android|react native|expo/.test(normalized);
|
|
24
|
+
const isBackend = /backend|api|server|fastify|express/.test(normalized);
|
|
25
|
+
const isWeb = /web|frontend|react|vite/.test(normalized);
|
|
22
26
|
const appName = isCrm ? "crm-dashboard" : slugifyName(description).split("-").slice(0, 4).join("-");
|
|
23
27
|
|
|
28
|
+
let platform: AppSpec["platform"] = "full-stack";
|
|
29
|
+
if (isMobile) platform = "mobile";
|
|
30
|
+
else if (isBackend && !isWeb) platform = "backend";
|
|
31
|
+
else if (isWeb && !isBackend) platform = "web";
|
|
32
|
+
|
|
24
33
|
return {
|
|
25
34
|
rawDescription: description,
|
|
26
35
|
appName,
|
|
27
36
|
title: isCrm ? "CRM Dashboard" : titleCase(appName),
|
|
28
37
|
domain: isCrm ? "CRM" : "Business",
|
|
38
|
+
platform,
|
|
29
39
|
modules: {
|
|
30
40
|
auth: hasAuth || isCrm,
|
|
31
41
|
users: hasAuth || hasRoles || isCrm,
|
|
@@ -43,7 +53,7 @@ export async function collectCreateAppDescription(args: string[]): Promise<strin
|
|
|
43
53
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
44
54
|
try {
|
|
45
55
|
const idea = await rl.question("What do you want to build? ");
|
|
46
|
-
const platform = await rl.question("Platform? (full-stack/web/backend) ");
|
|
56
|
+
const platform = await rl.question("Platform? (full-stack/web/backend/mobile) ");
|
|
47
57
|
const auth = await rl.question("Auth and roles? (yes/no) ");
|
|
48
58
|
const reports = await rl.question("Reports/dashboard? (yes/no) ");
|
|
49
59
|
return [idea, platform, auth.includes("y") ? "with auth and roles" : "", reports.includes("y") ? "with reports dashboard" : ""].filter(Boolean).join(" ");
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import type { AppSpec } from "./app-inferrer.js";
|
|
3
|
+
import { createBaseTypeFiles } from "./app-types.js";
|
|
4
|
+
import { writeJsonFile, writeTextFile } from "./fs.js";
|
|
5
|
+
import { getConfiguredPaths } from "./memory.js";
|
|
6
|
+
|
|
7
|
+
const targetDir = process.cwd();
|
|
8
|
+
|
|
9
|
+
export function createMobileFiles(spec: AppSpec): void {
|
|
10
|
+
const pathsMap = getConfiguredPaths();
|
|
11
|
+
// Defaulting mobile to apps/mobile if not configured
|
|
12
|
+
const mobileDir = pathsMap.mobile || "apps/mobile";
|
|
13
|
+
|
|
14
|
+
createBaseTypeFiles(path.join(targetDir, mobileDir, "src"));
|
|
15
|
+
|
|
16
|
+
writeJsonFile(path.join(targetDir, mobileDir, "package.json"), {
|
|
17
|
+
name: "@agent-enderun/mobile",
|
|
18
|
+
version: "0.1.0",
|
|
19
|
+
private: true,
|
|
20
|
+
scripts: {
|
|
21
|
+
"start": "expo start",
|
|
22
|
+
"android": "expo start --android",
|
|
23
|
+
"ios": "expo start --ios",
|
|
24
|
+
"web": "expo start --web"
|
|
25
|
+
},
|
|
26
|
+
dependencies: {
|
|
27
|
+
"expo": "~52.0.0",
|
|
28
|
+
"expo-status-bar": "~2.0.0",
|
|
29
|
+
"react": "18.3.1",
|
|
30
|
+
"react-native": "0.76.0",
|
|
31
|
+
"lucide-react-native": "^0.468.0"
|
|
32
|
+
},
|
|
33
|
+
devDependencies: {
|
|
34
|
+
"@babel/core": "^7.25.2",
|
|
35
|
+
"@types/react": "~18.3.12",
|
|
36
|
+
"typescript": "^5.3.3"
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
writeTextFile(path.join(targetDir, mobileDir, "App.tsx"), [
|
|
41
|
+
"import React from 'react';",
|
|
42
|
+
"import { StyleSheet, Text, View, SafeAreaView, ScrollView } from 'react-native';",
|
|
43
|
+
"import { StatusBar } from 'expo-status-bar';",
|
|
44
|
+
"import { BarChart3, Users, Shield } from 'lucide-react-native';",
|
|
45
|
+
"",
|
|
46
|
+
"export default function App() {",
|
|
47
|
+
" return (",
|
|
48
|
+
" <SafeAreaView style={styles.container}>",
|
|
49
|
+
" <StatusBar style=\"auto\" />",
|
|
50
|
+
" <View style={styles.header}>",
|
|
51
|
+
" <Text style={styles.subtitle}>{'" + spec.domain + "'}</Text>",
|
|
52
|
+
" <Text style={styles.title}>{'" + spec.title + "'}</Text>",
|
|
53
|
+
" </View>",
|
|
54
|
+
" <ScrollView style={styles.content}>",
|
|
55
|
+
" <View style={styles.metricRow}>",
|
|
56
|
+
" <View style={[styles.card, { borderLeftColor: '#49a078' }]}>",
|
|
57
|
+
" <BarChart3 color=\"#49a078\" size={20} />",
|
|
58
|
+
" <Text style={styles.cardLabel}>Pipeline</Text>",
|
|
59
|
+
" <Text style={styles.cardValue}>$261K</Text>",
|
|
60
|
+
" </View>",
|
|
61
|
+
" <View style={[styles.card, { borderLeftColor: '#3f7cac' }]}>",
|
|
62
|
+
" <Users color=\"#3f7cac\" size={20} />",
|
|
63
|
+
" <Text style={styles.cardLabel}>Customers</Text>",
|
|
64
|
+
" <Text style={styles.cardValue}>18</Text>",
|
|
65
|
+
" </View>",
|
|
66
|
+
" </View>",
|
|
67
|
+
" <View style={styles.panel}>",
|
|
68
|
+
" <Text style={styles.panelTitle}>Recent Activity</Text>",
|
|
69
|
+
" <View style={styles.row}>",
|
|
70
|
+
" <Text style={styles.rowText}>Northwind updated by Manager</Text>",
|
|
71
|
+
" </View>",
|
|
72
|
+
" <View style={styles.row}>",
|
|
73
|
+
" <Text style={styles.rowText}>Acme Corp status changed to Lead</Text>",
|
|
74
|
+
" </View>",
|
|
75
|
+
" </View>",
|
|
76
|
+
" </ScrollView>",
|
|
77
|
+
" </SafeAreaView>",
|
|
78
|
+
" );",
|
|
79
|
+
"}",
|
|
80
|
+
"",
|
|
81
|
+
"const styles = StyleSheet.create({",
|
|
82
|
+
" container: { flex: 1, backgroundColor: '#f4f7f6' },",
|
|
83
|
+
" header: { padding: 24, backgroundColor: '#fff', borderBottomWidth: 1, borderBottomColor: '#d9e3e0' },",
|
|
84
|
+
" subtitle: { fontSize: 14, color: '#58666a', marginBottom: 4 },",
|
|
85
|
+
" title: { fontSize: 28, fontWeight: '800', color: '#172026' },",
|
|
86
|
+
" content: { flex: 1, padding: 16 },",
|
|
87
|
+
" metricRow: { flexDirection: 'row', gap: 12, marginBottom: 16 },",
|
|
88
|
+
" card: { flex: 1, backgroundColor: '#fff', padding: 16, borderRadius: 12, borderLeftWidth: 4, elevation: 2, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.1, shadowRadius: 2 },",
|
|
89
|
+
" cardLabel: { fontSize: 12, color: '#58666a', marginVertical: 4 },",
|
|
90
|
+
" cardValue: { fontSize: 20, fontWeight: '700', color: '#172026' },",
|
|
91
|
+
" panel: { backgroundColor: '#fff', padding: 16, borderRadius: 12, borderWidth: 1, borderColor: '#d9e3e0' },",
|
|
92
|
+
" panelTitle: { fontSize: 18, fontWeight: '700', color: '#172026', marginBottom: 12 },",
|
|
93
|
+
" row: { paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: '#f0f4f3' },",
|
|
94
|
+
" rowText: { color: '#58666a' }",
|
|
95
|
+
"});"
|
|
96
|
+
].join("\n"));
|
|
97
|
+
|
|
98
|
+
writeTextFile(path.join(targetDir, mobileDir, ".env.example"), [
|
|
99
|
+
"# Agent Enderun - Mobile Environment Variables",
|
|
100
|
+
"EXPO_PUBLIC_API_URL=http://localhost:4000/api/v1",
|
|
101
|
+
"EXPO_PUBLIC_APP_VARIANT=development",
|
|
102
|
+
].join("\n"));
|
|
103
|
+
|
|
104
|
+
writeTextFile(path.join(targetDir, mobileDir, "README.md"), [
|
|
105
|
+
`# ${spec.title} Mobile`,
|
|
106
|
+
"",
|
|
107
|
+
"Expo / React Native app generated by Agent Enderun.",
|
|
108
|
+
"",
|
|
109
|
+
"## Commands",
|
|
110
|
+
"",
|
|
111
|
+
"- `npx expo start`",
|
|
112
|
+
].join("\n"));
|
|
113
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { computeTypesHash, ensureDir, writeTextFile } from "./fs.js";
|
|
3
|
+
import { computeTypesHash, ensureDir, writeTextFile, writeJsonFile } from "./fs.js";
|
|
4
4
|
import { getConfiguredPaths } from "./memory.js";
|
|
5
5
|
import { UI } from "./ui.js";
|
|
6
6
|
|
|
@@ -65,7 +65,7 @@ export function updateContractHashFile(): void {
|
|
|
65
65
|
const contract = JSON.parse(fs.readFileSync(contractPath, "utf8"));
|
|
66
66
|
contract.contract_hash = currentHash;
|
|
67
67
|
contract.last_updated = new Date().toISOString();
|
|
68
|
-
|
|
68
|
+
writeJsonFile(contractPath, contract);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export function createBaseTypeFiles(baseDir: string): void {
|
|
@@ -173,7 +173,8 @@ export interface AgentActionLog {
|
|
|
173
173
|
}
|
|
174
174
|
`);
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
const modelsPath = path.join(typesDir, "models.ts");
|
|
177
|
+
const baseModelsContent = `import { UserID, TraceID, AgentID } from "./brands.js";
|
|
177
178
|
import { ProjectPhase, ExecutionProfile, TaskPriority, TaskStatus } from "./constants.js";
|
|
178
179
|
|
|
179
180
|
/**
|
|
@@ -238,6 +239,10 @@ export interface Task {
|
|
|
238
239
|
createdAt: string;
|
|
239
240
|
updatedAt: string;
|
|
240
241
|
}
|
|
241
|
-
|
|
242
|
+
`;
|
|
243
|
+
// Append generated application contract types
|
|
244
|
+
const finalModelsContent = buildSharedTypesContent(baseModelsContent);
|
|
245
|
+
writeTextFile(modelsPath, finalModelsContent);
|
|
246
|
+
|
|
242
247
|
UI.success(`Base types created in ${path.relative(targetDir, typesDir)}`);
|
|
243
248
|
}
|
package/src/cli/utils/app.ts
CHANGED
package/src/cli/utils/claude.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { writeTextFile } from "./fs.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Finds the Claude config file path (if it exists).
|
|
@@ -53,7 +54,7 @@ export function addMcpServerToClaude(configPath: string, serverName: string, ser
|
|
|
53
54
|
fs.mkdirSync(dir, { recursive: true });
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
writeTextFile(configPath, JSON.stringify(config, null, 2));
|
|
57
58
|
return true;
|
|
58
59
|
} catch (e) {
|
|
59
60
|
console.error(`⚠️ Failed to add MCP server to Claude config at ${configPath}:`, e);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { logger } from "../../shared/logger.js";
|
|
4
3
|
|
|
5
4
|
interface ComplianceIssue {
|
|
6
5
|
file: string;
|
|
@@ -10,9 +9,20 @@ interface ComplianceIssue {
|
|
|
10
9
|
|
|
11
10
|
export function scanProjectCompliance(): ComplianceIssue[] {
|
|
12
11
|
const issues: ComplianceIssue[] = [];
|
|
12
|
+
if (!fs.existsSync("src")) return [];
|
|
13
13
|
const files = getAllFiles("src");
|
|
14
14
|
|
|
15
15
|
for (const file of files) {
|
|
16
|
+
// Absolute skip for the scanner itself to avoid recursion/self-flagging
|
|
17
|
+
if (file.includes("compliance") ||
|
|
18
|
+
file.includes("definitions") ||
|
|
19
|
+
file.includes("agents/registry") || // Skip agent definitions
|
|
20
|
+
file.includes("app-backend.ts") || // Template generator
|
|
21
|
+
file.includes("scaffold-ops.ts") || // Template generator
|
|
22
|
+
file.includes("logger") ||
|
|
23
|
+
file.includes("errors") ||
|
|
24
|
+
file.includes("shared/fs")) continue;
|
|
25
|
+
|
|
16
26
|
const content = fs.readFileSync(file, "utf8");
|
|
17
27
|
const lines = content.split("\n");
|
|
18
28
|
|
|
@@ -24,26 +34,47 @@ export function scanProjectCompliance(): ComplianceIssue[] {
|
|
|
24
34
|
if (trimmedLine.startsWith("//") ||
|
|
25
35
|
trimmedLine.startsWith("*") ||
|
|
26
36
|
trimmedLine.startsWith("-") ||
|
|
27
|
-
trimmedLine.
|
|
28
|
-
trimmedLine.
|
|
37
|
+
trimmedLine.includes("\": \"") || // Ignore JSON-like values
|
|
38
|
+
trimmedLine.includes("default: ") || // Ignore default template values
|
|
39
|
+
trimmedLine.startsWith("`")) return; // Ignore template literals
|
|
29
40
|
|
|
30
41
|
// Only check if it's NOT inside a UI/console message
|
|
31
42
|
const isUIMessage = line.includes("console.warn") || line.includes("console.error") || line.includes("UI.");
|
|
43
|
+
const isTypeDefinition = line.includes("interface ") || line.includes("type ");
|
|
32
44
|
|
|
33
45
|
// 1. Console.log check - only if it's actual code
|
|
34
46
|
if (line.includes("console.log") && !isUIMessage) {
|
|
35
47
|
issues.push({ file, line: lineNum, rule: "No console.log allowed" });
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
// 2. Secret check (Regex for simple API keys) - skip UI messages
|
|
39
|
-
if (/API_KEY|SECRET|PASSWORD/i.test(line) &&
|
|
40
|
-
|
|
50
|
+
// 2. Secret check (Regex for simple API keys/assignments) - skip UI messages and templates
|
|
51
|
+
if (/(API_KEY|SECRET|PASSWORD)\s*[:=]/i.test(line) &&
|
|
52
|
+
!file.includes(".env") &&
|
|
53
|
+
!isUIMessage &&
|
|
54
|
+
!trimmedLine.includes(".env.example") && // Skip template lines
|
|
55
|
+
!trimmedLine.includes("your_secret_key_here") && // Skip common placeholders
|
|
56
|
+
!trimmedLine.includes("pattern:")) {
|
|
57
|
+
issues.push({ file, line: lineNum, rule: "Potential hardcoded secret assignment detected" });
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
// 3. 'Any' type check
|
|
44
|
-
if (/\bany\b/.test(line) && !
|
|
61
|
+
if (/\bany\b/.test(line) && !isTypeDefinition && !trimmedLine.includes("\":")) {
|
|
45
62
|
issues.push({ file, line: lineNum, rule: "Usage of 'any' type is forbidden" });
|
|
46
63
|
}
|
|
64
|
+
|
|
65
|
+
// 4. Technical Debt Detection (TODO/FIXME)
|
|
66
|
+
if (/\b(TODO|FIXME)\b/i.test(line)) {
|
|
67
|
+
issues.push({ file, line: lineNum, rule: "Unresolved Technical Debt (TODO/FIXME) found" });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 5. Raw fs write check (Atomic safety enforcement)
|
|
71
|
+
if ((line.includes("fs.writeFileSync") || line.includes("fs.appendFileSync")) &&
|
|
72
|
+
!file.includes("src/shared/fs.ts") && // Ignore the utility itself
|
|
73
|
+
!line.includes(".lock") && // Allow lock files
|
|
74
|
+
!line.includes("lockPath") && // Allow lock path variables
|
|
75
|
+
!file.includes("bin/")) { // Ignore standalone binary scripts
|
|
76
|
+
issues.push({ file, line: lineNum, rule: "Use internal atomic utilities (writeTextFile) instead of raw fs" });
|
|
77
|
+
}
|
|
47
78
|
});
|
|
48
79
|
|
|
49
80
|
}
|
|
@@ -10,10 +10,10 @@ export const ColorPaletteSchema = z.object({
|
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Enderun
|
|
13
|
+
* Agent Enderun config.json Schema
|
|
14
14
|
*/
|
|
15
|
-
export const
|
|
16
|
-
name: z.string().default("Enderun
|
|
15
|
+
export const ConfigSchema = z.object({
|
|
16
|
+
name: z.string().default("Agent Enderun"),
|
|
17
17
|
version: z.string(),
|
|
18
18
|
frameworkDir: z.string().optional(),
|
|
19
19
|
theme: z.object({
|
|
@@ -44,5 +44,5 @@ export const McpConfigSchema = z.object({
|
|
|
44
44
|
}))
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
export type EnderunConfig = z.infer<typeof
|
|
47
|
+
export type EnderunConfig = z.infer<typeof ConfigSchema>;
|
|
48
48
|
export type McpConfig = z.infer<typeof McpConfigSchema>;
|
package/src/cli/utils/fs.ts
CHANGED
|
@@ -4,13 +4,13 @@ import crypto from "crypto";
|
|
|
4
4
|
|
|
5
5
|
import { remapFrameworkContent } from "../adapters/index.js"; // Import from the new adapters.js
|
|
6
6
|
import type { AdapterId } from "../adapters/index.js";
|
|
7
|
-
import { ensureDir, writeTextFile, writeJsonFile } from "../../shared/fs.js";
|
|
7
|
+
import { ensureDir, writeTextFile, writeJsonFile, appendFile } from "../../shared/fs.js";
|
|
8
8
|
|
|
9
|
-
export { ensureDir, writeTextFile, writeJsonFile };
|
|
9
|
+
export { ensureDir, writeTextFile, writeJsonFile, appendFile };
|
|
10
10
|
|
|
11
11
|
export function updateGitIgnore(targetPath: string, frameworkDir = ".gemini", dryRun = false): void {
|
|
12
12
|
const IGNORE_LINES = [
|
|
13
|
-
"#
|
|
13
|
+
"# Agent Enderun",
|
|
14
14
|
`${frameworkDir}/logs/*.json`,
|
|
15
15
|
`${frameworkDir}/*.lock`,
|
|
16
16
|
`${frameworkDir}/memory/`,
|
|
@@ -37,7 +37,7 @@ export function updateGitIgnore(targetPath: string, frameworkDir = ".gemini", dr
|
|
|
37
37
|
if (dryRun) {
|
|
38
38
|
console.warn(`[DRY RUN] Would update .gitignore at ${targetPath}`);
|
|
39
39
|
} else {
|
|
40
|
-
|
|
40
|
+
writeTextFile(targetPath, content);
|
|
41
41
|
console.warn("✅ .gitignore updated.");
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -114,20 +114,15 @@ export function copyDir(
|
|
|
114
114
|
if (ext === ".json") {
|
|
115
115
|
try {
|
|
116
116
|
const json = JSON.parse(content);
|
|
117
|
-
|
|
117
|
+
writeJsonFile(destPath, sanitizeJson(json, targetScope), dryRun);
|
|
118
118
|
} catch {
|
|
119
|
-
|
|
119
|
+
const fallback = content.replace(/workspace:[^"'\s]*/g, "*");
|
|
120
|
+
writeTextFile(destPath, fallback, dryRun);
|
|
120
121
|
}
|
|
121
122
|
} else {
|
|
122
123
|
content = content.replace(/workspace:[^"'\s]*/g, "*");
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (dryRun) {
|
|
128
|
-
console.warn(`[DRY RUN] Would process and write: ${destPath}`);
|
|
129
|
-
} else {
|
|
130
|
-
fs.writeFileSync(destPath, content);
|
|
124
|
+
content = remapFrameworkContent(content, frameworkDir, adapterId); // Apply remap once to the final content
|
|
125
|
+
writeTextFile(destPath, content, dryRun);
|
|
131
126
|
}
|
|
132
127
|
} else {
|
|
133
128
|
if (dryRun) {
|