@reqvire-org/ads 0.0.0-stage → 0.2.9

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.
Files changed (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +284 -2
  3. package/dist/assets.mjs +52 -0
  4. package/dist/bootstrap-ds/ADS.md +203 -0
  5. package/dist/bootstrap-ds/README.md +98 -0
  6. package/dist/bootstrap-ds/biome.css.json +21 -0
  7. package/dist/bootstrap-ds/design-system/assets/brand/README.md +28 -0
  8. package/dist/bootstrap-ds/design-system/assets/fonts/.gitkeep +0 -0
  9. package/dist/bootstrap-ds/design-system/components/.gitkeep +0 -0
  10. package/dist/bootstrap-ds/design-system/composition/.gitkeep +0 -0
  11. package/dist/bootstrap-ds/design-system/index.ts +5 -0
  12. package/dist/bootstrap-ds/design-system/patterns/.gitkeep +0 -0
  13. package/dist/bootstrap-ds/design-system/showcase/mcp/index.html +1 -0
  14. package/dist/bootstrap-ds/design-system/showcase/mcp/main.tsx +8 -0
  15. package/dist/bootstrap-ds/design-system/styles.css +5 -0
  16. package/dist/bootstrap-ds/design-system/tokens/Foundation.fixture.ts +47 -0
  17. package/dist/bootstrap-ds/design-system/tokens/Foundation.scenario.tsx +14 -0
  18. package/dist/bootstrap-ds/design-system/tokens/base.css +27 -0
  19. package/dist/bootstrap-ds/design-system/tokens/colors.css +29 -0
  20. package/dist/bootstrap-ds/design-system/tokens/elevation.css +15 -0
  21. package/dist/bootstrap-ds/design-system/tokens/spacing.css +15 -0
  22. package/dist/bootstrap-ds/design-system/tokens/typography.css +13 -0
  23. package/dist/bootstrap-ds/ds.config.json +13 -0
  24. package/dist/bootstrap-ds/gitignore.template +8 -0
  25. package/dist/bootstrap-ds/package-lock.json +4660 -0
  26. package/dist/bootstrap-ds/package.json +41 -0
  27. package/dist/bootstrap-ds/scripts/build-mcp-previews.mjs +33 -0
  28. package/dist/bootstrap-ds/src/vite-env.d.ts +7 -0
  29. package/dist/bootstrap-ds/tsconfig.build.json +12 -0
  30. package/dist/bootstrap-ds/tsconfig.json +20 -0
  31. package/dist/bootstrap-ds/vite.config.ts +21 -0
  32. package/dist/boundaries.mjs +130 -0
  33. package/dist/brand-assets.mjs +82 -0
  34. package/dist/check.mjs +222 -0
  35. package/dist/cli.mjs +106 -0
  36. package/dist/config.mjs +181 -0
  37. package/dist/contracts/tokens.json +52 -0
  38. package/dist/html.mjs +30 -0
  39. package/dist/index.mjs +9 -0
  40. package/dist/init.mjs +194 -0
  41. package/dist/lint-config.mjs +40 -0
  42. package/dist/mcp/THIRD_PARTY_NOTICES.md +786 -0
  43. package/dist/mcp/apps.mjs +53 -0
  44. package/dist/mcp/build-status.mjs +164 -0
  45. package/dist/mcp/catalog.mjs +65 -0
  46. package/dist/mcp/context.mjs +69 -0
  47. package/dist/mcp/mutations.mjs +301 -0
  48. package/dist/mcp/patch.mjs +114 -0
  49. package/dist/mcp/preview-watch.mjs +169 -0
  50. package/dist/mcp/preview-widget.bundle.js +113 -0
  51. package/dist/mcp/project-widget.bundle.js +113 -0
  52. package/dist/mcp/prompts.mjs +28 -0
  53. package/dist/mcp/resource-loader.js +138 -0
  54. package/dist/mcp/sandbox-host.mjs +22 -0
  55. package/dist/mcp/server.mjs +377 -0
  56. package/dist/mcp/showcase-host.mjs +68 -0
  57. package/dist/mcp/skills.mjs +77 -0
  58. package/dist/mcp/widget.bundle.js +150 -0
  59. package/dist/oxlint.mjs +81 -0
  60. package/dist/preview-resources.mjs +198 -0
  61. package/dist/project-documents.mjs +27 -0
  62. package/dist/public-props.mjs +74 -0
  63. package/dist/scenarios-compiler.mjs +287 -0
  64. package/dist/scenarios-vite.d.mts +3 -0
  65. package/dist/scenarios-vite.mjs +71 -0
  66. package/dist/scenarios.mjs +212 -0
  67. package/dist/showcase/client.bundle.js +127 -0
  68. package/dist/showcase/index.html +17 -0
  69. package/dist/showcase/sandbox.js +30 -0
  70. package/dist/showcase/style.css +7 -0
  71. package/dist/showcase-coverage.mjs +118 -0
  72. package/dist/showcase.mjs +77 -0
  73. package/dist/skills/README.md +68 -0
  74. package/dist/skills/ads-assimilate/SKILL.md +292 -0
  75. package/dist/skills/ads-assimilate/agents/openai.yaml +4 -0
  76. package/dist/skills/ads-assimilate/references/cli.md +111 -0
  77. package/dist/skills/ads-assimilate/references/lint-and-docs.md +87 -0
  78. package/dist/skills/ads-assimilate/references/native-implementation.md +98 -0
  79. package/dist/skills/ads-assimilate/references/testing.md +107 -0
  80. package/dist/skills/ads-break-ui/LICENSE.upstream +21 -0
  81. package/dist/skills/ads-break-ui/README.md +16 -0
  82. package/dist/skills/ads-break-ui/SKILL.md +235 -0
  83. package/dist/skills/ads-break-ui/agents/openai.yaml +4 -0
  84. package/dist/skills/ads-break-ui/references/catalog.md +135 -0
  85. package/dist/skills/ads-break-ui/references/verification.md +48 -0
  86. package/dist/skills/ads-designer/LICENSE.upstream +21 -0
  87. package/dist/skills/ads-designer/README.md +19 -0
  88. package/dist/skills/ads-designer/SKILL.md +400 -0
  89. package/dist/skills/ads-designer/agents/openai.yaml +4 -0
  90. package/dist/skills/ads-designer/assets/bootstrap-ds/ADS.md +203 -0
  91. package/dist/skills/ads-designer/assets/bootstrap-ds/README.md +98 -0
  92. package/dist/skills/ads-designer/assets/bootstrap-ds/biome.css.json +21 -0
  93. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/assets/brand/README.md +28 -0
  94. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/assets/fonts/.gitkeep +0 -0
  95. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/components/.gitkeep +0 -0
  96. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/composition/.gitkeep +0 -0
  97. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/index.ts +5 -0
  98. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/.gitkeep +0 -0
  99. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/showcase/mcp/index.html +1 -0
  100. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/showcase/mcp/main.tsx +8 -0
  101. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/styles.css +5 -0
  102. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/Foundation.fixture.ts +47 -0
  103. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/Foundation.scenario.tsx +14 -0
  104. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/base.css +27 -0
  105. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/colors.css +29 -0
  106. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/elevation.css +15 -0
  107. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/spacing.css +15 -0
  108. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/typography.css +13 -0
  109. package/dist/skills/ads-designer/assets/bootstrap-ds/ds.config.json +13 -0
  110. package/dist/skills/ads-designer/assets/bootstrap-ds/gitignore.template +8 -0
  111. package/dist/skills/ads-designer/assets/bootstrap-ds/package-lock.json +4660 -0
  112. package/dist/skills/ads-designer/assets/bootstrap-ds/package.json +41 -0
  113. package/dist/skills/ads-designer/assets/bootstrap-ds/scripts/build-mcp-previews.mjs +33 -0
  114. package/dist/skills/ads-designer/assets/bootstrap-ds/src/vite-env.d.ts +7 -0
  115. package/dist/skills/ads-designer/assets/bootstrap-ds/tsconfig.build.json +12 -0
  116. package/dist/skills/ads-designer/assets/bootstrap-ds/tsconfig.json +20 -0
  117. package/dist/skills/ads-designer/assets/bootstrap-ds/vite.config.ts +21 -0
  118. package/dist/skills/ads-designer/references/cli.md +111 -0
  119. package/dist/skills/ads-designer/references/design-craft.md +65 -0
  120. package/dist/skills/ads-designer/references/mobile.md +73 -0
  121. package/dist/skills/ads-import/SKILL.md +335 -0
  122. package/dist/skills/ads-import/agents/openai.yaml +4 -0
  123. package/dist/skills/ads-import/references/branding.md +44 -0
  124. package/dist/skills/ads-import/references/cli.md +111 -0
  125. package/dist/skills/ads-import/references/implementation.md +111 -0
  126. package/dist/skills/ads-import/references/tokens.md +96 -0
  127. package/dist/skills/ads-motion/LICENSE.upstream +21 -0
  128. package/dist/skills/ads-motion/README.md +22 -0
  129. package/dist/skills/ads-motion/SKILL.md +217 -0
  130. package/dist/skills/ads-motion/agents/openai.yaml +4 -0
  131. package/dist/skills/ads-motion/references/audit.md +44 -0
  132. package/dist/skills/ads-motion/references/build.md +81 -0
  133. package/dist/skills/ads-motion/references/performance.md +55 -0
  134. package/dist/skills/ads-motion/references/review.md +35 -0
  135. package/dist/skills/ads-motion/references/verification.md +39 -0
  136. package/dist/token-policy.mjs +10 -0
  137. package/dist/tokens.mjs +142 -0
  138. package/dist/ui-framework.mjs +59 -0
  139. package/dist/units.mjs +168 -0
  140. package/docs/ADS.md +310 -0
  141. package/docs/ARCHITECTURE.md +311 -0
  142. package/docs/CHANGELOG.md +106 -0
  143. package/docs/GUIDE.md +722 -0
  144. package/docs/MCP.md +690 -0
  145. package/package.json +107 -4
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="en" data-theme="light">
3
+ <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>ADS Showcase</title><link rel="stylesheet" href="/style.css"></head>
4
+ <body>
5
+ <header id="header">
6
+ <div id="brand"><span class="mark">ADS</span><span id="title">Design System</span><button id="pane-toggle" aria-label="Hide navigation pane" aria-expanded="true" aria-controls="sidebar" title="Hide navigation pane"><svg viewBox="0 0 16 16"><path d="M10 4l-4 4 4 4"/></svg></button></div>
7
+ <nav id="sections" aria-label="Showcase sections">
8
+ <button data-section="tokens" aria-current="page"><svg viewBox="0 0 16 16"><path d="m8 2 6 3-6 3-6-3 6-3Zm-6 6 6 3 6-3M2 11l6 3 6-3"/></svg>Tokens</button>
9
+ <button data-section="components"><svg viewBox="0 0 16 16"><path d="m8 1 6 3.5v7L8 15l-6-3.5v-7L8 1Zm-6 3.5 6 3.5 6-3.5M8 8v7"/></svg>Components</button>
10
+ <button data-section="patterns"><svg viewBox="0 0 16 16"><rect x="2" y="2" width="5" height="5"/><rect x="10" y="2" width="4" height="5"/><rect x="2" y="10" width="5" height="4"/><rect x="10" y="10" width="4" height="4"/></svg>Patterns</button>
11
+ <button data-section="composition"><svg viewBox="0 0 16 16"><path d="M2 2h4v4H2zM10 2h4v4h-4zM2 10h4v4H2zM10 10h4v4h-4z"/></svg>Composition</button>
12
+ </nav>
13
+ <div class="actions"><button id="theme" aria-label="Use dark theme" title="Use dark theme"><svg viewBox="0 0 16 16"><path d="M13.5 9a5.5 5.5 0 0 1-6.5-6.5A5.5 5.5 0 1 0 13.5 9Z"/></svg></button><button id="minimize" aria-label="Minimize showcase menu" title="Minimize showcase menu (refresh to restore)"><svg viewBox="0 0 16 16"><path d="m4 10 4-4 4 4"/></svg></button></div>
14
+ </header>
15
+ <main><aside id="sidebar"><nav id="entries" aria-label="Tokens"></nav></aside><section id="preview" aria-label="Preview"><p id="status" role="status">Connecting to ADS MCP…</p><div id="loader" role="status" aria-label="Loading preview" hidden><span class="spinner" aria-hidden="true"></span></div><div id="frame-slot"></div></section></main>
16
+ <script type="module" src="/client.js"></script>
17
+ </body></html>
@@ -0,0 +1,30 @@
1
+ const parentOrigin = new URL(location.href).searchParams.get("parent");
2
+ let view;
3
+ function domains(values = []) {
4
+ return values.filter(value => /^(?:https?:\/\/[a-z0-9.*:[\]-]+(?::\d+)?|data:|blob:|about:)$/i.test(value)).join(" ");
5
+ }
6
+ function policy(csp = {}) {
7
+ const resources = domains(csp.resourceDomains);
8
+ return `default-src 'none';script-src 'unsafe-inline' ${resources};style-src 'unsafe-inline' ${resources};img-src data: ${resources};font-src ${resources || "'none'"};media-src ${resources || "'none'"};worker-src ${resources || "'none'"};connect-src ${domains(csp.connectDomains) || "'none'"};frame-src ${domains(csp.frameDomains) || "'none'"};base-uri ${domains(csp.baseUriDomains) || "'none'"};object-src 'none'`;
9
+ }
10
+ window.addEventListener("message", event => {
11
+ if (event.source === parent && event.origin === parentOrigin) {
12
+ const message = event.data;
13
+ if (message?.method === "ui/notifications/sandbox-resource-ready") {
14
+ const { html, csp } = message.params ?? {};
15
+ if (typeof html !== "string") return;
16
+ const document = new DOMParser().parseFromString(html, "text/html");
17
+ const meta = document.createElement("meta");
18
+ meta.httpEquiv = "Content-Security-Policy";
19
+ meta.content = policy(csp);
20
+ document.head.prepend(meta);
21
+ view?.remove();
22
+ view = window.document.createElement("iframe");
23
+ view.title = "Design-system App";
24
+ view.setAttribute("sandbox", "allow-scripts");
25
+ window.document.body.append(view);
26
+ view.srcdoc = "<!doctype html>" + document.documentElement.outerHTML;
27
+ } else if (message?.jsonrpc === "2.0" && !message.method?.startsWith("ui/notifications/sandbox-")) view?.contentWindow.postMessage(message, "*");
28
+ } else if (event.source === view?.contentWindow && event.data?.jsonrpc === "2.0" && !event.data.method?.startsWith("ui/notifications/sandbox-")) parent.postMessage(event.data, parentOrigin);
29
+ });
30
+ parent.postMessage({ jsonrpc: "2.0", method: "ui/notifications/sandbox-proxy-ready", params: {} }, parentOrigin);
@@ -0,0 +1,7 @@
1
+ :root{font:13px/1.5 system-ui,sans-serif;color-scheme:light;background:#fafafa;color:#444;--frame-bg:#fafafa;--frame-ink:#444;--frame-line:#ddd;--pane-width:min(276px,42vw)}
2
+ :root[data-theme="dark"]{color-scheme:dark;--frame-bg:#181818;--frame-ink:#ddd;--frame-line:#444;background:var(--frame-bg);color:var(--frame-ink)}
3
+ *{box-sizing:border-box}body{margin:0;height:100vh;display:flex;flex-direction:column;overflow:hidden}button,a{font:inherit;color:inherit}button{cursor:pointer;background:transparent;border:1px solid var(--frame-line);border-radius:4px}button:focus-visible,a:focus-visible{outline:2px solid var(--frame-ink);outline-offset:2px}svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:none}svg:not([aria-label]){pointer-events:none}
4
+ header{height:52px;display:flex;flex:none;border-bottom:1px solid var(--frame-line);align-items:stretch;background:var(--frame-bg)}#brand{width:var(--pane-width);display:flex;flex:none;gap:8px;align-items:center;padding:0 12px;border-right:1px solid var(--frame-line);font-weight:600;white-space:nowrap}#brand .mark{font-weight:700}#title{min-width:0;overflow:hidden;text-overflow:ellipsis}#pane-toggle{width:28px;height:28px;margin-inline-start:auto;display:grid;place-items:center;flex:none}.collapsed #brand{width:44px;padding:0 8px;border-right:0}.collapsed #brand .mark,.collapsed #title{display:none}
5
+ #sections{display:flex;gap:4px;align-items:center;min-width:0;overflow-x:auto;padding:8px}#sections button{display:flex;align-items:center;gap:8px;flex:none;border-color:transparent;padding:6px 10px}#sections button[aria-current="page"]{border-color:var(--frame-line)}#sections svg{opacity:.7}.actions{display:flex;align-items:center;gap:4px;margin-inline-start:auto;padding:8px;flex:none}.actions button{width:28px;height:28px;display:grid;place-items:center}
6
+ main{flex:1;min-height:0;display:flex}#sidebar{width:var(--pane-width);flex:none;border-right:1px solid var(--frame-line);overflow-y:auto;background:var(--frame-bg)}#entries{display:flex;flex-direction:column;gap:4px;padding:8px}#entries a{flex:none;padding:8px;border:1px solid transparent;border-radius:4px;text-decoration:none;overflow-wrap:anywhere}#entries a:hover,#entries a[aria-current="page"]{border-color:var(--frame-line)}#entries a[aria-current="page"]{font-weight:600}
7
+ #preview{position:relative;flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:hidden}#frame-slot{flex:1;min-height:0;min-width:0}iframe{display:block;width:100%;height:100%;border:0}#status{position:absolute;z-index:1;inset:12px 12px auto;margin:0;padding:12px 16px;border:1px solid var(--frame-line);border-radius:4px;background:var(--frame-bg);white-space:pre-wrap;overflow-wrap:anywhere;max-height:30vh;overflow:auto}#status[data-error="true"]{color:CanvasText;background:Canvas;border-color:GrayText}#loader{position:absolute;inset:0;z-index:2;display:grid;place-items:center;background:var(--frame-bg)}.spinner{width:24px;height:24px;border:2px solid var(--frame-line);border-top-color:var(--frame-ink);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.spinner{animation:none}}[hidden],.collapsed #sidebar{display:none!important}@media(max-width:760px){#title{display:none}}
@@ -0,0 +1,118 @@
1
+ import path from "node:path";
2
+ import ts from "typescript";
3
+ import { uiOperation } from "./ui-framework.mjs";
4
+ import { isInside, isTestFile, isDevelopmentFile } from "./config.mjs";
5
+
6
+ // Compare statically rendered public UI, not imports or every value in a barrel.
7
+ // Symbol identity keeps aliases, same-file exports, and shadowed names distinct.
8
+ export function inspectShowcaseCoverage(options, program, report) {
9
+ const { dsRoot, sourceRoot, config } = options;
10
+ const checker = program.getTypeChecker();
11
+ const entry = program.getSourceFile(path.join(dsRoot, config.publicEntry));
12
+ const module = entry && checker.getSymbolAtLocation(entry);
13
+ if (!module) return;
14
+ const showcase = path.join(dsRoot, "showcase");
15
+ const implementations = [path.join(dsRoot, "components"), path.join(dsRoot, "patterns")];
16
+
17
+ function symbolOf(expression) {
18
+ while (expression && (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression) || ts.isSatisfiesExpression(expression) || ts.isNonNullExpression(expression))) expression = expression.expression;
19
+ if (!expression) return null;
20
+ if (ts.isElementAccessExpression(expression) && expression.argumentExpression && ts.isStringLiteralLike(expression.argumentExpression)) {
21
+ return checker.getPropertyOfType(checker.getTypeAtLocation(expression.expression), expression.argumentExpression.text);
22
+ }
23
+ return checker.getSymbolAtLocation(expression);
24
+ }
25
+ function canonical(symbol, seen = new Set()) {
26
+ if (!symbol || seen.has(symbol)) return null;
27
+ seen.add(symbol);
28
+ if (symbol.flags & ts.SymbolFlags.Alias) return canonical(checker.getAliasedSymbol(symbol), seen);
29
+ for (const declaration of symbol.declarations ?? []) {
30
+ if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
31
+ const target = symbolOf(declaration.initializer);
32
+ if (target) return canonical(target, seen);
33
+ }
34
+ if (ts.isBindingElement(declaration) && ts.isObjectBindingPattern(declaration.parent) && ts.isVariableDeclaration(declaration.parent.parent)) {
35
+ const initializer = declaration.parent.parent.initializer;
36
+ const key = declaration.propertyName ?? declaration.name;
37
+ if (initializer && (ts.isIdentifier(key) || ts.isStringLiteralLike(key))) {
38
+ const target = checker.getPropertyOfType(checker.getTypeAtLocation(initializer), key.text);
39
+ if (target) return canonical(target, seen);
40
+ }
41
+ }
42
+ }
43
+ return symbol.declarations?.length ? symbol : null;
44
+ }
45
+ // The declaration also unifies a named default export with its local name.
46
+ function identity(symbol) { return symbol?.valueDeclaration ?? symbol?.declarations?.[0]; }
47
+ const publicUi = new Map();
48
+ for (const exported of checker.getExportsOfModule(module)) {
49
+ const symbol = canonical(exported);
50
+ const declaration = identity(symbol);
51
+ if (!declaration || !(symbol.flags & ts.SymbolFlags.Value)) continue;
52
+ if (!implementations.some((directory) => isInside(directory, declaration.getSourceFile().fileName))) continue;
53
+ const item = publicUi.get(declaration) ?? { symbol, names: [] };
54
+ item.names.push(exported.name);
55
+ publicUi.set(declaration, item);
56
+ }
57
+ if (!publicUi.size) return;
58
+
59
+
60
+ function uses(node, consume, helpers = false) {
61
+ function visit(child) {
62
+ if (ts.isJsxOpeningElement(child) || ts.isJsxSelfClosingElement(child)) {
63
+ if (!(ts.isIdentifier(child.tagName) && /^[a-z]/.test(child.tagName.text))) consume(canonical(symbolOf(child.tagName)), child, true);
64
+ }
65
+ if (ts.isCallExpression(child)) {
66
+ const operation = uiOperation(child.expression, checker);
67
+ if (operation === "createElement" || helpers && ["memo", "forwardRef"].includes(operation)) consume(canonical(symbolOf(child.arguments[0])), child, true);
68
+ // A shared render helper can contain the actual component JSX.
69
+ if (helpers && !operation) consume(canonical(symbolOf(child.expression)), child, false);
70
+ }
71
+ ts.forEachChild(child, visit);
72
+ }
73
+ visit(node);
74
+ }
75
+ const dependencies = new Map();
76
+ function children(symbol) {
77
+ const key = identity(symbol);
78
+ if (dependencies.has(key)) return dependencies.get(key);
79
+ const result = new Map();
80
+ dependencies.set(key, result);
81
+ for (const declaration of symbol.declarations ?? []) {
82
+ const file = declaration.getSourceFile().fileName;
83
+ if (isTestFile(file) || ![sourceRoot, showcase, ...implementations].some((directory) => isInside(directory, file))) continue;
84
+ uses(declaration, (child, _node, ui) => { if (child) result.set(child, ui || result.get(child) || false); }, true);
85
+ }
86
+ return result;
87
+ }
88
+ function rendered(symbol, consume, seen = new Map(), ui = true) {
89
+ const key = identity(symbol);
90
+ if (!key || seen.has(key) && (!ui || seen.get(key))) return;
91
+ seen.set(key, ui || seen.get(key) || false);
92
+ if (ui && publicUi.has(key)) consume(key);
93
+ for (const [child, childUi] of children(symbol)) rendered(child, consume, seen, childUi);
94
+ }
95
+
96
+ const production = new Map();
97
+ const demonstrated = new Set();
98
+ for (const source of program.getSourceFiles()) {
99
+ const file = source.fileName;
100
+ if (isTestFile(file)) continue;
101
+ const example = isDevelopmentFile(file, options);
102
+ const application = isInside(sourceRoot, file) && !isInside(dsRoot, file);
103
+ if (!example && !application) continue;
104
+ uses(source, (symbol, node) => rendered(symbol, (key) => {
105
+ if (example) demonstrated.add(key);
106
+ else {
107
+ const direct = identity(symbol) === key;
108
+ if (!production.has(key) || direct && !production.get(key).direct) production.set(key, { node, direct });
109
+ }
110
+ }));
111
+ }
112
+ for (const [key, { node }] of production) {
113
+ if (demonstrated.has(key)) continue;
114
+ const source = node.getSourceFile();
115
+ const position = source.getLineAndCharacterOfPosition(node.getStart(source));
116
+ report(source.fileName, "showcase-coverage", `Public ADS UI ${publicUi.get(key).names.join(" / ")} is rendered by application source but has no showcase render reference. Add an example using the public API; an import alone or a test harness does not count.`, position.line + 1, position.character + 1);
117
+ }
118
+ }
@@ -0,0 +1,77 @@
1
+ import { existsSync, readdirSync } from "node:fs";
2
+ import path from "node:path";
3
+ import ts from "typescript";
4
+ import { isInside, isTestFile } from "./config.mjs";
5
+
6
+ export const showcasePages = ["TokensPage", "ComponentsPage", "PatternsPage", "CompositionPage"];
7
+
8
+ export function inspectShowcasePages({ dsRoot, config }, program, resolve, report) {
9
+ const pages = path.join(dsRoot, "showcase/pages");
10
+ if (!existsSync(pages)) return; // A project with no showcase yet still checks.
11
+ const entries = readdirSync(pages, { withFileTypes: true }).filter((entry) => entry.isFile() && /\.[cm]?[jt]sx?$/.test(entry.name) && !isTestFile(entry.name));
12
+ if (!entries.length) return; // The built-in MCP client needs no project browser pages.
13
+ for (const entry of entries) {
14
+ if (!showcasePages.includes(entry.name.replace(/\.[^.]+$/, ""))) report(path.join(pages, entry.name), "showcase-pages", "Showcase pages are TokensPage, ComponentsPage, PatternsPage, and CompositionPage. Put scenarios beside their owners or under composition/.");
15
+ }
16
+ for (const name of showcasePages) {
17
+ if (!entries.some((entry) => entry.name.replace(/\.[^.]+$/, "") === name)) report(pages, "showcase-pages", `Missing ${name}: use the standard Tokens, Components, Patterns, and Composition showcase pages.`);
18
+ }
19
+ const cache = new Map();
20
+ function exports(file, chain = new Set()) {
21
+ if (cache.has(file)) return cache.get(file);
22
+ if (chain.has(file)) return new Map();
23
+ chain = new Set([...chain, file]);
24
+ const result = new Map();
25
+ const source = program.getSourceFile(file);
26
+ if (!source) return result;
27
+ for (const node of source.statements) {
28
+ if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
29
+ const target = resolve(node.moduleSpecifier.text, file)[0];
30
+ const nested = exports(target, chain);
31
+ if (node.exportClause && ts.isNamedExports(node.exportClause)) {
32
+ for (const item of node.exportClause.elements) result.set(item.name.text, nested.get((item.propertyName ?? item.name).text) ?? target);
33
+ } else if (!node.exportClause) for (const [name, owner] of nested) result.set(name, owner);
34
+ } else if (node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) {
35
+ if (node.name && ts.isIdentifier(node.name)) result.set(node.name.text, file);
36
+ if (ts.isVariableStatement(node)) for (const decl of node.declarationList.declarations) if (ts.isIdentifier(decl.name)) result.set(decl.name.text, file);
37
+ }
38
+ }
39
+ cache.set(file, result);
40
+ return result;
41
+ }
42
+ const publicExports = exports(path.join(dsRoot, config.publicEntry));
43
+ const visited = new Set();
44
+ function catalogue(file) {
45
+ if (visited.has(file)) return;
46
+ visited.add(file);
47
+ const source = program.getSourceFile(file);
48
+ if (!source) return;
49
+ function visit(node) {
50
+ let specifier;
51
+ if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) specifier = node.moduleSpecifier.text;
52
+ const dynamic = ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword;
53
+ if (dynamic && node.arguments[0] && ts.isStringLiteral(node.arguments[0])) specifier = node.arguments[0].text;
54
+ if (specifier === config.publicAlias && !node.importClause?.isTypeOnly && !node.isTypeOnly) {
55
+ const bindings = node.importClause?.namedBindings ?? node.exportClause;
56
+ // Named imports/re-exports keep the catalogue's dependency ownership explicit.
57
+ // Namespace/dynamic imports can select arbitrary exports, so check their whole surface.
58
+ const named = bindings && (ts.isNamedImports(bindings) || ts.isNamedExports(bindings));
59
+ const imported = named ? bindings.elements.filter((item) => !item.isTypeOnly).map((item) => (item.propertyName ?? item.name).text)
60
+ : dynamic || bindings || ts.isExportDeclaration(node) ? [...publicExports.keys()]
61
+ : node.importClause?.name ? ["default"] : [];
62
+ for (const name of imported) {
63
+ const owner = publicExports.get(name);
64
+ if (owner && isInside(path.join(dsRoot, "patterns"), owner) && !isInside(path.join(dsRoot, "patterns/showcase"), owner)) {
65
+ const position = source.getLineAndCharacterOfPosition(node.getStart(source));
66
+ report(file, "showcase-catalogue", `${name} is a pattern. Demonstrate it in PatternsPage or CompositionPage; TokensPage and ComponentsPage use primitives and the shared showcase frame.`, position.line + 1, position.character + 1);
67
+ }
68
+ }
69
+ } else if (specifier) {
70
+ for (const target of resolve(specifier, file)) if (isInside(path.join(dsRoot, "showcase"), target)) catalogue(target);
71
+ }
72
+ ts.forEachChild(node, visit);
73
+ }
74
+ visit(source);
75
+ }
76
+ for (const entry of entries) if (/^(?:TokensPage|ComponentsPage)\./.test(entry.name)) catalogue(path.join(pages, entry.name));
77
+ }
@@ -0,0 +1,68 @@
1
+ # ADS skills
2
+
3
+ Install the skills you need with `npx skills`:
4
+
5
+ ```sh
6
+ npx skills add reqvire-org/design-system --skill ads-designer --skill ads-import --skill ads-assimilate --skill ads-break-ui --skill ads-motion
7
+ ```
8
+
9
+ For local development, install from this checkout:
10
+
11
+ ```sh
12
+ npx skills add ./skills --skill ads-designer --skill ads-import --skill ads-assimilate --skill ads-break-ui --skill ads-motion
13
+ ```
14
+
15
+ Each skill includes its own instructions and references. `ads-designer` also
16
+ includes an empty bootstrap scaffold, so starting from zero needs no example
17
+ repository. Skills operate on a project's local ADS; they do not install a UI
18
+ catalogue or replace the project's theme values.
19
+
20
+ The [stdio MCP server](../docs/MCP.md#skills) also serves these skills and supporting
21
+ files from the npm distribution. Native Skills discovery is available on the
22
+ newer protocol; ordinary tools/resources provide explicit access on older
23
+ clients. MCP serving does not install or automatically activate a skill.
24
+
25
+ For inspection, start with `ads_status`, search the public API with `ads_catalog`,
26
+ read its source/available guides and relevant tokens, then discover an entry with
27
+ `ads_scenarios` and render it with `ads_show_scenario`. Check build freshness after
28
+ edits. The [MCP inspection guide](../docs/MCP.md#inspect-the-design-system) explains
29
+ the sequence, resource-only fallback and limits of metadata versus rendered review.
30
+
31
+ Each workflow updates relevant showcase examples, runs build guards, inspects
32
+ the browser, and provides a running URL or exact command for review. See the
33
+ [architecture](../docs/ARCHITECTURE.md) for the rationale and tooling requirements.
34
+
35
+ | Skill | Use | Example |
36
+ |-------|-----|---------|
37
+ | [ads-designer](ads-designer/SKILL.md) | Bootstrap or build UI using the local ADS, with craft/mobile guidance | `$ads-designer build a settings page using this project's ADS` |
38
+ | [ads-import](ads-import/SKILL.md) | Import selected external ADS source, brand artwork, or compatible source token values | `$ads-import /path/to/source-repo component Toast` |
39
+ | [ads-assimilate](ads-assimilate/SKILL.md) | Study an external component library and implement a native counterpart | `$ads-assimilate https://github.com/emilkowalski/sonner` |
40
+ | [ads-break-ui](ads-break-ui/SKILL.md) | Stress-test real components/patterns; optionally fix demonstrated failures | `$ads-break-ui AppShell +fix` |
41
+ | [ads-motion](ads-motion/SKILL.md) | Implement, review, audit, or profile motion | `$ads-motion review Toast` |
42
+
43
+ For token values, use `$ads-import /path/to/source-repo tokens`; for original
44
+ artwork and its guidance, use `$ads-import /path/to/source-repo brand`. ADS token
45
+ names and ownership prefixes are fixed; imports conform to that architecture.
46
+ For motion, the
47
+ request selects the mode, for example `build`, `audit`, or `performance`.
48
+ Review/audit requests report findings; a fix request authorizes implementation.
49
+ The import workflow is a skill, not a CLI `ads import` command.
50
+
51
+ `ads-break-ui`, `ads-motion`, and the craft/mobile references in `ads-designer`
52
+ adapt [Emil Kowalski's MIT-licensed skills](https://github.com/emilkowalski/skills).
53
+ Their local READMEs record pinned source revisions and specific influences;
54
+ each folder retains the upstream MIT notice. Preserve those notices when
55
+ redistributing the skills. Component-library notices belong beside the imported component in its receiving
56
+ project, separate from these skill notices.
57
+
58
+ The showcase is a tool-owned minimal shell plus an MCP client and Apps host.
59
+ Its four sections discover token categories and scenario entries through MCP.
60
+ The skills use the connected runtime URL, or `ads showcase` for browser-only work;
61
+ they do not generate page browsers or duplicate the tool shell. Scenarios,
62
+ fixtures and adapters remain colocated with their owners; larger entries live in
63
+ `composition/`. One managed project compiler supplies both human and agent views.
64
+
65
+ Project/component rules are registered in `ds.config.json`. Scoped Oxlint settings
66
+ do not disable independent architecture checks. Each skill contains the workflow
67
+ needed when installed on its own; the designer includes the empty foundation and
68
+ a React/Vite preview compiler adapter, without any component catalogue.
@@ -0,0 +1,292 @@
1
+ ---
2
+ name: ads-assimilate
3
+ description: "Implement or refine a native design-system component from a component-library URL, studying the original implementation and verifying behavior, visuals, and motion against the real reference. Use for component assimilation, including local documentation and justified usage lint rules; not for simply installing or wrapping a dependency."
4
+ ---
5
+
6
+ # ADS Assimilate
7
+
8
+ When ADS MCP is connected, discover public UI and addressable scenarios with
9
+ `ads_status`/`ads_catalog`; use `ads_tokens` for definitions and values, and
10
+ `ads_scenarios`/`ads_show_scenario` for real project scenarios. Keep the external
11
+ library as the behavioral reference.
12
+ If Apps are unavailable, inspect the normal showcase. Resolve MCP-served skill
13
+ references relative to this `SKILL.md` URI and load them lazily; a resource read
14
+ does not itself activate the skill.
15
+ Use the returned `projectRoot` and `project.commands`; the connected ADS may be
16
+ inside a different or nested repository. Inspect the selected public API, owning
17
+ source/available guides and relevant tokens, then mount its discovered scenario.
18
+ Metadata and source reads do not prove rendered behavior.
19
+
20
+ When `ads_status.mutations.enabled`, discover the owner with `ads_units`, read
21
+ relevant ranges with `ads_read_file` and send only a Git unified diff through
22
+ `ads_apply_patch({ unit, patch, dryRun })`. A unit includes its own implementation,
23
+ scenarios and fixtures; imported peers remain separate. `tokens` is the token
24
+ foundation unit. Unit discovery and file ownership are distinct from preview IDs.
25
+ Include only that owner's required re-exports in the public entry. Use
26
+ `dryRun: true` to inspect validation; applying re-runs the gates. Fix rejected
27
+ patches in their owner. Shared styles/helpers use `foundation`, root guides use
28
+ `documentation`, and branding/fonts use their discovered `assets/*` unit.
29
+ Intentional configuration, rule exceptions, registered guard code and compiler
30
+ changes use `configuration`; validate the proposed settings and keep mandatory
31
+ ADS gates. For binary/large assets, generate `git diff --binary --full-index` into
32
+ `.ds/patches/<name>.patch` and send `patchFile` instead of inline `patch`, so bytes
33
+ stay out of model context. Binary changes require Git. When editing is disabled,
34
+ use the client's normal source-editing tools.
35
+
36
+ Before trusting a preview after edits, check `ads_status.build` or
37
+ `ads://project/build`. Fix build diagnostics in owned source; an older view or
38
+ unreported freshness is not evidence of current code. Notifications may not
39
+ reach the agent.
40
+
41
+ Turn a supplied component-library reference into a native component in the current
42
+ design-system repository. Preserve the requested interaction contract while
43
+ using the target system's primitives, tokens, styling architecture, and public API.
44
+ Aim for a close adaptation: the reference's function, layout, interaction details,
45
+ and animation style should remain recognizable. Change what native integration
46
+ requires; broader redesign belongs to an explicit user request.
47
+
48
+ React and native Preact are supported. Preserve the target runtime in both
49
+ production and scenario builds; never alias React to Preact just to shrink a
50
+ preview. Native Preact uses its own JSX transform, hooks and DOM events (live
51
+ text updates use `onInput`). Native SVG uses DOM names such as `stroke-width`,
52
+ not React presentation aliases. Keep Linaria extraction and the same public APIs.
53
+ The shipped empty starter uses React; the tool repository's working example
54
+ uses Preact. Neither is a component dependency of the receiving project.
55
+
56
+ ADS is tooling only. Implement in the target project's
57
+ local ADS folder: the project owns the component source and theme values, and
58
+ the app imports its local public barrel (normally `@ds`). Shared tooling supplies
59
+ contracts, rules, skills, and empty scaffolding. Component libraries, patterns,
60
+ themes and scenarios are external sources, loaded through explicit ADS
61
+ workflows. Do not look for a built-in or optional UI catalogue in the tool.
62
+
63
+ ## Input
64
+
65
+ Invocation accepts a library/repository/documentation URL as its first argument:
66
+
67
+ ```text
68
+ $ads-assimilate <library-url> [component-name] [requirements]
69
+ $ads-assimilate https://github.com/emilkowalski/sonner toast
70
+ ```
71
+
72
+ The URL is the required reference, not a request to install the library into the
73
+ product. Use the current repository as the target unless the user names another.
74
+ Infer the component from the request or a single-component library. If the URL
75
+ is missing, ask for it. If a multi-component library leaves the component
76
+ ambiguous, inspect its catalogue and clarify the target while doing independent
77
+ repository research. Optional requirements can specify API compatibility,
78
+ appearance, behavior, migrations, and a playground.
79
+
80
+ Read [references/cli.md](references/cli.md) and invoke supported ADS CLI commands
81
+ through `npx` using the actual published version or a local tarball. Use the CLI
82
+ for setup and checks while this skill owns reference research and implementation.
83
+
84
+ ## Establish the contract
85
+
86
+ Read repository instructions, the main README, architecture/token documentation
87
+ such as `docs/ARCHITECTURE.md` and `docs/ADS.md` when present (or existing project guides), relevant component guides,
88
+ public exports, and lint/build scripts.
89
+ Reuse the target's structure; do not redesign the system to accommodate the reference.
90
+ ADS requires Linaria for component and pattern styling. Adapt reference styles to
91
+ colocated `@linaria/atomic` blocks and verify extraction in application and
92
+ preview builds. Preserve the target framework; `ads init` does not configure
93
+ Linaria for it.
94
+
95
+ Open the supplied URL and the relevant primary source, official usage docs, CSS,
96
+ animation code, tests, and license. Record the version or commit inspected.
97
+ Published-package behavior can differ from repository HEAD: use one identified
98
+ runtime reference for the comparison and call out source-version differences.
99
+
100
+ Establish what should match: supported states, lifecycle, keyboard/pointer
101
+ behavior, focus, timing, layout/stacking, motion, and responsive behavior. Treat
102
+ token/brand adaptation and API reshaping as explicit design decisions. When the
103
+ user requests matching UX, reproduce the observed behavior, including quirks.
104
+ Do not silently improve timers, focus restoration, cleanup, gestures, or placement.
105
+ Propose any necessary deviation with its concrete effect and obtain a direction
106
+ when existing instructions do not resolve the tradeoff.
107
+
108
+ ## Implement and integrate
109
+
110
+ Use [native-implementation.md](references/native-implementation.md) for research
111
+ and implementation mechanics. Keep state, geometry, and visual policy in their
112
+ owning layers. Export the native API through the public barrel, add real showcase
113
+ examples, and migrate authorized consumers without changing unrelated surfaces.
114
+
115
+ Write the component-local README with usage, API, behavior, motion, token hooks,
116
+ validation, and any agreed differences. Include a References and credits section:
117
+ link the original library, studied source/docs/articles, identify the reference
118
+ version or commit, credit its authors, and say which features influenced the
119
+ native implementation. Keep shared project architecture in its ADS guide; the
120
+ receiving project's main README also credits inspiration and links to the local
121
+ guide. Do not add the imported component's catalogue or API to core tooling docs.
122
+
123
+ Read [lint-and-docs.md](references/lint-and-docs.md) when documenting the component
124
+ or evaluating usage rules. Add local rules only for concrete misuse that static
125
+ analysis can establish. Colocate rule ownership with the component and register
126
+ it through shared tooling; avoid duplicating existing TypeScript or lint checks.
127
+
128
+ ## Verify against the original
129
+
130
+ Use the project showcase as the permanent native demonstration and shared
131
+ review surface for agents and humans. Discover its existing run/build commands;
132
+ use the built-in MCP client and configure project preview compilation. Examples and
133
+ composition scenarios import the real public ADS API and the same token/foundation styles
134
+ as the application. Put reusable UI discovered while building a mock in ADS
135
+ components/patterns first. Colocate sample data and state/callback adapters with
136
+ the scenario; larger entries belong under `composition/`. Browsing pages only
137
+ select these entries. The scenario labels, controls and review layouts are public ADS entities with defined
138
+ APIs. The outer shell belongs to the tool client. Showcase/scenario files define no CSS, custom classes, or widget markup.
139
+ Change the owning ADS pattern when a frame layout is missing; do not recreate
140
+ the assimilated UI there or override its internals.
141
+
142
+ The showcase is a minimal shell plus an MCP client and Apps host, supplied by ADS
143
+ tooling. It discovers Tokens/Components/Patterns/Composition entries through MCP
144
+ tools and renders their scenarios in the preview App. Navigation, theme and
145
+ pane/header visibility belong to the tool client. Do not create page files,
146
+ copy its shell into the project or assemble a second catalogue/rendering pipeline.
147
+
148
+ When MCP is connected, open the running URL from `ads_status`. Otherwise run the
149
+ installed `ads showcase` or the project's `dev:showcase` script. Do not launch a
150
+ second runtime/compiler for the same connected project. A configured project
151
+ preview watcher publishes a shared graph on first demand and after source
152
+ changes. The built-in client refreshes discovery and the active scenario in the
153
+ same App after a successful build. Shared runtime, foundation CSS, fonts and
154
+ selected scenario modules load through MCP
155
+ resources inside the sandboxed App. Never inject project styles/runtime into
156
+ the outer host. Keep the configured framework, compiler and mount/unmount adapter
157
+ consistent; scenario teardown must release owned timers, portals and workers.
158
+ The host shows errors and marks retained output as stale. Other hosts may need an
159
+ explicit preview-tool invocation. Compilation remains project-owned and required
160
+ for TSX/Linaria; it is automatic, not eliminated.
161
+
162
+ Reusable review layouts belong in public project ADS patterns, while scenario
163
+ files define no CSS, custom classes or widget replicas. Keep real presentation in
164
+ its component/pattern owner. The tooling shell's CSS is outside that project
165
+ contract. Legacy custom showcase pages may be retained during migration; new
166
+ projects require no TokensPage/ComponentsPage/PatternsPage/CompositionPage files.
167
+
168
+ Colocate `Scenario.tsx` and `fixture.ts` with tokens and each component/pattern; flat owners
169
+ may use `<Owner>.scenario.tsx` and `<Owner>.fixture.ts`. Put larger entries under
170
+ `composition/<Name>/Scenario.tsx` with their own `fixture.ts`. Export a default
171
+ zero-input mountable view and literal metadata, for example
172
+ `export const scenario = { title: "Button states", covers: ["Button"] };`.
173
+ Import the real UI from the public ADS alias. Keep fixture inputs, simulated
174
+ services and initial state/callback adapters beside the scenario. Empty fixtures
175
+ are valid for an entry with no inputs. Extra development helpers use a
176
+ `scenario/` or `fixtures/` subfolder, or `<Owner>.scenario-adapter.ts`, so guards
177
+ recognize their role even beside runtime code. Never require a page, router or store to
178
+ initialize the entry. Several contextual public parts may share one scenario.
179
+
180
+ IDs derive from ADS-relative filenames: both `components/core/Button/Scenario.tsx`
181
+ and `components/core/Button.scenario.tsx` identify `components/core/Button`.
182
+ Use one form, no duplicate IDs or hand-maintained registry. Renames change IDs.
183
+ The showcase and external hosts mount the same discovered entry. The Vite
184
+ adapter uses `previewEntriesPlugin` and `createPreviewResources` with
185
+ `runScenarioCompiler` to publish the shared graph. Its framework mount adapter
186
+ returns cleanup; the project owns rendering and Linaria extraction. The older
187
+ `scenarioRegistryPlugin` is only for retained legacy browsers. MCP discovers
188
+ metadata without importing executable TSX. Existing apps need an explicitly
189
+ integrated compiler; init alone adds no compiler or extraction setup.
190
+ Use `ads_scenarios` (query/kind/limit) and `ads_show_scenario({id})` to open an exact
191
+ entry. Check its build freshness; HTML delivery is not browser verification.
192
+ If Apps or resource forwarding are unavailable, open that scenario in the real
193
+ showcase, using the tool result's URL. Do not build a preview-only replica.
194
+
195
+ For a production screen, find and render the application's public screen pattern.
196
+ Its owner supplies structure, controls, layout and presentation. Scenario fixtures
197
+ supply data/state/callbacks. Move shared presentation into a pattern if needed,
198
+ preserving existing behavior and lazy imports, workers, caching and cancellation.
199
+ Do not reassemble an alternative screen or substitute placeholder content.
200
+ Screen reuse remains skill guidance, not a dedicated screen-parity lint.
201
+
202
+ Resolve `scenario-contract`, `scenario-render` and `scenario-coverage` findings
203
+ with meaningful entries. Every public renderable component and pattern needs an
204
+ addressable scenario, including unused exports; types/constants/utilities do not.
205
+ Only public render references reachable from the default entry count. Tests and
206
+ unused imports/functions do not. Static reachability does not prove successful
207
+ mounting, correct content, every branch/state or visual parity: open each affected
208
+ entry independently and verify real behavior at narrow/wide sizes in both themes.
209
+ The older `showcase-coverage` policy separately checks application references.
210
+
211
+ Token previews use that same scenario pipeline. Colocate a token scenario and
212
+ fixture under the configured token directory. Use static metadata
213
+ `{ title: "Typography", covers: ["TokenSamples"], tokens: fixture.tokens }` with
214
+ literal const fixture fields; names/sample text are fixture data, values come
215
+ from the real foundation CSS. Reuse a public project review pattern for styled
216
+ samples. The minimal starter's foundation value scenario can have `covers: []`.
217
+ Every declared token needs reachable scenario coverage; adding/removing a token
218
+ requires fixture updates. Fix `token-scenario-reference`, `token-scenario-render`
219
+ and `token-scenario-coverage` findings. Metadata and unused fixture fields do not
220
+ count. Discover exact token IDs with `ads_scenarios({kind:"tokens"})`; mount them
221
+ with `ads_show_scenario({id})` or `ads_show_tokens({category:id})`. With the shared
222
+ resource compiler, omitting category opens the first project token scenario.
223
+ Legacy compilers retain the generic definition inspector. Use `ads_tokens` for
224
+ source definitions and values; inspecting definitions does not prove UI parity.
225
+ The tool keeps the shared naming contract; sample templates and their token
226
+ lists belong to the project.
227
+
228
+ Scenarios, colocated fixtures and helpers are development-only. Never export them
229
+ from the runtime barrel or import them in production, including through aliases,
230
+ re-exports or dynamic imports. They may not import application stores, routers,
231
+ providers or HTTP clients. Live business data is application-owned; UI uses typed
232
+ inputs or injected services/callbacks. Direct global fetch/XHR/WebSocket/EventSource
233
+ is rejected; custom clients and computed access require review/project guards.
234
+ Use local simulated services in fixtures. Tests may import fixtures; load real
235
+ foundation CSS rather than assigning shared token values in JavaScript. Keep
236
+ full-app integration harnesses and workflow coverage in application test support.
237
+
238
+
239
+
240
+ Register component/project Oxlint plugins and rules in `ds.config.json`. Use
241
+ scoped `oxlint.overrides` for justified file-specific settings; never edit
242
+ `.ds/oxlintrc.json`. These overrides configure Oxlint, not the independent
243
+ architecture checks in `ads check`. Measured renderer properties and documented
244
+ non-state hooks use explicit `boundaries`; shared token writes and primitive
245
+ state overrides cannot be allowlisted. Add generic architectural protections to
246
+ ADS core and keep domain/component-specific rules registered in project setup.
247
+
248
+ Update meaningful variants, states, content, themes, and container sizes in the
249
+ showcase. Run ADS/project guards before its build as well as the app build.
250
+ Fix appearance and motion in the shared implementation so both consumers change
251
+ together. Temporary upstream comparison pages are separate from the permanent
252
+ native showcase and use the actual upstream runtime.
253
+
254
+ Use [testing.md](references/testing.md) to select meaningful tests and compare the
255
+ native component with the **actual original component**, not another native demo.
256
+ Use matching content, configuration, theme intent, viewport, and input modality.
257
+ Measure state changes, computed geometry, timing, and animation frames, then
258
+ inspect screenshots. A screenshot alone does not establish behavior or motion parity.
259
+
260
+ Keep browser automation in isolated pages/contexts. Rebuild static playgrounds
261
+ after source changes. Test the public consumer path as well as component internals;
262
+ check root mounting and routing where the component has shared lifecycle.
263
+
264
+ Preserve the target's performance strategy when changing ownership: lazy imports,
265
+ worker execution, caches, memoization, cancellation, and stale-result rejection.
266
+ Public exports must not eagerly load heavy renderers for unrelated consumers.
267
+ Compare relevant bundle loading and existing performance/lifecycle tests before
268
+ and after a migration. Shared screen patterns can accept injected services;
269
+ architectural reuse does not require moving application services into the ADS.
270
+
271
+ Run the target's required lint, type checking, build, and relevant component/rule
272
+ tests. Inspect the target's actual scripts; an imported component or upstream
273
+ example may have its own test entry. Do not assume `test:toast` or a showcase
274
+ build exists in every project. Repeat only affected checks after new changes.
275
+
276
+ Follow [references/cli.md](references/cli.md) to integrate the tool as a
277
+ development dependency in the target's actual lint/build pipeline.
278
+ Register applicable local rules through its project-owned plugin adapter and
279
+ `ds.config.json`, then run the normal project build. Its lint step refreshes
280
+ configuration and runs ADS/core/project rules automatically. Use npx for bootstrap
281
+ or ad hoc checks. Core checks complement component/rule tests and the browser
282
+ comparison; they do not establish runtime or motion parity.
283
+
284
+ ## Deliver
285
+
286
+ Report what was implemented, verified matches, remaining agreed differences,
287
+ test evidence, and any concrete limits of the comparison. Link the component
288
+ guide and give full local URLs for running playgrounds, clearly identifying
289
+ which page is native and which uses the original. State the reference version.
290
+ Do not claim complete parity for untested states, or call a native replica a real
291
+ upstream reference. Keep comparison dependencies and downloaded source outside
292
+ the production dependency graph unless the user chose otherwise.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "ADS Assimilate"
3
+ short_description: "Adapt reference components into a native design system"
4
+ default_prompt: "Use $ads-assimilate with a component-library URL to implement and verify a native design-system component."