designwithai-mcp 0.1.0
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/README.md +153 -0
- package/dist/connectors.js +76 -0
- package/dist/decisions.js +67 -0
- package/dist/embeddings.js +98 -0
- package/dist/evals.js +172 -0
- package/dist/finding-identity.js +229 -0
- package/dist/handbook.js +98 -0
- package/dist/paths.js +62 -0
- package/dist/profile.js +79 -0
- package/dist/reviews.js +99 -0
- package/dist/server.js +1136 -0
- package/dist/skills.js +57 -0
- package/dist/state.js +48 -0
- package/handbook-embeddings.json +1 -0
- package/package.json +46 -0
- package/skills/EVALS.md +122 -0
- package/skills/README.md +59 -0
- package/skills/_shared/delivery-modes.md +12 -0
- package/skills/_shared/execution-contract.md +43 -0
- package/skills/_shared/issue-schema.md +25 -0
- package/skills/_shared/severity-model.md +16 -0
- package/skills/analyze-figma/evals/cases.json +140 -0
- package/skills/analyze-url/evals/cases.json +136 -0
- package/skills/better-accessibility/SKILL.md +141 -0
- package/skills/better-accessibility/evals/cases.json +83 -0
- package/skills/better-components/SKILL.md +125 -0
- package/skills/better-components/evals/cases.json +77 -0
- package/skills/better-consistency/SKILL.md +125 -0
- package/skills/better-consistency/evals/cases.json +77 -0
- package/skills/better-forms/SKILL.md +135 -0
- package/skills/better-forms/evals/cases.json +78 -0
- package/skills/better-interface/SKILL.md +143 -0
- package/skills/better-interface/evals/cases.json +80 -0
- package/skills/better-layout/SKILL.md +132 -0
- package/skills/better-layout/evals/cases.json +81 -0
- package/skills/better-navigation/SKILL.md +170 -0
- package/skills/better-navigation/evals/cases.json +131 -0
- package/skills/better-performance/SKILL.md +195 -0
- package/skills/better-performance/evals/cases.json +114 -0
- package/skills/better-responsive/SKILL.md +123 -0
- package/skills/better-responsive/evals/cases.json +77 -0
- package/skills/better-states/SKILL.md +129 -0
- package/skills/better-states/evals/cases.json +78 -0
- package/skills/better-writing/SKILL.md +138 -0
- package/skills/better-writing/evals/cases.json +77 -0
- package/skills/review-ai-product/SKILL.md +231 -0
- package/skills/review-ai-product/evals/cases.json +120 -0
- package/skills/review-data-security/SKILL.md +210 -0
- package/skills/review-data-security/evals/cases.json +138 -0
- package/skills/review-figma-hygiene/SKILL.md +186 -0
- package/skills/review-figma-hygiene/evals/cases.json +158 -0
package/dist/skills.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chargement de la bibliothèque de skills (`skills/`).
|
|
3
|
+
*
|
|
4
|
+
* Comme pour le Handbook, le serveur ne recopie rien : il lit les `SKILL.md`
|
|
5
|
+
* canoniques. Chaque skill devient un PROMPT MCP self-contained (socle commun +
|
|
6
|
+
* corps du skill + invocation renseignée) que Claude ou un IDE peut déclencher.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { skillsRoot } from "./paths.js";
|
|
11
|
+
function parseFrontmatter(raw) {
|
|
12
|
+
const m = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
13
|
+
if (!m)
|
|
14
|
+
return { fm: {}, body: raw.trim() };
|
|
15
|
+
const fm = {};
|
|
16
|
+
for (const line of m[1].split("\n")) {
|
|
17
|
+
const mm = line.match(/^([A-Za-z_]+):\s*(.*)$/);
|
|
18
|
+
if (mm)
|
|
19
|
+
fm[mm[1]] = mm[2].trim();
|
|
20
|
+
}
|
|
21
|
+
return { fm, body: m[2].trim() };
|
|
22
|
+
}
|
|
23
|
+
export function loadSkills() {
|
|
24
|
+
const dir = skillsRoot();
|
|
25
|
+
if (!existsSync(dir))
|
|
26
|
+
return { skills: [], sharedContract: "", origin: dir };
|
|
27
|
+
const sharedDir = path.join(dir, "_shared");
|
|
28
|
+
const sharedOrder = [
|
|
29
|
+
"execution-contract.md",
|
|
30
|
+
"issue-schema.md",
|
|
31
|
+
"severity-model.md",
|
|
32
|
+
"delivery-modes.md",
|
|
33
|
+
];
|
|
34
|
+
const sharedContract = existsSync(sharedDir)
|
|
35
|
+
? sharedOrder
|
|
36
|
+
.filter((f) => existsSync(path.join(sharedDir, f)))
|
|
37
|
+
.map((f) => readFileSync(path.join(sharedDir, f), "utf8").trim())
|
|
38
|
+
.join("\n\n---\n\n")
|
|
39
|
+
: "";
|
|
40
|
+
const skills = [];
|
|
41
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
42
|
+
if (!entry.isDirectory() || entry.name === "_shared")
|
|
43
|
+
continue;
|
|
44
|
+
const p = path.join(dir, entry.name, "SKILL.md");
|
|
45
|
+
if (!existsSync(p))
|
|
46
|
+
continue;
|
|
47
|
+
const { fm, body } = parseFrontmatter(readFileSync(p, "utf8"));
|
|
48
|
+
skills.push({
|
|
49
|
+
name: fm.name ?? entry.name,
|
|
50
|
+
description: fm.description ?? "",
|
|
51
|
+
role: fm.role ?? "",
|
|
52
|
+
body,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
skills.sort((a, b) => a.name.localeCompare(b.name));
|
|
56
|
+
return { skills, sharedContract, origin: dir };
|
|
57
|
+
}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L'état de progression, côté MCP — version locale.
|
|
3
|
+
*
|
|
4
|
+
* Miroir exact de la forme persistée par le site (`lib/store.ts`) : les gates
|
|
5
|
+
* franchis, chacun avec sa preuve (`artifactRef`) et sa date. Grâce à cette
|
|
6
|
+
* forme identique, le pont Supabase (étape D « complète ») se branchera dessus
|
|
7
|
+
* sans reformater. Ici tout reste local dans `.designwithai/state.json` —
|
|
8
|
+
* aucun secret, aucune auth.
|
|
9
|
+
*
|
|
10
|
+
* Discipline du produit conservée : un gate ne se ferme QUE sur un artefact
|
|
11
|
+
* localisable (voir `clear_gate` côté serveur).
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { workspaceDir } from "./paths.js";
|
|
16
|
+
export function statePath() {
|
|
17
|
+
return process.env.DWAI_STATE_PATH ?? workspaceDir("state.json");
|
|
18
|
+
}
|
|
19
|
+
export function loadState() {
|
|
20
|
+
const p = statePath();
|
|
21
|
+
if (existsSync(p)) {
|
|
22
|
+
try {
|
|
23
|
+
const s = JSON.parse(readFileSync(p, "utf8"));
|
|
24
|
+
return { gates: s.gates ?? {}, maturity: s.maturity ?? {} };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
/* fichier illisible : on repart d'un état vide */
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { gates: {}, maturity: {} };
|
|
31
|
+
}
|
|
32
|
+
export function saveState(state) {
|
|
33
|
+
const p = statePath();
|
|
34
|
+
mkdirSync(path.dirname(p), { recursive: true });
|
|
35
|
+
writeFileSync(p, `${JSON.stringify(state, null, 2)}\n`);
|
|
36
|
+
return p;
|
|
37
|
+
}
|
|
38
|
+
export function clearGate(state, gateId, artifactRef, now) {
|
|
39
|
+
return {
|
|
40
|
+
...state,
|
|
41
|
+
gates: { ...state.gates, [gateId]: { artifactRef, clearedAt: now.toISOString() } },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function reopenGate(state, gateId) {
|
|
45
|
+
const gates = { ...state.gates };
|
|
46
|
+
delete gates[gateId];
|
|
47
|
+
return { ...state, gates };
|
|
48
|
+
}
|