agent-enderun 1.1.6 → 1.1.7
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.md +12 -9
- package/README.md +12 -29
- package/bin/run-multi-test.js +77 -0
- package/dist/framework-mcp/src/tools/dashboard/start_dashboard.d.ts +5 -0
- package/dist/framework-mcp/src/tools/dashboard/start_dashboard.js +30 -0
- package/dist/framework-mcp/src/tools/dashboard/start_dashboard.js.map +1 -0
- package/dist/framework-mcp/src/tools/definitions.js +118 -0
- package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.d.ts +5 -0
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +51 -0
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js.map +1 -0
- package/dist/framework-mcp/src/tools/file_system/replace_text.js +8 -4
- 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 -0
- package/dist/framework-mcp/src/tools/file_system/write_file.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/audit_deps.d.ts +6 -0
- package/dist/framework-mcp/src/tools/framework/audit_deps.js +42 -0
- package/dist/framework-mcp/src/tools/framework/audit_deps.js.map +1 -0
- package/dist/framework-mcp/src/tools/framework/run_tests.d.ts +5 -0
- package/dist/framework-mcp/src/tools/framework/run_tests.js +26 -0
- package/dist/framework-mcp/src/tools/framework/run_tests.js.map +1 -0
- package/dist/framework-mcp/src/tools/index.js +24 -0
- package/dist/framework-mcp/src/tools/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/memory/get_insights.d.ts +6 -0
- package/dist/framework-mcp/src/tools/memory/get_insights.js +35 -0
- package/dist/framework-mcp/src/tools/memory/get_insights.js.map +1 -0
- package/dist/framework-mcp/src/tools/memory/read_memory.d.ts +6 -0
- package/dist/framework-mcp/src/tools/memory/read_memory.js +29 -0
- package/dist/framework-mcp/src/tools/memory/read_memory.js.map +1 -0
- package/dist/framework-mcp/src/tools/messaging/send_message.js +1 -1
- package/dist/framework-mcp/src/tools/messaging/send_message.js.map +1 -1
- package/dist/framework-mcp/src/tools/observability/check_ports.d.ts +5 -0
- package/dist/framework-mcp/src/tools/observability/check_ports.js +27 -0
- package/dist/framework-mcp/src/tools/observability/check_ports.js.map +1 -0
- package/dist/framework-mcp/src/tools/observability/get_health.d.ts +5 -0
- package/dist/framework-mcp/src/tools/observability/get_health.js +21 -0
- package/dist/framework-mcp/src/tools/observability/get_health.js.map +1 -0
- package/dist/framework-mcp/src/tools/search/get_gaps.d.ts +6 -0
- package/dist/framework-mcp/src/tools/search/get_gaps.js +49 -0
- package/dist/framework-mcp/src/tools/search/get_gaps.js.map +1 -0
- package/dist/framework-mcp/src/tools/search/get_map.d.ts +6 -0
- package/dist/framework-mcp/src/tools/search/get_map.js +45 -0
- package/dist/framework-mcp/src/tools/search/get_map.js.map +1 -0
- package/dist/framework-mcp/src/tools/search/grep_search.d.ts +5 -0
- package/dist/framework-mcp/src/tools/search/grep_search.js +60 -0
- package/dist/framework-mcp/src/tools/search/grep_search.js.map +1 -0
- package/dist/framework-mcp/src/tools/search/list_dir.d.ts +5 -0
- package/dist/framework-mcp/src/tools/search/list_dir.js +29 -0
- package/dist/framework-mcp/src/tools/search/list_dir.js.map +1 -0
- package/dist/framework-mcp/src/tools/types.d.ts +10 -5
- package/dist/framework-mcp/src/utils/compliance.d.ts +5 -0
- package/dist/framework-mcp/src/utils/compliance.js +30 -0
- package/dist/framework-mcp/src/utils/compliance.js.map +1 -0
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +5 -5
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
- package/dist/src/cli/adapters/types.d.ts +2 -2
- package/dist/src/cli/adapters.d.ts +1 -1
- package/dist/src/cli/adapters.js +45 -77
- package/dist/src/cli/adapters.js.map +1 -1
- package/dist/src/cli/commands/check.js +52 -6
- package/dist/src/cli/commands/check.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts +5 -1
- package/dist/src/cli/commands/init.js +183 -124
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/orchestrate.d.ts +3 -3
- package/dist/src/cli/commands/orchestrate.js +14 -8
- package/dist/src/cli/commands/orchestrate.js.map +1 -1
- package/dist/src/cli/commands/status.js +3 -2
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/index.js +4 -3
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/shims.js +6 -6
- package/dist/src/cli/utils/app-backend.d.ts +2 -0
- package/dist/src/cli/utils/app-backend.js +236 -0
- package/dist/src/cli/utils/app-backend.js.map +1 -0
- package/dist/src/cli/utils/app-docs.d.ts +3 -0
- package/dist/src/cli/utils/app-docs.js +59 -0
- package/dist/src/cli/utils/app-docs.js.map +1 -0
- package/dist/src/cli/utils/app-frontend.d.ts +2 -0
- package/dist/src/cli/utils/app-frontend.js +248 -0
- package/dist/src/cli/utils/app-frontend.js.map +1 -0
- package/dist/src/cli/utils/app-inferrer.d.ts +14 -0
- package/dist/src/cli/utils/app-inferrer.js +39 -0
- package/dist/src/cli/utils/app-inferrer.js.map +1 -0
- package/dist/src/cli/utils/app-types.d.ts +3 -0
- package/dist/src/cli/utils/app-types.js +233 -0
- package/dist/src/cli/utils/app-types.js.map +1 -0
- package/dist/src/cli/utils/app.d.ts +5 -32
- package/dist/src/cli/utils/app.js +5 -794
- package/dist/src/cli/utils/app.js.map +1 -1
- package/dist/src/cli/utils/memory.js +8 -4
- package/dist/src/cli/utils/memory.js.map +1 -1
- package/dist/src/modules/adapters/antigravity-cli.js +3 -3
- package/dist/src/modules/adapters/antigravity-cli.js.map +1 -1
- package/dist/src/modules/adapters/claude.js +1 -1
- package/dist/src/modules/adapters/claude.js.map +1 -1
- package/dist/src/modules/adapters/codex.js +2 -2
- package/dist/src/modules/adapters/codex.js.map +1 -1
- package/dist/src/modules/adapters/cursor.js +1 -1
- package/dist/src/modules/adapters/cursor.js.map +1 -1
- package/dist/src/modules/adapters/definitions.d.ts +9 -0
- package/dist/src/modules/adapters/definitions.js +124 -0
- package/dist/src/modules/adapters/definitions.js.map +1 -0
- package/dist/src/modules/adapters/gemini.js +2 -2
- package/dist/src/modules/adapters/gemini.js.map +1 -1
- package/dist/src/modules/adapters/grok.js +1 -1
- package/dist/src/modules/adapters/grok.js.map +1 -1
- package/dist/src/modules/agents/definitions.js +26 -27
- package/dist/src/modules/agents/definitions.js.map +1 -1
- package/dist/src/shared/config.d.ts +3 -3
- package/dist/src/shared/logger.js +8 -5
- package/dist/src/shared/logger.js.map +1 -1
- package/dist/tests/adapter.test.d.ts +1 -0
- package/dist/tests/adapter.test.js +129 -0
- package/dist/tests/adapter.test.js.map +1 -0
- package/dist/tests/agents-definitions.test.d.ts +1 -0
- package/dist/tests/agents-definitions.test.js +54 -0
- package/dist/tests/agents-definitions.test.js.map +1 -0
- package/dist/tests/approve.test.d.ts +1 -0
- package/dist/tests/approve.test.js +88 -0
- package/dist/tests/approve.test.js.map +1 -0
- package/dist/tests/config.test.d.ts +1 -0
- package/dist/tests/config.test.js +58 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/container.runner.d.ts +1 -0
- package/dist/tests/container.runner.js +68 -0
- package/dist/tests/container.runner.js.map +1 -0
- package/dist/tests/container.test.d.ts +1 -0
- package/dist/tests/container.test.js +73 -0
- package/dist/tests/container.test.js.map +1 -0
- package/dist/tests/errors.test.d.ts +1 -0
- package/dist/tests/errors.test.js +64 -0
- package/dist/tests/errors.test.js.map +1 -0
- package/dist/tests/fs-utils.test.d.ts +1 -0
- package/dist/tests/fs-utils.test.js +101 -0
- package/dist/tests/fs-utils.test.js.map +1 -0
- package/dist/tests/logger.test.d.ts +1 -0
- package/dist/tests/logger.test.js +81 -0
- package/dist/tests/logger.test.js.map +1 -0
- package/dist/tests/memory-utils.test.d.ts +1 -0
- package/dist/tests/memory-utils.test.js +173 -0
- package/dist/tests/memory-utils.test.js.map +1 -0
- package/dist/tests/orchestrate.test.d.ts +1 -0
- package/dist/tests/orchestrate.test.js +131 -0
- package/dist/tests/orchestrate.test.js.map +1 -0
- package/dist/tests/skills-definitions.test.d.ts +1 -0
- package/dist/tests/skills-definitions.test.js +34 -0
- package/dist/tests/skills-definitions.test.js.map +1 -0
- package/dist/tests/status.test.d.ts +1 -0
- package/dist/tests/status.test.js +105 -0
- package/dist/tests/status.test.js.map +1 -0
- package/dist/tests/string.test.d.ts +1 -0
- package/dist/tests/string.test.js +89 -0
- package/dist/tests/string.test.js.map +1 -0
- package/dist/tests/time.test.d.ts +1 -0
- package/dist/tests/time.test.js +48 -0
- package/dist/tests/time.test.js.map +1 -0
- package/dist/tests/trace.test.d.ts +1 -0
- package/dist/tests/trace.test.js +61 -0
- package/dist/tests/trace.test.js.map +1 -0
- package/dist/vitest.config.js +1 -0
- package/dist/vitest.config.js.map +1 -1
- package/docs/getting-started.md +4 -0
- package/docs/user/corporate-governance.md +25 -0
- package/framework-mcp/dist/tools/dashboard/start_dashboard.js +29 -0
- package/framework-mcp/dist/tools/definitions.js +118 -0
- package/framework-mcp/dist/tools/file_system/batch_surgical_edit.js +50 -0
- package/framework-mcp/dist/tools/file_system/replace_text.js +8 -4
- package/framework-mcp/dist/tools/file_system/write_file.js +3 -0
- package/framework-mcp/dist/tools/framework/audit_deps.js +41 -0
- package/framework-mcp/dist/tools/framework/run_tests.js +25 -0
- package/framework-mcp/dist/tools/index.js +24 -0
- package/framework-mcp/dist/tools/memory/get_insights.js +34 -0
- package/framework-mcp/dist/tools/memory/read_memory.js +28 -0
- package/framework-mcp/dist/tools/messaging/send_message.js +1 -1
- package/framework-mcp/dist/tools/observability/check_ports.js +26 -0
- package/framework-mcp/dist/tools/observability/get_health.js +20 -0
- package/framework-mcp/dist/tools/search/get_gaps.js +48 -0
- package/framework-mcp/dist/tools/search/get_map.js +44 -0
- package/framework-mcp/dist/tools/search/grep_search.js +59 -0
- package/framework-mcp/dist/tools/search/list_dir.js +28 -0
- package/framework-mcp/dist/utils/compliance.js +29 -0
- package/framework-mcp/src/tools/dashboard/start_dashboard.ts +33 -0
- package/framework-mcp/src/tools/definitions.ts +118 -0
- package/framework-mcp/src/tools/file_system/batch_surgical_edit.ts +70 -0
- package/framework-mcp/src/tools/file_system/replace_text.ts +10 -4
- package/framework-mcp/src/tools/file_system/write_file.ts +5 -0
- package/framework-mcp/src/tools/framework/audit_deps.ts +49 -0
- package/framework-mcp/src/tools/framework/run_tests.ts +28 -0
- package/framework-mcp/src/tools/index.ts +24 -0
- package/framework-mcp/src/tools/memory/get_insights.ts +41 -0
- package/framework-mcp/src/tools/memory/read_memory.ts +31 -0
- package/framework-mcp/src/tools/messaging/send_message.ts +1 -1
- package/framework-mcp/src/tools/observability/check_ports.ts +30 -0
- package/framework-mcp/src/tools/observability/get_health.ts +25 -0
- package/framework-mcp/src/tools/search/get_gaps.ts +54 -0
- package/framework-mcp/src/tools/search/get_map.ts +50 -0
- package/framework-mcp/src/tools/search/grep_search.ts +66 -0
- package/framework-mcp/src/tools/search/list_dir.ts +34 -0
- package/framework-mcp/src/tools/types.ts +11 -1
- package/framework-mcp/src/utils/compliance.ts +37 -0
- package/framework-mcp/tests/tools/messaging/send_message.test.ts +5 -5
- package/package.json +2 -2
- package/src/cli/adapters/types.ts +2 -2
- package/src/cli/adapters.ts +45 -80
- package/src/cli/commands/check.ts +52 -6
- package/src/cli/commands/init.ts +193 -138
- package/src/cli/commands/orchestrate.ts +14 -8
- package/src/cli/commands/status.ts +3 -2
- package/src/cli/index.ts +4 -3
- package/src/cli/shims.ts +6 -6
- package/src/cli/utils/app-backend.ts +249 -0
- package/src/cli/utils/app-docs.ts +65 -0
- package/src/cli/utils/app-frontend.ts +257 -0
- package/src/cli/utils/app-inferrer.ts +53 -0
- package/src/cli/utils/app-types.ts +243 -0
- package/src/cli/utils/app.ts +5 -849
- package/src/cli/utils/memory.ts +8 -4
- package/src/modules/adapters/definitions.ts +125 -0
- package/src/modules/agents/definitions.ts +26 -27
- package/src/shared/logger.ts +8 -5
- package/templates/prompts/bug-fix-recipe.md +20 -0
- package/templates/prompts/new-feature-recipe.md +19 -0
- package/templates/prompts/refactoring-recipe.md +21 -0
- package/templates/standards/architecture-standards.md +23 -0
- package/templates/standards/crud-governance.md +21 -0
- package/templates/standards/frontend-standards.md +38 -0
- package/templates/standards/i18n-standards.md +17 -0
- package/templates/standards/logging-and-secrets.md +29 -0
- package/templates/standards/mobile-standards.md +24 -0
- package/templates/standards/quality-standards.md +31 -0
- package/templates/standards/security-standards.md +21 -0
- package/templates/standards/tailwind-standards.md +20 -0
- package/templates/standards/testing-standards.md +31 -0
- package/src/modules/adapters/antigravity-cli.ts +0 -25
- package/src/modules/adapters/claude.ts +0 -36
- package/src/modules/adapters/codex.ts +0 -22
- package/src/modules/adapters/cursor.ts +0 -22
- package/src/modules/adapters/gemini.ts +0 -27
- package/src/modules/adapters/grok.ts +0 -20
- package/templates/architecture/agents-manifest.md +0 -79
- package/templates/architecture/approval-flows.md +0 -61
- package/templates/architecture/enterprise-architecture.md +0 -69
- package/templates/architecture/standards/crud-governance.md +0 -46
- package/templates/architecture/standards/data-fetching-patterns.md +0 -13
- package/templates/architecture/standards/design-system.md +0 -31
- package/templates/architecture/standards/documentation-ownership.md +0 -21
- package/templates/architecture/standards/logging.md +0 -7
- package/templates/architecture/standards/mobile-standards.md +0 -48
- package/templates/architecture/standards/tech-stack.md +0 -9
- package/templates/backend/error-handling.md +0 -74
- package/templates/frontend/component-patterns.md +0 -91
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { safePath } from "../../utils/security.js";
|
|
4
|
+
import { ToolArgs, ToolResult } from "../types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Searches for a regex pattern within files in the project.
|
|
8
|
+
*/
|
|
9
|
+
export function handleGrepSearch(projectRoot: string, args: ToolArgs): ToolResult {
|
|
10
|
+
const pattern = args.pattern as string;
|
|
11
|
+
const includePattern = args.includePattern as string || ""; // e.g., ".ts"
|
|
12
|
+
const excludePattern = args.excludePattern as string || "node_modules";
|
|
13
|
+
|
|
14
|
+
if (!pattern) {
|
|
15
|
+
throw new Error("Search pattern is required.");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const results: string[] = [];
|
|
19
|
+
const regex = new RegExp(pattern, "g");
|
|
20
|
+
|
|
21
|
+
const walk = (dir: string) => {
|
|
22
|
+
const files = fs.readdirSync(dir);
|
|
23
|
+
for (const file of files) {
|
|
24
|
+
const fullPath = path.join(dir, file);
|
|
25
|
+
const relativePath = path.relative(projectRoot, fullPath);
|
|
26
|
+
|
|
27
|
+
// Skip excluded directories/files
|
|
28
|
+
if (relativePath.includes(excludePattern)) continue;
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const stat = fs.statSync(fullPath);
|
|
32
|
+
if (stat.isDirectory()) {
|
|
33
|
+
walk(fullPath);
|
|
34
|
+
} else if (stat.isFile()) {
|
|
35
|
+
// Check include pattern
|
|
36
|
+
if (includePattern && !file.endsWith(includePattern)) continue;
|
|
37
|
+
|
|
38
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
39
|
+
const lines = content.split("\n");
|
|
40
|
+
lines.forEach((line, index) => {
|
|
41
|
+
if (regex.test(line)) {
|
|
42
|
+
results.push(`${relativePath}:${index + 1}: ${line.trim()}`);
|
|
43
|
+
// Reset regex lastIndex because of 'g' flag
|
|
44
|
+
regex.lastIndex = 0;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
// Ignore read errors
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (results.length > 100) break; // Limit results
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
walk(projectRoot);
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
content: [{
|
|
60
|
+
type: "text",
|
|
61
|
+
text: results.length > 0
|
|
62
|
+
? `Found ${results.length} matches:\n\n${results.join("\n")}`
|
|
63
|
+
: "No matches found."
|
|
64
|
+
}]
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { safePath } from "../../utils/security.js";
|
|
4
|
+
import { ToolArgs, ToolResult } from "../types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lists the contents of a directory.
|
|
8
|
+
*/
|
|
9
|
+
export function handleListDir(projectRoot: string, args: ToolArgs): ToolResult {
|
|
10
|
+
const dirPath = safePath(projectRoot, args.path as string || ".");
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(dirPath)) {
|
|
13
|
+
throw new Error(`Directory not found: ${args.path}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const stats = fs.statSync(dirPath);
|
|
17
|
+
if (!stats.isDirectory()) {
|
|
18
|
+
throw new Error(`Path is not a directory: ${args.path}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const files = fs.readdirSync(dirPath);
|
|
22
|
+
const results = files.map(file => {
|
|
23
|
+
const fullPath = path.join(dirPath, file);
|
|
24
|
+
const isDir = fs.statSync(fullPath).isDirectory();
|
|
25
|
+
return `${isDir ? "[DIR] " : " "}${file}`;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
content: [{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: `Directory listing for ${args.path || "."}:\n\n${results.join("\n")}`
|
|
32
|
+
}]
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -3,7 +3,7 @@ export interface ToolDefinition {
|
|
|
3
3
|
description: string;
|
|
4
4
|
inputSchema: {
|
|
5
5
|
type: "object";
|
|
6
|
-
properties: Record<string,
|
|
6
|
+
properties: Record<string, any>;
|
|
7
7
|
required?: string[];
|
|
8
8
|
};
|
|
9
9
|
}
|
|
@@ -36,6 +36,16 @@ export interface ToolArgs {
|
|
|
36
36
|
timeout?: number;
|
|
37
37
|
from?: string;
|
|
38
38
|
priority?: "HIGH" | "NORMAL" | "LOW";
|
|
39
|
+
// Added for new tools
|
|
40
|
+
port?: number;
|
|
41
|
+
pattern?: string;
|
|
42
|
+
includePattern?: string;
|
|
43
|
+
excludePattern?: string;
|
|
44
|
+
maxDepth?: number;
|
|
45
|
+
includeFiles?: boolean;
|
|
46
|
+
edits?: any[];
|
|
47
|
+
command?: string;
|
|
48
|
+
filter?: string;
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
export interface ToolResult {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Compliance Guardrail
|
|
3
|
+
* Checks content against corporate standards before allowing file mutations.
|
|
4
|
+
*/
|
|
5
|
+
export function verifyCorporateCompliance(content: string, filePath: string): void {
|
|
6
|
+
// 1. Zero Console Policy
|
|
7
|
+
if (content.includes("console.log(") || content.includes("console.warn(") || content.includes("console.error(")) {
|
|
8
|
+
if (!filePath.includes("logger.ts") && !filePath.includes("check.ts") && !filePath.includes("cli.ts")) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"❌ Corporate Compliance Breach: 'console.log/warn/error' usage is forbidden. " +
|
|
11
|
+
"Use the 'logger' system from '@/shared/logger' instead."
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 2. No Explicit Any Policy
|
|
17
|
+
const anyRegex = /[:<]\s*any\b|\bas\s+any\b/g;
|
|
18
|
+
if (anyRegex.test(content)) {
|
|
19
|
+
if (!filePath.includes("definitions.ts") && !filePath.includes("types.ts")) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"❌ Corporate Compliance Breach: 'any' type is forbidden. " +
|
|
22
|
+
"Use 'unknown', 'generics', or proper interfaces for type safety."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 3. Hardcoded Secrets Guard (Simple heuristic)
|
|
28
|
+
const secretKeywords = [/API_KEY\s*=\s*['"][^'"]+['"]/i, /SECRET\s*=\s*['"][^'"]+['"]/i, /PASSWORD\s*=\s*['"][^'"]+['"]/i];
|
|
29
|
+
for (const regex of secretKeywords) {
|
|
30
|
+
if (regex.test(content) && !filePath.endsWith(".env.example")) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
"❌ Corporate Compliance Breach: Hardcoded secrets detected. " +
|
|
33
|
+
"All sensitive data must be managed via '.env' files."
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -6,7 +6,7 @@ import { ToolArgs } from "../../../src/tools/types.js";
|
|
|
6
6
|
|
|
7
7
|
const TEST_DIR = path.resolve(__dirname, "../../_temp_messaging_tests");
|
|
8
8
|
const MESSAGES_DIR = path.join(TEST_DIR, ".gemini/messages");
|
|
9
|
-
const
|
|
9
|
+
const BACKEND_LOCK_FILE = path.join(MESSAGES_DIR, "backend.lock");
|
|
10
10
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
fs.mkdirSync(TEST_DIR, { recursive: true });
|
|
@@ -56,7 +56,7 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
56
56
|
it("should retry and fail to send message if lock is kept busy", async () => {
|
|
57
57
|
// Prepare a busy lock file
|
|
58
58
|
fs.mkdirSync(MESSAGES_DIR, { recursive: true });
|
|
59
|
-
fs.writeFileSync(
|
|
59
|
+
fs.writeFileSync(BACKEND_LOCK_FILE, "Locked by @test at " + new Date().toISOString(), "utf8");
|
|
60
60
|
|
|
61
61
|
const args: ToolArgs = {
|
|
62
62
|
to: "@backend",
|
|
@@ -79,9 +79,9 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
79
79
|
it("should bypass and acquire lock if existing lock is stale (older than 5s)", async () => {
|
|
80
80
|
fs.mkdirSync(MESSAGES_DIR, { recursive: true });
|
|
81
81
|
// Set lock file mtime to 10 seconds ago
|
|
82
|
-
fs.writeFileSync(
|
|
82
|
+
fs.writeFileSync(BACKEND_LOCK_FILE, "Locked by @test at " + new Date().toISOString(), "utf8");
|
|
83
83
|
const tenSecondsAgo = new Date(Date.now() - 10000);
|
|
84
|
-
fs.utimesSync(
|
|
84
|
+
fs.utimesSync(BACKEND_LOCK_FILE, tenSecondsAgo, tenSecondsAgo);
|
|
85
85
|
|
|
86
86
|
const args: ToolArgs = {
|
|
87
87
|
to: "@backend",
|
|
@@ -93,7 +93,7 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
93
93
|
|
|
94
94
|
const result = await handleSendAgentMessage(TEST_DIR, args);
|
|
95
95
|
expect(result.content[0].text).toContain("✅ Message sent to @backend");
|
|
96
|
-
expect(fs.existsSync(
|
|
96
|
+
expect(fs.existsSync(BACKEND_LOCK_FILE)).toBe(false); // Lock should have been unlinked in finally
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
it("should safely resolve concurrent messages and execute them in sequence", async () => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-enderun",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "The Supreme AI Governance & Orchestration Framework for Enterprise Development",
|
|
3
|
+
"version": "1.1.7",
|
|
4
|
+
"description": "The Supreme AI Governance & Autonomous Orchestration Framework for Enterprise Development. Acts as a Corporate AL Management Assistant.",
|
|
5
5
|
"author": "Yusuf BEKAR",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"readme": "README.md",
|
|
@@ -11,6 +11,6 @@ export interface AdapterConfig {
|
|
|
11
11
|
role: AdapterRole;
|
|
12
12
|
templateDir: ".enderun";
|
|
13
13
|
nestedDirs?: string[];
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
agentsDir?: string; // Directory to write individual agents/rules, relative to projectRoot
|
|
15
|
+
agentsExt?: string; // Extensions for agent files (.md or .mdc)
|
|
16
16
|
}
|
package/src/cli/adapters.ts
CHANGED
|
@@ -2,35 +2,18 @@ import path from "path";
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import { writeJsonFile } from "./utils/fs.js";
|
|
4
4
|
import { getPackageRoot } from "./utils/pkg.js";
|
|
5
|
-
import {
|
|
5
|
+
import { UI } from "./utils/ui.js";
|
|
6
|
+
import { ALL_AGENTS, buildAgentJson } from "../modules/agents/definitions.js";
|
|
7
|
+
import { logger } from "../shared/logger.js";
|
|
6
8
|
|
|
7
9
|
import type { AdapterId, AdapterConfig } from "./adapters/types.js";
|
|
8
10
|
export { ADAPTER_IDS, type AdapterId, type AdapterRole, type AdapterConfig } from "./adapters/types.js";
|
|
9
11
|
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import * as antigravityCli from "../modules/adapters/antigravity-cli.js";
|
|
16
|
-
|
|
17
|
-
export const ADAPTERS: Record<AdapterId, AdapterConfig> = {
|
|
18
|
-
gemini: gemini.config,
|
|
19
|
-
claude: claude.config,
|
|
20
|
-
grok: grok.config,
|
|
21
|
-
cursor: cursor.config,
|
|
22
|
-
codex: codex.config,
|
|
23
|
-
"antigravity-cli": antigravityCli.config,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const POST_INIT_MAP: Record<AdapterId, (projectRoot: string, mcpBlock: unknown) => void> = {
|
|
27
|
-
gemini: gemini.postInit,
|
|
28
|
-
claude: claude.postInit,
|
|
29
|
-
grok: grok.postInit,
|
|
30
|
-
cursor: cursor.postInit,
|
|
31
|
-
codex: codex.postInit,
|
|
32
|
-
"antigravity-cli": antigravityCli.postInit,
|
|
33
|
-
};
|
|
12
|
+
import { ADAPTER_CONFIGS, POST_INIT_HANDLERS } from "../modules/adapters/definitions.js";
|
|
13
|
+
|
|
14
|
+
export const ADAPTERS: Record<AdapterId, AdapterConfig> = ADAPTER_CONFIGS;
|
|
15
|
+
|
|
16
|
+
const POST_INIT_MAP: Record<AdapterId, (projectRoot: string, mcpBlock: unknown) => void> = POST_INIT_HANDLERS;
|
|
34
17
|
|
|
35
18
|
export const FRAMEWORK_DIR_CANDIDATES = [
|
|
36
19
|
".enderun",
|
|
@@ -60,41 +43,10 @@ export function resolveAdapter(input?: string): AdapterConfig {
|
|
|
60
43
|
if (normalized in ADAPTERS) {
|
|
61
44
|
config = { ...ADAPTERS[normalized as AdapterId] };
|
|
62
45
|
} else {
|
|
63
|
-
|
|
46
|
+
UI.warning(`Unknown adapter "${input}". Falling back to gemini.`);
|
|
64
47
|
config = { ...ADAPTERS.gemini };
|
|
65
48
|
}
|
|
66
49
|
|
|
67
|
-
const targetDir = process.cwd();
|
|
68
|
-
const enderunExists = fs.existsSync(path.join(targetDir, ".enderun"));
|
|
69
|
-
const hasUnifiedFlag = process.argv.includes("--unified");
|
|
70
|
-
const isTesting = process.env.VITEST === "true" || process.env.NODE_ENV === "test";
|
|
71
|
-
|
|
72
|
-
let forceEnderun = (enderunExists && !isTesting) || hasUnifiedFlag;
|
|
73
|
-
try {
|
|
74
|
-
const pkgPath = path.join(targetDir, "package.json");
|
|
75
|
-
if (fs.existsSync(pkgPath)) {
|
|
76
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
77
|
-
if (pkg.enderun && (pkg.enderun.frameworkDir === ".enderun" || pkg.enderun.frameworkDir === "unified")) {
|
|
78
|
-
if (isTesting && config.frameworkDir !== ".enderun") {
|
|
79
|
-
if (config.id !== "cursor" && config.id !== "codex") {
|
|
80
|
-
forceEnderun = false;
|
|
81
|
-
} else {
|
|
82
|
-
forceEnderun = true;
|
|
83
|
-
}
|
|
84
|
-
} else {
|
|
85
|
-
forceEnderun = true;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
} catch {
|
|
90
|
-
// ignore
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (forceEnderun) {
|
|
94
|
-
config.frameworkDir = ".enderun";
|
|
95
|
-
config.nestedDirs = ["agents", "skills", "knowledge"];
|
|
96
|
-
}
|
|
97
|
-
|
|
98
50
|
return config;
|
|
99
51
|
}
|
|
100
52
|
|
|
@@ -147,8 +99,8 @@ export function remapFrameworkContent(
|
|
|
147
99
|
if (config.paths.tests) tests = config.paths.tests;
|
|
148
100
|
}
|
|
149
101
|
}
|
|
150
|
-
} catch {
|
|
151
|
-
|
|
102
|
+
} catch (err) {
|
|
103
|
+
logger.debug("Failed to read config.json in remapFrameworkContent", err);
|
|
152
104
|
}
|
|
153
105
|
|
|
154
106
|
result = result.replace(/\{\{BACKEND_DIR\}\}/g, backend);
|
|
@@ -169,15 +121,15 @@ export function buildMcpServerEntry(projectRoot: string) {
|
|
|
169
121
|
};
|
|
170
122
|
}
|
|
171
123
|
|
|
172
|
-
export function
|
|
124
|
+
export function scaffoldAgents(projectRoot: string, adapterId: AdapterId, dryRun: boolean): void {
|
|
173
125
|
const adapter = ADAPTERS[adapterId];
|
|
174
|
-
if (!adapter || !adapter.
|
|
126
|
+
if (!adapter || !adapter.agentsDir || !adapter.agentsExt) return;
|
|
175
127
|
|
|
176
|
-
const
|
|
177
|
-
const fileExt = adapter.
|
|
128
|
+
const destAgentsDir = path.join(projectRoot, adapter.agentsDir);
|
|
129
|
+
const fileExt = adapter.agentsExt;
|
|
178
130
|
|
|
179
131
|
try {
|
|
180
|
-
fs.mkdirSync(
|
|
132
|
+
if (!dryRun) fs.mkdirSync(destAgentsDir, { recursive: true });
|
|
181
133
|
|
|
182
134
|
const GLOB_MAP: Record<string, string> = {
|
|
183
135
|
backend: "apps/backend/**/*",
|
|
@@ -200,11 +152,17 @@ export function generateAdapterAgentRules(projectRoot: string, frameworkDir: str
|
|
|
200
152
|
const description = agent.description || "";
|
|
201
153
|
const systemPrompt = agent.instructions || "";
|
|
202
154
|
const glob = GLOB_MAP[name] || "*";
|
|
203
|
-
const ruleDestPath = path.join(destRulesDir, `${name}${fileExt}`);
|
|
204
155
|
|
|
205
|
-
|
|
156
|
+
// Support nested format for Antigravity-CLI standard if needed
|
|
157
|
+
const isAntigravity = adapterId === "antigravity-cli";
|
|
158
|
+
const agentDir = isAntigravity ? path.join(destAgentsDir, name) : destAgentsDir;
|
|
159
|
+
const agentFileName = isAntigravity ? "agent.md" : `${name}${fileExt}`;
|
|
160
|
+
|
|
161
|
+
if (isAntigravity && !dryRun) fs.mkdirSync(agentDir, { recursive: true });
|
|
162
|
+
|
|
163
|
+
let content: string;
|
|
206
164
|
if (fileExt === ".mdc") {
|
|
207
|
-
|
|
165
|
+
content = `---
|
|
208
166
|
description: Agent Enderun — @${name} rules for ${displayName}. ${description.slice(0, 100)}
|
|
209
167
|
globs: ${glob}
|
|
210
168
|
alwaysApply: false
|
|
@@ -215,9 +173,9 @@ alwaysApply: false
|
|
|
215
173
|
You are the **${displayName}** of the Agent Enderun Army.
|
|
216
174
|
|
|
217
175
|
## 🏛️ Hierarchy of Authority
|
|
218
|
-
1. **Supreme Law:** [
|
|
219
|
-
2. **Global Rules:** [
|
|
220
|
-
3. **Project Memory:** [
|
|
176
|
+
1. **Supreme Law:** [\`.enderun/ENDERUN.md\`](\`.enderun/ENDERUN.md\`)
|
|
177
|
+
2. **Global Rules:** [\`.enderun/knowledge/architecture-standards.md\`](\`.enderun/knowledge/architecture-standards.md\`), [\`.enderun/knowledge/security-standards.md\`](\`.enderun/knowledge/security-standards.md\`)
|
|
178
|
+
3. **Project Memory:** [\`.enderun/memory/PROJECT_MEMORY.md\`](\`.enderun/memory/PROJECT_MEMORY.md\`)
|
|
221
179
|
|
|
222
180
|
## 🤖 Specialist Directive (Role: @${name})
|
|
223
181
|
${systemPrompt}
|
|
@@ -227,15 +185,21 @@ ${systemPrompt}
|
|
|
227
185
|
- **Traceability:** Inherit and pass the active Trace ID across all delegations.
|
|
228
186
|
- **Approval Signature:** High-risk actions require manager approval signature.
|
|
229
187
|
`;
|
|
188
|
+
} else if (isAntigravity) {
|
|
189
|
+
// Antigravity-CLI specific JSON
|
|
190
|
+
content = buildAgentJson(agent);
|
|
191
|
+
if (!dryRun) fs.writeFileSync(path.join(agentDir, "agent.json"), content);
|
|
192
|
+
// Also write MD rule
|
|
193
|
+
content = `# 🎖️ Agent Enderun — @${name} (${displayName})\n\n${systemPrompt}`;
|
|
230
194
|
} else {
|
|
231
|
-
|
|
195
|
+
content = `# 🎖️ Agent Enderun — @${name} (${displayName})
|
|
232
196
|
|
|
233
197
|
You are the **${displayName}** of the Agent Enderun Army.
|
|
234
198
|
|
|
235
199
|
## 🏛️ Hierarchy of Authority
|
|
236
|
-
1. **Supreme Law:** [
|
|
237
|
-
2. **Global Rules:** [
|
|
238
|
-
3. **Project Memory:** [
|
|
200
|
+
1. **Supreme Law:** [\`.enderun/ENDERUN.md\`](\`.enderun/ENDERUN.md\`)
|
|
201
|
+
2. **Global Rules:** [\`.enderun/knowledge/architecture-standards.md\`](\`.enderun/knowledge/architecture-standards.md\`)
|
|
202
|
+
3. **Project Memory:** [\`.enderun/memory/PROJECT_MEMORY.md\`](\`.enderun/memory/PROJECT_MEMORY.md\`)
|
|
239
203
|
|
|
240
204
|
## 🤖 Specialist Directive (Role: @${name})
|
|
241
205
|
${systemPrompt}
|
|
@@ -243,19 +207,20 @@ ${systemPrompt}
|
|
|
243
207
|
## 🛡️ Core Mandates
|
|
244
208
|
- **Surgical Precision:** Enforce replace_text / replace_file_content for all code modifications.
|
|
245
209
|
- **Traceability:** Inherit and pass the active Trace ID across all delegations.
|
|
246
|
-
- **Approval Signature:** High-risk actions require manager approval signature.
|
|
247
210
|
`;
|
|
248
211
|
}
|
|
249
212
|
|
|
250
|
-
|
|
213
|
+
if (!dryRun) {
|
|
214
|
+
const finalPath = isAntigravity ? path.join(agentDir, "agent.md") : path.join(agentDir, agentFileName);
|
|
215
|
+
fs.writeFileSync(finalPath, content);
|
|
216
|
+
}
|
|
251
217
|
}
|
|
252
|
-
console.warn(`✅ Generated 13 Agent
|
|
218
|
+
console.warn(`✅ Generated 13 Agent/Rule definitions under ${path.relative(projectRoot, destAgentsDir)}/`);
|
|
253
219
|
} catch (e) {
|
|
254
|
-
console.warn(`⚠️ Failed to
|
|
220
|
+
console.warn(`⚠️ Failed to scaffold agents: ${e}`);
|
|
255
221
|
}
|
|
256
222
|
}
|
|
257
223
|
|
|
258
|
-
|
|
259
224
|
export function runAdapterPostInit(adapter: AdapterConfig, projectRoot: string): void {
|
|
260
225
|
const mcpEntry = buildMcpServerEntry(projectRoot);
|
|
261
226
|
const mcpBlock = { mcpServers: { "agent-enderun": mcpEntry } };
|
|
@@ -263,7 +228,7 @@ export function runAdapterPostInit(adapter: AdapterConfig, projectRoot: string):
|
|
|
263
228
|
const postInitFn = POST_INIT_MAP[adapter.id];
|
|
264
229
|
if (postInitFn) {
|
|
265
230
|
postInitFn(projectRoot, mcpBlock);
|
|
266
|
-
|
|
231
|
+
// We handle agent scaffolding centrally now in initCommand
|
|
267
232
|
}
|
|
268
233
|
|
|
269
234
|
const rootMcpPath = path.join(projectRoot, "mcp.json");
|
|
@@ -5,6 +5,7 @@ import { execSync } from "child_process";
|
|
|
5
5
|
import { getFrameworkDir, getMemoryPath, getConfiguredPaths } from "../utils/memory.js";
|
|
6
6
|
import { getPackageVersion, getValidatorPath } from "../utils/pkg.js";
|
|
7
7
|
import { UI } from "../utils/ui.js";
|
|
8
|
+
import { logger } from "../../shared/logger.js";
|
|
8
9
|
|
|
9
10
|
const FRAMEWORK_VERSION = getPackageVersion();
|
|
10
11
|
|
|
@@ -40,8 +41,8 @@ export function checkCommand() {
|
|
|
40
41
|
isFrameworkDevelopment = true;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
} catch {
|
|
44
|
-
|
|
44
|
+
} catch (err) {
|
|
45
|
+
logger.debug("Failed to read package.json in checkCommand", err);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
const checks = [
|
|
@@ -53,6 +54,17 @@ export function checkCommand() {
|
|
|
53
54
|
{ name: "MCP Config (mcp.json)", path: "mcp.json" },
|
|
54
55
|
{ name: "ESLint Config (eslint.config.js)", path: "eslint.config.js", optional: !isFrameworkDevelopment },
|
|
55
56
|
{ name: "ESLint Standards", path: path.join(frameworkDir, `${knowledgeDir}/eslint-standards.md`) },
|
|
57
|
+
{ name: "CRUD Governance Standards", path: path.join(frameworkDir, `${knowledgeDir}/crud-governance.md`) },
|
|
58
|
+
{ name: "Architecture Standards", path: path.join(frameworkDir, `${knowledgeDir}/architecture-standards.md`) },
|
|
59
|
+
{ name: "Frontend Standards", path: path.join(frameworkDir, `${knowledgeDir}/frontend-standards.md`) },
|
|
60
|
+
{ name: "Tailwind Standards", path: path.join(frameworkDir, `${knowledgeDir}/tailwind-standards.md`), optional: true },
|
|
61
|
+
{ name: "Mobile Standards", path: path.join(frameworkDir, `${knowledgeDir}/mobile-standards.md`) },
|
|
62
|
+
{ name: "Security Standards", path: path.join(frameworkDir, `${knowledgeDir}/security-standards.md`) },
|
|
63
|
+
{ name: "Quality & Discipline Standards", path: path.join(frameworkDir, `${knowledgeDir}/quality-standards.md`) },
|
|
64
|
+
{ name: "Logging & Secrets Standards", path: path.join(frameworkDir, `${knowledgeDir}/logging-and-secrets.md`) },
|
|
65
|
+
{ name: "Testing Standards", path: path.join(frameworkDir, `${knowledgeDir}/testing-standards.md`) },
|
|
66
|
+
{ name: "i18n Standards", path: path.join(frameworkDir, `${knowledgeDir}/i18n-standards.md`) },
|
|
67
|
+
{ name: ".env.example", path: ".env.example" },
|
|
56
68
|
...(isFrameworkDevelopment ? [{ name: "MCP Server", path: "framework-mcp/package.json" }] : []),
|
|
57
69
|
{ name: "Panda CSS Config", path: appPandaPath, optional: true },
|
|
58
70
|
{ name: "Brain Dashboard", path: path.join(frameworkDir, "BRAIN_DASHBOARD.md") },
|
|
@@ -95,6 +107,14 @@ export function checkCommand() {
|
|
|
95
107
|
UI.success("No forbidden 'console.log' detected.");
|
|
96
108
|
}
|
|
97
109
|
|
|
110
|
+
const anyUsageIssues = checkAnyUsage();
|
|
111
|
+
if (anyUsageIssues.length > 0) {
|
|
112
|
+
UI.error(`Forbidden 'any' type usage found in ${anyUsageIssues.length} locations.`);
|
|
113
|
+
issues++;
|
|
114
|
+
} else {
|
|
115
|
+
UI.success("No forbidden 'any' type usage detected.");
|
|
116
|
+
}
|
|
117
|
+
|
|
98
118
|
const rootTestFiles = checkRootTestFiles();
|
|
99
119
|
if (rootTestFiles.length > 0) {
|
|
100
120
|
UI.warning(`Test files found in the root directory: ${rootTestFiles.join(", ")}. It is recommended to place all test files under the 'tests/' folder or application-specific directories.`);
|
|
@@ -103,8 +123,9 @@ export function checkCommand() {
|
|
|
103
123
|
try {
|
|
104
124
|
execSync("npx tsc --noEmit", { stdio: "pipe" });
|
|
105
125
|
UI.success("TypeScript type check PASSED.");
|
|
106
|
-
} catch {
|
|
126
|
+
} catch (err) {
|
|
107
127
|
UI.error("TypeScript type check FAILED.");
|
|
128
|
+
logger.debug("npx tsc --noEmit check failed", err);
|
|
108
129
|
issues++;
|
|
109
130
|
}
|
|
110
131
|
|
|
@@ -146,8 +167,9 @@ export function checkCommand() {
|
|
|
146
167
|
} else {
|
|
147
168
|
console.warn("\n📊 Token Consumption Report: No token usage logged yet.");
|
|
148
169
|
}
|
|
149
|
-
} catch {
|
|
170
|
+
} catch (err) {
|
|
150
171
|
console.warn("\n📊 Token Consumption Report: Could not read or parse metrics file.");
|
|
172
|
+
logger.debug("Failed to read or parse metrics.json in checkCommand", err);
|
|
151
173
|
}
|
|
152
174
|
} else {
|
|
153
175
|
console.warn("\n📊 Token Consumption Report: No token usage logged yet.");
|
|
@@ -184,6 +206,30 @@ function checkConsoleLogs(): string[] {
|
|
|
184
206
|
return issues;
|
|
185
207
|
}
|
|
186
208
|
|
|
209
|
+
function checkAnyUsage(): string[] {
|
|
210
|
+
const issues: string[] = [];
|
|
211
|
+
const srcDir = path.join(process.cwd(), "src");
|
|
212
|
+
if (!fs.existsSync(srcDir)) return [];
|
|
213
|
+
|
|
214
|
+
const walk = (dir: string) => {
|
|
215
|
+
const files = fs.readdirSync(dir);
|
|
216
|
+
for (const file of files) {
|
|
217
|
+
const fullPath = path.join(dir, file);
|
|
218
|
+
if (fs.statSync(fullPath).isDirectory()) walk(fullPath);
|
|
219
|
+
else if (file.endsWith(".ts") && !file.includes(".test.")) {
|
|
220
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
221
|
+
// Match ": any", "<any>", "as any" but try to avoid false positives in comments if possible
|
|
222
|
+
const anyRegex = /[:<]\s*any\b|\bas\s+any\b/g;
|
|
223
|
+
if (anyRegex.test(content) && !fullPath.includes("check.ts") && !fullPath.includes("definitions.ts")) {
|
|
224
|
+
issues.push(fullPath);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
walk(srcDir);
|
|
230
|
+
return issues;
|
|
231
|
+
}
|
|
232
|
+
|
|
187
233
|
function checkRootTestFiles(): string[] {
|
|
188
234
|
const rootDir = process.cwd();
|
|
189
235
|
if (!fs.existsSync(rootDir)) return [];
|
|
@@ -197,8 +243,8 @@ function checkRootTestFiles(): string[] {
|
|
|
197
243
|
testFiles.push(file);
|
|
198
244
|
}
|
|
199
245
|
}
|
|
200
|
-
} catch {
|
|
201
|
-
|
|
246
|
+
} catch (err) {
|
|
247
|
+
logger.debug(`Failed to stat file ${fullPath} in checkRootTestFiles`, err);
|
|
202
248
|
}
|
|
203
249
|
}
|
|
204
250
|
return testFiles;
|