Skill: nonlinear/contract-diagram (version 1.0.1)

--- name: contract-diagram description: "Diagram as contract for agreed-upon AI development" type: public version: 1.0.0 status: stable dependencies: [] author: nonlinear license: MIT --- | Legend | Description | |--------|-------------| | ![default](https://img.shields.io/badge/default-lightgray) | Not discussed yet | | ![approved](https://img.shields.io/badge/approved-yellow) | Agreed by stakeholders | | ![blocker](https://img.shields.io/badge/blocker-red) | Needs discussion/failed implementation (always has notes) | | ![developed](https://img.shields.io/badge/developed-lightgreen) | Agreed and implemented | | ![notes](https://img.shields.io/badge/notes-blue) | Implemented but developer made decisions (in notes) | | ![outside](https://img.shields.io/badge/outside-lightgreen) | (dashed border) To be performed outside system | --- ## SKILL contract diagram ![Ready%20to%20check](https://img.shields.io/badge/Ready%20to%20check-lightgray) [ℹ️](https://github.com/nonlinear/skills/tree/main/contract-diagram/SKILL.md) ```mermaid %%{init: {'theme':'base','themeVariables':{"primaryColor":"#4A90E2","primaryTextColor":"#fff","primaryBorderColor":"#2E5C8A","lineColor":"#666","secondaryColor":"#50E3C2","tertiaryColor":"#FFD700","edgeLabelBackground":"#666"},'flowchart':{"nodeSpacing":50,"rankSpacing":50,"padding":15,"curve":"basis"}}}%% flowchart TD TRIGGER["Trigger + contract"] CHECK_CONTRACT{"Has contract?"} OPEN["Open contract"] CLARIFY["Clarify"] CHECK_DIAGRAM{"Has diagram?"} CREATE["New 1️⃣"] CLAIM["Claimed 1️⃣"] ERROR["Error 2️⃣"] DESIGN["Design phase"] SIGNOFF["Ready to approve"] DEVELOPMENT["Developing..."] BLOCKERS{"Has blockers?"} TESTS{"Pass checks? 3️⃣"} PUBLISH["Publish 3️⃣"] TRIGGER --> CHECK_CONTRACT CHECK_CONTRACT -->|Yes| OPEN CHECK_CONTRACT -->|Yes but<br/>not editable| ERROR CHECK_CONTRACT -->|No| CLARIFY CLARIFY --> TRIGGER OPEN --> CHECK_DIAGRAM CHECK_DIAGRAM -->|Yes, more<br/>than one| ERROR CHECK_DIAGRAM -->|Yes, one| CLAIM CHECK_DIAGRAM -->|No| CREATE CREATE --> DESIGN CLAIM --> DESIGN DESIGN --> SIGNOFF SIGNOFF -->|Approved| DEVELOPMENT DEVELOPMENT --> BLOCKERS BLOCKERS -->|Yes| DESIGN BLOCKERS -->|No| TESTS TESTS -->|Yes| PUBLISH TESTS -->|No| DESIGN classDef default fill:#e0e0e0,stroke:#666,color:#000 classDef approved fill:#FFF9C4,stroke:#F9A825,color:#000 classDef developed fill:#D5F5D5,stroke:#388E3C,color:#000 classDef blocker fill:#FFCDD2,stroke:#D32F2F,color:#000 classDef notes fill:#E3F2FD,stroke:#1976D2,color:#000 classDef outside fill:#D5F5D5,stroke:#388E3C,stroke-dasharray:5 5,color:#000 class CHECK_DIAGRAM,CREATE,CLAIM,ERROR,SIGNOFF,DESIGN,DEVELOPMENT,BLOCKERS,CHECK_CONTRACT,OPEN,CLARIFY,TRIGGER developed class PUBLISH,TESTS outside ``` **1️⃣** Wrapper auto-injects title + phase badge + CSS on first load and watches for change of phase on badge. **2️⃣** More than one diagram confuses system. For now, only one per md in order to run. **3️⃣** Checks and publication depend on what and where final product goes, so it's user discretion. --- ## Numbered Notes (1️⃣ 2️⃣ 3️⃣) **When to use:** **Pre-execution (design phase):** - Questions that need discussion - Trade-offs that need decisions - Unclear requirements **During execution:** - Errors AI can't resolve alone - Permission needed (destructive action, cost implications) - Ambiguity in implementation **Format:** ```markdown ### 1️⃣ [Component Name] - [Issue Title] **Question/Error:** ... **Context:** ... **Options:** A, B, C **Needed:** Decision / Permission / Help ``` **Notes without numbers = just explanations, turn yellow when approved.** --- ## Localhost Trigger **Trigger:** "lets diagram [PATH]" **Assumes:** File at PATH already has mermaid diagram. **Action:** 1. Start localhost server (port 8080) 2. Open browser with diagram **Example:** ``` User: "lets diagram epic-notes/webhook-contract.md" AI executes: cd ~/Documents/skills/contract-diagram/engine ./serve.sh & open "http://localhost:8080/?md=../../epic-notes/webhook-contract.md" ``` **Hot reload enabled by default** (2s interval). ---

path: github-markdown.css
content: /**
 * Minified by jsDelivr using clean-css v5.3.3.
 * Original file: /npm/github-markdown-css@5.9.0/github-markdown-light.css
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
.markdown-body{color-scheme:light;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;margin:0;font-weight:400;color:#1f2328;background-color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body a{text-decoration:underline;text-underline-offset:.2rem}.markdown-body .octicon{display:inline-block;fill:currentColor;vertical-align:text-bottom}.markdown-body h1:hover .anchor .octicon-link:before,.markdown-body h2:hover .anchor .octicon-link:before,.markdown-body h3:hover .anchor .octicon-link:before,.markdown-body h4:hover .anchor .octicon-link:before,.markdown-body h5:hover .anchor .octicon-link:before,.markdown-body h6:hover .anchor .octicon-link:before{width:16px;height:16px;content:' ';display:inline-block;background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");mask-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>")}.markdown-body details,.markdown-body figcaption,.markdown-body figure{display:block}.markdown-body summary{display:list-item}.markdown-body [hidden]{display:none!important}.markdown-body a{background-color:rgba(0,0,0,0);color:#0969da;text-decoration:none}.markdown-body abbr[title]{border-bottom:none;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.markdown-body b,.markdown-body strong{font-weight:600}.markdown-body dfn{font-style:italic}.markdown-body h1{margin:.67em 0;font-weight:600;padding-bottom:.3em;font-size:2em;border-bottom:1px solid #d1d9e0b3}.markdown-body mark{background-color:#fff8c5;color:#1f2328}.markdown-body small{font-size:90%}.markdown-body sub,.markdown-body sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.markdown-body sub{bottom:-.25em}.markdown-body sup{top:-.5em}.markdown-body img{border-style:none;max-width:100%;box-sizing:content-box}.markdown-body code,.markdown-body kbd,.markdown-body pre,.markdown-body samp{font-family:monospace;font-size:1em}.markdown-body figure{margin:1em 2.5rem}.markdown-body hr{box-sizing:content-box;overflow:hidden;background:rgba(0,0,0,0);border-bottom:1px solid #d1d9e0b3;height:.25em;padding:0;margin:1.5rem 0;background-color:#d1d9e0;border:0}.markdown-body input{font:inherit;margin:0;overflow:visible;font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body [type=button],.markdown-body [type=reset],.markdown-body [type=submit]{-webkit-appearance:button;appearance:button}.markdown-body [type=checkbox],.markdown-body [type=radio]{box-sizing:border-box;padding:0}.markdown-body [type=number]::-webkit-inner-spin-button,.markdown-body [type=number]::-webkit-outer-spin-button{height:auto}.markdown-body [type=search]::-webkit-search-cancel-button,.markdown-body [type=search]::-webkit-search-decoration{-webkit-appearance:none;appearance:none}.markdown-body ::-webkit-input-placeholder{color:inherit;opacity:.54}.markdown-body ::-webkit-file-upload-button{-webkit-appearance:button;appearance:button;font:inherit}.markdown-body a:hover{text-decoration:underline}.markdown-body ::placeholder{color:#59636e;opacity:1}.markdown-body hr::before{display:table;content:""}.markdown-body hr::after{display:table;clear:both;content:""}.markdown-body table{border-spacing:0;border-collapse:collapse;display:block;width:max-content;max-width:100%;overflow:auto;font-variant:tabular-nums}.markdown-body td,.markdown-body th{padding:0}.markdown-body details summary{cursor:pointer}.markdown-body [role=button]:focus,.markdown-body a:focus,.markdown-body input[type=checkbox]:focus,.markdown-body input[type=radio]:focus{outline:2px solid var(--borderColor-accent-emphasis);outline-offset:-2px;box-shadow:none}.markdown-body [role=button]:focus:not(:focus-visible),.markdown-body a:focus:not(:focus-visible),.markdown-body input[type=checkbox]:focus:not(:focus-visible),.markdown-body input[type=radio]:focus:not(:focus-visible){outline:solid 1px rgba(0,0,0,0)}.markdown-body [role=button]:focus-visible,.markdown-body a:focus-visible,.markdown-body input[type=checkbox]:focus-visible,.markdown-body input[type=radio]:focus-visible{outline:2px solid var(--borderColor-accent-emphasis);outline-offset:-2px;box-shadow:none}.markdown-body a:not([class]):focus,.markdown-body a:not([class]):focus-visible,.markdown-body input[type=checkbox]:focus,.markdown-body input[type=checkbox]:focus-visible,.markdown-body input[type=radio]:focus,.markdown-body input[type=radio]:focus-visible{outline-offset:0}.markdown-body kbd{display:inline-block;padding:.25rem;font:11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;line-height:10px;color:#1f2328;vertical-align:middle;background-color:#f6f8fa;border:solid 1px var(--borderColor-muted);border-bottom-color:var(--borderColor-muted);border-radius:6px;box-shadow:inset 0 -1px 0 var(--borderColor-muted)}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:1.5rem;margin-bottom:1rem;font-weight:600;line-height:1.25}.markdown-body h2{font-weight:600;padding-bottom:.3em;font-size:1.5em;border-bottom:1px solid #d1d9e0b3}.markdown-body h3{font-weight:600;font-size:1.25em}.markdown-body h4{font-weight:600;font-size:1em}.markdown-body h5{font-weight:600;font-size:.875em}.markdown-body h6{font-weight:600;font-size:.85em;color:#59636e}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0;padding:0 1em;color:#59636e;border-left:.25em solid #d1d9e0}.markdown-body ol,.markdown-body ul{margin-top:0;margin-bottom:0;padding-left:2em}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code,.markdown-body samp,.markdown-body tt{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:12px;word-wrap:normal}.markdown-body .octicon{display:inline-block;overflow:visible!important;vertical-align:text-bottom;fill:currentColor}.markdown-body input::-webkit-inner-spin-button,.markdown-body input::-webkit-outer-spin-button{margin:0;appearance:none}.markdown-body .mr-2{margin-right:.5rem!important}.markdown-body::before{display:table;content:""}.markdown-body::after{display:table;clear:both;content:""}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .absent{color:#d1242f}.markdown-body .anchor{float:left;padding-right:.25rem;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:0}.markdown-body blockquote,.markdown-body details,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:1rem}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1f2328;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1 code,.markdown-body h1 tt,.markdown-body h2 code,.markdown-body h2 tt,.markdown-body h3 code,.markdown-body h3 tt,.markdown-body h4 code,.markdown-body h4 tt,.markdown-body h5 code,.markdown-body h5 tt,.markdown-body h6 code,.markdown-body h6 tt{padding:0 .2em;font-size:inherit}.markdown-body summary h1,.markdown-body summary h2,.markdown-body summary h3,.markdown-body summary h4,.markdown-body summary h5,.markdown-body summary h6{display:inline-block}.markdown-body summary h1 .anchor,.markdown-body summary h2 .anchor,.markdown-body summary h3 .anchor,.markdown-body summary h4 .anchor,.markdown-body summary h5 .anchor,.markdown-body summary h6 .anchor{margin-left:-40px}.markdown-body summary h1,.markdown-body summary h2{padding-bottom:0;border-bottom:0}.markdown-body ol.no-list,.markdown-body ul.no-list{padding:0;list-style-type:none}.markdown-body ol[type="a s"]{list-style-type:lower-alpha}.markdown-body ol[type="A s"]{list-style-type:upper-alpha}.markdown-body ol[type="i s"]{list-style-type:lower-roman}.markdown-body ol[type="I s"]{list-style-type:upper-roman}.markdown-body ol[type="1"]{list-style-type:decimal}.markdown-body div>ol:not([type]){list-style-type:decimal}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:1rem}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:1rem;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 1rem;margin-bottom:1rem}.markdown-body table th{font-weight:600}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #d1d9e0}.markdown-body table td>:last-child{margin-bottom:0}.markdown-body table tr{background-color:#fff;border-top:1px solid #d1d9e0b3}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body table img{background-color:rgba(0,0,0,0)}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body .emoji{max-width:none;vertical-align:text-top;background-color:rgba(0,0,0,0)}.markdown-body span.frame{display:block;overflow:hidden}.markdown-body span.frame>span{display:block;float:left;width:auto;padding:7px;margin:13px 0 0;overflow:hidden;border:1px solid #d1d9e0}.markdown-body span.frame span img{display:block;float:left}.markdown-body span.frame span span{display:block;padding:5px 0 0;clear:both;color:#1f2328}.markdown-body span.align-center{display:block;overflow:hidden;clear:both}.markdown-body span.align-center>span{display:block;margin:13px auto 0;overflow:hidden;text-align:center}.markdown-body span.align-center span img{margin:0 auto;text-align:center}.markdown-body span.align-right{display:block;overflow:hidden;clear:both}.markdown-body span.align-right>span{display:block;margin:13px 0 0;overflow:hidden;text-align:right}.markdown-body span.align-right span img{margin:0;text-align:right}.markdown-body span.float-left{display:block;float:left;margin-right:13px;overflow:hidden}.markdown-body span.float-left span{margin:13px 0 0}.markdown-body span.float-right{display:block;float:right;margin-left:13px;overflow:hidden}.markdown-body span.float-right>span{display:block;margin:13px auto 0;overflow:hidden;text-align:right}.markdown-body code,.markdown-body tt{padding:.2em .4em;margin:0;font-size:85%;white-space:break-spaces;background-color:#818b981f;border-radius:6px}.markdown-body code br,.markdown-body tt br{display:none}.markdown-body del code{text-decoration:inherit}.markdown-body samp{font-size:85%}.markdown-body pre code{font-size:100%}.markdown-body pre>code{padding:0;margin:0;word-break:normal;white-space:pre;background:rgba(0,0,0,0);border:0}.markdown-body .highlight{margin-bottom:1rem}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:1rem;overflow:auto;font-size:85%;line-height:1.45;color:#1f2328;background-color:#f6f8fa;border-radius:6px}.markdown-body pre code,.markdown-body pre tt{display:inline;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:rgba(0,0,0,0);border:0}.markdown-body .csv-data td,.markdown-body .csv-data th{padding:5px;overflow:hidden;font-size:12px;line-height:1;text-align:left;white-space:nowrap}.markdown-body .csv-data .blob-num{padding:10px .5rem 9px;text-align:right;background:#fff;border:0}.markdown-body .csv-data tr{border-top:0}.markdown-body .csv-data th{font-weight:600;background:#f6f8fa;border-top:0}.markdown-body [data-footnote-ref]::before{content:"["}.markdown-body [data-footnote-ref]::after{content:"]"}.markdown-body .footnotes{font-size:12px;color:#59636e;border-top:1px solid #d1d9e0}.markdown-body .footnotes ol{padding-left:1rem}.markdown-body .footnotes ol ul{display:inline-block;padding-left:1rem;margin-top:1rem}.markdown-body .footnotes li{position:relative}.markdown-body .footnotes li:target::before{position:absolute;top:calc(.5rem*-1);right:calc(.5rem*-1);bottom:calc(.5rem*-1);left:calc(1.5rem*-1);pointer-events:none;content:"";border:2px solid #0969da;border-radius:6px}.markdown-body .footnotes li:target{color:#1f2328}.markdown-body .footnotes .data-footnote-backref g-emoji{font-family:monospace}.markdown-body .pl-c{color:#59636e}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#0550ae}.markdown-body .pl-e,.markdown-body .pl-en{color:#6639ba}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:#1f2328}.markdown-body .pl-ent{color:#0550ae}.markdown-body .pl-k{color:#cf222e}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:#0a3069}.markdown-body .pl-smw,.markdown-body .pl-v{color:#953800}.markdown-body .pl-bu{color:#82071e}.markdown-body .pl-ii{color:var(--fgColor-danger);background-color:var(--bgColor-danger-muted)}.markdown-body .pl-c2{color:#f6f8fa;background-color:#cf222e}.markdown-body .pl-sr .pl-cce{font-weight:700;color:#116329}.markdown-body .pl-ml{color:#3b2300}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:#0550ae}.markdown-body .pl-mi{font-style:italic;color:#1f2328}.markdown-body .pl-mb{font-weight:700;color:#1f2328}.markdown-body .pl-md{color:#82071e;background-color:#ffebe9}.markdown-body .pl-mi1{color:#116329;background-color:#dafbe1}.markdown-body .pl-mc{color:#953800;background-color:#ffd8b5}.markdown-body .pl-mi2{color:#d1d9e0;background-color:#0550ae}.markdown-body .pl-mdr{font-weight:700;color:#8250df}.markdown-body .pl-ba{color:#59636e}.markdown-body .pl-sg{color:#818b98}.markdown-body .pl-corl{text-decoration:underline;color:#0a3069}.markdown-body [role=button]:focus:not(:focus-visible),.markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible),.markdown-body a:focus:not(:focus-visible),.markdown-body button:focus:not(:focus-visible),.markdown-body summary:focus:not(:focus-visible){outline:0;box-shadow:none}.markdown-body [tabindex="0"]:focus:not(:focus-visible),.markdown-body details-dialog:focus:not(:focus-visible){outline:0}.markdown-body g-emoji{display:inline-block;min-width:1ch;font-family:"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1em;font-style:normal!important;font-weight:400;line-height:1;vertical-align:-.075em}.markdown-body g-emoji img{width:1em;height:1em}.markdown-body a:has(>p,>div,>pre,>blockquote){display:block}.markdown-body a:has(>p,>div,>pre,>blockquote):not(:has(.snippet-clipboard-content,>pre)){width:fit-content}.markdown-body a:has(>p,>div,>pre,>blockquote):has(.snippet-clipboard-content,>pre):focus-visible{outline:2px solid var(--borderColor-accent-emphasis);outline-offset:2px}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item label{font-weight:400}.markdown-body .task-list-item.enabled label{cursor:pointer}.markdown-body .task-list-item+.task-list-item{margin-top:.25rem}.markdown-body .task-list-item .handle{display:none}.markdown-body .task-list-item-checkbox{margin:0 .2em .25em -1.4em;vertical-align:middle}.markdown-body ul:dir(rtl) .task-list-item-checkbox{margin:0 -1.6em .25em .2em}.markdown-body ol:dir(rtl) .task-list-item-checkbox{margin:0 -1.6em .25em .2em}.markdown-body .contains-task-list:focus-within .task-list-item-convert-container,.markdown-body .contains-task-list:hover .task-list-item-convert-container{display:block;width:auto;height:24px;overflow:visible;clip-path:none}.markdown-body ::-webkit-calendar-picker-indicator{filter:invert(50%)}.markdown-body .markdown-alert{padding:.5rem 1rem;margin-bottom:1rem;color:inherit;border-left:.25em solid #d1d9e0}.markdown-body .markdown-alert>:first-child{margin-top:0}.markdown-body .markdown-alert>:last-child{margin-bottom:0}.markdown-body .markdown-alert .markdown-alert-title{display:flex;font-weight:500;align-items:center;line-height:1}.markdown-body .markdown-alert.markdown-alert-note{border-left-color:#0969da}.markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title{color:#0969da}.markdown-body .markdown-alert.markdown-alert-important{border-left-color:#8250df}.markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title{color:#8250df}.markdown-body .markdown-alert.markdown-alert-warning{border-left-color:#9a6700}.markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title{color:#9a6700}.markdown-body .markdown-alert.markdown-alert-tip{border-left-color:#1a7f37}.markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title{color:#1a7f37}.markdown-body .markdown-alert.markdown-alert-caution{border-left-color:#cf222e}.markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title{color:#d1242f}.markdown-body>:first-child>.heading-element:first-child{margin-top:0!important}.markdown-body .highlight pre:has(+.zeroclipboard-container){min-height:52px}
/*# sourceMappingURL=/sm/ed51229496fbc66644b6f8c9ae5da276c9ae43a5b9abff3a205e33365ae7bd1a.map */

path: serve.sh
content: #!/bin/bash
# Contract Diagram Engine - Read/Write Server Launcher

ENGINE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PORT=8080

echo "🏴 Contract Diagram Engine starting..."
echo "Engine: $ENGINE_DIR"
echo "Port: $PORT"
echo ""
echo "Usage: http://localhost:$PORT/?md=/path/to/file.md"
echo ""
echo "Example tape:"
echo "  http://localhost:$PORT/?md=contract-skill.md"
echo ""
echo "Press Ctrl+C to stop"
echo ""

cd "$ENGINE_DIR" && node server.js


path: server.js
content: #!/usr/bin/env node
// Contract Diagram Engine - Read/Write Server

const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');

const PORT = 8080;
const ENGINE_DIR = __dirname;

const mimeTypes = {
  '.html': 'text/html',
  '.js': 'text/javascript',
  '.css': 'text/css',
  '.json': 'application/json',
  '.md': 'text/markdown',
};

const server = http.createServer((req, res) => {
  const parsedUrl = url.parse(req.url, true);
  
  // REALPATH endpoint (GET /realpath?path=...)
  if (req.method === 'GET' && parsedUrl.pathname === '/realpath') {
    try {
      const filePath = parsedUrl.query.path;
      const fullPath = path.join(ENGINE_DIR, filePath);
      const realPath = fs.realpathSync(fullPath);
      const basename = path.basename(realPath);
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ basename }));
    } catch (error) {
      res.writeHead(500, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ error: error.message }));
    }
    return;
  }
  
  // WRITE endpoint (POST /write)
  if (req.method === 'POST' && parsedUrl.pathname === '/write') {
    let body = '';
    req.on('data', chunk => { body += chunk.toString(); });
    req.on('end', () => {
      try {
        const { path: filePath, content } = JSON.parse(body);
        const fullPath = path.join(ENGINE_DIR, filePath);
        
        // Security: only allow writes within engine directory
        if (!fullPath.startsWith(ENGINE_DIR)) {
          res.writeHead(403, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: 'Path outside engine directory' }));
          return;
        }
        
        fs.writeFileSync(fullPath, content, 'utf8');
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
      } catch (error) {
        res.writeHead(500, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ error: error.message }));
      }
    });
    return;
  }
  
  // READ endpoint (GET files)
  let filePath = parsedUrl.pathname === '/' ? '/index.html' : parsedUrl.pathname;
  filePath = path.join(ENGINE_DIR, filePath);
  
  const ext = path.extname(filePath);
  const contentType = mimeTypes[ext] || 'application/octet-stream';
  
  fs.readFile(filePath, (error, content) => {
    if (error) {
      if (error.code === 'ENOENT') {
        res.writeHead(404);
        res.end('File not found');
      } else {
        res.writeHead(500);
        res.end(`Server error: ${error.code}`);
      }
    } else {
      res.writeHead(200, { 'Content-Type': contentType });
      res.end(content, 'utf-8');
    }
  });
});

