agent-enderun 0.8.8 ā 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.enderun/BRAIN_DASHBOARD.md +5 -5
- package/{ENDERUN.md ā .enderun/ENDERUN.md} +4 -2
- package/.enderun/PROJECT_MEMORY.md +32 -43
- package/.enderun/STATUS.md +25 -28
- package/.enderun/agents/agent_army_schema.json +29 -7
- package/.enderun/agents/backend.md +48 -39
- package/.enderun/agents/database.md +55 -0
- package/.enderun/agents/devops.md +30 -17
- package/.enderun/agents/explorer.md +5 -5
- package/.enderun/agents/frontend.md +97 -76
- package/.enderun/agents/git.md +4 -4
- package/.enderun/agents/manager.md +68 -59
- package/.enderun/agents/mobile.md +4 -4
- package/.enderun/agents/native.md +106 -0
- package/.enderun/agents/quality.md +122 -0
- package/.enderun/agents/schema/agent-lifecycle-schema.json +29 -8
- package/.enderun/cli-commands.json +7 -3
- package/.enderun/config.json +8 -2
- package/.enderun/knowledge/SHIM_TEMPLATE.md +25 -0
- package/.enderun/knowledge/context_boundary_rules.md +57 -0
- package/.enderun/knowledge/corporate-governance/high-risk-action-approval-flow.md +29 -0
- package/.enderun/knowledge/documentation_ownership.md +53 -0
- package/.enderun/knowledge/eslint-standards.md +63 -0
- package/.enderun/knowledge/frontend_professionalization_guidelines.md +7 -7
- package/.enderun/knowledge/hermes_live_test_guidelines.md +5 -5
- package/.enderun/knowledge/hermes_protocol.md +1 -1
- package/.enderun/knowledge/lessons-learned.md +14 -0
- package/.enderun/knowledge/manager_authority_audit_enforcement.md +10 -10
- package/.enderun/knowledge/project_scaffold_guidelines.md +4 -4
- package/.enderun/knowledge/reference_application_guidelines.md +6 -6
- package/.enderun/mcp_config.json +9 -0
- package/.enderun/memory-graph/agent-contexts/backend.json +1 -1
- package/.enderun/memory-graph/agent-contexts/devops.json +1 -1
- package/.enderun/memory-graph/agent-contexts/explorer.json +1 -1
- package/.enderun/memory-graph/agent-contexts/frontend.json +1 -1
- package/.enderun/memory-graph/agent-contexts/git.json +1 -1
- package/.enderun/memory-graph/agent-contexts/manager.json +1 -1
- package/.enderun/memory-graph/agent-contexts/mobile.json +1 -1
- package/.enderun/memory-graph/agent-contexts/native.json +1 -0
- package/.enderun/memory-graph/agent-contexts/quality.json +1 -0
- package/.enderun/memory-graph/graph.json +123 -15
- package/.enderun/memory-graph/shared-facts.json +26 -31
- package/.enderun/queue/README.md +13 -13
- package/README.md +171 -393
- package/agent.md +25 -0
- package/bin/cli.js +10 -10
- package/bin/init-check.js +69 -0
- package/bin/update-contract.js +57 -38
- package/bin/validate-agent-army.js +38 -13
- package/claude.md +14 -8
- package/docs/README.md +24 -16
- package/docs/architecture/README.md +9 -0
- package/docs/architecture/standards/data-fetching-patterns.md +13 -0
- package/docs/architecture/standards/design-system.md +31 -0
- package/docs/architecture/standards/logging.md +7 -0
- package/docs/architecture/standards/tech-stack.md +9 -0
- package/docs/getting-started.md +9 -259
- package/docs/user/README.md +35 -0
- package/docs/user/action-plan-2026.md +9 -0
- package/docs/user/getting-started.md +13 -0
- package/docs/user/roadmap.md +13 -0
- package/eslint.config.js +68 -0
- package/framework-mcp/dist/index.js +178 -24
- package/framework-mcp/package.json +6 -33
- package/framework-mcp/tsconfig.json +3 -6
- package/gemini.md +12 -6
- package/grok.md +25 -0
- package/package.json +13 -5
- package/panda.config.ts +86 -86
- package/src/cli/adapters.ts +208 -0
- package/src/cli/commands/app.ts +38 -0
- package/src/cli/commands/check.ts +87 -0
- package/src/cli/commands/compliance.ts +55 -0
- package/src/cli/commands/contract.ts +45 -0
- package/src/cli/commands/explorer.ts +45 -0
- package/src/cli/commands/git.ts +39 -0
- package/src/cli/commands/init.ts +272 -0
- package/src/cli/commands/knowledge.ts +44 -0
- package/src/cli/commands/lint.ts +25 -0
- package/src/cli/commands/log.ts +37 -0
- package/src/cli/commands/memory.ts +78 -0
- package/src/cli/commands/orchestrate.ts +111 -0
- package/src/cli/commands/script.ts +20 -0
- package/src/cli/commands/security.ts +38 -0
- package/src/cli/commands/status.ts +59 -0
- package/src/cli/commands/trace.ts +46 -0
- package/src/cli/index.ts +74 -2155
- package/src/cli/utils/app.ts +764 -0
- package/src/cli/utils/claude.ts +56 -0
- package/src/cli/utils/fs.ts +139 -0
- package/src/cli/utils/memory.ts +141 -0
- package/src/cli/utils/pkg.ts +215 -0
- package/src/cli/utils/string.ts +48 -0
- package/src/cli/utils/time.ts +27 -0
- package/tsconfig.json +9 -0
- package/.enderun/agents/analyst.md +0 -238
- package/.enderun/agents/orchestrator.md +0 -172
- package/.enderun/agents/qa.md +0 -124
- package/.enderun/agents/security.md +0 -202
- package/.enderun/knowledge/api_design_rules.md +0 -6
- package/.enderun/knowledge/branded_types_pattern.md +0 -8
- package/.enderun/knowledge/code_review_checklist.md +0 -7
- package/.enderun/knowledge/contract_versioning.md +0 -7
- package/.enderun/knowledge/database_migration.md +0 -6
- package/.enderun/knowledge/deployment_checklist.md +0 -7
- package/.enderun/knowledge/git_commit_strategy.md +0 -10
- package/.enderun/knowledge/monitoring_setup.md +0 -5
- package/.enderun/knowledge/performance_guidelines.md +0 -11
- package/.enderun/knowledge/repository_patterns.md +0 -9
- package/.enderun/knowledge/security_scanning.md +0 -6
- package/.enderun/knowledge/testing_standards.md +0 -7
- package/.enderun/knowledge/troubleshooting_guide.md +0 -5
- package/.enderun/logs/analyst.json +0 -1
- package/.enderun/logs/backend.json +0 -1
- package/.enderun/logs/devops.json +0 -1
- package/.enderun/logs/explorer.json +0 -1
- package/.enderun/logs/frontend.json +0 -1
- package/.enderun/logs/git.json +0 -1
- package/.enderun/logs/manager.json +0 -1
- package/.enderun/logs/mobile.json +0 -1
- package/.enderun/logs/native.json +0 -1
- package/.enderun/logs/orchestrator.json +0 -1
- package/.enderun/logs/qa.json +0 -1
- package/.enderun/logs/security.json +0 -1
- package/.enderun/memory-graph/agent-contexts/analyst.json +0 -1
- package/.enderun/memory-graph/agent-contexts/orchestrator.json +0 -1
- package/.enderun/memory-graph/agent-contexts/qa.json +0 -1
- package/.enderun/memory-graph/agent-contexts/security.json +0 -1
- package/.env.example +0 -10
- package/cursor.md +0 -19
- package/docs/action-plan-2026.md +0 -119
- package/docs/roadmap.md +0 -142
- package/framework-mcp/README.md +0 -55
- package/framework-mcp/dist/schemas.js +0 -84
- package/framework-mcp/dist/tools/codebase.js +0 -294
- package/framework-mcp/dist/tools/contract.js +0 -197
- package/framework-mcp/dist/tools/framework.js +0 -225
- package/framework-mcp/dist/tools/git.js +0 -51
- package/framework-mcp/dist/tools/governance.js +0 -696
- package/framework-mcp/dist/tools/index.js +0 -47
- package/framework-mcp/dist/tools/knowledge.js +0 -133
- package/framework-mcp/dist/tools/memory.js +0 -217
- package/framework-mcp/dist/tools/messages.js +0 -193
- package/framework-mcp/dist/tools/monitoring.js +0 -294
- package/framework-mcp/dist/tools/orchestration.js +0 -369
- package/framework-mcp/dist/tools/pipeline.js +0 -267
- package/framework-mcp/dist/tools/security.js +0 -137
- package/framework-mcp/dist/utils.js +0 -121
- package/framework-mcp/src/index.ts +0 -49
- package/framework-mcp/src/schemas.ts +0 -106
- package/framework-mcp/src/tools/codebase.ts +0 -284
- package/framework-mcp/src/tools/contract.ts +0 -221
- package/framework-mcp/src/tools/framework.ts +0 -223
- package/framework-mcp/src/tools/git.ts +0 -42
- package/framework-mcp/src/tools/governance.ts +0 -891
- package/framework-mcp/src/tools/index.ts +0 -50
- package/framework-mcp/src/tools/knowledge.ts +0 -141
- package/framework-mcp/src/tools/memory.ts +0 -207
- package/framework-mcp/src/tools/messages.ts +0 -213
- package/framework-mcp/src/tools/monitoring.ts +0 -351
- package/framework-mcp/src/tools/orchestration.ts +0 -440
- package/framework-mcp/src/tools/pipeline.ts +0 -353
- package/framework-mcp/src/tools/security.ts +0 -143
- package/framework-mcp/src/utils.ts +0 -130
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
import { getMemoryPath, acquireMemoryLock, releaseMemoryLock } from "../utils/memory.js";
|
|
5
|
+
|
|
6
|
+
export function updateProjectMemoryCommand(section: string, content: string) {
|
|
7
|
+
const memoryPath = getMemoryPath();
|
|
8
|
+
if (!fs.existsSync(memoryPath)) {
|
|
9
|
+
console.error("ā Error: PROJECT_MEMORY.md not found.");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const lockPath = `${memoryPath}.lock`;
|
|
14
|
+
if (!acquireMemoryLock(lockPath)) {
|
|
15
|
+
console.error("ā Error: Memory lock timeout.");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
let memoryContent = fs.readFileSync(memoryPath, "utf8");
|
|
21
|
+
|
|
22
|
+
if (section === "HISTORY") {
|
|
23
|
+
const headers = ["## HISTORY (Persistent Memory)", "## HISTORY"];
|
|
24
|
+
let sectionIndex = -1;
|
|
25
|
+
for (const h of headers) {
|
|
26
|
+
sectionIndex = memoryContent.indexOf(h);
|
|
27
|
+
if (sectionIndex !== -1) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (sectionIndex === -1) {
|
|
33
|
+
console.error("ā Error: HISTORY section not found.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const headerEnd = memoryContent.indexOf("\n", sectionIndex) + 1;
|
|
37
|
+
memoryContent =
|
|
38
|
+
memoryContent.slice(0, headerEnd) +
|
|
39
|
+
`\n${content.trim()}\n` +
|
|
40
|
+
memoryContent.slice(headerEnd);
|
|
41
|
+
|
|
42
|
+
// --- Auto-Prune Logic ---
|
|
43
|
+
const historySplit = memoryContent.split("### ");
|
|
44
|
+
if (historySplit.length > 11) { // Title + 10 entries
|
|
45
|
+
const frameworkDir = path.dirname(memoryPath);
|
|
46
|
+
const archiveDir = path.join(frameworkDir, "archive/history");
|
|
47
|
+
if (!fs.existsSync(archiveDir)) fs.mkdirSync(archiveDir, { recursive: true });
|
|
48
|
+
|
|
49
|
+
const toArchive = historySplit.slice(11); // Keep the first 10 entries (newest)
|
|
50
|
+
const preserved = historySplit.slice(0, 11);
|
|
51
|
+
|
|
52
|
+
const archiveContent = "### " + toArchive.join("### ");
|
|
53
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
54
|
+
fs.writeFileSync(path.join(archiveDir, `history-${timestamp}.md`), archiveContent);
|
|
55
|
+
|
|
56
|
+
memoryContent = preserved.join("### ").trim() + "\n";
|
|
57
|
+
console.warn(`š¦ Auto-Pruned: ${toArchive.length} old entries moved to archive.`);
|
|
58
|
+
}
|
|
59
|
+
// ------------------------
|
|
60
|
+
} else {
|
|
61
|
+
const escaped = section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62
|
+
const sectionRegex = new RegExp(`## ${escaped}[\\s\\S]*?(?=\\n## |$)`, "m");
|
|
63
|
+
if (!sectionRegex.test(memoryContent)) {
|
|
64
|
+
console.error(`ā Error: Section not found: ${section}`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
memoryContent = memoryContent.replace(
|
|
68
|
+
sectionRegex,
|
|
69
|
+
`## ${section}\n\n${content.trim()}\n`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fs.writeFileSync(memoryPath, memoryContent);
|
|
74
|
+
console.warn(`ā
Section ${section} updated in PROJECT_MEMORY.md`);
|
|
75
|
+
} finally {
|
|
76
|
+
releaseMemoryLock(lockPath);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
import { getFrameworkDir } from "../utils/memory.js";
|
|
5
|
+
|
|
6
|
+
interface HermesMessage {
|
|
7
|
+
timestamp: string;
|
|
8
|
+
from: string;
|
|
9
|
+
to: string;
|
|
10
|
+
category: "ACTION" | "DELEGATION" | "INFO" | "ALERT";
|
|
11
|
+
traceId: string;
|
|
12
|
+
content: string;
|
|
13
|
+
status: "PENDING" | "PROCESSED";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Start the live Hermes Orchestration & Message Loop
|
|
18
|
+
*/
|
|
19
|
+
export function orchestrateCommand() {
|
|
20
|
+
const frameworkDir = getFrameworkDir();
|
|
21
|
+
const messagesDir = path.join(process.cwd(), frameworkDir, "messages");
|
|
22
|
+
const statusPath = path.join(process.cwd(), frameworkDir, "STATUS.md");
|
|
23
|
+
|
|
24
|
+
console.log(`\n================================================================`);
|
|
25
|
+
console.log(`šļø AGENT ENDERUN ā DYNAMIC HERMES ORCHESTRATĆR DĆNGĆSĆ`);
|
|
26
|
+
console.log(`================================================================`);
|
|
27
|
+
console.log(`š°ļø Hermes Message Broker dinleniyor: ${frameworkDir}/messages/...`);
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(messagesDir)) {
|
|
30
|
+
fs.mkdirSync(messagesDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Scan all JSON files in the messages directory
|
|
34
|
+
const messageFiles = fs.readdirSync(messagesDir).filter(f => f.endsWith(".json"));
|
|
35
|
+
const pendingMessages: HermesMessage[] = [];
|
|
36
|
+
|
|
37
|
+
for (const file of messageFiles) {
|
|
38
|
+
const filePath = path.join(messagesDir, file);
|
|
39
|
+
try {
|
|
40
|
+
const content = fs.readFileSync(filePath, "utf8").trim();
|
|
41
|
+
if (!content) continue;
|
|
42
|
+
// Messages are stored as newline-delimited JSON
|
|
43
|
+
const lines = content.split("\n");
|
|
44
|
+
lines.forEach((line, index) => {
|
|
45
|
+
if (!line.trim()) return;
|
|
46
|
+
const msg = JSON.parse(line) as HermesMessage;
|
|
47
|
+
if (msg.status === "PENDING") {
|
|
48
|
+
pendingMessages.push(msg);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
} catch (e) {
|
|
52
|
+
// ignore malformed lines
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (pendingMessages.length === 0) {
|
|
57
|
+
console.log(`\nš¢ Kuyruk Temiz: İÅlenecek aktif Hermes mesajı bulunamadı.`);
|
|
58
|
+
console.log(`š” İpucu: Bir uzman ajanı tetiklemek iƧin send_agent_message aracını kullanın.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(`\nš„ Kuyrukta ${pendingMessages.length} adet bekleyen Hermes mesajı tespit edildi:\n`);
|
|
63
|
+
|
|
64
|
+
// Process the first pending message
|
|
65
|
+
const activeMessage = pendingMessages[0];
|
|
66
|
+
const toAgent = activeMessage.to;
|
|
67
|
+
const fromAgent = activeMessage.from;
|
|
68
|
+
|
|
69
|
+
console.log(`āļø [GĆNDEREN] : ${fromAgent}`);
|
|
70
|
+
console.log(`š„ [ALICI] : ${toAgent}`);
|
|
71
|
+
console.log(`š [TRACE ID] : ${activeMessage.traceId}`);
|
|
72
|
+
console.log(`š·ļø [KATEGORİ] : ${activeMessage.category}`);
|
|
73
|
+
console.log(`š¬ [MESAJ] : "${activeMessage.content}"`);
|
|
74
|
+
console.log(`----------------------------------------------------------------`);
|
|
75
|
+
|
|
76
|
+
// 1. Transition the target agent state to EXECUTING in STATUS.md
|
|
77
|
+
console.log(`ā³ Ajan Durum GeƧiÅi: ${toAgent} durumu EXECUTING olarak kilitleniyor...`);
|
|
78
|
+
transitionAgentState(statusPath, toAgent, "EXECUTING", activeMessage.content);
|
|
79
|
+
|
|
80
|
+
console.log(`\nš¤ Gƶrev Devredildi!`);
|
|
81
|
+
console.log(`š Lütfen ${toAgent} agent talimatlarını (${frameworkDir}/agents/${toAgent.replace("@", "")}.md) okuyun ve gƶrevi yerine getirin.`);
|
|
82
|
+
console.log(`š” Gƶrev tamamlandıÄında, mesajı PROCESSED olarak iÅaretlemek ve ajanı boÅa Ƨıkarmak iƧin:`);
|
|
83
|
+
console.log(` npx agent-enderun status komutuyla kontrol edin.`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function transitionAgentState(statusPath: string, agent: string, state: string, task: string) {
|
|
87
|
+
if (!fs.existsSync(statusPath)) return;
|
|
88
|
+
try {
|
|
89
|
+
let content = fs.readFileSync(statusPath, "utf8");
|
|
90
|
+
const lines = content.split("\n");
|
|
91
|
+
const targetName = agent;
|
|
92
|
+
|
|
93
|
+
for (let i = 0; i < lines.length; i++) {
|
|
94
|
+
if (lines[i].includes(`| ${targetName} |`)) {
|
|
95
|
+
// e.g., | @backend | IDLE | ā | ā | 9.2/10 | ā |
|
|
96
|
+
const parts = lines[i].split("|");
|
|
97
|
+
if (parts.length >= 7) {
|
|
98
|
+
parts[2] = ` ${state} `;
|
|
99
|
+
parts[3] = ` ${task.slice(0, 20)}... `;
|
|
100
|
+
lines[i] = parts.join("|");
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
fs.writeFileSync(statusPath, lines.join("\n"));
|
|
107
|
+
console.log(`ā
STATUS.md üzerinde ${agent} durumu baÅarıyla '${state}' yapıldı.`);
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.error("ā STATUS.md güncellenirken hata oluÅtu:", e);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import cp from "child_process";
|
|
4
|
+
|
|
5
|
+
const targetDir = process.cwd(); // Assuming targetDir is process.cwd() in the CLI context
|
|
6
|
+
|
|
7
|
+
export function runScriptCommand(script: string, projectPath: string) {
|
|
8
|
+
const fullPath = path.join(targetDir, projectPath);
|
|
9
|
+
if (!fs.existsSync(fullPath)) {
|
|
10
|
+
console.warn(`ā Project path not found: ${projectPath}`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.warn(`š Running 'npm run ${script}' in ${projectPath}...`);
|
|
14
|
+
try {
|
|
15
|
+
cp.spawnSync("npm", ["run", script], { cwd: fullPath, stdio: "inherit", shell: true });
|
|
16
|
+
} catch (e: unknown) {
|
|
17
|
+
const message = e instanceof Error ? e.message : "Unknown error";
|
|
18
|
+
console.warn(`ā Failed to run script: ${message}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
import { collectFiles } from "../utils/fs.js";
|
|
5
|
+
|
|
6
|
+
const targetDir = process.cwd();
|
|
7
|
+
|
|
8
|
+
export function securityAuditCommand(targetPath: string) {
|
|
9
|
+
console.warn(`š Running Advanced Security Audit on: ${targetPath}...`);
|
|
10
|
+
const scanRules = [
|
|
11
|
+
{ pattern: /sql`/, message: "Potential Raw SQL usage detected", severity: "HIGH" },
|
|
12
|
+
{
|
|
13
|
+
pattern: /(password|secret|api_?key)\s*[:=]\s*['"][^'"]+['"]/i,
|
|
14
|
+
message: "Potential hardcoded secret detected",
|
|
15
|
+
severity: "CRITICAL",
|
|
16
|
+
},
|
|
17
|
+
{ pattern: /:\s*any(?!\w)/, message: "Usage of 'any' type detected", severity: "MEDIUM" },
|
|
18
|
+
{ pattern: /\.innerHTML\s*=/, message: "Unsafe innerHTML assignment detected", severity: "MEDIUM" },
|
|
19
|
+
];
|
|
20
|
+
const issues: string[] = [];
|
|
21
|
+
const files = collectFiles(path.join(targetDir, targetPath), [".ts", ".tsx", ".js", ".jsx"]);
|
|
22
|
+
files.forEach((f) => {
|
|
23
|
+
const content = fs.readFileSync(f, "utf8");
|
|
24
|
+
const lines = content.split("\n");
|
|
25
|
+
lines.forEach((line, i) => {
|
|
26
|
+
scanRules.forEach((rule) => {
|
|
27
|
+
if (rule.pattern.test(line)) {
|
|
28
|
+
issues.push(`[${rule.severity}] ${rule.message} in ${path.relative(targetDir, f)}:${i + 1}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
if (issues.length === 0) {
|
|
34
|
+
console.warn("ā
No security issues detected.");
|
|
35
|
+
} else {
|
|
36
|
+
issues.forEach((issue) => console.warn(`ā ļø ${issue}`));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
|
|
3
|
+
import { getMemoryPath, getFrameworkDir } from "../utils/memory.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Print the current framework status.
|
|
7
|
+
*/
|
|
8
|
+
export function statusCommand() {
|
|
9
|
+
const memoryPath = getMemoryPath();
|
|
10
|
+
const frameworkDir = getFrameworkDir();
|
|
11
|
+
if (!fs.existsSync(memoryPath)) {
|
|
12
|
+
console.error(`ā Error: ${frameworkDir}/PROJECT_MEMORY.md not found. Please run 'init' first.`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const content = fs.readFileSync(memoryPath, "utf8");
|
|
17
|
+
|
|
18
|
+
// Format 1: Table Style (Original)
|
|
19
|
+
const tableMatch = content.match(
|
|
20
|
+
/\| Active Phase \| Profile \| Last Update \| Active Trace ID \| Blockers \|\n\| :----------- \| :------ \| :---------- \| :-------------- \| :------- \|\n\| (.*?) \| (.*?) \| (.*?) \| (.*?) \| (.*?) \|/,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// Format 2: List Style (New)
|
|
24
|
+
const phaseMatch = content.match(/- Phase: (.*)/);
|
|
25
|
+
const traceIdMatch = content.match(/- Trace ID: (.*)/);
|
|
26
|
+
const profileMatch = content.match(/- Profile: (.*)/);
|
|
27
|
+
const updateMatch = content.match(/- Last Update: (.*)/);
|
|
28
|
+
const blockersMatch = content.match(/- Blockers: (.*)/);
|
|
29
|
+
|
|
30
|
+
console.warn("\nš --- PROJECT STATUS ---");
|
|
31
|
+
|
|
32
|
+
if (tableMatch) {
|
|
33
|
+
console.warn(`š¹ Phase: ${tableMatch[1].trim()}`);
|
|
34
|
+
console.warn(`š§ Profile: ${tableMatch[2].trim()}`);
|
|
35
|
+
console.warn(`š
Update: ${tableMatch[3].trim()}`);
|
|
36
|
+
console.warn(`š Trace ID: ${tableMatch[4].trim()}`);
|
|
37
|
+
console.warn(`ā Blockers: ${tableMatch[5].trim()}`);
|
|
38
|
+
} else if (phaseMatch || traceIdMatch) {
|
|
39
|
+
if (phaseMatch) console.warn(`š¹ Phase: ${phaseMatch[1].trim()}`);
|
|
40
|
+
if (profileMatch) console.warn(`š§ Profile: ${profileMatch[1].trim()}`);
|
|
41
|
+
if (updateMatch) console.warn(`š
Update: ${updateMatch[1].trim()}`);
|
|
42
|
+
if (traceIdMatch) console.warn(`š Trace ID: ${traceIdMatch[1].trim()}`);
|
|
43
|
+
if (blockersMatch) console.warn(`ā Blockers: ${blockersMatch[1].trim()}`);
|
|
44
|
+
|
|
45
|
+
// Check for manager state in list style
|
|
46
|
+
const managerState = content.match(/- @manager state: (.*)/);
|
|
47
|
+
if (managerState) console.warn(`š¤ Manager: ${managerState[1].trim()}`);
|
|
48
|
+
} else {
|
|
49
|
+
console.warn("ā ļø Status data could not be parsed in standard formats.");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const tasksSection = content.match(/## ACTIVE TASKS\n\n([\s\S]*?)(?=\n##|$)/);
|
|
53
|
+
if (tasksSection) {
|
|
54
|
+
console.warn("\nš Active Tasks:");
|
|
55
|
+
console.warn(tasksSection[1].trim());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.warn("\n-----------------------\n");
|
|
59
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
|
|
3
|
+
import { getMemoryPath, acquireMemoryLock, releaseMemoryLock } from "../utils/memory.js";
|
|
4
|
+
import { generateULID } from "../utils/time.js";
|
|
5
|
+
import { sanitizeTableCell, normalizeAgentName, normalizePriority, insertTaskRow } from "../utils/string.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate a new Trace ID and add it to project memory.
|
|
9
|
+
*/
|
|
10
|
+
export function traceNewCommand(description: string, agent = "manager", priority = "P2"): string | void {
|
|
11
|
+
const memoryPath = getMemoryPath();
|
|
12
|
+
if (!fs.existsSync(memoryPath)) {
|
|
13
|
+
console.error("ā Error: PROJECT_MEMORY.md not found.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const traceId = generateULID();
|
|
18
|
+
const safeDescription = sanitizeTableCell(description);
|
|
19
|
+
const safeAgent = normalizeAgentName(agent);
|
|
20
|
+
const safePriority = normalizePriority(priority);
|
|
21
|
+
const newTask = `| ${traceId} | ${safeDescription} | @${safeAgent} | ${safePriority} | IN_PROGRESS |`;
|
|
22
|
+
const lockPath = `${memoryPath}.lock`;
|
|
23
|
+
|
|
24
|
+
if (!acquireMemoryLock(lockPath)) {
|
|
25
|
+
console.error("ā Error: Memory lock timeout (5 retries).");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const content = fs.readFileSync(memoryPath, "utf8");
|
|
31
|
+
const updated = insertTaskRow(content, newTask);
|
|
32
|
+
if (!updated) {
|
|
33
|
+
console.error("ā Error: ACTIVE TASKS table not found, task could not be added.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fs.writeFileSync(memoryPath, updated);
|
|
38
|
+
console.warn(`
|
|
39
|
+
ā
New Trace ID created: ${traceId}`);
|
|
40
|
+
console.warn(`š Added to task list: ${description}
|
|
41
|
+
`);
|
|
42
|
+
return traceId;
|
|
43
|
+
} finally {
|
|
44
|
+
releaseMemoryLock(lockPath);
|
|
45
|
+
}
|
|
46
|
+
}
|