Files
diagrams-drawio/scripts/src/actions/page-hierarchy-full/action.ts
T
oleg-lukasonokandClaude Fable 5 77655d1d97 Restructure to skill-manager conventions
- Move the TypeScript project under scripts/ (src, tsconfig,
  package.json, pnpm lockfile/workspace, canonical .gitignore);
  drop the npm package-lock
- Add scripts/Taskfile.yml aggregator plus .scripts modules
  (loggers, base, cli) with build, run, and validate tasks
- Move the six SKILL-*.md docs into references/ with kebab names
  and extract the connector-routing sections from SKILL.md into
  references/routing-best-practices.md (SKILL.md 666 -> ~310 lines)
- Add license/metadata/compatibility frontmatter, an Available
  scripts section, and update all CLI paths in README and references

skill-manager validate: 13/13 passed, 0 warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 15:20:26 +03:00

101 lines
2.7 KiB
TypeScript

/**
* Action: page-hierarchy-full
*
* Extends page-hierarchy with full geometry for every shape at each nesting level.
*
* Reuses the shared hierarchy-builder service (same logic as page-hierarchy).
*
* "Levels" = containment depth levels in the shape hierarchy (diagramming term):
* level 1 (depth 0) = root-level shapes (parentId === "1")
* level 2 (depth 1) = shapes whose parent is at level 1
* level N (depth N-1) = shapes nested N-1 levels deep
*
* Output structure:
* summary:
* levelsTotal — number of distinct nesting levels
* shapesTotal — total shape count
* shapesPerLevel — { levelNumber: count }
* levels:
* - number — 1-based nesting level (1 = root, 2 = children, …)
* shapeCount
* shapes:
* - id, label, x, y, width, height, parentId
*
* IMPORTANT: Parser returns absolute canvas coordinates for all shapes.
*/
import { parseAllPages } from "../../services/drawio-parser/parser.js";
import { buildHierarchy } from "../../services/hierarchy-builder/hierarchy-builder.js";
import type { Shape } from "../../services/drawio-parser/parser.js";
interface ShapeEntry {
id: string;
label: string;
x: number;
y: number;
width: number;
height: number;
parentId: string;
}
interface NestingLevel {
number: number;
shapeCount: number;
shapes: ShapeEntry[];
}
export function run(
filePath: string,
pageIndex: number = 0
): Record<string, unknown> {
const pages = parseAllPages(filePath);
const page = pages[pageIndex];
if (!page) {
return { error: true, message: `Page index ${pageIndex} not found` };
}
// Reuse shared hierarchy builder
const { depthMap, maxDepth, totalLevels } = buildHierarchy(page);
const allShapes = Array.from(page.shapes.values());
// Group shapes by depth
const levelMap = new Map<number, Shape[]>();
for (const s of allShapes) {
const d = depthMap.get(s.id);
if (d === undefined) continue;
if (!levelMap.has(d)) levelMap.set(d, []);
levelMap.get(d)!.push(s);
}
const levels: NestingLevel[] = [];
for (let d = 0; d <= maxDepth; d++) {
const shapes = (levelMap.get(d) ?? []).sort((a, b) => a.y - b.y || a.x - b.x);
levels.push({
number: d + 1,
shapeCount: shapes.length,
shapes: shapes.map((s) => ({
id: s.id,
label: s.label.replace(/\n/g, " / "),
x: s.x,
y: s.y,
width: s.width,
height: s.height,
parentId: s.parentId,
})),
});
}
return {
action: "page-hierarchy-full",
file: filePath,
pageIndex,
summary: {
levelsTotal: totalLevels,
shapesTotal: allShapes.length,
shapesPerLevel: Object.fromEntries(levels.map((l) => [l.number, l.shapeCount])),
},
levels,
};
}