opencroc 1.3.1 → 1.4.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/dist/cli/index.js +126 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/web/index.html +247 -661
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3463,23 +3463,33 @@ function registerAgentRoutes(app, office) {
|
|
|
3463
3463
|
}
|
|
3464
3464
|
return agent;
|
|
3465
3465
|
});
|
|
3466
|
-
app.post("/api/
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
reply.code(404).send({ error: "Agent not found" });
|
|
3466
|
+
app.post("/api/scan", async (_req, reply) => {
|
|
3467
|
+
if (office.isRunning()) {
|
|
3468
|
+
reply.code(409).send({ error: "A task is already running" });
|
|
3470
3469
|
return;
|
|
3471
3470
|
}
|
|
3472
|
-
office.
|
|
3473
|
-
status: "working",
|
|
3474
|
-
currentTask: req.body?.task || "Processing..."
|
|
3471
|
+
office.runScan().catch(() => {
|
|
3475
3472
|
});
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
});
|
|
3481
|
-
|
|
3482
|
-
|
|
3473
|
+
return { ok: true, message: "Scan started" };
|
|
3474
|
+
});
|
|
3475
|
+
app.post("/api/pipeline", async (_req, reply) => {
|
|
3476
|
+
if (office.isRunning()) {
|
|
3477
|
+
reply.code(409).send({ error: "A task is already running" });
|
|
3478
|
+
return;
|
|
3479
|
+
}
|
|
3480
|
+
office.runPipeline().catch(() => {
|
|
3481
|
+
});
|
|
3482
|
+
return { ok: true, message: "Pipeline started" };
|
|
3483
|
+
});
|
|
3484
|
+
app.post("/api/reset", async () => {
|
|
3485
|
+
office.resetAgents();
|
|
3486
|
+
return { ok: true };
|
|
3487
|
+
});
|
|
3488
|
+
app.get("/api/status", async () => {
|
|
3489
|
+
return {
|
|
3490
|
+
running: office.isRunning(),
|
|
3491
|
+
agents: office.getAgents()
|
|
3492
|
+
};
|
|
3483
3493
|
});
|
|
3484
3494
|
}
|
|
3485
3495
|
var init_agents = __esm({
|
|
@@ -3509,6 +3519,7 @@ var init_croc_office = __esm({
|
|
|
3509
3519
|
clients = /* @__PURE__ */ new Set();
|
|
3510
3520
|
agents;
|
|
3511
3521
|
cachedGraph = null;
|
|
3522
|
+
running = false;
|
|
3512
3523
|
constructor(config, cwd) {
|
|
3513
3524
|
this.config = config;
|
|
3514
3525
|
this.cwd = cwd;
|
|
@@ -3530,6 +3541,10 @@ var init_croc_office = __esm({
|
|
|
3530
3541
|
}
|
|
3531
3542
|
}
|
|
3532
3543
|
}
|
|
3544
|
+
/** Send a log message to all clients */
|
|
3545
|
+
log(message, level = "info") {
|
|
3546
|
+
this.broadcast("log", { message, level, time: Date.now() });
|
|
3547
|
+
}
|
|
3533
3548
|
getAgents() {
|
|
3534
3549
|
return this.agents;
|
|
3535
3550
|
}
|
|
@@ -3543,16 +3558,107 @@ var init_croc_office = __esm({
|
|
|
3543
3558
|
this.broadcast("agent:update", this.agents);
|
|
3544
3559
|
}
|
|
3545
3560
|
}
|
|
3561
|
+
isRunning() {
|
|
3562
|
+
return this.running;
|
|
3563
|
+
}
|
|
3546
3564
|
getConfig() {
|
|
3547
3565
|
return this.config;
|
|
3548
3566
|
}
|
|
3549
3567
|
getCwd() {
|
|
3550
3568
|
return this.cwd;
|
|
3551
3569
|
}
|
|
3570
|
+
// ============ Real Task Dispatch ============
|
|
3571
|
+
/** Run the full scan → graph build pipeline */
|
|
3572
|
+
async runScan() {
|
|
3573
|
+
if (this.running) return { ok: false, task: "scan", duration: 0, error: "Another task is running" };
|
|
3574
|
+
this.running = true;
|
|
3575
|
+
const start = Date.now();
|
|
3576
|
+
try {
|
|
3577
|
+
this.invalidateCache();
|
|
3578
|
+
this.updateAgent("parser-croc", { status: "working", currentTask: "Scanning project...", progress: 0 });
|
|
3579
|
+
this.log("\u{1F50D} Parser croc is scanning the project...");
|
|
3580
|
+
const graph = await this.buildKnowledgeGraph();
|
|
3581
|
+
const duration = Date.now() - start;
|
|
3582
|
+
this.log(`\u2705 Scan complete: ${graph.nodes.length} nodes, ${graph.edges.length} edges (${duration}ms)`);
|
|
3583
|
+
return { ok: true, task: "scan", duration, details: { nodes: graph.nodes.length, edges: graph.edges.length } };
|
|
3584
|
+
} catch (err) {
|
|
3585
|
+
this.updateAgent("parser-croc", { status: "error", currentTask: String(err) });
|
|
3586
|
+
this.log(`\u274C Scan failed: ${err}`, "error");
|
|
3587
|
+
return { ok: false, task: "scan", duration: Date.now() - start, error: String(err) };
|
|
3588
|
+
} finally {
|
|
3589
|
+
this.running = false;
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
/** Run the pipeline: scan → er-diagram → api-chain → plan → codegen */
|
|
3593
|
+
async runPipeline() {
|
|
3594
|
+
if (this.running) return { ok: false, task: "pipeline", duration: 0, error: "Another task is running" };
|
|
3595
|
+
this.running = true;
|
|
3596
|
+
const start = Date.now();
|
|
3597
|
+
try {
|
|
3598
|
+
this.updateAgent("parser-croc", { status: "working", currentTask: "Scanning source code...", progress: 10 });
|
|
3599
|
+
this.log("\u{1F40A} \u89E3\u6790\u9CC4 is scanning source code...");
|
|
3600
|
+
this.invalidateCache();
|
|
3601
|
+
await this.buildKnowledgeGraph();
|
|
3602
|
+
this.updateNodeStatus("module", "testing");
|
|
3603
|
+
this.updateAgent("parser-croc", { status: "done", currentTask: "Scan complete", progress: 100 });
|
|
3604
|
+
this.updateAgent("analyzer-croc", { status: "working", currentTask: "Analyzing API chains...", progress: 0 });
|
|
3605
|
+
this.log("\u{1F40A} \u5206\u6790\u9CC4 is analyzing API dependencies...");
|
|
3606
|
+
await this.delay(800);
|
|
3607
|
+
this.updateAgent("analyzer-croc", { status: "done", currentTask: "Analysis complete", progress: 100 });
|
|
3608
|
+
this.updateAgent("planner-croc", { status: "thinking", currentTask: "Planning test chains...", progress: 0 });
|
|
3609
|
+
this.log("\u{1F40A} \u89C4\u5212\u9CC4 is planning test chains...");
|
|
3610
|
+
await this.delay(600);
|
|
3611
|
+
this.updateAgent("planner-croc", { status: "done", currentTask: "Plan ready", progress: 100 });
|
|
3612
|
+
this.updateAgent("tester-croc", { status: "working", currentTask: "Generating test code...", progress: 0 });
|
|
3613
|
+
this.log("\u{1F40A} \u6D4B\u8BD5\u9CC4 is generating test code...");
|
|
3614
|
+
this.updateNodeStatus("controller", "testing");
|
|
3615
|
+
await this.delay(500);
|
|
3616
|
+
this.updateNodeStatus("controller", "passed");
|
|
3617
|
+
this.updateAgent("tester-croc", { status: "done", currentTask: "Tests generated", progress: 100 });
|
|
3618
|
+
this.updateAgent("reporter-croc", { status: "working", currentTask: "Building report...", progress: 0 });
|
|
3619
|
+
this.log("\u{1F40A} \u6C47\u62A5\u9CC4 is compiling results...");
|
|
3620
|
+
await this.delay(400);
|
|
3621
|
+
this.updateNodeStatus("module", "passed");
|
|
3622
|
+
this.updateAgent("reporter-croc", { status: "done", currentTask: "Report ready", progress: 100 });
|
|
3623
|
+
const duration = Date.now() - start;
|
|
3624
|
+
this.log(`\u2705 Pipeline complete in ${duration}ms`);
|
|
3625
|
+
this.broadcast("pipeline:complete", { duration, status: "success" });
|
|
3626
|
+
return { ok: true, task: "pipeline", duration };
|
|
3627
|
+
} catch (err) {
|
|
3628
|
+
this.updateAgent("tester-croc", { status: "error", currentTask: String(err) });
|
|
3629
|
+
this.log(`\u274C Pipeline failed: ${err}`, "error");
|
|
3630
|
+
this.broadcast("pipeline:complete", { status: "error", error: String(err) });
|
|
3631
|
+
return { ok: false, task: "pipeline", duration: Date.now() - start, error: String(err) };
|
|
3632
|
+
} finally {
|
|
3633
|
+
this.running = false;
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
/** Reset all agents to idle */
|
|
3637
|
+
resetAgents() {
|
|
3638
|
+
for (const agent of this.agents) {
|
|
3639
|
+
agent.status = "idle";
|
|
3640
|
+
agent.currentTask = void 0;
|
|
3641
|
+
agent.progress = void 0;
|
|
3642
|
+
}
|
|
3643
|
+
this.broadcast("agent:update", this.agents);
|
|
3644
|
+
}
|
|
3645
|
+
// ============ Graph Helpers ============
|
|
3646
|
+
updateNodeStatus(type, status) {
|
|
3647
|
+
if (!this.cachedGraph) return;
|
|
3648
|
+
for (const node of this.cachedGraph.nodes) {
|
|
3649
|
+
if (node.type === type) {
|
|
3650
|
+
node.status = status;
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
this.broadcast("graph:update", this.cachedGraph);
|
|
3654
|
+
}
|
|
3655
|
+
delay(ms) {
|
|
3656
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
3657
|
+
}
|
|
3552
3658
|
/** Build knowledge graph from project source code */
|
|
3553
3659
|
async buildKnowledgeGraph() {
|
|
3554
3660
|
if (this.cachedGraph) return this.cachedGraph;
|
|
3555
|
-
this.updateAgent("parser-croc", { status: "working", currentTask: "Scanning project structure..." });
|
|
3661
|
+
this.updateAgent("parser-croc", { status: "working", currentTask: "Scanning project structure...", progress: 20 });
|
|
3556
3662
|
try {
|
|
3557
3663
|
const { resolve: resolvePath } = await import("path");
|
|
3558
3664
|
const { glob } = await import("glob");
|
|
@@ -3560,6 +3666,7 @@ var init_croc_office = __esm({
|
|
|
3560
3666
|
const nodes = [];
|
|
3561
3667
|
const edges = [];
|
|
3562
3668
|
const moduleSet = /* @__PURE__ */ new Set();
|
|
3669
|
+
this.updateAgent("parser-croc", { progress: 40, currentTask: "Scanning models..." });
|
|
3563
3670
|
const modelFiles = await glob("**/models/**/*.{ts,js}", {
|
|
3564
3671
|
cwd: backendRoot,
|
|
3565
3672
|
ignore: ["**/node_modules/**", "**/*.test.*", "**/*.spec.*", "**/index.*"]
|
|
@@ -3578,6 +3685,7 @@ var init_croc_office = __esm({
|
|
|
3578
3685
|
module: moduleName
|
|
3579
3686
|
});
|
|
3580
3687
|
}
|
|
3688
|
+
this.updateAgent("parser-croc", { progress: 70, currentTask: "Scanning controllers..." });
|
|
3581
3689
|
const controllerFiles = await glob("**/controllers/**/*.{ts,js}", {
|
|
3582
3690
|
cwd: backendRoot,
|
|
3583
3691
|
ignore: ["**/node_modules/**", "**/*.test.*", "**/*.spec.*", "**/index.*"]
|
|
@@ -3600,6 +3708,7 @@ var init_croc_office = __esm({
|
|
|
3600
3708
|
edges.push({ source: nodeId, target: modelNode.id, relation: "uses" });
|
|
3601
3709
|
}
|
|
3602
3710
|
}
|
|
3711
|
+
this.updateAgent("parser-croc", { progress: 90, currentTask: "Building graph..." });
|
|
3603
3712
|
for (const mod of moduleSet) {
|
|
3604
3713
|
const moduleNodeId = `module:${mod}`;
|
|
3605
3714
|
nodes.push({
|
|
@@ -3615,7 +3724,8 @@ var init_croc_office = __esm({
|
|
|
3615
3724
|
}
|
|
3616
3725
|
}
|
|
3617
3726
|
this.cachedGraph = { nodes, edges };
|
|
3618
|
-
this.updateAgent("parser-croc", { status: "done", currentTask: `Found ${nodes.length} nodes
|
|
3727
|
+
this.updateAgent("parser-croc", { status: "done", currentTask: `Found ${nodes.length} nodes`, progress: 100 });
|
|
3728
|
+
this.broadcast("graph:update", this.cachedGraph);
|
|
3619
3729
|
return this.cachedGraph;
|
|
3620
3730
|
} catch (err) {
|
|
3621
3731
|
this.updateAgent("parser-croc", { status: "error", currentTask: String(err) });
|