sunpeak 0.15.4 → 0.16.1
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 +51 -48
- package/bin/commands/build.mjs +13 -4
- package/bin/commands/dev.mjs +64 -19
- package/bin/commands/new.mjs +13 -3
- package/bin/lib/extract-resource.mjs +1 -1
- package/bin/lib/extract-tool.mjs +78 -0
- package/bin/lib/patterns.mjs +2 -26
- package/dist/chatgpt/index.cjs +3 -6
- package/dist/chatgpt/index.cjs.map +1 -1
- package/dist/chatgpt/index.d.ts +1 -1
- package/dist/chatgpt/index.js +6 -9
- package/dist/claude/index.cjs +1 -1
- package/dist/claude/index.js +1 -1
- package/dist/discovery-CH80W5l9.js +217 -0
- package/dist/discovery-CH80W5l9.js.map +1 -0
- package/dist/discovery-DmB8_4QL.cjs +216 -0
- package/dist/discovery-DmB8_4QL.cjs.map +1 -0
- package/dist/{index-CutQgPzR.js → index-BjnAsaqp.js} +3 -6
- package/dist/index-BjnAsaqp.js.map +1 -0
- package/dist/{index-Cngntkp2.cjs → index-BvQ_ZuOO.cjs} +3 -6
- package/dist/{index-Cngntkp2.cjs.map → index-BvQ_ZuOO.cjs.map} +1 -1
- package/dist/{index-B0dxRJvS.cjs → index-C9CVbGFt.cjs} +3 -6
- package/dist/index-C9CVbGFt.cjs.map +1 -0
- package/dist/{index-Ce_5ZIdJ.js → index-CTGEqlgk.js} +3 -6
- package/dist/{index-Ce_5ZIdJ.js.map → index-CTGEqlgk.js.map} +1 -1
- package/dist/index.cjs +48 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3404 -3361
- package/dist/index.js.map +1 -1
- package/dist/lib/discovery-cli.cjs +58 -5
- package/dist/lib/discovery-cli.cjs.map +1 -1
- package/dist/lib/discovery-cli.d.ts +3 -2
- package/dist/lib/discovery-cli.js +61 -8
- package/dist/lib/discovery-cli.js.map +1 -1
- package/dist/lib/discovery.d.ts +42 -43
- package/dist/lib/extract-tool.d.ts +12 -0
- package/dist/mcp/favicon.d.ts +1 -1
- package/dist/mcp/index.cjs +3 -2
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +3 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/types.d.ts +24 -1
- package/dist/platform/chatgpt/index.cjs +1 -1
- package/dist/platform/chatgpt/index.js +1 -1
- package/dist/simulator/index.cjs +2 -5
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.ts +1 -1
- package/dist/simulator/index.js +5 -8
- package/dist/simulator/simulator-url.d.ts +9 -9
- package/dist/{simulator-DcfQBRXE.cjs → simulator-B56j5P8W.cjs} +8 -2
- package/dist/{simulator-DcfQBRXE.cjs.map → simulator-B56j5P8W.cjs.map} +1 -1
- package/dist/{simulator-CxrtnguM.js → simulator-C0H_k092.js} +8 -2
- package/dist/{simulator-CxrtnguM.js.map → simulator-C0H_k092.js.map} +1 -1
- package/dist/simulator-url-CuLqtnSS.js.map +1 -1
- package/dist/simulator-url-rgg_KYOg.cjs.map +1 -1
- package/dist/types/resource-config.d.ts +7 -5
- package/dist/{use-app-D_TeaMFG.js → use-app-BThbgFFT.js} +51 -22
- package/dist/{use-app-D_TeaMFG.js.map → use-app-BThbgFFT.js.map} +1 -1
- package/dist/{use-app-BnoSPiUT.cjs → use-app-BuufpXTQ.cjs} +49 -20
- package/dist/{use-app-BnoSPiUT.cjs.map → use-app-BuufpXTQ.cjs.map} +1 -1
- package/package.json +1 -1
- package/template/.sunpeak/dev.tsx +8 -4
- package/template/.sunpeak/resource-loader.tsx +2 -1
- package/template/README.md +14 -10
- package/template/package.json +2 -1
- package/template/src/resources/albums/{albums-resource.test.tsx → albums.test.tsx} +1 -1
- package/template/src/resources/albums/{albums-resource.tsx → albums.tsx} +0 -1
- package/template/src/resources/carousel/{carousel-resource.test.tsx → carousel.test.tsx} +1 -1
- package/template/src/resources/carousel/{carousel-resource.tsx → carousel.tsx} +0 -1
- package/template/src/resources/index.ts +4 -4
- package/template/src/resources/map/{map-resource.test.tsx → map.test.tsx} +1 -1
- package/template/src/resources/map/{map-resource.tsx → map.tsx} +0 -1
- package/template/src/resources/review/{review-resource.test.tsx → review.test.tsx} +1 -1
- package/template/src/resources/review/{review-resource.tsx → review.tsx} +1 -2
- package/template/src/server.ts +15 -0
- package/template/src/tools/review-diff.ts +24 -0
- package/template/src/tools/review-post.ts +26 -0
- package/template/src/tools/review-purchase.ts +31 -0
- package/template/src/tools/show-albums.ts +22 -0
- package/template/src/tools/show-carousel.ts +25 -0
- package/template/src/tools/show-map.ts +29 -0
- package/template/tests/e2e/albums.spec.ts +6 -6
- package/template/tests/e2e/carousel.spec.ts +6 -6
- package/template/tests/e2e/map.spec.ts +11 -11
- package/template/tests/simulations/{review/review-diff-simulation.json → review-diff.json} +1 -31
- package/template/tests/simulations/{review/review-post-simulation.json → review-post.json} +1 -37
- package/template/tests/simulations/{review/review-purchase-simulation.json → review-purchase.json} +1 -38
- package/template/tests/simulations/{albums/albums-show-simulation.json → show-albums.json} +1 -24
- package/template/tests/simulations/{carousel/carousel-show-simulation.json → show-carousel.json} +1 -24
- package/template/tests/simulations/{map/map-show-simulation.json → show-map.json} +1 -35
- package/dist/discovery-CRR3SlyI.cjs +0 -156
- package/dist/discovery-CRR3SlyI.cjs.map +0 -1
- package/dist/discovery-DzV3HLXs.js +0 -157
- package/dist/discovery-DzV3HLXs.js.map +0 -1
- package/dist/index-B0dxRJvS.cjs.map +0 -1
- package/dist/index-CutQgPzR.js.map +0 -1
|
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
25
|
-
const discovery = require("../discovery-
|
|
25
|
+
const discovery = require("../discovery-DmB8_4QL.cjs");
|
|
26
26
|
const path = require("path");
|
|
27
27
|
async function extractResourceExport(tsxPath) {
|
|
28
28
|
const esbuild = await import("esbuild");
|
|
@@ -67,19 +67,72 @@ async function extractResourceExport(tsxPath) {
|
|
|
67
67
|
const resource = mod.exports.resource;
|
|
68
68
|
if (!resource) {
|
|
69
69
|
throw new Error(
|
|
70
|
-
`No "resource" export found in ${tsxPath}. Add: export const resource: ResourceConfig = {
|
|
70
|
+
`No "resource" export found in ${tsxPath}. Add: export const resource: ResourceConfig = { title: '...', ... };`
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
return resource;
|
|
74
74
|
}
|
|
75
|
+
async function extractToolExport(tsPath) {
|
|
76
|
+
const esbuild = await import("esbuild");
|
|
77
|
+
const absolutePath = path.resolve(tsPath);
|
|
78
|
+
const dir = path.dirname(absolutePath);
|
|
79
|
+
const base = path.basename(absolutePath);
|
|
80
|
+
const result = await esbuild.build({
|
|
81
|
+
stdin: {
|
|
82
|
+
contents: `export { tool } from './${base}';`,
|
|
83
|
+
resolveDir: dir,
|
|
84
|
+
loader: "ts"
|
|
85
|
+
},
|
|
86
|
+
bundle: true,
|
|
87
|
+
write: false,
|
|
88
|
+
format: "esm",
|
|
89
|
+
treeShaking: true,
|
|
90
|
+
loader: { ".tsx": "tsx", ".ts": "ts", ".jsx": "jsx" },
|
|
91
|
+
logLevel: "silent",
|
|
92
|
+
plugins: [
|
|
93
|
+
{
|
|
94
|
+
name: "externalize-node-modules",
|
|
95
|
+
setup(build) {
|
|
96
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
97
|
+
if (args.kind !== "import-statement") return;
|
|
98
|
+
if (!args.path.startsWith(".") && !args.path.startsWith("/")) {
|
|
99
|
+
return { external: true };
|
|
100
|
+
}
|
|
101
|
+
return void 0;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
if (!result.outputFiles?.length) {
|
|
108
|
+
throw new Error(`Failed to extract tool from ${tsPath}`);
|
|
109
|
+
}
|
|
110
|
+
const code = result.outputFiles[0].text.replace(/^import\s+.*$/gm, "").replace(/^export\s*\{[^}]*\}\s*;?\s*$/m, "");
|
|
111
|
+
let tool;
|
|
112
|
+
try {
|
|
113
|
+
const fn = new Function(code + "\nreturn tool;");
|
|
114
|
+
tool = fn();
|
|
115
|
+
} catch {
|
|
116
|
+
const toolMatch = result.outputFiles[0].text.match(/var tool\s*=\s*(\{[\s\S]*?\n\});/);
|
|
117
|
+
if (toolMatch) {
|
|
118
|
+
tool = new Function("return " + toolMatch[1])();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!tool) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`No "tool" export found in ${tsPath}. Add: export const tool: AppToolConfig = { resource, ... };`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return { tool };
|
|
127
|
+
}
|
|
75
128
|
exports.extractResourceKey = discovery.extractResourceKey;
|
|
76
129
|
exports.extractSimulationKey = discovery.extractSimulationKey;
|
|
77
|
-
exports.extractSimulationName = discovery.extractSimulationName;
|
|
78
130
|
exports.findResourceDirs = discovery.findResourceDirs;
|
|
79
131
|
exports.findResourceKey = discovery.findResourceKey;
|
|
80
|
-
exports.
|
|
132
|
+
exports.findSimulationFilesFlat = discovery.findSimulationFilesFlat;
|
|
133
|
+
exports.findToolFiles = discovery.findToolFiles;
|
|
81
134
|
exports.getComponentName = discovery.getComponentName;
|
|
82
|
-
exports.isSimulationFile = discovery.isSimulationFile;
|
|
83
135
|
exports.toPascalCase = discovery.toPascalCase;
|
|
84
136
|
exports.extractResourceExport = extractResourceExport;
|
|
137
|
+
exports.extractToolExport = extractToolExport;
|
|
85
138
|
//# sourceMappingURL=discovery-cli.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery-cli.cjs","sources":["../../src/lib/extract-resource.ts"],"sourcesContent":["import path from 'path';\n\n/**\n * Extract the `resource` named export from a resource .tsx file.\n *\n * Uses esbuild to bundle only the `resource` export, stubbing all of the\n * resource file's own imports (React, components, etc.) so only the static\n * config object is evaluated.\n */\nexport async function extractResourceExport(tsxPath: string): Promise<Record<string, unknown>> {\n const esbuild = await import('esbuild');\n const absolutePath = path.resolve(tsxPath);\n const dir = path.dirname(absolutePath);\n const base = path.basename(absolutePath);\n\n const result = await esbuild.build({\n stdin: {\n contents: `export { resource } from './${base}';`,\n resolveDir: dir,\n loader: 'ts',\n },\n bundle: true,\n write: false,\n format: 'cjs',\n treeShaking: true,\n loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx' },\n logLevel: 'silent',\n plugins: [\n {\n name: 'externalize-deps',\n setup(build) {\n let entryResolved = false;\n // Let stdin's import of the resource file resolve normally,\n // but externalize everything the resource file itself imports.\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind !== 'import-statement') return;\n if (!entryResolved) {\n entryResolved = true;\n return;\n }\n return { external: true };\n });\n },\n },\n ],\n });\n\n if (!result.outputFiles?.length) {\n throw new Error(`Failed to extract resource from ${tsxPath}`);\n }\n\n const code = result.outputFiles[0].text;\n const mod: { exports: Record<string, unknown> } = { exports: {} };\n new Function('module', 'exports', 'require', code)(mod, mod.exports, () => ({}));\n\n const resource = mod.exports.resource as Record<string, unknown> | undefined;\n if (!resource) {\n throw new Error(\n `No \"resource\" export found in ${tsxPath}. ` +\n `Add: export const resource: ResourceConfig = {
|
|
1
|
+
{"version":3,"file":"discovery-cli.cjs","sources":["../../src/lib/extract-resource.ts","../../src/lib/extract-tool.ts"],"sourcesContent":["import path from 'path';\n\n/**\n * Extract the `resource` named export from a resource .tsx file.\n *\n * Uses esbuild to bundle only the `resource` export, stubbing all of the\n * resource file's own imports (React, components, etc.) so only the static\n * config object is evaluated.\n */\nexport async function extractResourceExport(tsxPath: string): Promise<Record<string, unknown>> {\n const esbuild = await import('esbuild');\n const absolutePath = path.resolve(tsxPath);\n const dir = path.dirname(absolutePath);\n const base = path.basename(absolutePath);\n\n const result = await esbuild.build({\n stdin: {\n contents: `export { resource } from './${base}';`,\n resolveDir: dir,\n loader: 'ts',\n },\n bundle: true,\n write: false,\n format: 'cjs',\n treeShaking: true,\n loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx' },\n logLevel: 'silent',\n plugins: [\n {\n name: 'externalize-deps',\n setup(build) {\n let entryResolved = false;\n // Let stdin's import of the resource file resolve normally,\n // but externalize everything the resource file itself imports.\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind !== 'import-statement') return;\n if (!entryResolved) {\n entryResolved = true;\n return;\n }\n return { external: true };\n });\n },\n },\n ],\n });\n\n if (!result.outputFiles?.length) {\n throw new Error(`Failed to extract resource from ${tsxPath}`);\n }\n\n const code = result.outputFiles[0].text;\n const mod: { exports: Record<string, unknown> } = { exports: {} };\n new Function('module', 'exports', 'require', code)(mod, mod.exports, () => ({}));\n\n const resource = mod.exports.resource as Record<string, unknown> | undefined;\n if (!resource) {\n throw new Error(\n `No \"resource\" export found in ${tsxPath}. ` +\n `Add: export const resource: ResourceConfig = { title: '...', ... };`\n );\n }\n\n return resource;\n}\n","import path from 'path';\n\n/**\n * Extract the `tool` named export from a tool .ts file.\n *\n * Uses esbuild in ESM mode to compile TypeScript and tree-shake to just the\n * `tool` export. ESM tree-shaking drops unused exports (schema, handler) so\n * their dependencies (zod, etc.) are never evaluated.\n *\n * `schema` and `default` handler are loaded at runtime via Vite SSR.\n */\nexport async function extractToolExport(\n tsPath: string\n): Promise<{ tool: Record<string, unknown> }> {\n const esbuild = await import('esbuild');\n const absolutePath = path.resolve(tsPath);\n const dir = path.dirname(absolutePath);\n const base = path.basename(absolutePath);\n\n const result = await esbuild.build({\n stdin: {\n contents: `export { tool } from './${base}';`,\n resolveDir: dir,\n loader: 'ts',\n },\n bundle: true,\n write: false,\n format: 'esm',\n treeShaking: true,\n loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx' },\n logLevel: 'silent',\n plugins: [\n {\n name: 'externalize-node-modules',\n setup(build) {\n // Resolve relative imports normally (resource files, local modules)\n // but externalize everything from node_modules\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind !== 'import-statement') return;\n // Bare specifiers (not starting with . or /) are node_modules\n if (!args.path.startsWith('.') && !args.path.startsWith('/')) {\n return { external: true };\n }\n return undefined;\n });\n },\n },\n ],\n });\n\n if (!result.outputFiles?.length) {\n throw new Error(`Failed to extract tool from ${tsPath}`);\n }\n\n // Strip import statements and export block so we can eval as plain JS.\n // `tool` is pure data (no dependencies), so stripping imports is safe.\n // Other top-level code (schema, etc.) may reference stripped imports but\n // we only need the `tool` variable — errors in other code are caught and ignored.\n const code = result.outputFiles[0].text\n .replace(/^import\\s+.*$/gm, '')\n .replace(/^export\\s*\\{[^}]*\\}\\s*;?\\s*$/m, '');\n let tool: Record<string, unknown> | undefined;\n try {\n const fn = new Function(code + '\\nreturn tool;');\n tool = fn() as Record<string, unknown> | undefined;\n } catch {\n // If other top-level code crashes (e.g. schema using stripped zod),\n // extract just the tool variable declaration and eval that alone.\n const toolMatch = result.outputFiles[0].text.match(/var tool\\s*=\\s*(\\{[\\s\\S]*?\\n\\});/);\n if (toolMatch) {\n tool = new Function('return ' + toolMatch[1])() as Record<string, unknown>;\n }\n }\n if (!tool) {\n throw new Error(\n `No \"tool\" export found in ${tsPath}. ` +\n `Add: export const tool: AppToolConfig = { resource, ... };`\n );\n }\n\n return { tool };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This module re-exports only the Node.js-compatible discovery utilities
|
|
5
5
|
* without pulling in React components. Used by CLI commands like `sunpeak dev`.
|
|
6
6
|
*/
|
|
7
|
-
export { findResourceDirs,
|
|
8
|
-
export type { ResourceDirInfo, FsOps } from './discovery';
|
|
7
|
+
export { findResourceDirs, findSimulationFilesFlat, findToolFiles, extractResourceKey, extractSimulationKey, toPascalCase, getComponentName, findResourceKey, } from './discovery';
|
|
8
|
+
export type { ResourceDirInfo, ToolFileInfo, SimulationFileInfo, FsOps } from './discovery';
|
|
9
9
|
export { extractResourceExport } from './extract-resource';
|
|
10
|
+
export { extractToolExport } from './extract-tool';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e, f, g, h,
|
|
1
|
+
import { e, f, g, h, j, k, i, t } from "../discovery-CH80W5l9.js";
|
|
2
2
|
import path from "path";
|
|
3
3
|
async function extractResourceExport(tsxPath) {
|
|
4
4
|
const esbuild = await import("esbuild");
|
|
@@ -43,21 +43,74 @@ async function extractResourceExport(tsxPath) {
|
|
|
43
43
|
const resource = mod.exports.resource;
|
|
44
44
|
if (!resource) {
|
|
45
45
|
throw new Error(
|
|
46
|
-
`No "resource" export found in ${tsxPath}. Add: export const resource: ResourceConfig = {
|
|
46
|
+
`No "resource" export found in ${tsxPath}. Add: export const resource: ResourceConfig = { title: '...', ... };`
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
return resource;
|
|
50
50
|
}
|
|
51
|
+
async function extractToolExport(tsPath) {
|
|
52
|
+
const esbuild = await import("esbuild");
|
|
53
|
+
const absolutePath = path.resolve(tsPath);
|
|
54
|
+
const dir = path.dirname(absolutePath);
|
|
55
|
+
const base = path.basename(absolutePath);
|
|
56
|
+
const result = await esbuild.build({
|
|
57
|
+
stdin: {
|
|
58
|
+
contents: `export { tool } from './${base}';`,
|
|
59
|
+
resolveDir: dir,
|
|
60
|
+
loader: "ts"
|
|
61
|
+
},
|
|
62
|
+
bundle: true,
|
|
63
|
+
write: false,
|
|
64
|
+
format: "esm",
|
|
65
|
+
treeShaking: true,
|
|
66
|
+
loader: { ".tsx": "tsx", ".ts": "ts", ".jsx": "jsx" },
|
|
67
|
+
logLevel: "silent",
|
|
68
|
+
plugins: [
|
|
69
|
+
{
|
|
70
|
+
name: "externalize-node-modules",
|
|
71
|
+
setup(build) {
|
|
72
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
73
|
+
if (args.kind !== "import-statement") return;
|
|
74
|
+
if (!args.path.startsWith(".") && !args.path.startsWith("/")) {
|
|
75
|
+
return { external: true };
|
|
76
|
+
}
|
|
77
|
+
return void 0;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
});
|
|
83
|
+
if (!result.outputFiles?.length) {
|
|
84
|
+
throw new Error(`Failed to extract tool from ${tsPath}`);
|
|
85
|
+
}
|
|
86
|
+
const code = result.outputFiles[0].text.replace(/^import\s+.*$/gm, "").replace(/^export\s*\{[^}]*\}\s*;?\s*$/m, "");
|
|
87
|
+
let tool;
|
|
88
|
+
try {
|
|
89
|
+
const fn = new Function(code + "\nreturn tool;");
|
|
90
|
+
tool = fn();
|
|
91
|
+
} catch {
|
|
92
|
+
const toolMatch = result.outputFiles[0].text.match(/var tool\s*=\s*(\{[\s\S]*?\n\});/);
|
|
93
|
+
if (toolMatch) {
|
|
94
|
+
tool = new Function("return " + toolMatch[1])();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!tool) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`No "tool" export found in ${tsPath}. Add: export const tool: AppToolConfig = { resource, ... };`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return { tool };
|
|
103
|
+
}
|
|
51
104
|
export {
|
|
52
105
|
extractResourceExport,
|
|
53
106
|
e as extractResourceKey,
|
|
54
107
|
f as extractSimulationKey,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
j as
|
|
59
|
-
k as
|
|
60
|
-
|
|
108
|
+
extractToolExport,
|
|
109
|
+
g as findResourceDirs,
|
|
110
|
+
h as findResourceKey,
|
|
111
|
+
j as findSimulationFilesFlat,
|
|
112
|
+
k as findToolFiles,
|
|
113
|
+
i as getComponentName,
|
|
61
114
|
t as toPascalCase
|
|
62
115
|
};
|
|
63
116
|
//# sourceMappingURL=discovery-cli.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery-cli.js","sources":["../../src/lib/extract-resource.ts"],"sourcesContent":["import path from 'path';\n\n/**\n * Extract the `resource` named export from a resource .tsx file.\n *\n * Uses esbuild to bundle only the `resource` export, stubbing all of the\n * resource file's own imports (React, components, etc.) so only the static\n * config object is evaluated.\n */\nexport async function extractResourceExport(tsxPath: string): Promise<Record<string, unknown>> {\n const esbuild = await import('esbuild');\n const absolutePath = path.resolve(tsxPath);\n const dir = path.dirname(absolutePath);\n const base = path.basename(absolutePath);\n\n const result = await esbuild.build({\n stdin: {\n contents: `export { resource } from './${base}';`,\n resolveDir: dir,\n loader: 'ts',\n },\n bundle: true,\n write: false,\n format: 'cjs',\n treeShaking: true,\n loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx' },\n logLevel: 'silent',\n plugins: [\n {\n name: 'externalize-deps',\n setup(build) {\n let entryResolved = false;\n // Let stdin's import of the resource file resolve normally,\n // but externalize everything the resource file itself imports.\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind !== 'import-statement') return;\n if (!entryResolved) {\n entryResolved = true;\n return;\n }\n return { external: true };\n });\n },\n },\n ],\n });\n\n if (!result.outputFiles?.length) {\n throw new Error(`Failed to extract resource from ${tsxPath}`);\n }\n\n const code = result.outputFiles[0].text;\n const mod: { exports: Record<string, unknown> } = { exports: {} };\n new Function('module', 'exports', 'require', code)(mod, mod.exports, () => ({}));\n\n const resource = mod.exports.resource as Record<string, unknown> | undefined;\n if (!resource) {\n throw new Error(\n `No \"resource\" export found in ${tsxPath}. ` +\n `Add: export const resource: ResourceConfig = {
|
|
1
|
+
{"version":3,"file":"discovery-cli.js","sources":["../../src/lib/extract-resource.ts","../../src/lib/extract-tool.ts"],"sourcesContent":["import path from 'path';\n\n/**\n * Extract the `resource` named export from a resource .tsx file.\n *\n * Uses esbuild to bundle only the `resource` export, stubbing all of the\n * resource file's own imports (React, components, etc.) so only the static\n * config object is evaluated.\n */\nexport async function extractResourceExport(tsxPath: string): Promise<Record<string, unknown>> {\n const esbuild = await import('esbuild');\n const absolutePath = path.resolve(tsxPath);\n const dir = path.dirname(absolutePath);\n const base = path.basename(absolutePath);\n\n const result = await esbuild.build({\n stdin: {\n contents: `export { resource } from './${base}';`,\n resolveDir: dir,\n loader: 'ts',\n },\n bundle: true,\n write: false,\n format: 'cjs',\n treeShaking: true,\n loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx' },\n logLevel: 'silent',\n plugins: [\n {\n name: 'externalize-deps',\n setup(build) {\n let entryResolved = false;\n // Let stdin's import of the resource file resolve normally,\n // but externalize everything the resource file itself imports.\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind !== 'import-statement') return;\n if (!entryResolved) {\n entryResolved = true;\n return;\n }\n return { external: true };\n });\n },\n },\n ],\n });\n\n if (!result.outputFiles?.length) {\n throw new Error(`Failed to extract resource from ${tsxPath}`);\n }\n\n const code = result.outputFiles[0].text;\n const mod: { exports: Record<string, unknown> } = { exports: {} };\n new Function('module', 'exports', 'require', code)(mod, mod.exports, () => ({}));\n\n const resource = mod.exports.resource as Record<string, unknown> | undefined;\n if (!resource) {\n throw new Error(\n `No \"resource\" export found in ${tsxPath}. ` +\n `Add: export const resource: ResourceConfig = { title: '...', ... };`\n );\n }\n\n return resource;\n}\n","import path from 'path';\n\n/**\n * Extract the `tool` named export from a tool .ts file.\n *\n * Uses esbuild in ESM mode to compile TypeScript and tree-shake to just the\n * `tool` export. ESM tree-shaking drops unused exports (schema, handler) so\n * their dependencies (zod, etc.) are never evaluated.\n *\n * `schema` and `default` handler are loaded at runtime via Vite SSR.\n */\nexport async function extractToolExport(\n tsPath: string\n): Promise<{ tool: Record<string, unknown> }> {\n const esbuild = await import('esbuild');\n const absolutePath = path.resolve(tsPath);\n const dir = path.dirname(absolutePath);\n const base = path.basename(absolutePath);\n\n const result = await esbuild.build({\n stdin: {\n contents: `export { tool } from './${base}';`,\n resolveDir: dir,\n loader: 'ts',\n },\n bundle: true,\n write: false,\n format: 'esm',\n treeShaking: true,\n loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx' },\n logLevel: 'silent',\n plugins: [\n {\n name: 'externalize-node-modules',\n setup(build) {\n // Resolve relative imports normally (resource files, local modules)\n // but externalize everything from node_modules\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind !== 'import-statement') return;\n // Bare specifiers (not starting with . or /) are node_modules\n if (!args.path.startsWith('.') && !args.path.startsWith('/')) {\n return { external: true };\n }\n return undefined;\n });\n },\n },\n ],\n });\n\n if (!result.outputFiles?.length) {\n throw new Error(`Failed to extract tool from ${tsPath}`);\n }\n\n // Strip import statements and export block so we can eval as plain JS.\n // `tool` is pure data (no dependencies), so stripping imports is safe.\n // Other top-level code (schema, etc.) may reference stripped imports but\n // we only need the `tool` variable — errors in other code are caught and ignored.\n const code = result.outputFiles[0].text\n .replace(/^import\\s+.*$/gm, '')\n .replace(/^export\\s*\\{[^}]*\\}\\s*;?\\s*$/m, '');\n let tool: Record<string, unknown> | undefined;\n try {\n const fn = new Function(code + '\\nreturn tool;');\n tool = fn() as Record<string, unknown> | undefined;\n } catch {\n // If other top-level code crashes (e.g. schema using stripped zod),\n // extract just the tool variable declaration and eval that alone.\n const toolMatch = result.outputFiles[0].text.match(/var tool\\s*=\\s*(\\{[\\s\\S]*?\\n\\});/);\n if (toolMatch) {\n tool = new Function('return ' + toolMatch[1])() as Record<string, unknown>;\n }\n }\n if (!tool) {\n throw new Error(\n `No \"tool\" export found in ${tsPath}. ` +\n `Add: export const tool: AppToolConfig = { resource, ... };`\n );\n }\n\n return { tool };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/lib/discovery.d.ts
CHANGED
|
@@ -6,21 +6,20 @@ import { Simulation } from '../types/simulation.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function toPascalCase(str: string): string;
|
|
8
8
|
/**
|
|
9
|
-
* Extract the resource key from a resource file path
|
|
10
|
-
*
|
|
11
|
-
* @example extractResourceKey('../src/resources/albums-resource.tsx') // 'albums'
|
|
9
|
+
* Extract the resource key from a resource file path.
|
|
10
|
+
* Matches {name}.tsx (e.g., './albums/albums.tsx' → 'albums')
|
|
12
11
|
*/
|
|
13
12
|
export declare function extractResourceKey(path: string): string | undefined;
|
|
14
13
|
/**
|
|
15
|
-
* Extract the simulation key from a simulation file path
|
|
16
|
-
*
|
|
14
|
+
* Extract the simulation key from a simulation file path.
|
|
15
|
+
* Matches any *.json file (e.g., './show-albums.json' → 'show-albums')
|
|
17
16
|
*/
|
|
18
17
|
export declare function extractSimulationKey(path: string): string | undefined;
|
|
19
18
|
/**
|
|
20
19
|
* Find the best matching resource key for a simulation key.
|
|
21
20
|
* Matches the longest resource name that is a prefix of the simulation key.
|
|
22
|
-
* @example findResourceKey('albums-show', ['albums', 'album']) // 'albums'
|
|
23
21
|
* @example findResourceKey('review-diff', ['review', 'carousel']) // 'review'
|
|
22
|
+
* @example findResourceKey('albums', ['albums', 'review']) // 'albums'
|
|
24
23
|
*/
|
|
25
24
|
export declare function findResourceKey(simulationKey: string, resourceKeys: string[]): string | undefined;
|
|
26
25
|
/**
|
|
@@ -35,7 +34,7 @@ type GlobModules = Record<string, unknown>;
|
|
|
35
34
|
* Extracts components and exports them with PascalCase names.
|
|
36
35
|
*
|
|
37
36
|
* @example
|
|
38
|
-
* const modules = import.meta.glob('
|
|
37
|
+
* const modules = import.meta.glob('./*\/*.tsx', { eager: true });
|
|
39
38
|
* export default createResourceExports(modules);
|
|
40
39
|
*/
|
|
41
40
|
export declare function createResourceExports(modules: GlobModules): Record<string, React.ComponentType>;
|
|
@@ -44,7 +43,7 @@ export declare function createResourceExports(modules: GlobModules): Record<stri
|
|
|
44
43
|
* Used for connecting simulations to their resource definitions.
|
|
45
44
|
*
|
|
46
45
|
* @example
|
|
47
|
-
* const modules = import.meta.glob('../src/resources
|
|
46
|
+
* const modules = import.meta.glob('../src/resources/*\/*.tsx', { eager: true });
|
|
48
47
|
* const resourcesMap = buildResourceMap(modules);
|
|
49
48
|
*/
|
|
50
49
|
export declare function buildResourceMap<T>(modules: GlobModules): Map<string, T>;
|
|
@@ -69,7 +68,7 @@ export interface BuildSimulationsOptions<TResource, TSimulation> {
|
|
|
69
68
|
*/
|
|
70
69
|
export declare function buildSimulations<TResource, TSimulation>(options: BuildSimulationsOptions<TResource, TSimulation>): Record<string, TSimulation>;
|
|
71
70
|
/**
|
|
72
|
-
* Resource metadata from
|
|
71
|
+
* Resource metadata from resource .tsx files
|
|
73
72
|
*/
|
|
74
73
|
export interface ResourceMetadata {
|
|
75
74
|
name: string;
|
|
@@ -79,23 +78,19 @@ export interface ResourceMetadata {
|
|
|
79
78
|
* Options for building dev simulations
|
|
80
79
|
*/
|
|
81
80
|
export interface BuildDevSimulationsOptions {
|
|
82
|
-
/** Glob result of simulation JSON files
|
|
81
|
+
/** Glob result of simulation JSON files */
|
|
83
82
|
simulationModules: GlobModules;
|
|
84
|
-
/** Glob result of resource JSON files: import.meta.glob('*-resource.tsx', { eager: true }) */
|
|
85
|
-
resourceModules: GlobModules;
|
|
86
83
|
/** Resource components map from src/resources/index.ts */
|
|
87
84
|
resourceComponents: Record<string, React.ComponentType>;
|
|
85
|
+
/** Glob result of tool files: import.meta.glob('src/tools/*.ts', { eager: true }) */
|
|
86
|
+
toolModules: GlobModules;
|
|
87
|
+
/** Glob result of resource .tsx files from src/resources/ */
|
|
88
|
+
resourceModules: GlobModules;
|
|
88
89
|
}
|
|
89
90
|
/**
|
|
90
91
|
* Build simulations for the dev server from glob results.
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* const simulations = buildDevSimulations({
|
|
95
|
-
* simulationModules: import.meta.glob('../src/resources/**\/*-simulation.json', { eager: true }),
|
|
96
|
-
* resourceModules: import.meta.glob('../src/resources/**\/*-resource.tsx', { eager: true }),
|
|
97
|
-
* resourceComponents: resourceComponents,
|
|
98
|
-
* });
|
|
92
|
+
* Simulation JSON has `"tool": "tool-name"` string referencing a tool file.
|
|
93
|
+
* Tool files have `resource: 'name'` linking to a resource discovered from resourceModules.
|
|
99
94
|
*/
|
|
100
95
|
export declare function buildDevSimulations(options: BuildDevSimulationsOptions): Record<string, Simulation>;
|
|
101
96
|
/**
|
|
@@ -131,7 +126,7 @@ export interface FsOps {
|
|
|
131
126
|
*
|
|
132
127
|
* @example
|
|
133
128
|
* // Find source resources (tsx files)
|
|
134
|
-
* const resources = findResourceDirs('src/resources', key => `${key}
|
|
129
|
+
* const resources = findResourceDirs('src/resources', key => `${key}.tsx`);
|
|
135
130
|
*
|
|
136
131
|
* @example
|
|
137
132
|
* // Find built resources (js files)
|
|
@@ -139,35 +134,39 @@ export interface FsOps {
|
|
|
139
134
|
*/
|
|
140
135
|
export declare function findResourceDirs(baseDir: string, filePattern: (key: string) => string, fs: FsOps): ResourceDirInfo[];
|
|
141
136
|
/**
|
|
142
|
-
*
|
|
143
|
-
* Matches pattern: {resourceKey}-*-simulation.json
|
|
144
|
-
*
|
|
145
|
-
* @example
|
|
146
|
-
* isSimulationFile('albums-show-simulation.json', 'albums') // true
|
|
147
|
-
* isSimulationFile('albums-show-simulation.json', 'carousel') // false
|
|
148
|
-
* isSimulationFile('albums-resource.tsx', 'albums') // false
|
|
137
|
+
* Information about a discovered tool file
|
|
149
138
|
*/
|
|
150
|
-
export
|
|
139
|
+
export interface ToolFileInfo {
|
|
140
|
+
/** Tool name derived from filename (e.g., 'show-albums') */
|
|
141
|
+
name: string;
|
|
142
|
+
/** Full path to the tool file */
|
|
143
|
+
path: string;
|
|
144
|
+
}
|
|
151
145
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
146
|
+
* Find all tool files in a tools directory.
|
|
147
|
+
* Matches *.ts files directly in the directory (not recursive).
|
|
154
148
|
*
|
|
155
149
|
* @example
|
|
156
|
-
*
|
|
157
|
-
*
|
|
150
|
+
* findToolFiles('src/tools', fs)
|
|
151
|
+
* // [{ name: 'show-albums', path: 'src/tools/show-albums.ts' }]
|
|
158
152
|
*/
|
|
159
|
-
export declare function
|
|
153
|
+
export declare function findToolFiles(toolsDir: string, fs: Pick<FsOps, 'readdirSync' | 'existsSync'>): ToolFileInfo[];
|
|
160
154
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* @param resourceDir - Path to the resource directory
|
|
164
|
-
* @param resourceKey - Resource key (e.g., 'albums')
|
|
165
|
-
* @param fs - File system operations (for testing)
|
|
166
|
-
* @returns Array of { filename, name } objects
|
|
155
|
+
* Information about a discovered simulation file (flat convention)
|
|
167
156
|
*/
|
|
168
|
-
export
|
|
169
|
-
|
|
157
|
+
export interface SimulationFileInfo {
|
|
158
|
+
/** Filename without extension (e.g., 'show-albums') */
|
|
170
159
|
name: string;
|
|
160
|
+
/** Full path to the simulation file */
|
|
171
161
|
path: string;
|
|
172
|
-
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Find all simulation JSON files in a flat simulations directory.
|
|
165
|
+
* Matches any *.json file directly in the directory.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* findSimulationFilesFlat('tests/simulations', fs)
|
|
169
|
+
* // [{ name: 'show-albums', path: 'tests/simulations/show-albums.json' }]
|
|
170
|
+
*/
|
|
171
|
+
export declare function findSimulationFilesFlat(simulationsDir: string, fs: Pick<FsOps, 'readdirSync' | 'existsSync'>): SimulationFileInfo[];
|
|
173
172
|
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the `tool` named export from a tool .ts file.
|
|
3
|
+
*
|
|
4
|
+
* Uses esbuild in ESM mode to compile TypeScript and tree-shake to just the
|
|
5
|
+
* `tool` export. ESM tree-shaking drops unused exports (schema, handler) so
|
|
6
|
+
* their dependencies (zod, etc.) are never evaluated.
|
|
7
|
+
*
|
|
8
|
+
* `schema` and `default` handler are loaded at runtime via Vite SSR.
|
|
9
|
+
*/
|
|
10
|
+
export declare function extractToolExport(tsPath: string): Promise<{
|
|
11
|
+
tool: Record<string, unknown>;
|
|
12
|
+
}>;
|
package/dist/mcp/favicon.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const FAVICON_BASE64 = "
|
|
1
|
+
export declare const FAVICON_BASE64 = "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";
|
|
2
2
|
export declare const FAVICON_BUFFER: Buffer<ArrayBuffer>;
|
package/dist/mcp/index.cjs
CHANGED
|
@@ -7,7 +7,7 @@ const path = require("node:path");
|
|
|
7
7
|
const protocol = require("../protocol-CL4_Npj5.cjs");
|
|
8
8
|
const zod = require("zod");
|
|
9
9
|
const sse_js = require("@modelcontextprotocol/sdk/server/sse.js");
|
|
10
|
-
const FAVICON_BASE64 = "
|
|
10
|
+
const FAVICON_BASE64 = "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";
|
|
11
11
|
const FAVICON_BUFFER = Buffer.from(FAVICON_BASE64, "base64");
|
|
12
12
|
function getDefaultExportFromCjs(x2) {
|
|
13
13
|
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
@@ -14225,7 +14225,8 @@ function readResourceHtmlProd(distPath) {
|
|
|
14225
14225
|
return fs.readFileSync(htmlPath, "utf8");
|
|
14226
14226
|
}
|
|
14227
14227
|
function getViteResourceHtml(srcPath) {
|
|
14228
|
-
const
|
|
14228
|
+
const rawFileName = srcPath.split("/").pop() ?? "";
|
|
14229
|
+
const fileName = rawFileName.replace(/\.tsx$/, "");
|
|
14229
14230
|
const componentName = fileName.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("") + "Resource";
|
|
14230
14231
|
const devServerUrl = LOCAL_DEV_SERVER_URL;
|
|
14231
14232
|
const entryParams = new URLSearchParams({ src: srcPath, component: componentName });
|