server.listen(PORT, () => {
  console.log('🏴 Contract Diagram Engine starting...');
  console.log(`Engine: ${ENGINE_DIR}`);
  console.log(`Port: ${PORT}`);
  console.log('');
  console.log(`Usage: http://localhost:${PORT}/?md=/path/to/file.md`);
  console.log('');
  console.log('Example tape:');
  console.log(`  http://localhost:${PORT}/?md=contract-skill.md`);
  console.log('');
  console.log('Press Ctrl+C to stop');
});


path: styles.css
content: /* Arch Engine Styles - Minimal + CSS Variables */

:root {
    /* Librarian mermaid colors */
    --default-bg: #e0e0e0;
    --default-border: #666;
    --approved-bg: #FFF9C4;
    --approved-border: #F9A825;
    --blocker-bg: #FFCDD2;
    --blocker-border: #D32F2F;
    --developed-bg: #D5F5D5;
    --developed-border: #388E3C;
    --notes-bg: #E3F2FD;
    --notes-border: #1976D2;
    --outside-bg: #D5F5D5;
    --outside-border: #388E3C;
    --partial-bg: #E1BEE7;
    --partial-border: #7B1FA2;
    --border-radius: 5px;
    
    /* Legacy */
    --in-progress-bg: #4A90E2;
    --pending-bg: #FFD700;
}

