@domphy/mcp 0.14.0 → 0.16.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/dist/{chunk-6UXRYQDB.js → chunk-A3GLD3TT.js} +18 -2
- package/dist/chunk-A3GLD3TT.js.map +1 -0
- package/dist/index.js +30 -3
- package/dist/index.js.map +1 -1
- package/dist/tools.d.ts +16 -1
- package/dist/tools.js +5 -1
- package/package.json +4 -4
- package/dist/chunk-6UXRYQDB.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/tools.ts
|
|
2
2
|
import { readFile } from "fs/promises";
|
|
3
3
|
import { dirname, isAbsolute, resolve } from "path";
|
|
4
|
-
import { diagnose, format, validate } from "@domphy/doctor";
|
|
4
|
+
import { diagnose, fix, format, validate } from "@domphy/doctor";
|
|
5
5
|
var ORIGIN = process.env.DOMPHY_ORIGIN ?? "https://www.domphy.com";
|
|
6
6
|
function appManifestSetting() {
|
|
7
7
|
return process.env.DOMPHY_APP_MANIFEST ?? "./app-manifest.json";
|
|
@@ -38,6 +38,11 @@ async function getRules() {
|
|
|
38
38
|
if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);
|
|
39
39
|
return res.text();
|
|
40
40
|
}
|
|
41
|
+
async function getTones() {
|
|
42
|
+
const res = await fetch(`${ORIGIN}/tones.json`);
|
|
43
|
+
if (!res.ok) throw new Error(`Failed to fetch tones: ${res.status}`);
|
|
44
|
+
return res.text();
|
|
45
|
+
}
|
|
41
46
|
function diagnoseTree(elementJson) {
|
|
42
47
|
let tree;
|
|
43
48
|
try {
|
|
@@ -56,6 +61,15 @@ function validateTree(elementJson) {
|
|
|
56
61
|
}
|
|
57
62
|
return JSON.stringify(validate(tree), null, 2);
|
|
58
63
|
}
|
|
64
|
+
function fixTree(elementJson) {
|
|
65
|
+
let tree;
|
|
66
|
+
try {
|
|
67
|
+
tree = JSON.parse(elementJson);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return `Invalid JSON: ${error.message}`;
|
|
70
|
+
}
|
|
71
|
+
return JSON.stringify(fix(tree), null, 2);
|
|
72
|
+
}
|
|
59
73
|
function appManifestPath() {
|
|
60
74
|
const setting = appManifestSetting();
|
|
61
75
|
return isAbsolute(setting) ? setting : resolve(process.cwd(), setting);
|
|
@@ -135,9 +149,11 @@ export {
|
|
|
135
149
|
getPatch,
|
|
136
150
|
listPackages,
|
|
137
151
|
getRules,
|
|
152
|
+
getTones,
|
|
138
153
|
diagnoseTree,
|
|
139
154
|
validateTree,
|
|
155
|
+
fixTree,
|
|
140
156
|
listAppBlocks,
|
|
141
157
|
getAppBlock
|
|
142
158
|
};
|
|
143
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-A3GLD3TT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport { diagnose, fix, format, validate } from \"@domphy/doctor\";\n\n/**\n * Pure tool implementations for the Domphy MCP server. Kept transport-free so\n * they are unit-testable. The server (index.ts) wires these to MCP requests.\n */\n\nconst ORIGIN = process.env.DOMPHY_ORIGIN ?? \"https://www.domphy.com\";\n\n// Path to the app-block registry produced by `apps/web/scripts/app-manifest.mjs`.\n// Read lazily (per call) so the env var can be set after this module loads, and\n// overridable so the same MCP server can serve any app's blocks.\nfunction appManifestSetting(): string {\n return process.env.DOMPHY_APP_MANIFEST ?? \"./app-manifest.json\";\n}\n\ninterface Manifest {\n version: string;\n packages: Array<{\n name: string;\n version: string;\n description: string;\n subpaths: string[];\n peerDependencies: string[];\n }>;\n patches: Array<{\n name: string;\n hostTag: string | null;\n signature: string;\n props: Array<{\n name: string;\n type: string;\n optional: boolean;\n doc: string;\n }>;\n doc: string;\n example: string;\n source: string;\n }>;\n}\n\nlet cache: Manifest | null = null;\n\nexport async function loadManifest(): Promise<Manifest> {\n if (cache) return cache;\n const res = await fetch(`${ORIGIN}/manifest.json`);\n if (!res.ok) throw new Error(`Failed to fetch manifest: ${res.status}`);\n cache = (await res.json()) as Manifest;\n return cache;\n}\n\nexport async function listPatches(): Promise<string> {\n const m = await loadManifest();\n return m.patches\n .map(\n (p) => `${p.name}${p.hostTag ? ` <${p.hostTag}>` : \"\"} — ${p.signature}`,\n )\n .join(\"\\n\");\n}\n\nexport async function getPatch(name: string): Promise<string> {\n const m = await loadManifest();\n const patch = m.patches.find((p) => p.name === name);\n if (!patch) {\n const near = m.patches\n .filter((p) => p.name.includes(name) || name.includes(p.name))\n .map((p) => p.name);\n return `No patch named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\n }\n return JSON.stringify(patch, null, 2);\n}\n\nexport async function listPackages(): Promise<string> {\n const m = await loadManifest();\n return m.packages\n .map((p) => `${p.name}@${p.version} — ${p.description}`)\n .join(\"\\n\");\n}\n\nexport async function getRules(): Promise<string> {\n const res = await fetch(`${ORIGIN}/llms.txt`);\n if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);\n return res.text();\n}\n\n/** Valid tone names + theme color names (tones.json) for themeColor()/dataTone. */\nexport async function getTones(): Promise<string> {\n const res = await fetch(`${ORIGIN}/tones.json`);\n if (!res.ok) throw new Error(`Failed to fetch tones: ${res.status}`);\n return res.text();\n}\n\n/** Runs @domphy/doctor on a JSON element tree (static parts only). */\nexport function diagnoseTree(elementJson: string): string {\n let tree: unknown;\n try {\n tree = JSON.parse(elementJson);\n } catch (error) {\n return `Invalid JSON: ${(error as Error).message}`;\n }\n return format(diagnose(tree));\n}\n\n/**\n * Runs @domphy/doctor's aggregate `validate()` on a JSON element tree and\n * returns the structured report (ok flag, issues, severity counts) as JSON.\n */\nexport function validateTree(elementJson: string): string {\n let tree: unknown;\n try {\n tree = JSON.parse(elementJson);\n } catch (error) {\n return `Invalid JSON: ${(error as Error).message}`;\n }\n return JSON.stringify(validate(tree), null, 2);\n}\n\n/**\n * Applies @domphy/doctor's lossless autofix to a JSON element tree and returns\n * the fixed tree, the fixes applied, and a validation report of what remains\n * (issues needing intent are not auto-fixed).\n */\nexport function fixTree(elementJson: string): string {\n let tree: unknown;\n try {\n tree = JSON.parse(elementJson);\n } catch (error) {\n return `Invalid JSON: ${(error as Error).message}`;\n }\n return JSON.stringify(fix(tree), null, 2);\n}\n\n// --- app-block registry (an app's OWN reusable Domphy blocks) ---\n\ninterface AppBlock {\n name: string;\n kind: \"block\" | \"patch\";\n /** Repo-relative path of the file the block is declared in. */\n file: string;\n signature: string;\n jsdoc: string;\n exportKind: \"default\" | \"named\";\n}\n\n/** Resolves the app-manifest path against the manifest dir / cwd as needed. */\nfunction appManifestPath(): string {\n const setting = appManifestSetting();\n return isAbsolute(setting) ? setting : resolve(process.cwd(), setting);\n}\n\nasync function loadAppBlocks(): Promise<AppBlock[]> {\n const text = await readFile(appManifestPath(), \"utf8\");\n return JSON.parse(text) as AppBlock[];\n}\n\nfunction missingManifestHint(): string {\n return (\n `No app-manifest found at \"${appManifestPath()}\". ` +\n \"Generate it with `node apps/web/scripts/app-manifest.mjs <srcDir> <outFile>` \" +\n \"and point DOMPHY_APP_MANIFEST at the output (default ./app-manifest.json).\"\n );\n}\n\n/** Lists the app's own blocks (name + signature + file) from the app-manifest. */\nexport async function listAppBlocks(): Promise<string> {\n let blocks: AppBlock[];\n try {\n blocks = await loadAppBlocks();\n } catch {\n return missingManifestHint();\n }\n if (blocks.length === 0) {\n return \"The app-manifest is empty — no exported Domphy blocks were found.\";\n }\n return blocks\n .map((b) => `${b.name} [${b.kind}] — ${b.signature} (${b.file})`)\n .join(\"\\n\");\n}\n\n/**\n * Returns one app block's full source (the file at the manifest's `file`),\n * along with its signature and jsdoc.\n */\nexport async function getAppBlock(name: string): Promise<string> {\n let blocks: AppBlock[];\n try {\n blocks = await loadAppBlocks();\n } catch {\n return missingManifestHint();\n }\n const block = blocks.find((b) => b.name === name);\n if (!block) {\n const near = blocks\n .filter((b) => b.name.includes(name) || name.includes(b.name))\n .map((b) => b.name);\n return `No app block named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\n }\n // The manifest stores repo-relative paths; resolve them against the repo root,\n // which is the manifest's directory walked up out of apps/web/public, falling\n // back to cwd-relative resolution when that layout does not apply.\n let source: string;\n try {\n source = await readBlockSource(block.file);\n } catch (error) {\n source = `// Could not read source: ${(error as Error).message}`;\n }\n return JSON.stringify(\n {\n name: block.name,\n kind: block.kind,\n file: block.file,\n signature: block.signature,\n jsdoc: block.jsdoc,\n exportKind: block.exportKind,\n source,\n },\n null,\n 2,\n );\n}\n\n/** Reads a block's source file, resolving its repo-relative `file` path. */\nasync function readBlockSource(repoRelativeFile: string): Promise<string> {\n // The app-manifest lives at <repo>/apps/web/public/app-manifest.json by\n // default, so the repo root is three levels up from the manifest directory.\n const manifestDir = dirname(appManifestPath());\n const candidates = [\n resolve(manifestDir, \"../../..\", repoRelativeFile),\n resolve(process.cwd(), repoRelativeFile),\n resolve(manifestDir, repoRelativeFile),\n ];\n let lastError: unknown;\n for (const candidate of candidates) {\n try {\n return await readFile(candidate, \"utf8\");\n } catch (error) {\n lastError = error;\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new Error(`file not found: ${repoRelativeFile}`);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
diagnoseTree,
|
|
4
|
+
fixTree,
|
|
4
5
|
getAppBlock,
|
|
5
6
|
getPatch,
|
|
6
7
|
getRules,
|
|
8
|
+
getTones,
|
|
7
9
|
listAppBlocks,
|
|
8
10
|
listPackages,
|
|
9
11
|
listPatches,
|
|
10
12
|
validateTree
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-A3GLD3TT.js";
|
|
12
14
|
|
|
13
15
|
// src/index.ts
|
|
14
16
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -18,7 +20,7 @@ import {
|
|
|
18
20
|
ListToolsRequestSchema
|
|
19
21
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
20
22
|
var server = new Server(
|
|
21
|
-
{ name: "domphy", version: "0.
|
|
23
|
+
{ name: "domphy", version: "0.14.0" },
|
|
22
24
|
{ capabilities: { tools: {} } }
|
|
23
25
|
);
|
|
24
26
|
var tools = [
|
|
@@ -29,7 +31,7 @@ var tools = [
|
|
|
29
31
|
},
|
|
30
32
|
{
|
|
31
33
|
name: "domphy_get_patch",
|
|
32
|
-
description: "Get one patch's full contract
|
|
34
|
+
description: "Get one patch's full contract: host tag, signature, props (name/type/optional/doc), example, doc, and source.",
|
|
33
35
|
inputSchema: {
|
|
34
36
|
type: "object",
|
|
35
37
|
properties: {
|
|
@@ -48,6 +50,11 @@ var tools = [
|
|
|
48
50
|
description: "Get the Domphy code-generation rules (llms.txt) to follow.",
|
|
49
51
|
inputSchema: { type: "object", properties: {} }
|
|
50
52
|
},
|
|
53
|
+
{
|
|
54
|
+
name: "domphy_tones",
|
|
55
|
+
description: 'Get the valid tone names and theme color names for themeColor()/dataTone (e.g. themeColor(l, "shift-9", "primary")). Use this to avoid invented tones like "surface"/"text".',
|
|
56
|
+
inputSchema: { type: "object", properties: {} }
|
|
57
|
+
},
|
|
51
58
|
{
|
|
52
59
|
name: "domphy_diagnose",
|
|
53
60
|
description: "Run @domphy/doctor on a JSON Domphy element tree and return issues to fix (inline-typography, void-content, unknown-tag, missing/duplicate/unstable _key, \u2026).",
|
|
@@ -76,6 +83,20 @@ var tools = [
|
|
|
76
83
|
required: ["element"]
|
|
77
84
|
}
|
|
78
85
|
},
|
|
86
|
+
{
|
|
87
|
+
name: "domphy_fix",
|
|
88
|
+
description: "Apply @domphy/doctor's lossless autofix to a JSON Domphy element tree. Returns { tree, applied, report }; only provably-safe fixes (e.g. void-content) are applied, remaining issues are in report.",
|
|
89
|
+
inputSchema: {
|
|
90
|
+
type: "object",
|
|
91
|
+
properties: {
|
|
92
|
+
element: {
|
|
93
|
+
type: "string",
|
|
94
|
+
description: "JSON of the Domphy element tree"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
required: ["element"]
|
|
98
|
+
}
|
|
99
|
+
},
|
|
79
100
|
{
|
|
80
101
|
name: "domphy_list_app_blocks",
|
|
81
102
|
description: "List the current app's OWN reusable Domphy blocks (name, kind, signature, file) from its app-manifest.json. Run `app-manifest.mjs` first if absent.",
|
|
@@ -112,12 +133,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
112
133
|
case "domphy_rules":
|
|
113
134
|
text = await getRules();
|
|
114
135
|
break;
|
|
136
|
+
case "domphy_tones":
|
|
137
|
+
text = await getTones();
|
|
138
|
+
break;
|
|
115
139
|
case "domphy_diagnose":
|
|
116
140
|
text = diagnoseTree(String(args.element));
|
|
117
141
|
break;
|
|
118
142
|
case "domphy_validate":
|
|
119
143
|
text = validateTree(String(args.element));
|
|
120
144
|
break;
|
|
145
|
+
case "domphy_fix":
|
|
146
|
+
text = fixTree(String(args.element));
|
|
147
|
+
break;
|
|
121
148
|
case "domphy_list_app_blocks":
|
|
122
149
|
text = await listAppBlocks();
|
|
123
150
|
break;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n diagnoseTree,\n fixTree,\n getAppBlock,\n getPatch,\n getRules,\n getTones,\n listAppBlocks,\n listPackages,\n listPatches,\n validateTree,\n} from \"./tools.js\";\n\nconst server = new Server(\n { name: \"domphy\", version: \"0.14.0\" },\n { capabilities: { tools: {} } },\n);\n\nconst tools = [\n {\n name: \"domphy_list_patches\",\n description: \"List every @domphy/ui patch with its host tag and signature.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_get_patch\",\n description:\n \"Get one patch's full contract: host tag, signature, props (name/type/optional/doc), example, doc, and source.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"patch name, e.g. button\" },\n },\n required: [\"name\"],\n },\n },\n {\n name: \"domphy_list_packages\",\n description: \"List all @domphy/* packages with versions and descriptions.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_rules\",\n description: \"Get the Domphy code-generation rules (llms.txt) to follow.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_tones\",\n description:\n 'Get the valid tone names and theme color names for themeColor()/dataTone (e.g. themeColor(l, \"shift-9\", \"primary\")). Use this to avoid invented tones like \"surface\"/\"text\".',\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_diagnose\",\n description:\n \"Run @domphy/doctor on a JSON Domphy element tree and return issues to fix (inline-typography, void-content, unknown-tag, missing/duplicate/unstable _key, …).\",\n inputSchema: {\n type: \"object\",\n properties: {\n element: {\n type: \"string\",\n description: \"JSON of the Domphy element tree\",\n },\n },\n required: [\"element\"],\n },\n },\n {\n name: \"domphy_validate\",\n description:\n \"Run @domphy/doctor's aggregate validate() on a JSON Domphy element tree. Returns a structured report { ok, issues, summary } with severity counts.\",\n inputSchema: {\n type: \"object\",\n properties: {\n element: {\n type: \"string\",\n description: \"JSON of the Domphy element tree\",\n },\n },\n required: [\"element\"],\n },\n },\n {\n name: \"domphy_fix\",\n description:\n \"Apply @domphy/doctor's lossless autofix to a JSON Domphy element tree. Returns { tree, applied, report }; only provably-safe fixes (e.g. void-content) are applied, remaining issues are in report.\",\n inputSchema: {\n type: \"object\",\n properties: {\n element: {\n type: \"string\",\n description: \"JSON of the Domphy element tree\",\n },\n },\n required: [\"element\"],\n },\n },\n {\n name: \"domphy_list_app_blocks\",\n description:\n \"List the current app's OWN reusable Domphy blocks (name, kind, signature, file) from its app-manifest.json. Run `app-manifest.mjs` first if absent.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_get_app_block\",\n description:\n \"Get one app block's full source plus signature and jsdoc, by name, from the app-manifest.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"app block name, e.g. App\" },\n },\n required: [\"name\"],\n },\n },\n];\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name } = request.params;\n const args = (request.params.arguments ?? {}) as Record<string, unknown>;\n let text: string;\n try {\n switch (name) {\n case \"domphy_list_patches\":\n text = await listPatches();\n break;\n case \"domphy_get_patch\":\n text = await getPatch(String(args.name));\n break;\n case \"domphy_list_packages\":\n text = await listPackages();\n break;\n case \"domphy_rules\":\n text = await getRules();\n break;\n case \"domphy_tones\":\n text = await getTones();\n break;\n case \"domphy_diagnose\":\n text = diagnoseTree(String(args.element));\n break;\n case \"domphy_validate\":\n text = validateTree(String(args.element));\n break;\n case \"domphy_fix\":\n text = fixTree(String(args.element));\n break;\n case \"domphy_list_app_blocks\":\n text = await listAppBlocks();\n break;\n case \"domphy_get_app_block\":\n text = await getAppBlock(String(args.name));\n break;\n default:\n text = `Unknown tool: ${name}`;\n }\n } catch (error) {\n text = `Error: ${(error as Error).message}`;\n }\n return { content: [{ type: \"text\", text }] };\n});\n\nawait server.connect(new StdioServerTransport());\n"],"mappings":"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","names":[]}
|
package/dist/tools.d.ts
CHANGED
|
@@ -11,7 +11,14 @@ interface Manifest {
|
|
|
11
11
|
name: string;
|
|
12
12
|
hostTag: string | null;
|
|
13
13
|
signature: string;
|
|
14
|
+
props: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
type: string;
|
|
17
|
+
optional: boolean;
|
|
18
|
+
doc: string;
|
|
19
|
+
}>;
|
|
14
20
|
doc: string;
|
|
21
|
+
example: string;
|
|
15
22
|
source: string;
|
|
16
23
|
}>;
|
|
17
24
|
}
|
|
@@ -20,6 +27,8 @@ declare function listPatches(): Promise<string>;
|
|
|
20
27
|
declare function getPatch(name: string): Promise<string>;
|
|
21
28
|
declare function listPackages(): Promise<string>;
|
|
22
29
|
declare function getRules(): Promise<string>;
|
|
30
|
+
/** Valid tone names + theme color names (tones.json) for themeColor()/dataTone. */
|
|
31
|
+
declare function getTones(): Promise<string>;
|
|
23
32
|
/** Runs @domphy/doctor on a JSON element tree (static parts only). */
|
|
24
33
|
declare function diagnoseTree(elementJson: string): string;
|
|
25
34
|
/**
|
|
@@ -27,6 +36,12 @@ declare function diagnoseTree(elementJson: string): string;
|
|
|
27
36
|
* returns the structured report (ok flag, issues, severity counts) as JSON.
|
|
28
37
|
*/
|
|
29
38
|
declare function validateTree(elementJson: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Applies @domphy/doctor's lossless autofix to a JSON element tree and returns
|
|
41
|
+
* the fixed tree, the fixes applied, and a validation report of what remains
|
|
42
|
+
* (issues needing intent are not auto-fixed).
|
|
43
|
+
*/
|
|
44
|
+
declare function fixTree(elementJson: string): string;
|
|
30
45
|
/** Lists the app's own blocks (name + signature + file) from the app-manifest. */
|
|
31
46
|
declare function listAppBlocks(): Promise<string>;
|
|
32
47
|
/**
|
|
@@ -35,4 +50,4 @@ declare function listAppBlocks(): Promise<string>;
|
|
|
35
50
|
*/
|
|
36
51
|
declare function getAppBlock(name: string): Promise<string>;
|
|
37
52
|
|
|
38
|
-
export { diagnoseTree, getAppBlock, getPatch, getRules, listAppBlocks, listPackages, listPatches, loadManifest, validateTree };
|
|
53
|
+
export { diagnoseTree, fixTree, getAppBlock, getPatch, getRules, getTones, listAppBlocks, listPackages, listPatches, loadManifest, validateTree };
|
package/dist/tools.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
diagnoseTree,
|
|
3
|
+
fixTree,
|
|
3
4
|
getAppBlock,
|
|
4
5
|
getPatch,
|
|
5
6
|
getRules,
|
|
7
|
+
getTones,
|
|
6
8
|
listAppBlocks,
|
|
7
9
|
listPackages,
|
|
8
10
|
listPatches,
|
|
9
11
|
loadManifest,
|
|
10
12
|
validateTree
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-A3GLD3TT.js";
|
|
12
14
|
export {
|
|
13
15
|
diagnoseTree,
|
|
16
|
+
fixTree,
|
|
14
17
|
getAppBlock,
|
|
15
18
|
getPatch,
|
|
16
19
|
getRules,
|
|
20
|
+
getTones,
|
|
17
21
|
listAppBlocks,
|
|
18
22
|
listPackages,
|
|
19
23
|
listPatches,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domphy/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Domphy MCP server - exposes patches, packages, rules, and the doctor to MCP-capable AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
40
|
-
"@domphy/doctor": "^0.
|
|
40
|
+
"@domphy/doctor": "^0.16.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@domphy/core": "^0.
|
|
43
|
+
"@domphy/core": "^0.16.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^25.9.2",
|
|
47
47
|
"tsup": "^8.5.0",
|
|
48
48
|
"typescript": "^5.8.3",
|
|
49
49
|
"vitest": "^4.0.18",
|
|
50
|
-
"@domphy/core": "0.
|
|
50
|
+
"@domphy/core": "0.16.0"
|
|
51
51
|
},
|
|
52
52
|
"files": [
|
|
53
53
|
"dist",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\r\nimport { dirname, isAbsolute, resolve } from \"node:path\";\r\nimport { diagnose, format, validate } from \"@domphy/doctor\";\r\n\r\n/**\r\n * Pure tool implementations for the Domphy MCP server. Kept transport-free so\r\n * they are unit-testable. The server (index.ts) wires these to MCP requests.\r\n */\r\n\r\nconst ORIGIN = process.env.DOMPHY_ORIGIN ?? \"https://www.domphy.com\";\r\n\r\n// Path to the app-block registry produced by `apps/web/scripts/app-manifest.mjs`.\r\n// Read lazily (per call) so the env var can be set after this module loads, and\r\n// overridable so the same MCP server can serve any app's blocks.\r\nfunction appManifestSetting(): string {\r\n return process.env.DOMPHY_APP_MANIFEST ?? \"./app-manifest.json\";\r\n}\r\n\r\ninterface Manifest {\r\n version: string;\r\n packages: Array<{\r\n name: string;\r\n version: string;\r\n description: string;\r\n subpaths: string[];\r\n peerDependencies: string[];\r\n }>;\r\n patches: Array<{\r\n name: string;\r\n hostTag: string | null;\r\n signature: string;\r\n doc: string;\r\n source: string;\r\n }>;\r\n}\r\n\r\nlet cache: Manifest | null = null;\r\n\r\nexport async function loadManifest(): Promise<Manifest> {\r\n if (cache) return cache;\r\n const res = await fetch(`${ORIGIN}/manifest.json`);\r\n if (!res.ok) throw new Error(`Failed to fetch manifest: ${res.status}`);\r\n cache = (await res.json()) as Manifest;\r\n return cache;\r\n}\r\n\r\nexport async function listPatches(): Promise<string> {\r\n const m = await loadManifest();\r\n return m.patches\r\n .map(\r\n (p) => `${p.name}${p.hostTag ? ` <${p.hostTag}>` : \"\"} — ${p.signature}`,\r\n )\r\n .join(\"\\n\");\r\n}\r\n\r\nexport async function getPatch(name: string): Promise<string> {\r\n const m = await loadManifest();\r\n const patch = m.patches.find((p) => p.name === name);\r\n if (!patch) {\r\n const near = m.patches\r\n .filter((p) => p.name.includes(name) || name.includes(p.name))\r\n .map((p) => p.name);\r\n return `No patch named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\r\n }\r\n return JSON.stringify(patch, null, 2);\r\n}\r\n\r\nexport async function listPackages(): Promise<string> {\r\n const m = await loadManifest();\r\n return m.packages\r\n .map((p) => `${p.name}@${p.version} — ${p.description}`)\r\n .join(\"\\n\");\r\n}\r\n\r\nexport async function getRules(): Promise<string> {\r\n const res = await fetch(`${ORIGIN}/llms.txt`);\r\n if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);\r\n return res.text();\r\n}\r\n\r\n/** Runs @domphy/doctor on a JSON element tree (static parts only). */\r\nexport function diagnoseTree(elementJson: string): string {\r\n let tree: unknown;\r\n try {\r\n tree = JSON.parse(elementJson);\r\n } catch (error) {\r\n return `Invalid JSON: ${(error as Error).message}`;\r\n }\r\n return format(diagnose(tree));\r\n}\r\n\r\n/**\r\n * Runs @domphy/doctor's aggregate `validate()` on a JSON element tree and\r\n * returns the structured report (ok flag, issues, severity counts) as JSON.\r\n */\r\nexport function validateTree(elementJson: string): string {\r\n let tree: unknown;\r\n try {\r\n tree = JSON.parse(elementJson);\r\n } catch (error) {\r\n return `Invalid JSON: ${(error as Error).message}`;\r\n }\r\n return JSON.stringify(validate(tree), null, 2);\r\n}\r\n\r\n// --- app-block registry (an app's OWN reusable Domphy blocks) ---\r\n\r\ninterface AppBlock {\r\n name: string;\r\n kind: \"block\" | \"patch\";\r\n /** Repo-relative path of the file the block is declared in. */\r\n file: string;\r\n signature: string;\r\n jsdoc: string;\r\n exportKind: \"default\" | \"named\";\r\n}\r\n\r\n/** Resolves the app-manifest path against the manifest dir / cwd as needed. */\r\nfunction appManifestPath(): string {\r\n const setting = appManifestSetting();\r\n return isAbsolute(setting) ? setting : resolve(process.cwd(), setting);\r\n}\r\n\r\nasync function loadAppBlocks(): Promise<AppBlock[]> {\r\n const text = await readFile(appManifestPath(), \"utf8\");\r\n return JSON.parse(text) as AppBlock[];\r\n}\r\n\r\nfunction missingManifestHint(): string {\r\n return (\r\n `No app-manifest found at \"${appManifestPath()}\". ` +\r\n \"Generate it with `node apps/web/scripts/app-manifest.mjs <srcDir> <outFile>` \" +\r\n \"and point DOMPHY_APP_MANIFEST at the output (default ./app-manifest.json).\"\r\n );\r\n}\r\n\r\n/** Lists the app's own blocks (name + signature + file) from the app-manifest. */\r\nexport async function listAppBlocks(): Promise<string> {\r\n let blocks: AppBlock[];\r\n try {\r\n blocks = await loadAppBlocks();\r\n } catch {\r\n return missingManifestHint();\r\n }\r\n if (blocks.length === 0) {\r\n return \"The app-manifest is empty — no exported Domphy blocks were found.\";\r\n }\r\n return blocks\r\n .map((b) => `${b.name} [${b.kind}] — ${b.signature} (${b.file})`)\r\n .join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Returns one app block's full source (the file at the manifest's `file`),\r\n * along with its signature and jsdoc.\r\n */\r\nexport async function getAppBlock(name: string): Promise<string> {\r\n let blocks: AppBlock[];\r\n try {\r\n blocks = await loadAppBlocks();\r\n } catch {\r\n return missingManifestHint();\r\n }\r\n const block = blocks.find((b) => b.name === name);\r\n if (!block) {\r\n const near = blocks\r\n .filter((b) => b.name.includes(name) || name.includes(b.name))\r\n .map((b) => b.name);\r\n return `No app block named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\r\n }\r\n // The manifest stores repo-relative paths; resolve them against the repo root,\r\n // which is the manifest's directory walked up out of apps/web/public, falling\r\n // back to cwd-relative resolution when that layout does not apply.\r\n let source: string;\r\n try {\r\n source = await readBlockSource(block.file);\r\n } catch (error) {\r\n source = `// Could not read source: ${(error as Error).message}`;\r\n }\r\n return JSON.stringify(\r\n {\r\n name: block.name,\r\n kind: block.kind,\r\n file: block.file,\r\n signature: block.signature,\r\n jsdoc: block.jsdoc,\r\n exportKind: block.exportKind,\r\n source,\r\n },\r\n null,\r\n 2,\r\n );\r\n}\r\n\r\n/** Reads a block's source file, resolving its repo-relative `file` path. */\r\nasync function readBlockSource(repoRelativeFile: string): Promise<string> {\r\n // The app-manifest lives at <repo>/apps/web/public/app-manifest.json by\r\n // default, so the repo root is three levels up from the manifest directory.\r\n const manifestDir = dirname(appManifestPath());\r\n const candidates = [\r\n resolve(manifestDir, \"../../..\", repoRelativeFile),\r\n resolve(process.cwd(), repoRelativeFile),\r\n resolve(manifestDir, repoRelativeFile),\r\n ];\r\n let lastError: unknown;\r\n for (const candidate of candidates) {\r\n try {\r\n return await readFile(candidate, \"utf8\");\r\n } catch (error) {\r\n lastError = error;\r\n }\r\n }\r\n throw lastError instanceof Error\r\n ? lastError\r\n : new Error(`file not found: ${repoRelativeFile}`);\r\n}\r\n"],"mappings":"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","names":[]}
|