sdlc-agent-4-enterprise-server 1.19.0 → 1.20.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 +3 -2
- package/dist/config/CoreTools.js +1 -0
- package/dist/config/CoreTools.js.map +1 -1
- package/dist/engine/graph/__tests__/graph-isolation.test.js +10 -4
- package/dist/engine/graph/__tests__/graph-isolation.test.js.map +1 -1
- package/dist/engine/graph/__tests__/graph-sync-service.test.js +11 -11
- package/dist/engine/graph/__tests__/graph-sync-service.test.js.map +1 -1
- package/dist/engine/tools/__tests__/drawio-tool.test.d.ts +5 -0
- package/dist/engine/tools/__tests__/drawio-tool.test.js +165 -0
- package/dist/engine/tools/__tests__/drawio-tool.test.js.map +1 -0
- package/dist/engine/tools/drawio-apply.d.ts +20 -0
- package/dist/engine/tools/drawio-apply.js +166 -0
- package/dist/engine/tools/drawio-apply.js.map +1 -0
- package/dist/engine/tools/drawio-layout-models.d.ts +50 -0
- package/dist/engine/tools/drawio-layout-models.js +2 -0
- package/dist/engine/tools/drawio-layout-models.js.map +1 -0
- package/dist/engine/tools/drawio-tool.d.ts +24 -7
- package/dist/engine/tools/drawio-tool.js +68 -53
- package/dist/engine/tools/drawio-tool.js.map +1 -1
- package/dist/engine/tools/drawio-writer.d.ts +6 -6
- package/dist/engine/tools/drawio-writer.js +73 -104
- package/dist/engine/tools/drawio-writer.js.map +1 -1
- package/dist/engine/tools/elk-layout.d.ts +8 -0
- package/dist/engine/tools/elk-layout.js +114 -0
- package/dist/engine/tools/elk-layout.js.map +1 -0
- package/dist/engine/tools/layout-models.d.ts +68 -0
- package/dist/engine/tools/layout-models.js +2 -0
- package/dist/engine/tools/layout-models.js.map +1 -0
- package/dist/engine/tools/register-tools.d.ts +27 -0
- package/dist/modules/memory/llm/analyzer.js +6 -5
- package/dist/modules/memory/llm/analyzer.js.map +1 -1
- package/dist/modules/memory/task-queue/__tests__/TaskWorker.it.test.js +7 -3
- package/dist/modules/memory/task-queue/__tests__/TaskWorker.it.test.js.map +1 -1
- package/package.json +2 -1
- package/src/config/CoreTools.ts +1 -0
- package/src/engine/graph/__tests__/graph-isolation.test.ts +10 -4
- package/src/engine/graph/__tests__/graph-sync-service.test.ts +11 -11
- package/src/engine/tools/__tests__/drawio-tool.test.ts +179 -0
- package/src/engine/tools/drawio-apply.ts +170 -0
- package/src/engine/tools/drawio-layout-models.ts +45 -0
- package/src/engine/tools/drawio-tool.ts +76 -53
- package/src/engine/tools/drawio-writer.ts +76 -109
- package/src/engine/tools/elk-layout.ts +126 -0
- package/src/engine/tools/layout-models.ts +62 -0
- package/src/modules/memory/llm/analyzer.ts +5 -4
- package/src/modules/memory/task-queue/__tests__/TaskWorker.it.test.ts +7 -3
- package/tests/integration/mcp-tools.test.ts +1 -1
- package/tests/integration/reindex.it.test.ts +5 -4
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<img src="https://img.shields.io/badge/version-1.
|
|
9
|
+
<img src="https://img.shields.io/badge/version-1.19.1-blue?style=for-the-badge" alt="Version">
|
|
10
10
|
<img src="https://img.shields.io/badge/tools-66+-teal?style=for-the-badge" alt="Tools">
|
|
11
11
|
<img src="https://img.shields.io/badge/node-%3E%3D18-green?style=for-the-badge" alt="Node">
|
|
12
12
|
</p>
|
|
@@ -38,7 +38,7 @@ Server starts at **http://localhost:48721**. Verify it's running:
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
curl http://localhost:48721/health
|
|
41
|
-
# → {"status":"healthy","version":"1.
|
|
41
|
+
# → {"status":"healthy","version":"1.19.1","uptime":5,"tools_loaded":52}
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
### Development Mode (auto-reload)
|
|
@@ -233,6 +233,7 @@ The embedding model is expected at `.code-intel/models/model.onnx`. Download it:
|
|
|
233
233
|
|
|
234
234
|
| Version | Date | Ticket | Changes |
|
|
235
235
|
|---------|------|--------|---------|
|
|
236
|
+
| 1.19.1 | 2026-07-31 | SA4E-81 | Version alignment with extension release. No backend code changes in this release. |
|
|
236
237
|
| 1.18.0 | 2026-07-31 | SA4E-79 | Client-Side LLM Knowledge Enrichment hardening: `handleIngestFile`/`handleIngest` always mark `pending` + enqueue TAG_ENRICHMENT (NEW-01/NEW-06/NEW-10), TaskWorker tags/structured_map conditional updates as race guards (NEW-03), USER-scoped entries enrichable without projectId (NEW-07), pending section LIMIT 3→10 (NEW-09). FTS fix: `knowledge_fts` auto-rebuild at startup when empty — restores `mem_search` for pre-existing entries. |
|
|
237
238
|
| 1.17.0 | 2026-07-30 | SA4E-77 | Pega Knowledge Graph: categorized node types (PROCESS, DECISION, DATA_MODEL, UI, etc.), config-driven mapping (`pega-categories.json`), Pega-mode color switching in graph legend. Code/KB split uses entry_id prefix. Dashboard includes Pega rules in codeSymbols. isPega flag in /positions API. |
|
|
238
239
|
| 1.16.0 | 2026-07-25 | — | Memory Evolution Levels L4-L6 (Collective Graph, Skill/Procedural Memory, Reflective Consolidation) implemented with real backend services and graph algorithms. Admin configuration checks resilience for Zen Upstream, TaskWorker endpoints, user management, and dynamic Admin Web UI. |
|
package/dist/config/CoreTools.js
CHANGED
|
@@ -15,6 +15,7 @@ export const CORE_TOOLS = [
|
|
|
15
15
|
'pega_get_rule', 'pega_get_session_context',
|
|
16
16
|
'pega_query_rule', 'pega_list_rules', 'pega_save_rule',
|
|
17
17
|
'pega_checkout_rule', 'pega_run_tests', 'pega_get_class_metadata',
|
|
18
|
+
'pega_create_branch',
|
|
18
19
|
];
|
|
19
20
|
/**
|
|
20
21
|
* Normalize allowlist: drop invalid (BR-05), de-dup (BR-08),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoreTools.js","sourceRoot":"","sources":["../../src/config/CoreTools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,YAAY,EAAE,sBAAsB,EAAE,sBAAsB;CACpD,CAAC;AAEX,sFAAsF;AACtF,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,YAAY,EAAE,YAAY,EAAE,iBAAiB;IAC7C,aAAa,EAAE,qBAAqB;IACpC,YAAY,EAAE,sBAAsB,EAAE,sBAAsB;IAC5D,mBAAmB,EAAE,oBAAoB;IACzC,eAAe,EAAE,0BAA0B;IAC3C,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB;IACtD,oBAAoB,EAAE,gBAAgB,EAAE,yBAAyB;
|
|
1
|
+
{"version":3,"file":"CoreTools.js","sourceRoot":"","sources":["../../src/config/CoreTools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,YAAY,EAAE,sBAAsB,EAAE,sBAAsB;CACpD,CAAC;AAEX,sFAAsF;AACtF,MAAM,CAAC,MAAM,UAAU,GAAsB;IAC3C,YAAY,EAAE,YAAY,EAAE,iBAAiB;IAC7C,aAAa,EAAE,qBAAqB;IACpC,YAAY,EAAE,sBAAsB,EAAE,sBAAsB;IAC5D,mBAAmB,EAAE,oBAAoB;IACzC,eAAe,EAAE,0BAA0B;IAC3C,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB;IACtD,oBAAoB,EAAE,gBAAgB,EAAE,yBAAyB;IACjE,oBAAoB;CACZ,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAClD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QAC3B,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE;YAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,4CAA4C,CAAC,CAAC;QAClF,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,GAAG,CAAS,CAAC,GAAG,KAAK,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -74,19 +74,25 @@ describe('SA4E-41 SEC-01 graph tool isolation (two tenants)', () => {
|
|
|
74
74
|
expect(res.results.every(r => r.symbol !== 'callerAlpha')).toBe(true);
|
|
75
75
|
expect(res.results.some(r => r.symbol === 'callerBravo')).toBe(true);
|
|
76
76
|
});
|
|
77
|
-
it('FileResolver only sees its own tenant files', () => {
|
|
77
|
+
it('FileResolver only sees its own tenant files', async () => {
|
|
78
78
|
// Both tenants use the same relative path; each resolver resolves it, but the
|
|
79
79
|
// underlying set is scoped (fail-closed variant proven to return null).
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
const frB = new FileResolver(new SqliteDbAdapter(db), '/w', PID_B);
|
|
81
|
+
await frB.ready();
|
|
82
|
+
expect(frB.resolveFile('src/app.ts')).toBe('src/app.ts');
|
|
83
|
+
const frNone = new FileResolver(new SqliteDbAdapter(db), '/w', undefined);
|
|
84
|
+
await frNone.ready();
|
|
85
|
+
expect(frNone.resolveFile('src/app.ts')).toBeNull();
|
|
82
86
|
});
|
|
83
|
-
it('DependencyGraphService outgoing deps are tenant-scoped', () => {
|
|
87
|
+
it('DependencyGraphService outgoing deps are tenant-scoped', async () => {
|
|
84
88
|
const fr = new FileResolver(new SqliteDbAdapter(db), '/w', PID_B);
|
|
89
|
+
await fr.ready();
|
|
85
90
|
const dep = new DependencyGraphService(new SqliteDbAdapter(db), fr, PID_B);
|
|
86
91
|
const res = dep.query('src/app.ts', 'outgoing', 1, true, 50);
|
|
87
92
|
expect(res.root).toBe('src/app.ts');
|
|
88
93
|
// Fail-closed variant returns nothing.
|
|
89
94
|
const frNone = new FileResolver(new SqliteDbAdapter(db), '/w', undefined);
|
|
95
|
+
await frNone.ready();
|
|
90
96
|
const depNone = new DependencyGraphService(new SqliteDbAdapter(db), frNone, undefined);
|
|
91
97
|
expect(depNone.query('src/app.ts', 'outgoing', 1, true, 50).results.length).toBe(0);
|
|
92
98
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-isolation.test.js","sourceRoot":"","sources":["../../../../src/engine/graph/__tests__/graph-isolation.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"graph-isolation.test.js","sourceRoot":"","sources":["../../../../src/engine/graph/__tests__/graph-isolation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,31 +44,31 @@ describe('SA4E-41 GraphSyncService', () => {
|
|
|
44
44
|
adminDb.prepare(`INSERT INTO graph_nodes (entry_id, label, type, tier, project_id) VALUES ('doc-1', 'KB', 'CONTEXT', 'SEMANTIC', ?)`).run(PID_A);
|
|
45
45
|
});
|
|
46
46
|
afterEach(() => { indexDb.close(); adminDb.close(); });
|
|
47
|
-
it('projects only the target tenant code nodes', () => {
|
|
48
|
-
new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols(PID_B);
|
|
47
|
+
it('projects only the target tenant code nodes', async () => {
|
|
48
|
+
await new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols(PID_B);
|
|
49
49
|
const codeNodes = adminDb.prepare("SELECT project_id FROM graph_nodes WHERE entry_id LIKE 'code:%'").all();
|
|
50
50
|
expect(codeNodes.length).toBe(1);
|
|
51
51
|
expect(codeNodes.every(n => n.project_id === PID_B)).toBe(true);
|
|
52
52
|
});
|
|
53
|
-
it('does not create code nodes for other tenants', () => {
|
|
54
|
-
new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols(PID_B);
|
|
53
|
+
it('does not create code nodes for other tenants', async () => {
|
|
54
|
+
await new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols(PID_B);
|
|
55
55
|
const aCode = adminDb.prepare("SELECT COUNT(*) c FROM graph_nodes WHERE entry_id LIKE 'code:%' AND project_id = ?").get(PID_A);
|
|
56
56
|
expect(aCode.c).toBe(0);
|
|
57
57
|
});
|
|
58
|
-
it('leaves KB (non-code) nodes untouched', () => {
|
|
59
|
-
new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols(PID_B);
|
|
58
|
+
it('leaves KB (non-code) nodes untouched', async () => {
|
|
59
|
+
await new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols(PID_B);
|
|
60
60
|
const kb = adminDb.prepare("SELECT COUNT(*) c FROM graph_nodes WHERE entry_id = 'doc-1'").get();
|
|
61
61
|
expect(kb.c).toBe(1);
|
|
62
62
|
});
|
|
63
|
-
it('is idempotent (re-sync replaces, does not duplicate)', () => {
|
|
63
|
+
it('is idempotent (re-sync replaces, does not duplicate)', async () => {
|
|
64
64
|
const svc = new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log);
|
|
65
|
-
svc.syncProjectSymbols(PID_B);
|
|
66
|
-
svc.syncProjectSymbols(PID_B);
|
|
65
|
+
await svc.syncProjectSymbols(PID_B);
|
|
66
|
+
await svc.syncProjectSymbols(PID_B);
|
|
67
67
|
const count = adminDb.prepare("SELECT COUNT(*) c FROM graph_nodes WHERE entry_id LIKE 'code:%' AND project_id = ?").get(PID_B);
|
|
68
68
|
expect(count.c).toBe(1);
|
|
69
69
|
});
|
|
70
|
-
it('fail-closed: empty projectId is a no-op', () => {
|
|
71
|
-
new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols('');
|
|
70
|
+
it('fail-closed: empty projectId is a no-op', async () => {
|
|
71
|
+
await new GraphSyncService(new SqliteDbAdapter(indexDb), new SqliteDbAdapter(adminDb), log).syncProjectSymbols('');
|
|
72
72
|
const count = adminDb.prepare("SELECT COUNT(*) c FROM graph_nodes WHERE entry_id LIKE 'code:%'").get();
|
|
73
73
|
expect(count.c).toBe(0);
|
|
74
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-sync-service.test.js","sourceRoot":"","sources":["../../../../src/engine/graph/__tests__/graph-sync-service.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,KAAK,GAAG,WAAW,CAAC;AAC1B,MAAM,KAAK,GAAG,WAAW,CAAC;AAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEtC,MAAM,YAAY,GAAG;;;;;;CAMpB,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;CAKpB,CAAC;AAEF,SAAS,WAAW,CAAC,EAAqB,EAAE,GAAW,EAAE,KAAe;IACtE,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,uGAAuG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC;IAC3J,MAAM,MAAM,GAAG,KAAK,CAAC,eAAyB,CAAC;IAC/C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,+IAA+I,CAAC,CAAC;IACxK,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,IAAI,OAA0B,CAAC;IAC/B,IAAI,OAA0B,CAAC;IAE/B,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/D,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/D,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QACtD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1C,mEAAmE;QACnE,OAAO,CAAC,OAAO,CAAC,oHAAoH,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnJ,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvD,EAAE,CAAC,4CAA4C,EAAE,
|
|
1
|
+
{"version":3,"file":"graph-sync-service.test.js","sourceRoot":"","sources":["../../../../src/engine/graph/__tests__/graph-sync-service.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,KAAK,GAAG,WAAW,CAAC;AAC1B,MAAM,KAAK,GAAG,WAAW,CAAC;AAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEtC,MAAM,YAAY,GAAG;;;;;;CAMpB,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;CAKpB,CAAC;AAEF,SAAS,WAAW,CAAC,EAAqB,EAAE,GAAW,EAAE,KAAe;IACtE,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,uGAAuG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC;IAC3J,MAAM,MAAM,GAAG,KAAK,CAAC,eAAyB,CAAC;IAC/C,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,+IAA+I,CAAC,CAAC;IACxK,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,IAAI,OAA0B,CAAC;IAC/B,IAAI,OAA0B,CAAC;IAE/B,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/D,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/D,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QACtD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1C,mEAAmE;QACnE,OAAO,CAAC,OAAO,CAAC,oHAAoH,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnJ,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvD,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,IAAI,gBAAgB,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACtH,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC,GAAG,EAA8B,CAAC;QACvI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,IAAI,gBAAgB,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACtH,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,oFAAoF,CAAC,CAAC,GAAG,CAAC,KAAK,CAAQ,CAAC;QACtI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,IAAI,gBAAgB,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACtH,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,6DAA6D,CAAC,CAAC,GAAG,EAAS,CAAC;QACvG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,GAAG,GAAG,IAAI,gBAAgB,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;QAClG,MAAM,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,oFAAoF,CAAC,CAAC,GAAG,CAAC,KAAK,CAAQ,CAAC;QACtI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,IAAI,gBAAgB,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACnH,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC,GAAG,EAAS,CAAC;QAC9G,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SA4E-84 — Unit tests for drawio_auto_layout (FIX mode).
|
|
3
|
+
* Tests: input validation, issue detection, auto-fix via ELK, file write.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect } from 'vitest';
|
|
6
|
+
import { handleDrawioLayout, DRAWIO_TOOL_DEFINITION, detectAllIssues } from '../drawio-tool.js';
|
|
7
|
+
import { normalizeLayoutArgs } from '../drawio-apply.js';
|
|
8
|
+
import { parseDrawio } from '../drawio-parser.js';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as os from 'os';
|
|
12
|
+
// Clean diagram — no issues expected
|
|
13
|
+
const SIMPLE_DIAGRAM = `<?xml version="1.0" encoding="UTF-8"?>
|
|
14
|
+
<mxfile><diagram name="Page-1" id="test">
|
|
15
|
+
<mxGraphModel><root>
|
|
16
|
+
<mxCell id="0"/>
|
|
17
|
+
<mxCell id="1" parent="0"/>
|
|
18
|
+
<mxCell id="n1" value="A" style="rounded=1;" vertex="1" parent="1">
|
|
19
|
+
<mxGeometry x="40" y="40" width="120" height="60" as="geometry"/>
|
|
20
|
+
</mxCell>
|
|
21
|
+
<mxCell id="n2" value="B" style="rounded=1;" vertex="1" parent="1">
|
|
22
|
+
<mxGeometry x="240" y="40" width="120" height="60" as="geometry"/>
|
|
23
|
+
</mxCell>
|
|
24
|
+
<mxCell id="e1" value="" style="edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="n1" target="n2">
|
|
25
|
+
<mxGeometry relative="1" as="geometry"/>
|
|
26
|
+
</mxCell>
|
|
27
|
+
</root></mxGraphModel></diagram></mxfile>`;
|
|
28
|
+
// Bad layout — overlapping nodes
|
|
29
|
+
const BAD_LAYOUT_DIAGRAM = `<?xml version="1.0" encoding="UTF-8"?>
|
|
30
|
+
<mxfile><diagram name="Page-1" id="test">
|
|
31
|
+
<mxGraphModel><root>
|
|
32
|
+
<mxCell id="0"/>
|
|
33
|
+
<mxCell id="1" parent="0"/>
|
|
34
|
+
<mxCell id="n1" value="A" style="rounded=1;" vertex="1" parent="1">
|
|
35
|
+
<mxGeometry x="40" y="40" width="120" height="60" as="geometry"/>
|
|
36
|
+
</mxCell>
|
|
37
|
+
<mxCell id="n2" value="B" style="rounded=1;" vertex="1" parent="1">
|
|
38
|
+
<mxGeometry x="50" y="50" width="120" height="60" as="geometry"/>
|
|
39
|
+
</mxCell>
|
|
40
|
+
<mxCell id="n3" value="C" style="rounded=1;" vertex="1" parent="1">
|
|
41
|
+
<mxGeometry x="240" y="40" width="120" height="60" as="geometry"/>
|
|
42
|
+
</mxCell>
|
|
43
|
+
<mxCell id="e1" value="" style="edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="n1" target="n3">
|
|
44
|
+
<mxGeometry relative="1" as="geometry"/>
|
|
45
|
+
</mxCell>
|
|
46
|
+
</root></mxGraphModel></diagram></mxfile>`;
|
|
47
|
+
describe('DRAWIO_TOOL_DEFINITION', () => {
|
|
48
|
+
it('has correct tool name', () => {
|
|
49
|
+
expect(DRAWIO_TOOL_DEFINITION.name).toBe('drawio_auto_layout');
|
|
50
|
+
});
|
|
51
|
+
it('requires file_path', () => {
|
|
52
|
+
expect(DRAWIO_TOOL_DEFINITION.inputSchema.required).toContain('file_path');
|
|
53
|
+
});
|
|
54
|
+
it('does not have mode property (always fix)', () => {
|
|
55
|
+
const props = DRAWIO_TOOL_DEFINITION.inputSchema.properties;
|
|
56
|
+
expect(props.mode).toBeUndefined();
|
|
57
|
+
});
|
|
58
|
+
it('has algorithm, spacing, direction optional params', () => {
|
|
59
|
+
const props = DRAWIO_TOOL_DEFINITION.inputSchema.properties;
|
|
60
|
+
expect(props.algorithm).toBeDefined();
|
|
61
|
+
expect(props.spacing).toBeDefined();
|
|
62
|
+
expect(props.direction).toBeDefined();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe('detectAllIssues', () => {
|
|
66
|
+
it('detects node overlaps', () => {
|
|
67
|
+
const tmp = writeTmp(BAD_LAYOUT_DIAGRAM);
|
|
68
|
+
const { graph } = parseDrawio(tmp);
|
|
69
|
+
const issues = detectAllIssues(graph);
|
|
70
|
+
const overlaps = issues.filter(i => i.type === 'node_overlap');
|
|
71
|
+
expect(overlaps.length).toBeGreaterThan(0);
|
|
72
|
+
cleanup(tmp);
|
|
73
|
+
});
|
|
74
|
+
it('returns no issues for clean diagram', () => {
|
|
75
|
+
const tmp = writeTmp(SIMPLE_DIAGRAM);
|
|
76
|
+
const { graph } = parseDrawio(tmp);
|
|
77
|
+
const issues = detectAllIssues(graph);
|
|
78
|
+
expect(issues.length).toBe(0);
|
|
79
|
+
cleanup(tmp);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('handleDrawioLayout — input validation', () => {
|
|
83
|
+
it('returns error when file_path missing', async () => {
|
|
84
|
+
const result = await handleDrawioLayout({}, os.tmpdir());
|
|
85
|
+
const parsed = JSON.parse(result);
|
|
86
|
+
expect(parsed.error).toContain('file_path is required');
|
|
87
|
+
});
|
|
88
|
+
it('returns error when file does not exist', async () => {
|
|
89
|
+
const result = await handleDrawioLayout({ file_path: path.join(os.tmpdir(), 'nonexistent-xyz.drawio') }, os.tmpdir());
|
|
90
|
+
const parsed = JSON.parse(result);
|
|
91
|
+
expect(parsed.error).toContain('File not found');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
describe('handleDrawioLayout — already_good', () => {
|
|
95
|
+
it('returns already_good for clean diagram', async () => {
|
|
96
|
+
const tmp = writeTmp(SIMPLE_DIAGRAM);
|
|
97
|
+
const workspace = path.dirname(path.dirname(tmp)); // parent of temp dir
|
|
98
|
+
const result = await handleDrawioLayout({ file_path: tmp }, workspace);
|
|
99
|
+
const parsed = JSON.parse(result);
|
|
100
|
+
expect(parsed.status).toBe('already_good');
|
|
101
|
+
expect(parsed.message).toBeDefined();
|
|
102
|
+
// No extra fields (token saving)
|
|
103
|
+
expect(parsed.nodes).toBeUndefined();
|
|
104
|
+
expect(parsed.edges).toBeUndefined();
|
|
105
|
+
expect(parsed.issues).toBeUndefined();
|
|
106
|
+
// File should NOT be modified
|
|
107
|
+
const after = fs.readFileSync(tmp, 'utf-8');
|
|
108
|
+
expect(after).toBe(SIMPLE_DIAGRAM);
|
|
109
|
+
cleanup(tmp);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('handleDrawioLayout — auto-fix', () => {
|
|
113
|
+
it('fixes overlapping diagram and writes to file', async () => {
|
|
114
|
+
const tmp = writeTmp(BAD_LAYOUT_DIAGRAM);
|
|
115
|
+
const workspace = path.dirname(path.dirname(tmp));
|
|
116
|
+
const result = await handleDrawioLayout({ file_path: tmp, algorithm: 'layered', direction: 'DOWN' }, workspace);
|
|
117
|
+
const parsed = JSON.parse(result);
|
|
118
|
+
if (parsed.error)
|
|
119
|
+
throw new Error(`Unexpected error: ${parsed.error}`);
|
|
120
|
+
expect(parsed.status).toBe('fixed');
|
|
121
|
+
expect(parsed.message).toContain('nodes repositioned');
|
|
122
|
+
// Minimal response — no extra fields
|
|
123
|
+
expect(parsed.repositioned_nodes).toBeUndefined();
|
|
124
|
+
expect(parsed.content_base64).toBeUndefined();
|
|
125
|
+
expect(parsed.issues).toBeUndefined();
|
|
126
|
+
// File should be modified
|
|
127
|
+
const after = fs.readFileSync(tmp, 'utf-8');
|
|
128
|
+
expect(after).not.toBe(BAD_LAYOUT_DIAGRAM);
|
|
129
|
+
expect(after).toContain('<mxCell');
|
|
130
|
+
cleanup(tmp);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe('normalizeLayoutArgs', () => {
|
|
134
|
+
it('returns defaults for empty args', () => {
|
|
135
|
+
const result = normalizeLayoutArgs({});
|
|
136
|
+
expect(result.algorithm).toBe('layered');
|
|
137
|
+
expect(result.spacing).toBe(80);
|
|
138
|
+
expect(result.direction).toBe('DOWN');
|
|
139
|
+
});
|
|
140
|
+
it('normalizes direction to uppercase', () => {
|
|
141
|
+
const result = normalizeLayoutArgs({ direction: 'right' });
|
|
142
|
+
expect(result.direction).toBe('RIGHT');
|
|
143
|
+
});
|
|
144
|
+
it('falls back invalid algorithm to layered', () => {
|
|
145
|
+
const result = normalizeLayoutArgs({ algorithm: 'invalid' });
|
|
146
|
+
expect(result.algorithm).toBe('layered');
|
|
147
|
+
});
|
|
148
|
+
it('falls back negative spacing to 80', () => {
|
|
149
|
+
const result = normalizeLayoutArgs({ spacing: -10 });
|
|
150
|
+
expect(result.spacing).toBe(80);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
function writeTmp(xml) {
|
|
154
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'drawio-test-'));
|
|
155
|
+
const file = path.join(dir, 'test.drawio');
|
|
156
|
+
fs.writeFileSync(file, xml, 'utf-8');
|
|
157
|
+
return file;
|
|
158
|
+
}
|
|
159
|
+
function cleanup(file) {
|
|
160
|
+
try {
|
|
161
|
+
fs.rmSync(path.dirname(file), { recursive: true, force: true });
|
|
162
|
+
}
|
|
163
|
+
catch { /* ignore */ }
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=drawio-tool.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawio-tool.test.js","sourceRoot":"","sources":["../../../../src/engine/tools/__tests__/drawio-tool.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SA4E-84 — Apply orchestrator for ELK auto-layout fix mode.
|
|
3
|
+
* Coordinates: normalize args → build ELK graph → run layout → write XML → validate.
|
|
4
|
+
* Writes fixed XML directly to file. Returns metadata only (no content_base64).
|
|
5
|
+
*/
|
|
6
|
+
import type { DiagramGraph } from './drawio-parser.js';
|
|
7
|
+
import type { NormalizedArgs } from './drawio-layout-models.js';
|
|
8
|
+
/**
|
|
9
|
+
* Orchestrate ELK layout fix: build graph → run ELK → write to file → return metadata.
|
|
10
|
+
* @param rawXml - Original XML content
|
|
11
|
+
* @param graph - Parsed diagram graph
|
|
12
|
+
* @param issues - Detected issues (before fix)
|
|
13
|
+
* @param nodeCount - Total node count
|
|
14
|
+
* @param args - Tool arguments for algorithm/spacing/direction
|
|
15
|
+
* @param filePath - Absolute path to write fixed XML
|
|
16
|
+
* @returns JSON string with status, repositioned_nodes (no content_base64)
|
|
17
|
+
*/
|
|
18
|
+
export declare function handleApply(rawXml: string, graph: DiagramGraph, issues: object[], nodeCount: number, args: Record<string, unknown>, filePath: string): Promise<string>;
|
|
19
|
+
/** Normalize layout args with safe defaults and upper bounds (SEC-03). */
|
|
20
|
+
export declare function normalizeLayoutArgs(args: Record<string, unknown>): NormalizedArgs;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SA4E-84 — Apply orchestrator for ELK auto-layout fix mode.
|
|
3
|
+
* Coordinates: normalize args → build ELK graph → run layout → write XML → validate.
|
|
4
|
+
* Writes fixed XML directly to file. Returns metadata only (no content_base64).
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
import { parseDrawio } from './drawio-parser.js';
|
|
10
|
+
import { buildElkGraph, runElkLayout } from './elk-layout.js';
|
|
11
|
+
import { applyLayoutToXml } from './drawio-writer.js';
|
|
12
|
+
/**
|
|
13
|
+
* Parse an integer from environment variable with bounds validation (SEC-02).
|
|
14
|
+
* Returns defaultVal if env var is missing, NaN, out of bounds, or non-finite.
|
|
15
|
+
* @param envVar - Environment variable name
|
|
16
|
+
* @param defaultVal - Fallback value
|
|
17
|
+
* @param min - Minimum allowed value (inclusive)
|
|
18
|
+
* @param max - Maximum allowed value (inclusive)
|
|
19
|
+
*/
|
|
20
|
+
function parseEnvInt(envVar, defaultVal, min, max) {
|
|
21
|
+
const raw = process.env[envVar];
|
|
22
|
+
if (raw === undefined)
|
|
23
|
+
return defaultVal;
|
|
24
|
+
const parsed = Number(raw);
|
|
25
|
+
if (!Number.isFinite(parsed) || parsed < min || parsed > max)
|
|
26
|
+
return defaultVal;
|
|
27
|
+
return Math.floor(parsed);
|
|
28
|
+
}
|
|
29
|
+
// BR-7: configurable limits via env (NFR-P5) — with bounds validation (SEC-02)
|
|
30
|
+
const MAX_NODES = parseEnvInt('SA4E_ELK_MAX_NODES', 500, 1, 5000);
|
|
31
|
+
const TIMEOUT_MS = parseEnvInt('SA4E_ELK_TIMEOUT_MS', 10_000, 1000, 60_000);
|
|
32
|
+
/** Maximum spacing in pixels to prevent resource exhaustion (SEC-03). */
|
|
33
|
+
const MAX_SPACING = 500;
|
|
34
|
+
/**
|
|
35
|
+
* Orchestrate ELK layout fix: build graph → run ELK → write to file → return metadata.
|
|
36
|
+
* @param rawXml - Original XML content
|
|
37
|
+
* @param graph - Parsed diagram graph
|
|
38
|
+
* @param issues - Detected issues (before fix)
|
|
39
|
+
* @param nodeCount - Total node count
|
|
40
|
+
* @param args - Tool arguments for algorithm/spacing/direction
|
|
41
|
+
* @param filePath - Absolute path to write fixed XML
|
|
42
|
+
* @returns JSON string with status, repositioned_nodes (no content_base64)
|
|
43
|
+
*/
|
|
44
|
+
export async function handleApply(rawXml, graph, issues, nodeCount, args, filePath) {
|
|
45
|
+
if (nodeCount > MAX_NODES)
|
|
46
|
+
return error(`Diagram too large (${nodeCount} nodes, max ${MAX_NODES})`);
|
|
47
|
+
const normalized = normalizeLayoutArgs(args);
|
|
48
|
+
// Container detected → edge-only fix (keep node positions, only distribute ports)
|
|
49
|
+
if (graph.containers.length > 0) {
|
|
50
|
+
return handleEdgeOnlyFix(rawXml, graph, issues, filePath);
|
|
51
|
+
}
|
|
52
|
+
// Flat diagram → full ELK repositioning
|
|
53
|
+
try {
|
|
54
|
+
const elkGraph = buildElkGraph(graph, normalized);
|
|
55
|
+
const laidOut = await runElkLayout(elkGraph, TIMEOUT_MS);
|
|
56
|
+
const { xml, repositionedNodes } = applyLayoutToXml(rawXml, laidOut);
|
|
57
|
+
if (repositionedNodes.length === 0)
|
|
58
|
+
return error('ELK layout produced no position changes');
|
|
59
|
+
validateReparse(xml);
|
|
60
|
+
fs.writeFileSync(filePath, xml, 'utf-8');
|
|
61
|
+
return JSON.stringify({
|
|
62
|
+
status: 'fixed',
|
|
63
|
+
message: `Fixed ${issues.length} issues with ELK ${normalized.algorithm} layout. ${repositionedNodes.length} nodes repositioned.`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
console.error('[drawio-apply] ELK layout error:', e);
|
|
68
|
+
return error('Layout engine failed. Please check input diagram and retry.');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Normalize layout args with safe defaults and upper bounds (SEC-03). */
|
|
72
|
+
export function normalizeLayoutArgs(args) {
|
|
73
|
+
const VALID_ALG = ['layered', 'force', 'mrtree', 'radial'];
|
|
74
|
+
const VALID_DIR = ['DOWN', 'RIGHT', 'LEFT', 'UP'];
|
|
75
|
+
const algorithm = typeof args.algorithm === 'string' && VALID_ALG.includes(args.algorithm)
|
|
76
|
+
? args.algorithm : 'layered';
|
|
77
|
+
// SEC-03: Cap spacing to MAX_SPACING to prevent resource exhaustion
|
|
78
|
+
const rawSpacing = typeof args.spacing === 'number' && args.spacing > 0 ? args.spacing : 80;
|
|
79
|
+
const spacing = Math.min(rawSpacing, MAX_SPACING);
|
|
80
|
+
const direction = typeof args.direction === 'string' && VALID_DIR.includes(args.direction.toUpperCase())
|
|
81
|
+
? args.direction.toUpperCase() : 'DOWN';
|
|
82
|
+
return { algorithm, spacing, direction };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Edge-only fix for container diagrams: distribute edge ports to prevent stacking.
|
|
86
|
+
* Keeps all node positions unchanged. Only modifies edge style attributes.
|
|
87
|
+
*/
|
|
88
|
+
function handleEdgeOnlyFix(rawXml, graph, issues, filePath) {
|
|
89
|
+
try {
|
|
90
|
+
let xml = rawXml;
|
|
91
|
+
const nodeMap = new Map([...graph.nodes, ...graph.containers].map(n => [n.id, n]));
|
|
92
|
+
const edgesBySource = new Map();
|
|
93
|
+
const edgesByTarget = new Map();
|
|
94
|
+
for (const e of graph.edges) {
|
|
95
|
+
if (!edgesBySource.has(e.sourceId))
|
|
96
|
+
edgesBySource.set(e.sourceId, []);
|
|
97
|
+
edgesBySource.get(e.sourceId).push(e);
|
|
98
|
+
if (!edgesByTarget.has(e.targetId))
|
|
99
|
+
edgesByTarget.set(e.targetId, []);
|
|
100
|
+
edgesByTarget.get(e.targetId).push(e);
|
|
101
|
+
}
|
|
102
|
+
for (const [nodeId, edges] of edgesBySource) {
|
|
103
|
+
if (edges.length <= 1 || !nodeMap.has(nodeId))
|
|
104
|
+
continue;
|
|
105
|
+
for (let i = 0; i < edges.length; i++) {
|
|
106
|
+
const exitX = (i + 1) / (edges.length + 1);
|
|
107
|
+
xml = addPortToEdge(xml, edges[i].id, 'exit', exitX, 1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
for (const [nodeId, edges] of edgesByTarget) {
|
|
111
|
+
if (edges.length <= 1 || !nodeMap.has(nodeId))
|
|
112
|
+
continue;
|
|
113
|
+
for (let i = 0; i < edges.length; i++) {
|
|
114
|
+
const entryX = (i + 1) / (edges.length + 1);
|
|
115
|
+
xml = addPortToEdge(xml, edges[i].id, 'entry', entryX, 0);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (xml === rawXml) {
|
|
119
|
+
return JSON.stringify({ status: 'already_good', message: 'Container diagram — no edge routing improvements needed.' });
|
|
120
|
+
}
|
|
121
|
+
validateReparse(xml);
|
|
122
|
+
fs.writeFileSync(filePath, xml, 'utf-8');
|
|
123
|
+
return JSON.stringify({
|
|
124
|
+
status: 'fixed',
|
|
125
|
+
message: `Fixed edge routing for container diagram. ${issues.length} issues detected, ports distributed.`,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
console.error('[drawio-apply] Edge-only fix error:', e);
|
|
130
|
+
return error('Edge routing fix failed. Please check diagram structure.');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Add exit/entry port coordinates to an edge style attribute. */
|
|
134
|
+
function addPortToEdge(xml, edgeId, type, x, y) {
|
|
135
|
+
const escaped = edgeId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
136
|
+
const regex = new RegExp(`(<mxCell\\b[^>]*\\bid="${escaped}"[^>]*style=")([^"]*)("`);
|
|
137
|
+
return xml.replace(regex, (_match, pre, style, post) => {
|
|
138
|
+
let clean = style.replace(new RegExp(`${type}X=[^;]*;?`, 'g'), '');
|
|
139
|
+
clean = clean.replace(new RegExp(`${type}Y=[^;]*;?`, 'g'), '');
|
|
140
|
+
clean = clean.replace(new RegExp(`${type}Dx=[^;]*;?`, 'g'), '');
|
|
141
|
+
clean = clean.replace(new RegExp(`${type}Dy=[^;]*;?`, 'g'), '');
|
|
142
|
+
const port = `${type}X=${x.toFixed(2)};${type}Y=${y};${type}Dx=0;${type}Dy=0;`;
|
|
143
|
+
return `${pre}${clean}${port}${post}`;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/** BR-7: Re-parse fixed XML to ensure it's valid before writing to file. */
|
|
147
|
+
function validateReparse(xml) {
|
|
148
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'drawio-fix-'));
|
|
149
|
+
try {
|
|
150
|
+
const tmpFile = path.join(tmpDir, 'fixed.drawio');
|
|
151
|
+
fs.writeFileSync(tmpFile, xml, 'utf-8');
|
|
152
|
+
parseDrawio(tmpFile); // Throws if XML is broken
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
try {
|
|
156
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
157
|
+
}
|
|
158
|
+
catch (cleanupErr) {
|
|
159
|
+
console.error('[drawio-apply] Temp cleanup failed:', cleanupErr);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function error(msg) {
|
|
164
|
+
return JSON.stringify({ error: msg });
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=drawio-apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawio-apply.js","sourceRoot":"","sources":["../../../src/engine/tools/drawio-apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface ElkNode {
|
|
2
|
+
id: string;
|
|
3
|
+
x?: number;
|
|
4
|
+
y?: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
children?: ElkNode[];
|
|
8
|
+
edges?: ElkEdge[];
|
|
9
|
+
layoutOptions?: Record<string, string | number>;
|
|
10
|
+
}
|
|
11
|
+
export interface ElkEdge {
|
|
12
|
+
id: string;
|
|
13
|
+
sources: string[];
|
|
14
|
+
targets: string[];
|
|
15
|
+
sections?: Array<{
|
|
16
|
+
startPoint?: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
};
|
|
20
|
+
bendPoints?: Array<{
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
}>;
|
|
24
|
+
endPoint?: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
export interface RepositionedNode {
|
|
31
|
+
id: string;
|
|
32
|
+
x_old: number;
|
|
33
|
+
y_old: number;
|
|
34
|
+
x_new: number;
|
|
35
|
+
y_new: number;
|
|
36
|
+
}
|
|
37
|
+
export interface LayoutFixResult {
|
|
38
|
+
status: 'fixed' | 'already_good';
|
|
39
|
+
message: string;
|
|
40
|
+
nodes: number;
|
|
41
|
+
edges: number;
|
|
42
|
+
issues: object[];
|
|
43
|
+
content_base64?: string;
|
|
44
|
+
repositioned_nodes?: RepositionedNode[];
|
|
45
|
+
}
|
|
46
|
+
export interface NormalizedArgs {
|
|
47
|
+
algorithm: string;
|
|
48
|
+
spacing: number;
|
|
49
|
+
direction: string;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawio-layout-models.js","sourceRoot":"","sources":["../../../src/engine/tools/drawio-layout-models.ts"],"names":[],"mappings":""}
|