/* Base */
body {
    background: lime !important; /* DEBUG: se aparecer verde = CSS carrega */
    margin: 0;
    padding: 0;
    font-family: Helvetica, Arial, sans-serif;
}

main.container {
    padding: 15px !important;
    border: 3px solid red !important;
    background: yellow !important; /* DEBUG */
}

/* Mermaid container */
.mermaid {
    background: transparent;
}

/* Modal mermaid: stretch to fit */
.modal-body .mermaid svg {
    width: 100% !important;
    height: auto !important;
    max-width: 100% !important;
}

/* === MERMAID NODE CUSTOMIZATION === */

/* Base styling (applies to ALL nodes) */
.node rect, .node polygon, .node circle, .node path, .node ellipse {
  stroke-width: 2px !important;
}

/* Node text (universal) */
.mermaid .nodeLabel,
.mermaid .label,
.node text,
g.node text {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
  fill: black !important;
  color: black !important;
}

g.node > * {
  stroke-width: 2px !important;
}

g.node rect {
  rx: 5px !important;
  ry: 5px !important;
}

/* Default state (explicit) */
.default rect, .default polygon, .default circle, .default path, .default ellipse {
  fill: var(--default-bg) !important;
  stroke: var(--default-border) !important;
}

g.node.default path {
  fill: var(--default-bg) !important;
  stroke: var(--default-border) !important;
  stroke-width: 2px !important;
}

