{"id":51061058,"url":"https://github.com/marianfoo/btp-drawio-skill","last_synced_at":"2026-06-23T02:01:07.840Z","repository":{"id":354508878,"uuid":"1217756486","full_name":"marianfoo/btp-drawio-skill","owner":"marianfoo","description":"drawio skill to create SAP Architecture Diagrams","archived":false,"fork":false,"pushed_at":"2026-06-14T05:58:48.000Z","size":5539,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T07:24:14.344Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marianfoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-22T07:28:43.000Z","updated_at":"2026-06-14T05:58:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marianfoo/btp-drawio-skill","commit_stats":null,"previous_names":["marianfoo/btp-drawio-skill"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/marianfoo/btp-drawio-skill","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marianfoo%2Fbtp-drawio-skill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marianfoo%2Fbtp-drawio-skill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marianfoo%2Fbtp-drawio-skill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marianfoo%2Fbtp-drawio-skill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marianfoo","download_url":"https://codeload.github.com/marianfoo/btp-drawio-skill/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marianfoo%2Fbtp-drawio-skill/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34672250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-23T02:00:07.161Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-23T02:01:06.798Z","updated_at":"2026-06-23T02:01:07.820Z","avatar_url":"https://github.com/marianfoo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# btp-drawio-skill\n\nA Claude Code plugin (and Agent-Skill-compatible standalone skill) that authors **SAP Architecture Center / BTP solution diagrams** as draw.io files from a natural-language description — following the **official SAP BTP Solution Diagram Guidelines**.\n\nBundles:\n- **100 SAP BTP service icons** (inline SVG data URIs, grey-background-circle variant — the one [SAP mandates](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/icons.md) for diagrams)\n- **448 indexed SAP draw.io starter-kit assets** across 10 bundled libraries: BTP service icons, generic icons, connector presets, area/default shapes, essential shapes, number markers, SAP brand-name text, text elements, and annotation/interface pills\n- **71 pristine reference templates** (Apache-2.0): canonical examples from [`SAP/btp-solution-diagrams`](https://github.com/SAP/btp-solution-diagrams), curated reference architectures from [`SAP/architecture-center`](https://github.com/SAP/architecture-center), and selected external SAP references, covering IAM, Joule, MCP / Agentic AI, multitenant SaaS, DevOps, Private Link, Cloud Connector, Event-Driven Architecture, resiliency, Business Data Cloud, integration, SIEM/SOAR, and SuccessFactors\n- **10 reference sheets** with the exact Horizon hex values, Helvetica typography hierarchy, shape / edge style strings, canvas layout, do-and-don't rules, corpus findings, generation-quality checklist, external-corpus guidance, researched improvement options, and the comparison methodology — every value cited from the [SAP BTP Solution Diagram Guidelines](https://sap.github.io/btp-solution-diagrams/) or observed in SAP's public corpus\n- **A validator** (`validate.py`) that catches bent arrows, clipped labels, off-palette colors, off-grid coordinates, duplicate ids, missing `labelBackgroundColor`, and XML comments\n- **An autofixer** (`autofix.py`) that mechanically repairs grid snap, hex case, missing `absoluteArcSize=1`, wrong `strokeWidth`, non-Helvetica fonts, and stray XML comments\n- **A metadata-aware template selector + comparison harness** (`select_reference.py`, `compare.py`, `score_corpus.py`) that picks the nearest SAP template, fingerprints a `.drawio`, reports corpus similarity, and reports a reference-free SAP-likeness score for semantic fallback diagrams\n\n\u003e **Why a dedicated skill?** Reproducing SAP Architecture Center style by hand or via a generic drawio skill consistently produces off-style output — wrong palette, bent `orthogonalEdgeStyle` arrows, clipped labels, text bleeding into `#EBF8FF` BTP fills, blank icon stencils (`shape=mxgraph.sap.icon;SAPIcon=…` doesn't render in many installs). This plugin bakes in the rules that matter and gates every output behind a validator.\n\n## Table of contents\n\n- [Quick start — Claude Code users](#quick-start--claude-code-users)\n- [Prompting for good diagrams](#prompting-for-good-diagrams)\n- [Use with npx, MCP, and MCPB](#use-with-npx-mcp-and-mcpb)\n- [Install in Claude Desktop / Claude.ai](#install-in-claude-desktop--claudeai)\n- [Use outside of Claude (other Agent-Skills runtimes)](#use-outside-of-claude-other-agent-skills-runtimes)\n- [Use the scripts directly (no LLM)](#use-the-scripts-directly-no-llm)\n- [What the skill does — workflow](#what-the-skill-does--workflow)\n- [Design rules the skill enforces](#design-rules-the-skill-enforces)\n- [Repo layout](#repo-layout)\n- [Development](#development)\n- [License \u0026 attribution](#license--attribution)\n- [Credits \u0026 research sources](#credits--research-sources)\n\n---\n\n## Quick start — Claude Code users\n\nIn Claude Code:\n\n```\n/plugin marketplace add marianfoo/btp-drawio-skill\n/plugin install sap-architecture\n```\n\nThen describe the diagram:\n\n\u003e Create an SAP architecture diagram showing a Copilot Studio MCP client calling an ARC-1 BTP Cloud Foundry app. ARC-1 authenticates via XSUAA OAuth, uses Destination Service + Cloud Connector with Principal Propagation to reach an on-prem S/4HANA system.\n\nClaude will auto-load the skill (its trigger phrases are tuned for SAP / BTP / architecture / drawio keywords), run `select_reference.py`, pick the closest reference template, drop the right icons, compose the XML, run `autofix.py` + `validate.py` + `score_corpus.py`, and hand you back a ready-to-open `.drawio` file plus a numbered flow narration.\n\n### Example prompts\n\n- \"Draw my BTP deployment — CAP app with XSUAA, HANA Cloud, Destination Service to on-prem ECC.\"\n- \"Diagram the XSUAA OAuth flow between Claude Desktop, our MCP server, and on-prem ABAP.\"\n- \"Show how a user on VS Code Copilot reaches SAP BW/4HANA through Cloud Connector with Principal Propagation.\"\n- \"Make an L1 conceptual diagram of a Joule integration with Task Center pulling from S/4, SuccessFactors, and Ariba.\"\n- \"Generate an L2 ref-arch for SAP Build Apps fronting a CAP service bound to SAP Event Mesh.\"\n\n## Prompting for good diagrams\n\nThe skill works best when the prompt describes an architecture, not just a product list. Give the agent enough context to choose the right SAP reference template and preserve its structure.\n\nUse this shape for high-quality prompts:\n\n```text\nCreate an L2 SAP Architecture Center-style draw.io diagram for \u003cscenario\u003e.\n\nAudience and level: \u003cbusiness overview | solution architecture | implementation flow\u003e.\nMain zones: \u003cUser/Client\u003e, \u003cSAP BTP subaccount/runtime\u003e, \u003cSAP Cloud Solutions\u003e, \u003cOn-Premise\u003e, \u003cThird-party/Hyperscaler\u003e, \u003cNetwork divider if relevant\u003e.\nActors and entry points: \u003cwho starts the flow and from where\u003e.\nSAP BTP services: \u003cexact service names\u003e.\nBackends/systems: \u003cSAP S/4HANA, ECC, BW/4HANA, SuccessFactors, Datasphere, Databricks, etc.\u003e.\nIdentity/security: \u003cIAS, XSUAA, OAuth, SAML, Principal Propagation, trust, authorization\u003e.\nFlow steps: 1. \u003cprotocol/action\u003e, 2. \u003cprotocol/action\u003e, 3. \u003cprotocol/action\u003e.\nConstraints: \u003cmust show Cloud Connector | use Joule as separate zone | prefer template RA0029 | avoid implementation internals\u003e.\nOutput: editable .drawio plus numbered flow narration below the diagram.\n```\n\nHelpful context to attach or paste:\n\n- Existing architecture notes, but trimmed to the services, actors, systems, and flows that should appear.\n- A numbered flow, even if rough. Protocol words such as `HTTPS`, `OData/REST`, `OAuth`, `SAML`, `A2A`, `MCP`, `ORD`, and `Principal Propagation` help the skill pick canonical pills and edge colors.\n- The intended abstraction level: `L0` for business overview, `L1` for solution components, `L2` for default technical flow. Avoid mixing all three in one diagram.\n- The deployment boundary: which systems are inside SAP BTP, which are SAP cloud apps, which are on-premise, and which are third party or hyperscaler.\n- Any preferred SAP reference/template name if you know it, for example `ac_RA0029_AgenticAI_root.drawio` for Agentic AI with Joule.\n- A short list of exclusions, such as \"do not show CI/CD\" or \"do not include database internals\".\n\nAvoid prompts like \"make a BTP diagram for our app\" unless you want the agent to ask a clarifying question. Also avoid dumping long unfiltered design docs: they usually contain several diagrams' worth of scope. If you paste a long document, add a short \"diagram scope\" paragraph that says exactly which flow to draw.\n\nStrong prompt:\n\n\u003e Create an L2 SAP Architecture Center-style draw.io diagram. A developer in VS Code uses ARC-1 running on SAP BTP Cloud Foundry. ARC-1 authenticates with XSUAA, reads a Destination, uses SAP Connectivity service and SAP Cloud Connector, and calls on-premise SAP S/4HANA via OData/REST with Principal Propagation. Show zones for Developer Workstation, SAP BTP Cloud Foundry, and Customer On-Premise Network. Output editable `.drawio` and a numbered flow narration.\n\nWeak prompt:\n\n\u003e Draw ARC-1 with BTP and S/4HANA.\n\n## Use with npx, MCP, and MCPB\n\nThis repo now ships a Node entry point for easier local use and packaging. The Node layer wraps the stable Python diagram engine, so **Python 3.8+ is still required** for the current implementation.\n\nFrom npm once published:\n\n```bash\nnpx btp-drawio-skill doctor\nnpx btp-drawio-skill semantic \\\n  \"Developer uses ARC-1 on SAP BTP Cloud Foundry to call on-premise SAP S/4HANA through Cloud Connector\" \\\n  --out arc1-onprem.drawio\nnpx btp-drawio-skill validate arc1-onprem.drawio\nnpx btp-drawio-skill score --min-sap-like 90 arc1-onprem.drawio\n```\n\nFrom this checkout:\n\n```bash\nnpm install\nnode bin/btp-drawio.js doctor\nnode bin/btp-drawio.js scaffold \"\u003crequest\u003e\" --out scaffold.drawio\nnode bin/btp-drawio.js semantic \"\u003crequest\u003e\" --out semantic.drawio\n```\n\nMCP stdio server:\n\n```bash\nnpx btp-drawio-skill mcp\n```\n\nFor a local Claude/Cursor-style MCP config before npm publish, point directly at the checkout:\n\n```json\n{\n  \"mcpServers\": {\n    \"btp-drawio\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/btp-drawio-skill/bin/btp-drawio-mcp.js\"],\n      \"env\": {\n        \"BTP_DRAWIO_PYTHON\": \"python3\"\n      }\n    }\n  }\n}\n```\n\nFor MCPB packaging, stage and pack a bundle:\n\n```bash\nnpm run mcpb:pack\n```\n\nThat creates `.cache/mcpb/btp-drawio-skill.mcpb` using `mcpb/manifest.json`. The manifest exposes tools for diagnostics, scaffolding, semantic rendering, validation, scoring, autofix, rendering, relabeling, icon extraction, and generic asset extraction.\n\nMCP clients can call `btp_drawio_relabel` with either a JSON mapping file path or inline JSON:\n\n```json\n{\n  \"file\": \"scaffold.drawio\",\n  \"mappingJson\": \"{\\\"SAP Cloud Connector\\\":\\\"SAP Cloud Connector (customer network)\\\"}\",\n  \"out\": \"diagram.drawio\"\n}\n```\n\nThe MCP server also exposes `btp_drawio_autofix` for deterministic mechanical cleanup and `btp_drawio_extract_asset` for generic SAP starter-kit assets such as `on-premise-sap`. Use `btp_drawio_doctor` first when Python or draw.io rendering is not configured; it reports the resolved package root, Python runtime, and `DRAWIO_CLI` setting.\n\nPure-JS migration is incremental. These commands already run through the JS engine by default and can be forced with `BTP_DRAWIO_ENGINE=js`: `select`, `scaffold`, `extract-icon`, `extract-asset`, `relabel`, and `autofix`. Other commands still use the Python engine until their parity gates are complete. Use `BTP_DRAWIO_ENGINE=python` as an escape hatch during the transition.\n\n### Updating the plugin\n\n```\n/plugin update sap-architecture\n```\n\n### Uninstalling\n\n```\n/plugin uninstall sap-architecture\n/plugin marketplace remove btp-drawio-skill\n```\n\n---\n\n## Install in Claude Desktop / Claude.ai\n\nClaude Desktop and Claude.ai load skills from the user's skills folder. Since this repo follows the [Agent Skills open standard](https://agentskills.io), you can drop the `SKILL.md` tree directly into the host's skills directory:\n\n**macOS / Linux:**\n\n```bash\ngit clone https://github.com/marianfoo/btp-drawio-skill.git\nmkdir -p ~/.claude/skills\ncp -R btp-drawio-skill/plugins/sap-architecture/skills/sap-architecture \\\n      ~/.claude/skills/\n```\n\n**Windows (PowerShell):**\n\n```powershell\ngit clone https://github.com/marianfoo/btp-drawio-skill.git\nNew-Item -ItemType Directory -Force \"$HOME\\.claude\\skills\"\nCopy-Item -Recurse `\n  btp-drawio-skill\\plugins\\sap-architecture\\skills\\sap-architecture `\n  \"$HOME\\.claude\\skills\\\"\n```\n\nRestart Claude. The skill shows up in the Skills panel; Claude will auto-invoke it when you describe an SAP architecture. You still need **Python 3.8+** on `$PATH` for `validate.py` / `autofix.py` to run.\n\n---\n\n## Use outside of Claude (other Agent-Skills runtimes)\n\nThe skill is a plain [Agent Skills](https://agentskills.io)-compliant bundle — the `SKILL.md` frontmatter sticks to the portable subset (`name`, `description`) and doesn't depend on any Claude Code-specific feature. Anything that loads an `SKILL.md` tree should work:\n\n- **Cursor / Windsurf / Continue** — point their custom-rules / rules-directory setting at `plugins/sap-architecture/skills/sap-architecture/`.\n- **Self-hosted MCP clients / Open Interpreter / any Agent-Skills runtime** — drop the folder into the skills directory your client expects (check your client's docs for the path; `~/.agents/skills/` and `~/.config/\u003cclient\u003e/skills/` are common).\n- **Raw prompt** — concatenate `SKILL.md` + the `references/*.md` you need into the system prompt.\n\n### Recommended minimal prompt if your host doesn't load skill files\n\n```\nYou have access to the SAP Architecture Skill. When the user asks for an SAP /\nBTP / on-prem architecture diagram, follow the 6-step workflow in SKILL.md:\n\n1. Parse description → plan (L0/L1/L2, zones, services, flow, accent)\n2. ALWAYS scaffold from a SAP reference template (NEVER write XML from scratch):\n     scripts/scaffold_diagram.py \"\u003crequest\u003e\" --out \u003cdestination\u003e.drawio\n3. Place BTP service icons via scripts/extract_icon.py / extract_asset.py\n4. Make surgical label edits with scripts/relabel.py where possible — do NOT\n   rewrite the file. Preserve canvas size, zone hierarchy, network divider,\n   SAP logos, footer, and identity flow.\n5. MANDATORY: run scripts/autofix.py --write \u003cfile\u003e, scripts/validate.py\n   \u003cfile\u003e, and scripts/score_corpus.py --min-score 90 \u003cfile\u003e\n   # for semantic fallback output: scripts/score_corpus.py --min-sap-like 90 \u003cfile\u003e\n6. Print the flow narration as a numbered markdown list\n\nHard rules enforced by the validator: no dark page backgrounds; flow pills must\nuse canonical SAP verbs (TRUST/Authenticate/Authorization/A2A/MCP/ORD/HTTPS/\nOData/REST/SAML2/OIDC); preserve grey-circle icons; trust=pink, auth=green,\nauthorization=indigo, firewalls=thick grey; 16-px corner radius.\n```\n\n---\n\n## Use the scripts directly (no LLM)\n\nThe plugin's Python scripts have zero third-party dependencies (stdlib only) and are useful on their own.\n\n### List all available BTP icons\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/extract_icon.py --list\n# → 100 icons, one per line: slug + display name\n```\n\n### Generate a ready-to-paste `\u003cmxCell\u003e` for a service icon\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/extract_icon.py \\\n  \"Destination Service\" \\\n  --x 600 --y 300 \\\n  --id svc-dest --parent 1\n```\n\nFuzzy matching is built in — `\"XSUAA\"`, `\"CPI\"`, `\"HANA\"`, `\"Cloud Connector\"`, `\"Audit Log\"`, `\"Authorization and Trust\"` all resolve correctly. Defaults are 32×32 px to match the SAP corpus; use 48×48 only for focal anchors.\n\nBackend systems such as `\"SAP S/4HANA\"` are not BTP service icons. `extract_icon.py` fails closed for those names so it does not return unrelated product-specific service icons. Use `extract_asset.py \"sap-s-4hana\" --kind sap-brand-name` for product text or `extract_asset.py \"on-premise-sap\" --kind generic-icon` for a generic backend icon.\n\n### List or extract any SAP starter-kit asset\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/extract_asset.py --list --kind connector\n\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/extract_asset.py \\\n  \"direct one-directional\" \\\n  --kind connector \\\n  --x 200 --y 300 \\\n  --id flow1\n\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/extract_asset.py \\\n  \"devices non sap\" \\\n  --kind generic-icon \\\n  --x 100 --y 200 \\\n  --id generic-devices\n```\n\n`extract_asset.py` reads `assets/asset-index.json`, which covers all bundled SAP draw.io starter-kit libraries, not only BTP service icons. Use it for generic icons, connector presets, area/default shapes, essential shapes, number bubbles, SAP brand-name text, text styles, and interface/annotation pills.\n\n### Pick the closest SAP template from a prompt\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/select_reference.py --top 5 \\\n  \"Joule agent calls S/4HANA through MCP and XSUAA\"\n```\n\nThe selector ranks the 71 bundled templates by curated scenario metadata, family, level, filename matches, visible labels in the draw.io file, and strong aliases such as `DevOps`, `Edge Integration Cell`, `Federated ML`, `SuccessFactors`, `Joule`, `MCP`, and `Private Link`. Use it before editing XML.\n\n### Score a diagram against a SAP reference\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/compare.py \\\n  plugins/sap-architecture/skills/sap-architecture/assets/reference-examples/btp_SAP_Cloud_Identity_Services_Authentication_L2.drawio \\\n  my-diagram.drawio\n\n# one-line score 0-100\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/compare.py --score \\\n  reference.drawio my-diagram.drawio\n```\n\nCalibration: a hand-crafted candidate built from scratch typically scores 50-55. A candidate built by copying a SAP reference template + relabeling for your scenario scores roughly 95-100 structurally, while visible label/content drift now lowers the target score. See [`references/methodology.md`](plugins/sap-architecture/skills/sap-architecture/references/methodology.md) for the full breakdown.\n\n### Score a diagram against the whole bundled corpus\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/score_corpus.py \\\n  --top 5 --min-score 90 my-diagram.drawio\n```\n\n`score_corpus.py` compares the candidate against all bundled SAP references and exits nonzero if the best score is below the threshold. For deeper research loops, pass cloned SAP repos with `--references /path/to/SAP/architecture-center --references /path/to/SAP/btp-solution-diagrams`.\n\nFor deterministic semantic fallback diagrams, corpus similarity can be low even when the diagram is visually correct. Use `--min-sap-like 90` to gate reference-free quality signals such as white canvas, SAP palette, Helvetica, canonical pills, zones, icons, grid snap, and validator errors.\n\n### Run an Ollama-backed corpus evaluation loop\n\n`eval_corpus.py` orchestrates the longer feedback loop: inventory SAP references, extract diagram descriptions, ask a local model for a generation plan, create candidates, run `autofix.py` + `validate.py`, score against the specific target reference and the whole corpus, and write reports under `.cache/sap-architecture-eval/`. The default pass mode is target-aware; corpus-only scoring is still available with `--pass-mode corpus`.\n\nWhen `--exclude-target-template` is used, the harness now adds explicit \"visual fallback\" hints computed from the target reference fingerprint. That means the exact target cannot be copied, but the selected starting template is the closest available SAP layout. Add `--no-style-neighbor-hints` if you want a stricter pure-semantic leave-one-out selector test.\n\nThe report now separates `near-miss` cases from `ceiling-limited` cases. Near misses are worth retrying; ceiling-limited cases need better sibling templates or geometry-aware generation because the selected alternate SAP layout is already too far below the target. The default `--retry-margin 8` only retries cases scoring 82+ when `--min-score 90`, which avoids wasting long Ollama runs on structurally impossible cases. Use `--retry-margin 100` only when you deliberately want the old exhaustive behavior.\n\nAfter a full run, focus only on the cases that can still benefit from more model attempts:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py dry-run \\\n  --from-run .cache/sap-architecture-eval/\u003crun-id\u003e \\\n  --case-class near-miss \\\n  --generator ollama \\\n  --model qwen3.6:35b-a3b-nvfp4 \\\n  --exclude-target-template \\\n  --apply-model-plan\n```\n\nUse `--case-id \u003csubstring\u003e` for manual family tests, for example `--case-id ra0024`, `--case-id agenticai`, or `--case-id cloudconnector`.\n\nFast smoke checks:\n\n```bash\npython3 -m py_compile plugins/sap-architecture/skills/sap-architecture/scripts/*.py\n\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py inventory\n\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py describe \\\n  --limit 3\n\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py dry-run \\\n  --limit 3 --generator ollama --model qwen3.6:35b-a3b-nvfp4\n```\n\nCreate one diagram directly from a description:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py create \\\n  --generator ollama \\\n  --model qwen3.6:35b-a3b-nvfp4 \\\n  --apply-model-plan \\\n  --out-file .cache/my-sap-diagram.drawio \\\n  \"Create an L2 SAP BTP diagram for ...\"\n```\n\nOne-case Ollama smoke:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py run \\\n  --limit 1 \\\n  --generator ollama \\\n  --model qwen3.6:35b-a3b-nvfp4 \\\n  --max-attempts 1 \\\n  --min-score 90\n```\n\nLeave-one-out smoke, where the harness may not copy the target diagram and uses the closest alternate SAP visual neighbor:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py run \\\n  --limit 3 \\\n  --generator ollama \\\n  --model qwen3.6:35b-a3b-nvfp4 \\\n  --exclude-target-template \\\n  --apply-model-plan \\\n  --max-attempts 1 \\\n  --retry-margin 8 \\\n  --min-score 90 \\\n  --continue-on-error\n```\n\nPure semantic leave-one-out, without target-derived visual-neighbor hints:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py run \\\n  --limit 3 \\\n  --generator baseline \\\n  --exclude-target-template \\\n  --no-style-neighbor-hints \\\n  --max-attempts 1 \\\n  --retry-margin 8 \\\n  --min-score 90 \\\n  --continue-on-error\n```\n\nLong runs are opt-in:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py run \\\n  --generator ollama \\\n  --model qwen3.6:35b-a3b-nvfp4 \\\n  --exclude-target-template \\\n  --apply-model-plan \\\n  --max-attempts 3 \\\n  --retry-margin 8 \\\n  --min-score 90 \\\n  --timeout-seconds 1200 \\\n  --continue-on-error\n```\n\nFocused near-miss retry after a previous run:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/eval_corpus.py run \\\n  --from-run .cache/sap-architecture-eval/\u003crun-id\u003e \\\n  --case-class near-miss \\\n  --generator ollama \\\n  --model qwen3.6:35b-a3b-nvfp4 \\\n  --exclude-target-template \\\n  --apply-model-plan \\\n  --max-attempts 5 \\\n  --retry-margin 100 \\\n  --min-score 90 \\\n  --timeout-seconds 1200 \\\n  --continue-on-error\n```\n\nGenerated candidates, raw model output, `summary.json`, and `report.md` are written below `.cache/` and are intentionally untracked. Curate any useful examples into the repo only after reviewing them.\n\nOptional external SAP corpus: clone [`SAP/sap-btp-reference-architectures`](https://github.com/SAP/sap-btp-reference-architectures) under `.cache/external/` and run `eval_corpus.py --references .cache/external/sap-btp-reference-architectures ...` after the bundled run. That Apache-2.0 repository adds 32 editable `.drawio` test targets, including older BTP reference architectures that are intentionally harder than the bundled corpus. See [`references/external-test-corpus.md`](plugins/sap-architecture/skills/sap-architecture/references/external-test-corpus.md).\n\n### Validate an existing `.drawio`\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/validate.py my-diagram.drawio\n\n# strict mode — warnings become errors (exit 1)\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/validate.py --strict my-diagram.drawio\n\n# machine-readable report (JSON on stdout)\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/validate.py --json my-diagram.drawio\n```\n\nThe validator catches:\n\n| Check | Level |\n|---|---|\n| Malformed XML, duplicate ids, missing `mxGeometry` | error |\n| XML comments (`\u003c!-- --\u003e`) inside the mxfile | error |\n| Bent orthogonal edges (source/target centers not aligned on any axis) | error |\n| Label text wider than its shape (overflow / clipping) | error |\n| Sibling shape overlap (not contained, not transparent, not pill) | error |\n| Coordinates not on the 10-px grid | warning |\n| `arcSize` without `absoluteArcSize=1` | warning |\n| `strokeWidth` not in `{1, 1.5, 2, 3, 4}` | warning |\n| `fontFamily` ≠ Helvetica | warning |\n| Edge label missing `labelBackgroundColor=default` | warning |\n| Hex color outside the SAP Horizon palette | warning |\n\n### Autofix mechanical issues\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/autofix.py --write my-diagram.drawio\n# writes in place with my-diagram.drawio.bak backup\n```\n\nAutofix automatically repairs: grid snapping, hex case, missing `absoluteArcSize=1`, `strokeWidth` rounding to `{1, 1.5, 2, 3, 4}`, non-Helvetica fonts.\n\n### Regenerate the asset indexes\n\nAfter refreshing bundled SAP libraries:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/build_icon_index.py\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/build_asset_index.py\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/check_asset_coverage.py\n```\n\n---\n\n## What the skill does — workflow\n\nThe skill is an **authoring assistant**, not a one-shot generator. The realistic workflow takes 15-30 min per diagram; ~⅓ of scenarios pass the corpus loop without manual editing, the remaining ⅔ need surgical edits in draw.io desktop. See [`references/manual-workflow.md`](plugins/sap-architecture/skills/sap-architecture/references/manual-workflow.md) for the time-budget table and the full loop.\n\nWhen triggered, the skill runs a 6-step pipeline (documented in full in [`plugins/sap-architecture/skills/sap-architecture/SKILL.md`](plugins/sap-architecture/skills/sap-architecture/SKILL.md)):\n\n1. **Parse → plan** — infer level (L0/L1/L2, default L2), zones, services, numbered flow steps, and which service is the \"star\" (accent color).\n2. **Scaffold from a SAP reference template — MANDATORY** — run `scaffold_diagram.py \"\u003crequest\u003e\" --out \u003cfile\u003e.drawio`. The script ranks the 71 bundled SAP templates against the request, copies the best match to the destination, and prints alternates. The single most common cause of bad diagrams is the LLM trying to write XML from scratch — `scaffold_diagram.py` removes that temptation. Use `template_browser.py` (pre-rendered thumbnail gallery of all 71) when picking visually is faster than reading filenames.\n3. **Place BTP service icons** — fuzzy-lookup each service via `extract_icon.py`, which emits an `\u003cmxCell\u003e` with the official inline-SVG data URI and grid-snapped geometry.\n4. **Surgical relabel** — change labels with `relabel.py` where possible, swap services, add a few cards next to the existing ones. **Preserve canvas size, zone hierarchy, network divider, SAP logos, footer, and identity flow.** For complex scenarios that need more than relabeling, open the file in draw.io desktop and edit directly. Reference docs: `references/layout.md`, `palette-and-typography.md`, `shapes-and-edges.md`, `do-and-dont.md`, `manual-workflow.md`.\n5. **Validate, autofix, score — mandatory** — `autofix.py --write` first (mechanical repairs), then `validate.py` (now catches dark page backgrounds, novelty pill verbs like PROMPT/ROUTE/CONTEXT/DELEGATE, multi-logo over-use), then `score_corpus.py --min-score 90` for template-derived diagrams or `score_corpus.py --min-sap-like 90` for semantic fallback diagrams.\n5b. **Visual review (the missing last 20%)** — `render_compare.py \u003cref\u003e.drawio \u003ccand\u003e.drawio --open` builds an HTML page with side-by-side rendered PNGs, structural score breakdown, and **actionable suggestions mapped to the lowest-scoring fingerprint dimensions**. The fingerprint score is necessary but insufficient; the visual review catches what XML diffing can't.\n6. **Narrate the flow** — print a numbered list explaining what each pill means, for pasting below the embedded image in Markdown / Confluence.\n\n---\n\n## Design rules the skill enforces\n\nEvery rule is citable back to the SAP upstream. The skill never improvises palette values or style strings.\n\n| Rule | Value | Source |\n|---|---|---|\n| **Primary SAP/BTP area** | stroke `#0070F2`, fill `#EBF8FF` | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Non-SAP area** | stroke `#475E75`, fill `#F5F6F7` | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Positive semantic** | stroke `#188918`, fill `#F5FAE5` | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Accent — indigo (authorization)** | stroke `#5D36FF`, fill `#F1ECFF` | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Accent — pink (trust)** | stroke `#CC00DC`, fill `#FFF0FA` | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Accent — teal (MCP / emphasis)** | stroke `#07838F`, fill `#DAFDF5` | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Corner radius** | fixed 16 px (`arcSize=16;absoluteArcSize=1`) | [areas.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/areas.md) |\n| **Nested areas** | alternate fill / no-fill for contrast; parent is the BTP layer | [areas.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/areas.md) |\n| **Icons** | grey-background-circle variant only — *mandatory for diagram visualization* | [icons.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/icons.md) |\n| **Trust flows** | pink | [lines_connectors.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/lines_connectors.md) |\n| **Authentication flows** | green | [lines_connectors.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/lines_connectors.md) |\n| **Authorization flows** | indigo | [lines_connectors.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/lines_connectors.md) |\n| **Firewalls / network barriers** | thick grey (`strokeWidth=3` or `4`) | [lines_connectors.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/diagr_comp/lines_connectors.md) |\n| **Line styles** | solid = sync request/response; dashed = async; dotted = optional; thick = firewall only | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Spacing** | even, ~height of the SAP logo | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n| **Legend** | mandatory in each diagram | [foundation.md](https://github.com/SAP/btp-solution-diagrams/blob/main/guideline/docs/btp_guideline/foundation.md) |\n\nConventions this skill adds on top of the SAP upstream (none of which are prescribed by SAP, but all are accepted defaults across the community — [lemaiwo/btp-drawio-skill](https://github.com/lemaiwo/btp-drawio-skill), [miyasuta/claude-drawio-btp-diagram](https://github.com/miyasuta/claude-drawio-btp-diagram)):\n\n- **Canvas**: preserve the selected SAP template size; default new L2 diagrams to 1169 × 827 px (A4 landscape)\n- **Grid**: 10 px, everything snapped\n- **Font**: Helvetica (draw.io-portable; SAP products use \"72\")\n- **L0 / L1 / L2** — the level taxonomy documented by SAP's BTP Solution Diagram Guidelines. Default is **L2** (technical stakeholders, services + auth flows + legend). See [`references/levels.md`](plugins/sap-architecture/skills/sap-architecture/references/levels.md).\n\n### How the validator helps\n\nCompared with the generic \"eyeball it\" approach, the validator catches classes of bug an LLM can't reliably self-police:\n\n- **Bent arrows** — an `orthogonalEdgeStyle` edge between A and B only renders straight if `A.centerX == B.centerX` OR `A.centerY == B.centerY`. Off-by-5-px → visible 90° kink. This single rule (credit: [miyasuta/claude-drawio-btp-diagram](https://github.com/miyasuta/claude-drawio-btp-diagram)) is the highest-leverage polish trick in the whole pipeline.\n- **Label overflow** — `whiteSpace=wrap;html=1` labels are checked word-by-word; non-wrap labels are checked full-string. Prevents the \"my pill says 'OAUT'\" bug.\n- **Missing `labelBackgroundColor=default`** — without it, edge label text bleeds into the `#EBF8FF` BTP zone fill and becomes unreadable.\n- **Off-grid coordinates** — draw.io's UI loves emitting `239.9999999...` after a nudge. Autofix quantises them.\n- **`arcSize` without `absoluteArcSize=1`** — a 16 without absolute treats 16 as *percent*, so a 700-px-wide zone gets a 112-px corner radius.\n\n---\n\n## Repo layout\n\n```\nbtp-drawio-skill/\n├── README.md                              ← you are here\n├── LICENSE                                ← MIT (plugin code)\n├── .gitignore\n├── .claude-plugin/\n│   └── marketplace.json                   ← single-plugin marketplace catalog\n└── plugins/\n    └── sap-architecture/\n        ├── .claude-plugin/\n        │   └── plugin.json\n        ├── README.md                      ← plugin-level deep dive\n        └── skills/\n            └── sap-architecture/\n                ├── SKILL.md               ← 6-step workflow (\u003c500 lines)\n                ├── references/\n                │   ├── levels.md          ← L0/L1/L2 decision guide\n                │   ├── palette-and-typography.md  ← Horizon hex + Helvetica + SAP rules\n                │   ├── shapes-and-edges.md ← style strings + line semantics\n                │   ├── layout.md          ← canvas + zone-by-zone placement\n                │   ├── do-and-dont.md     ← consolidated SAP rules (verbatim quotes)\n                │   ├── corpus-findings.md ← 2026 SAP corpus profile\n                │   ├── generation-quality.md ← research-backed output checklist\n                │   ├── external-test-corpus.md ← optional external SAP corpus\n                │   ├── improvement-options.md ← researched ranking of next improvements\n                │   └── methodology.md     ← comparison harness, fidelity claim\n                ├── assets/\n                │   ├── libraries/         ← 10 SAP draw.io libraries (Apache-2.0)\n                │   ├── reference-examples/ ← 71 pristine SAP templates (Apache-2.0)\n                │   │   └── template-metadata.json ← curated selector aliases/tags\n                │   ├── icon-index.json    ← pre-computed slug→mxCell style lookup\n                │   ├── asset-index.json   ← 448 searchable SAP starter-kit assets\n                │   └── NOTICE.md          ← per-file Apache-2.0 attribution\n                ├── examples/\n                │   └── iam-arc1-mcp-l2.drawio  ← worked example (96.6 vs source; 100 self-check)\n                └── scripts/\n                    ├── build_icon_index.py\n                    ├── build_asset_index.py\n                    ├── extract_icon.py\n                    ├── extract_asset.py\n                    ├── relabel.py         ← deterministic id/visible-label replacement helper\n                    ├── render_semantic.py  ← deterministic fallback renderer\n                    ├── check_asset_coverage.py\n                    ├── validate.py\n                    ├── autofix.py\n                    ├── select_reference.py\n                    ├── compare.py         ← pairwise fingerprint score\n                    ├── score_corpus.py    ← best score across reference corpus\n                    └── eval_corpus.py     ← Ollama-ready corpus evaluation loop\n```\n\n---\n\n## Development\n\n### Testing the plugin locally before publishing\n\n```bash\ngit clone https://github.com/marianfoo/btp-drawio-skill.git\ncd btp-drawio-skill\n\n# Option A: load directly into your Claude Code session\nclaude --plugin-dir ./plugins/sap-architecture\n\n# Option B: register this checkout as a local marketplace\n# (in Claude Code)\n/plugin marketplace add ./\n/plugin install sap-architecture\n```\n\n### Running the validator in CI\n\n```yaml\n# .github/workflows/validate-diagrams.yml\n- name: Validate SAP architecture diagrams\n  run: |\n    for f in docs/**/*.drawio; do\n      python3 plugins/sap-architecture/skills/sap-architecture/scripts/autofix.py \"$f\"\n      python3 plugins/sap-architecture/skills/sap-architecture/scripts/validate.py \"$f\"\n      python3 plugins/sap-architecture/skills/sap-architecture/scripts/score_corpus.py --min-score 90 \"$f\"\n    done\n```\n\n### Regenerating the asset indexes\n\nAfter refreshing `assets/libraries/*.xml` from the SAP upstream:\n\n```bash\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/build_icon_index.py\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/build_asset_index.py\npython3 plugins/sap-architecture/skills/sap-architecture/scripts/check_asset_coverage.py\n```\n\n---\n\n## License \u0026 attribution\n\n- **Plugin code** (Python scripts, markdown references, plugin manifests, this README): MIT — see [LICENSE](LICENSE).\n- **Bundled SAP assets** under `plugins/sap-architecture/skills/sap-architecture/assets/` (icon library + reference templates): **Apache-2.0**, © SAP SE or an SAP affiliate company — sourced from [`SAP/btp-solution-diagrams`](https://github.com/SAP/btp-solution-diagrams) and [`SAP/architecture-center`](https://github.com/SAP/architecture-center). See `plugins/sap-architecture/skills/sap-architecture/assets/NOTICE.md` for full attribution.\n\n---\n\n## Credits \u0026 research sources\n\nThe skill's conventions were cross-referenced from the following sources, each cited inline in the design-rules table above:\n\n**SAP upstream — the canonical rules:**\n- [architecture.learning.sap.com](https://architecture.learning.sap.com/) — SAP Architecture Center\n- [`SAP/architecture-center`](https://github.com/SAP/architecture-center) — source `.drawio` files for published ref-archs\n- [`SAP/btp-solution-diagrams`](https://github.com/SAP/btp-solution-diagrams) — the official design system (Atomic model, Horizon palette, line / icon / connector rules)\n- [SAP BTP Solution Diagram Guidelines site](https://sap.github.io/btp-solution-diagrams/)\n\n**Prior art — community skills that informed this one:**\n- [`miyasuta/claude-drawio-btp-diagram`](https://github.com/miyasuta/claude-drawio-btp-diagram) — the center-alignment rule for straight orthogonal edges; the `docs/rules + docs/styles + docs/GUIDELINES.md` layering pattern\n- [`lemaiwo/btp-drawio-skill`](https://github.com/lemaiwo/btp-drawio-skill) — the marketplace + single-plugin repo layout used here; the approach of bundling SAP icon XML libraries directly\n\n**Claude Code plugin + skills docs:**\n- [Claude Code plugins](https://docs.claude.com/en/docs/claude-code/plugins)\n- [Plugin marketplaces](https://docs.claude.com/en/docs/claude-code/plugin-marketplaces)\n- [Skills](https://docs.claude.com/en/docs/claude-code/skills)\n- [Plugins reference](https://docs.claude.com/en/docs/claude-code/plugins-reference)\n- [Agent Skills open standard](https://agentskills.io)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarianfoo%2Fbtp-drawio-skill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarianfoo%2Fbtp-drawio-skill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarianfoo%2Fbtp-drawio-skill/lists"}