Fix review findings: importer DoS, sync data loss, views/profile rendering, docs
Source importers: lstat before open so FIFOs no longer hang the directory walk; replace the quadratic Rust macro regex with a linear scan. Three-way sync: report page add/add and delete-vs-modify as conflicts instead of silently overwriting or resurrecting; canonical comparison so key order is not a change; the sync action withholds output and fails on conflicts unless --force. Story publishing escapes <, >, & and U+2028/9 inside the embedded JSON. Views: drop parentId of unselected containers, re-layout instead of manual geometry, validate before serialising; flatten() merges identical nodes repeated across pages so C4 output works with every analysis action. Dark theme edge labels get a background; tube-map corridors sit above the stations; C4 containers keep the swimlane style and orphan relationships land on the matching page; router keeps container header bands as obstacles; sequence self-messages loop on one side. Docs: SKILL.md lists all 23 CLI actions and how each capability family is invoked, task wrappers for query/test/what-if/doctor, capability tables and --page scope corrected, maintenance snippet uses the real synchronous action signature, duplicated rule bullets moved to the rule references, coverage matrix wording made verifiable. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -81,11 +81,13 @@ function parseStyle(style = ""): StyleEntry[] {
|
||||
});
|
||||
}
|
||||
|
||||
function themedStyle(style: string | undefined, colors: Partial<ThemeRoleStyle>, sketch: boolean, backgroundColor?: string): string {
|
||||
function themedStyle(style: string | undefined, colors: Partial<ThemeRoleStyle>, sketch: boolean, backgroundColor?: string, labelBackgroundColor?: string): string {
|
||||
const entries = parseStyle(style);
|
||||
const originalFillNone = entries.some(({ key, value }) => key === "fillColor" && value?.toLowerCase() === "none");
|
||||
const visual = new Map<string, string>();
|
||||
if (colors.fillColor) visual.set("fillColor", originalFillNone ? "none" : colors.fillColor);
|
||||
// Edge labels are drawn on the canvas, so their backdrop must follow the canvas colour or they render as boxes.
|
||||
if (labelBackgroundColor) visual.set("labelBackgroundColor", labelBackgroundColor);
|
||||
if (colors.strokeColor) visual.set("strokeColor", colors.strokeColor);
|
||||
if (colors.fontColor) {
|
||||
let fontColor = colors.fontColor;
|
||||
@@ -95,7 +97,7 @@ function themedStyle(style: string | undefined, colors: Partial<ThemeRoleStyle>,
|
||||
visual.set("fontColor", fontColor);
|
||||
}
|
||||
visual.set("sketch", sketch ? "1" : "0");
|
||||
const visualKeys = new Set(["fillColor", "strokeColor", "fontColor", "sketch"]);
|
||||
const visualKeys = new Set(["fillColor", "strokeColor", "fontColor", "labelBackgroundColor", "sketch"]);
|
||||
const handled = new Set<string>();
|
||||
const output = entries.flatMap((entry) => {
|
||||
if (!visualKeys.has(entry.key)) return [entry];
|
||||
@@ -106,7 +108,7 @@ function themedStyle(style: string | undefined, colors: Partial<ThemeRoleStyle>,
|
||||
visual.delete(entry.key);
|
||||
return [{ key: entry.key, value: replacement }];
|
||||
});
|
||||
for (const key of ["fillColor", "strokeColor", "fontColor", "sketch"]) {
|
||||
for (const key of ["fillColor", "strokeColor", "fontColor", "labelBackgroundColor", "sketch"]) {
|
||||
const value = visual.get(key);
|
||||
if (value !== undefined) output.push({ key, value });
|
||||
}
|
||||
@@ -122,7 +124,7 @@ export function applyTheme(ir: DiagramIRV2, selected: BuiltInThemeName | ThemeDe
|
||||
...node,
|
||||
style: themedStyle(node.style, node.kind === "container" ? selectedTheme.container : selectedTheme.node, selectedTheme.sketch === true, selectedTheme.backgroundColor),
|
||||
});
|
||||
const applyEdge = (edge: DiagramEdge): DiagramEdge => ({ ...edge, style: themedStyle(edge.style, selectedTheme.edge, selectedTheme.sketch === true) });
|
||||
const applyEdge = (edge: DiagramEdge): DiagramEdge => ({ ...edge, style: themedStyle(edge.style, selectedTheme.edge, selectedTheme.sketch === true, undefined, selectedTheme.backgroundColor) });
|
||||
return {
|
||||
...isolated,
|
||||
theme: selectedTheme.name,
|
||||
|
||||
Reference in New Issue
Block a user