g.node.default polygon {
  stroke-width: 2px !important;
}
.approved rect, .approved polygon, .approved circle, .approved path, .approved ellipse {
  fill: var(--approved-bg) !important;
  stroke: var(--approved-border) !important;
}

g.node.approved path {
  fill: var(--approved-bg) !important;
  stroke: var(--approved-border) !important;
  stroke-width: 2px !important;
}

g.node.approved polygon {
  stroke-width: 2px !important;
}

/* Blocker state */
.blocker rect, .blocker polygon, .blocker circle, .blocker path, .blocker ellipse {
  fill: var(--blocker-bg) !important;
  stroke: var(--blocker-border) !important;
}

g.node.blocker path {
  fill: var(--blocker-bg) !important;
  stroke: var(--blocker-border) !important;
  stroke-width: 2px !important;
}

g.node.blocker polygon {
  stroke-width: 2px !important;
}

/* Developed state */
.developed rect, .developed polygon, .developed circle, .developed path, .developed ellipse {
  fill: var(--developed-bg) !important;
  stroke: var(--developed-border) !important;
}

g.node.developed path {
  fill: var(--developed-bg) !important;
  stroke: var(--developed-border) !important;
  stroke-width: 2px !important;
}

g.node.developed polygon {
  stroke-width: 2px !important;
}

