@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.
- package/LICENSE +21 -0
- package/README.md +284 -2
- package/dist/assets.mjs +52 -0
- package/dist/bootstrap-ds/ADS.md +203 -0
- package/dist/bootstrap-ds/README.md +98 -0
- package/dist/bootstrap-ds/biome.css.json +21 -0
- package/dist/bootstrap-ds/design-system/assets/brand/README.md +28 -0
- package/dist/bootstrap-ds/design-system/assets/fonts/.gitkeep +0 -0
- package/dist/bootstrap-ds/design-system/components/.gitkeep +0 -0
- package/dist/bootstrap-ds/design-system/composition/.gitkeep +0 -0
- package/dist/bootstrap-ds/design-system/index.ts +5 -0
- package/dist/bootstrap-ds/design-system/patterns/.gitkeep +0 -0
- package/dist/bootstrap-ds/design-system/showcase/mcp/index.html +1 -0
- package/dist/bootstrap-ds/design-system/showcase/mcp/main.tsx +8 -0
- package/dist/bootstrap-ds/design-system/styles.css +5 -0
- package/dist/bootstrap-ds/design-system/tokens/Foundation.fixture.ts +47 -0
- package/dist/bootstrap-ds/design-system/tokens/Foundation.scenario.tsx +14 -0
- package/dist/bootstrap-ds/design-system/tokens/base.css +27 -0
- package/dist/bootstrap-ds/design-system/tokens/colors.css +29 -0
- package/dist/bootstrap-ds/design-system/tokens/elevation.css +15 -0
- package/dist/bootstrap-ds/design-system/tokens/spacing.css +15 -0
- package/dist/bootstrap-ds/design-system/tokens/typography.css +13 -0
- package/dist/bootstrap-ds/ds.config.json +13 -0
- package/dist/bootstrap-ds/gitignore.template +8 -0
- package/dist/bootstrap-ds/package-lock.json +4660 -0
- package/dist/bootstrap-ds/package.json +41 -0
- package/dist/bootstrap-ds/scripts/build-mcp-previews.mjs +33 -0
- package/dist/bootstrap-ds/src/vite-env.d.ts +7 -0
- package/dist/bootstrap-ds/tsconfig.build.json +12 -0
- package/dist/bootstrap-ds/tsconfig.json +20 -0
- package/dist/bootstrap-ds/vite.config.ts +21 -0
- package/dist/boundaries.mjs +130 -0
- package/dist/brand-assets.mjs +82 -0
- package/dist/check.mjs +222 -0
- package/dist/cli.mjs +106 -0
- package/dist/config.mjs +181 -0
- package/dist/contracts/tokens.json +52 -0
- package/dist/html.mjs +30 -0
- package/dist/index.mjs +9 -0
- package/dist/init.mjs +194 -0
- package/dist/lint-config.mjs +40 -0
- package/dist/mcp/THIRD_PARTY_NOTICES.md +786 -0
- package/dist/mcp/apps.mjs +53 -0
- package/dist/mcp/build-status.mjs +164 -0
- package/dist/mcp/catalog.mjs +65 -0
- package/dist/mcp/context.mjs +69 -0
- package/dist/mcp/mutations.mjs +301 -0
- package/dist/mcp/patch.mjs +114 -0
- package/dist/mcp/preview-watch.mjs +169 -0
- package/dist/mcp/preview-widget.bundle.js +113 -0
- package/dist/mcp/project-widget.bundle.js +113 -0
- package/dist/mcp/prompts.mjs +28 -0
- package/dist/mcp/resource-loader.js +138 -0
- package/dist/mcp/sandbox-host.mjs +22 -0
- package/dist/mcp/server.mjs +377 -0
- package/dist/mcp/showcase-host.mjs +68 -0
- package/dist/mcp/skills.mjs +77 -0
- package/dist/mcp/widget.bundle.js +150 -0
- package/dist/oxlint.mjs +81 -0
- package/dist/preview-resources.mjs +198 -0
- package/dist/project-documents.mjs +27 -0
- package/dist/public-props.mjs +74 -0
- package/dist/scenarios-compiler.mjs +287 -0
- package/dist/scenarios-vite.d.mts +3 -0
- package/dist/scenarios-vite.mjs +71 -0
- package/dist/scenarios.mjs +212 -0
- package/dist/showcase/client.bundle.js +127 -0
- package/dist/showcase/index.html +17 -0
- package/dist/showcase/sandbox.js +30 -0
- package/dist/showcase/style.css +7 -0
- package/dist/showcase-coverage.mjs +118 -0
- package/dist/showcase.mjs +77 -0
- package/dist/skills/README.md +68 -0
- package/dist/skills/ads-assimilate/SKILL.md +292 -0
- package/dist/skills/ads-assimilate/agents/openai.yaml +4 -0
- package/dist/skills/ads-assimilate/references/cli.md +111 -0
- package/dist/skills/ads-assimilate/references/lint-and-docs.md +87 -0
- package/dist/skills/ads-assimilate/references/native-implementation.md +98 -0
- package/dist/skills/ads-assimilate/references/testing.md +107 -0
- package/dist/skills/ads-break-ui/LICENSE.upstream +21 -0
- package/dist/skills/ads-break-ui/README.md +16 -0
- package/dist/skills/ads-break-ui/SKILL.md +235 -0
- package/dist/skills/ads-break-ui/agents/openai.yaml +4 -0
- package/dist/skills/ads-break-ui/references/catalog.md +135 -0
- package/dist/skills/ads-break-ui/references/verification.md +48 -0
- package/dist/skills/ads-designer/LICENSE.upstream +21 -0
- package/dist/skills/ads-designer/README.md +19 -0
- package/dist/skills/ads-designer/SKILL.md +400 -0
- package/dist/skills/ads-designer/agents/openai.yaml +4 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/ADS.md +203 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/README.md +98 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/biome.css.json +21 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/assets/brand/README.md +28 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/assets/fonts/.gitkeep +0 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/components/.gitkeep +0 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/composition/.gitkeep +0 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/index.ts +5 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/.gitkeep +0 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/showcase/mcp/index.html +1 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/showcase/mcp/main.tsx +8 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/styles.css +5 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/Foundation.fixture.ts +47 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/Foundation.scenario.tsx +14 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/base.css +27 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/colors.css +29 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/elevation.css +15 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/spacing.css +15 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/typography.css +13 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/ds.config.json +13 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/gitignore.template +8 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/package-lock.json +4660 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/package.json +41 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/scripts/build-mcp-previews.mjs +33 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/src/vite-env.d.ts +7 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/tsconfig.build.json +12 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/tsconfig.json +20 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/vite.config.ts +21 -0
- package/dist/skills/ads-designer/references/cli.md +111 -0
- package/dist/skills/ads-designer/references/design-craft.md +65 -0
- package/dist/skills/ads-designer/references/mobile.md +73 -0
- package/dist/skills/ads-import/SKILL.md +335 -0
- package/dist/skills/ads-import/agents/openai.yaml +4 -0
- package/dist/skills/ads-import/references/branding.md +44 -0
- package/dist/skills/ads-import/references/cli.md +111 -0
- package/dist/skills/ads-import/references/implementation.md +111 -0
- package/dist/skills/ads-import/references/tokens.md +96 -0
- package/dist/skills/ads-motion/LICENSE.upstream +21 -0
- package/dist/skills/ads-motion/README.md +22 -0
- package/dist/skills/ads-motion/SKILL.md +217 -0
- package/dist/skills/ads-motion/agents/openai.yaml +4 -0
- package/dist/skills/ads-motion/references/audit.md +44 -0
- package/dist/skills/ads-motion/references/build.md +81 -0
- package/dist/skills/ads-motion/references/performance.md +55 -0
- package/dist/skills/ads-motion/references/review.md +35 -0
- package/dist/skills/ads-motion/references/verification.md +39 -0
- package/dist/token-policy.mjs +10 -0
- package/dist/tokens.mjs +142 -0
- package/dist/ui-framework.mjs +59 -0
- package/dist/units.mjs +168 -0
- package/docs/ADS.md +310 -0
- package/docs/ARCHITECTURE.md +311 -0
- package/docs/CHANGELOG.md +106 -0
- package/docs/GUIDE.md +722 -0
- package/docs/MCP.md +690 -0
- package/package.json +107 -4
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { Readable } from "node:stream";
|
|
4
|
+
import { createMcpHandler } from "@modelcontextprotocol/server";
|
|
5
|
+
import { startSandboxHost } from "./sandbox-host.mjs";
|
|
6
|
+
|
|
7
|
+
/** A loopback HTTP MCP transport and static client; neither renders project UI. */
|
|
8
|
+
export async function startShowcaseHost(factory, { port = 0, observe } = {}) {
|
|
9
|
+
const assets = new Map(await Promise.all([
|
|
10
|
+
["/", "index.html", "text/html"], ["/client.js", "client.bundle.js", "text/javascript"], ["/style.css", "style.css", "text/css"],
|
|
11
|
+
].map(async ([route, file, type]) => [route, { type, bytes: await readFile(new URL(`../showcase/${file}`, import.meta.url)) }])));
|
|
12
|
+
const handler = createMcpHandler(factory, { legacy: "reject", maxRequestBodySize: 2 * 1024 * 1024 });
|
|
13
|
+
const observer = observe?.(handler.notify);
|
|
14
|
+
const requests = new Set();
|
|
15
|
+
let sandbox;
|
|
16
|
+
const web = createServer(async (req, res) => {
|
|
17
|
+
const origin = `http://127.0.0.1:${web.address().port}`;
|
|
18
|
+
if (req.headers.host !== new URL(origin).host || req.headers["sec-fetch-site"] === "cross-site" || req.headers.origin && req.headers.origin !== origin) {
|
|
19
|
+
res.writeHead(403); res.end("Only the local showcase may access this host."); return;
|
|
20
|
+
}
|
|
21
|
+
const url = new URL(req.url, origin);
|
|
22
|
+
if (url.pathname === "/host.json" && req.method === "GET") {
|
|
23
|
+
res.writeHead(200, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
24
|
+
res.end(JSON.stringify({ sandboxUrl: sandbox?.url })); return;
|
|
25
|
+
}
|
|
26
|
+
const asset = assets.get(url.pathname);
|
|
27
|
+
if (req.method === "GET" && (asset || url.pathname === "/favicon.ico")) {
|
|
28
|
+
res.writeHead(asset ? 200 : 204, { "Content-Type": asset?.type ?? "image/x-icon", "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff", "Content-Security-Policy": `default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src ${sandbox ? new URL(sandbox.url).origin : "'none'"};connect-src 'self';object-src 'none'` });
|
|
29
|
+
res.end(asset?.bytes); return;
|
|
30
|
+
}
|
|
31
|
+
if (url.pathname !== "/mcp") { res.writeHead(404); res.end("Not found"); return; }
|
|
32
|
+
const abort = new AbortController();
|
|
33
|
+
requests.add(abort);
|
|
34
|
+
res.once("close", () => { requests.delete(abort); abort.abort(); });
|
|
35
|
+
try {
|
|
36
|
+
const request = new Request(url, { method: req.method, headers: req.headers, signal: abort.signal,
|
|
37
|
+
...(req.method === "POST" ? { body: Readable.toWeb(req), duplex: "half" } : {}) });
|
|
38
|
+
const response = await handler.fetch(request);
|
|
39
|
+
res.writeHead(response.status, Object.fromEntries(response.headers));
|
|
40
|
+
if (response.body) {
|
|
41
|
+
const stream = Readable.fromWeb(response.body);
|
|
42
|
+
stream.on("error", () => res.destroy());
|
|
43
|
+
res.once("close", () => stream.destroy());
|
|
44
|
+
stream.pipe(res);
|
|
45
|
+
} else res.end();
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (!res.headersSent) { res.writeHead(500); res.end(error.message); }
|
|
48
|
+
else res.destroy();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
await new Promise((resolve, reject) => { web.once("error", reject); web.listen(port, "127.0.0.1", resolve); });
|
|
53
|
+
sandbox = await startSandboxHost(`http://127.0.0.1:${web.address().port}`);
|
|
54
|
+
}
|
|
55
|
+
catch (error) { web.close(); await observer?.close(); await handler.close(); throw error; }
|
|
56
|
+
let closing;
|
|
57
|
+
return { url: `http://127.0.0.1:${web.address().port}/`, close() {
|
|
58
|
+
return closing ??= (async () => {
|
|
59
|
+
for (const request of requests) request.abort();
|
|
60
|
+
await observer?.close();
|
|
61
|
+
await handler.close();
|
|
62
|
+
await sandbox?.close();
|
|
63
|
+
const stopped = new Promise(resolve => web.close(resolve));
|
|
64
|
+
web.closeAllConnections();
|
|
65
|
+
await stopped;
|
|
66
|
+
})();
|
|
67
|
+
} };
|
|
68
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { parse } from "yaml";
|
|
6
|
+
import { ProtocolError, INVALID_PARAMS } from "@modelcontextprotocol/server";
|
|
7
|
+
|
|
8
|
+
export const SKILLS_EXTENSION = "io.modelcontextprotocol/skills";
|
|
9
|
+
export const SKILLS_ROOT = "skill://ads";
|
|
10
|
+
export const digest = (bytes) => `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
11
|
+
|
|
12
|
+
export function page(items, cursor, namespace, size = 25) {
|
|
13
|
+
const revision = digest(Buffer.from(JSON.stringify(items))).slice(7, 23);
|
|
14
|
+
let offset = 0;
|
|
15
|
+
if (cursor !== undefined) {
|
|
16
|
+
const match = new RegExp(`^${namespace}:${revision}:(\\d+)$`).exec(cursor);
|
|
17
|
+
offset = match ? Number(match[1]) : -1;
|
|
18
|
+
if (!Number.isSafeInteger(offset) || offset <= 0 || offset >= items.length || offset % size) throw new ProtocolError(INVALID_PARAMS, "Invalid or stale listing cursor; start the listing again.");
|
|
19
|
+
}
|
|
20
|
+
return { items: items.slice(offset, offset + size), ...(offset + size < items.length ? { nextCursor: `${namespace}:${revision}:${offset + size}` } : {}) };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** A packaged, immutable snapshot: the bytes read match the advertised manifest. */
|
|
24
|
+
export function createSkillStore(directory = fileURLToPath(new URL("../skills/", import.meta.url))) {
|
|
25
|
+
const files = new Map();
|
|
26
|
+
const directories = new Map([[SKILLS_ROOT, []]]);
|
|
27
|
+
const skills = [];
|
|
28
|
+
if (!existsSync(directory)) throw new Error("ADS skill distribution is missing; run npm run build.");
|
|
29
|
+
function walk(folder, uri, manifest) {
|
|
30
|
+
const children = [];
|
|
31
|
+
directories.set(uri, children);
|
|
32
|
+
for (const entry of readdirSync(folder, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
33
|
+
if (entry.isSymbolicLink()) throw new Error(`Skills cannot contain symlinks: ${entry.name}`);
|
|
34
|
+
const name = entry.name === "gitignore.template" ? ".gitignore" : entry.name;
|
|
35
|
+
const childUri = `${uri}/${encodeURIComponent(name)}`;
|
|
36
|
+
const file = path.join(folder, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
children.push({ uri: childUri, name, mimeType: "inode/directory" });
|
|
39
|
+
walk(file, childUri, manifest);
|
|
40
|
+
} else if (entry.isFile()) {
|
|
41
|
+
const bytes = readFileSync(file);
|
|
42
|
+
const text = !bytes.includes(0) && Buffer.from(bytes.toString("utf8")).equals(bytes);
|
|
43
|
+
const mimeType = text ? file.endsWith(".json") ? "application/json" : file.endsWith(".md") ? "text/markdown" : "text/plain" : "application/octet-stream";
|
|
44
|
+
files.set(childUri, { uri: childUri, name, mimeType, bytes, text });
|
|
45
|
+
children.push({ uri: childUri, name, mimeType });
|
|
46
|
+
manifest.push({ uri: childUri, digest: digest(bytes), size: bytes.length });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const entry of readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
51
|
+
if (!entry.isDirectory() || !existsSync(path.join(directory, entry.name, "SKILL.md"))) continue;
|
|
52
|
+
const folder = path.join(directory, entry.name);
|
|
53
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(readFileSync(path.join(folder, "SKILL.md"), "utf8"));
|
|
54
|
+
const frontmatter = match && parse(match[1], { maxAliasCount: 25 });
|
|
55
|
+
if (!frontmatter || frontmatter.name !== entry.name || typeof frontmatter.description !== "string" || !/^[a-z][a-z0-9-]*$/.test(frontmatter.name)) throw new Error(`Invalid skill frontmatter: ${entry.name}`);
|
|
56
|
+
const uri = `${SKILLS_ROOT}/${entry.name}`;
|
|
57
|
+
const manifest = [];
|
|
58
|
+
directories.get(SKILLS_ROOT).push({ uri, name: entry.name, mimeType: "inode/directory" });
|
|
59
|
+
walk(folder, uri, manifest);
|
|
60
|
+
skills.push({ uri: `${uri}/SKILL.md`, frontmatter, resources: manifest });
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
skills,
|
|
64
|
+
files,
|
|
65
|
+
directories,
|
|
66
|
+
get(uri) {
|
|
67
|
+
const skill = skills.find((entry) => entry.uri === uri);
|
|
68
|
+
if (!skill) throw new Error("Unknown skill URI.");
|
|
69
|
+
return skill;
|
|
70
|
+
},
|
|
71
|
+
read(uri) {
|
|
72
|
+
const file = files.get(uri);
|
|
73
|
+
if (!file) throw new Error("Unknown skill file URI.");
|
|
74
|
+
return { uri, mimeType: file.mimeType, ...(file.text ? { text: file.bytes.toString("utf8") } : { blob: file.bytes.toString("base64") }) };
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|