@decantr/mcp-server 2.2.0 → 2.3.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 +3 -3
- package/dist/bin.js +1 -1
- package/dist/{chunk-SVLMT45O.js → chunk-GIVGJE76.js} +68 -0
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Design intelligence for AI-generated UI. Make Claude, Cursor, and Windsurf gener
|
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
15
|
-
- **Structured design context** -- gives your AI assistant patterns, layouts, component specs, and
|
|
15
|
+
- **Structured design context** -- gives your AI assistant patterns, layouts, component specs, Brownfield local law, and task-time context instead of letting it guess
|
|
16
16
|
- **Evidence-backed repair loops** -- gives AI agents Project Health, Evidence Bundles, workspace health, and scoped repair prompts without uploading source
|
|
17
17
|
- **Drift detection** -- catches when generated code deviates from your design intent
|
|
18
18
|
- **Zero config** -- run with `npx`, no API keys or accounts required
|
|
@@ -136,7 +136,7 @@ The server exposes Decantr registry, context, benchmark, and verification tools.
|
|
|
136
136
|
| `decantr_suggest_patterns` | Given a page description plus optional route/source excerpt, get ranked pattern suggestions | `{ "description": "recipe feed with avatars and infinite scroll", "route": "/feed" }` |
|
|
137
137
|
| `decantr_check_drift` | Check if generated code violates the design intent in the Essence spec | `{ "page_id": "overview", "components_used": ["Card", "LineChart"], "theme_used": "auradecantism" }` |
|
|
138
138
|
| `decantr_get_execution_pack` | Read compiled scaffold, section, page, review, or mutation execution packs, with hosted fallback when local context is missing | `{ "pack_type": "page", "id": "overview", "format": "json" }` |
|
|
139
|
-
| `decantr_prepare_task_context` | Resolve compact route/task context before editing a Brownfield or Essence route | `{ "route": "/feed", "task": "improve recipe card loading" }` |
|
|
139
|
+
| `decantr_prepare_task_context` | Resolve compact route/task context, local law, evidence, and changed-file impact before editing a Brownfield or Essence route | `{ "route": "/feed", "task": "improve recipe card loading" }` |
|
|
140
140
|
| `decantr_compile_execution_packs` | Compile a hosted execution-pack bundle from a local or inline essence document | `{ "path": "./decantr.essence.json", "namespace": "@official" }` |
|
|
141
141
|
| `decantr_audit_project` | Run the schema-backed Decantr project audit against essence and compiled packs, with hosted fallback when local pack artifacts are missing | `{ "namespace": "@official" }` |
|
|
142
142
|
| `decantr_critique` | Critique a file against the compiled review contract, with hosted fallback when local review packs are missing | `{ "file_path": "./src/pages/Overview.tsx", "namespace": "@official" }` |
|
|
@@ -171,7 +171,7 @@ The AI assistant calls these tools behind the scenes:
|
|
|
171
171
|
3. `decantr_suggest_patterns` -- recommends `kpi-grid`, `chart-grid`, `data-table`, and `form-sections` for the described pages
|
|
172
172
|
4. `decantr_resolve_pattern` -- fetches layout specs and component lists for each pattern
|
|
173
173
|
5. `decantr_get_execution_pack` -- loads the compiled scaffold/page/review packs as the task contract, falling back to hosted compilation when local pack artifacts are missing
|
|
174
|
-
6. `decantr_prepare_task_context` -- resolves route-local Brownfield context, visual evidence, and theme inventory before editing an existing app
|
|
174
|
+
6. `decantr_prepare_task_context` -- resolves route-local Brownfield context, accepted local law, changed-file impact, visual evidence, and theme inventory before editing an existing app
|
|
175
175
|
7. `decantr_compile_execution_packs` -- compiles the hosted pack bundle when the task needs a fresh remote contract from the essence document
|
|
176
176
|
8. `decantr_check_drift` -- validates the generated code against the Essence spec before presenting it
|
|
177
177
|
9. `decantr_critique` -- critiques a specific file, falling back to the hosted verifier when the local review pack is missing
|
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-GIVGJE76.js";
|
|
@@ -4,6 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
|
|
6
6
|
// src/tools.ts
|
|
7
|
+
import { execFileSync } from "child_process";
|
|
7
8
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
8
9
|
import { readFile as readFile2 } from "fs/promises";
|
|
9
10
|
import { basename as basename2, dirname as dirname2, join as join2, relative as relative2 } from "path";
|
|
@@ -137,6 +138,61 @@ function readJsonIfExists(path) {
|
|
|
137
138
|
return null;
|
|
138
139
|
}
|
|
139
140
|
}
|
|
141
|
+
function changedFilesForTask(projectRoot) {
|
|
142
|
+
const changed = /* @__PURE__ */ new Set();
|
|
143
|
+
try {
|
|
144
|
+
for (const args of [
|
|
145
|
+
["diff", "--name-only"],
|
|
146
|
+
["diff", "--name-only", "--cached"]
|
|
147
|
+
]) {
|
|
148
|
+
const output = execFileSync("git", args, {
|
|
149
|
+
cwd: projectRoot,
|
|
150
|
+
encoding: "utf-8",
|
|
151
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
152
|
+
});
|
|
153
|
+
for (const entry of output.split(/\r?\n/)) {
|
|
154
|
+
const file = entry.trim();
|
|
155
|
+
if (file) changed.add(file);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
return [...changed].sort();
|
|
161
|
+
}
|
|
162
|
+
function impactedRoutesForFiles(projectRoot, files) {
|
|
163
|
+
const analysis = readJsonIfExists(
|
|
164
|
+
join2(projectRoot, ".decantr", "analysis.json")
|
|
165
|
+
);
|
|
166
|
+
const routeEntries = analysis?.routes?.routes ?? [];
|
|
167
|
+
const impacted = /* @__PURE__ */ new Set();
|
|
168
|
+
for (const file of files) {
|
|
169
|
+
for (const route of routeEntries) {
|
|
170
|
+
if (route.file && (file === route.file || file.endsWith(route.file))) {
|
|
171
|
+
if (route.path) impacted.add(route.path);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return [...impacted].sort();
|
|
176
|
+
}
|
|
177
|
+
function localLawSummary(projectRoot) {
|
|
178
|
+
const patterns = readJsonIfExists(join2(projectRoot, ".decantr", "local-patterns.json"));
|
|
179
|
+
const rules = readJsonIfExists(join2(projectRoot, ".decantr", "rules.json"));
|
|
180
|
+
return {
|
|
181
|
+
patterns_path: patterns ? ".decantr/local-patterns.json" : null,
|
|
182
|
+
rules_path: rules ? ".decantr/rules.json" : null,
|
|
183
|
+
patterns: patterns?.patterns?.map((pattern) => ({
|
|
184
|
+
id: pattern.id ?? "unknown",
|
|
185
|
+
role: pattern.role ?? null,
|
|
186
|
+
component_paths: pattern.componentPaths ?? []
|
|
187
|
+
})) ?? [],
|
|
188
|
+
rules: rules?.rules?.map((rule) => ({
|
|
189
|
+
id: rule.id ?? "unknown",
|
|
190
|
+
enabled: rule.enabled ?? false,
|
|
191
|
+
severity: rule.severity ?? "warn",
|
|
192
|
+
description: rule.description ?? null
|
|
193
|
+
})) ?? []
|
|
194
|
+
};
|
|
195
|
+
}
|
|
140
196
|
function extractPatternIdsFromLayoutItem(item, ids) {
|
|
141
197
|
if (typeof item === "string") {
|
|
142
198
|
ids.add(item);
|
|
@@ -2371,6 +2427,9 @@ async function handleTool(name, args) {
|
|
|
2371
2427
|
const themeInventory = readJsonIfExists(
|
|
2372
2428
|
join2(process.cwd(), ".decantr", "theme-inventory.json")
|
|
2373
2429
|
);
|
|
2430
|
+
const localLaw = localLawSummary(process.cwd());
|
|
2431
|
+
const changedFiles = changedFilesForTask(process.cwd());
|
|
2432
|
+
const changedRoutes = impactedRoutesForFiles(process.cwd(), changedFiles);
|
|
2374
2433
|
const patternIds = extractPagePatternIds(page);
|
|
2375
2434
|
const ranked = rankPatternCandidates(
|
|
2376
2435
|
{
|
|
@@ -2419,10 +2478,19 @@ async function handleTool(name, args) {
|
|
|
2419
2478
|
variants: themeInventory.variants,
|
|
2420
2479
|
path: ".decantr/theme-inventory.json"
|
|
2421
2480
|
} : null,
|
|
2481
|
+
local_law: localLaw,
|
|
2482
|
+
change_impact: {
|
|
2483
|
+
changed_files: changedFiles.slice(0, 40),
|
|
2484
|
+
changed_file_count: changedFiles.length,
|
|
2485
|
+
impacted_routes: changedRoutes
|
|
2486
|
+
},
|
|
2487
|
+
verify_command: "decantr verify --brownfield --local-patterns",
|
|
2422
2488
|
local_files: {
|
|
2423
2489
|
page_pack: pageManifest?.markdown ?? null,
|
|
2424
2490
|
section_pack: sectionManifest?.markdown ?? null,
|
|
2425
2491
|
section_context: existsSync(sectionContextPath) ? `.decantr/context/section-${section.id}.md` : null,
|
|
2492
|
+
local_patterns: localLaw.patterns_path,
|
|
2493
|
+
local_rules: localLaw.rules_path,
|
|
2426
2494
|
visual_manifest: existsSync(
|
|
2427
2495
|
join2(process.cwd(), ".decantr", "evidence", "visual-manifest.json")
|
|
2428
2496
|
) ? ".decantr/evidence/visual-manifest.json" : null
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-GIVGJE76.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decantr/mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"mcpName": "io.github.decantr-ai/mcp-server",
|
|
5
5
|
"description": "MCP server for Decantr — exposes design intelligence, packs, and verification to AI coding assistants",
|
|
6
6
|
"keywords": [
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
52
52
|
"@decantr/essence-spec": "2.0.1",
|
|
53
|
-
"@decantr/
|
|
54
|
-
"@decantr/
|
|
53
|
+
"@decantr/registry": "2.2.0",
|
|
54
|
+
"@decantr/verifier": "2.2.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "tsup",
|