/* Developed-notes state */
.notes rect, .notes polygon, .notes circle, .notes path, .notes ellipse {
  fill: var(--notes-bg) !important;
  stroke: var(--notes-border) !important;
}

g.node.notes path {
  fill: var(--notes-bg) !important;
  stroke: var(--notes-border) !important;
  stroke-width: 2px !important;
}

g.node.notes polygon {
  stroke-width: 2px !important;
}

/* Outside-system state (green with dashed borders) */
.outside rect, .outside polygon, .outside circle, .outside path, .outside ellipse {
  fill: var(--outside-bg) !important;
  stroke: var(--outside-border) !important;
  stroke-dasharray: 5 5 !important;
}

g.node.outside path {
  fill: var(--outside-bg) !important;
  stroke: var(--outside-border) !important;
  stroke-width: 2px !important;
  stroke-dasharray: 5 5 !important;
}

g.node.outside polygon {
  stroke-width: 2px !important;
  stroke-dasharray: 5 5 !important;
}

/* Partial state */
.partial rect, .partial polygon, .partial circle, .partial path, .partial ellipse {
  fill: var(--partial-bg) !important;
  stroke: var(--partial-border) !important;
}

g.node.partial path {
  fill: var(--partial-bg) !important;
  stroke: var(--partial-border) !important;
  stroke-width: 2px !important;
}

g.node.partial polygon {
  stroke-width: 2px !important;
}

/* Default (explicit class) */
g.node.default path {
  fill: var(--node-bg) !important;
  stroke: var(--node-border) !important;
  stroke-width: 2px !important;
}

g.node.default polygon {
  stroke-width: 2px !important;
}

/* Edge styling */
.edgePath path,
path.edgePath,
.flowchart-link {
  stroke: var(--default-border) !important;
  stroke-width: 2px !important;
  fill: none !important;
}

/* Edge labels - match arrow color */
.edgeLabel {
  opacity: 1 !important;
}

.edgeLabel rect,
.edgeLabel foreignObject {
  fill: var(--default-border) !important;
  stroke: none !important;
  rx: 5px !important;
  ry: 5px !important;
  opacity: 1 !important;
}

.edgeLabel .labelBkg,
.edgeLabel div {
  background-color: var(--default-border) !important;
  opacity: 1 !important;
  border-radius: 5px !important;
  padding: 5px 10px !important;
}

.labelBkg {
  opacity: 1 !important;
  background-color: var(--default-border) !important;
  border-radius: 5px !important;
  padding: 5px 10px !important;
}

div.labelBkg {
  opacity: 1 !important;
  background-color: var(--default-border) !important;
  border-radius: 5px !important;
  padding: 5px 10px !important;
}

foreignObject:has(.labelBkg) {
  opacity: 1 !important;
}

span.edgeLabel {
  background: var(--default-border) !important;
  border: none !important;
  border-radius: 5px !important;
  padding: 5px 10px !important;
  color: white !important;
  font-size: 80% !important;
  font-weight: normal !important;
  line-height: 100% !important;
  white-space: normal !important;
  word-wrap: break-word !important;
  max-width: 150px !important;
  display: inline-block !important;
}

.edgeLabel text {
  transform: rotate(0deg) !important;
  writing-mode: horizontal-tb !important;
  fill: white !important;
  font-size: 80% !important;
  line-height: 100% !important;
}

/* Force ALL children of node groups */
g.node > * {
  stroke-width: 2px !important;
}

/* Rounded corners for all node shapes */
g.node rect {
  rx: var(--border-radius) !important;
  ry: var(--border-radius) !important;
}

/* Legacy compatibility */
.mermaid .node.in-progress rect,
.mermaid .node.in-progress polygon {
    fill: var(--in-progress-bg) !important;
}

.mermaid .node.pending rect,
.mermaid .node.pending polygon {
    fill: var(--pending-bg) !important;
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: clean (LOW)