@vulcan-energy/mcp-helper 0.1.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 +154 -0
- package/dist/bin/vulcan-mcp-helper.d.ts +9 -0
- package/dist/bin/vulcan-mcp-helper.d.ts.map +1 -0
- package/dist/bin/vulcan-mcp-helper.js +58 -0
- package/dist/bin/vulcan-mcp-helper.js.map +1 -0
- package/dist/src/engine/filesystem.d.ts +30 -0
- package/dist/src/engine/filesystem.d.ts.map +1 -0
- package/dist/src/engine/filesystem.js +61 -0
- package/dist/src/engine/filesystem.js.map +1 -0
- package/dist/src/engine/wasm.d.ts +23 -0
- package/dist/src/engine/wasm.d.ts.map +1 -0
- package/dist/src/engine/wasm.js +333 -0
- package/dist/src/engine/wasm.js.map +1 -0
- package/dist/src/engine/workspace.d.ts +23 -0
- package/dist/src/engine/workspace.d.ts.map +1 -0
- package/dist/src/engine/workspace.js +82 -0
- package/dist/src/engine/workspace.js.map +1 -0
- package/dist/src/server.d.ts +8 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +166 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/tools/calculateMetrics.d.ts +31 -0
- package/dist/src/tools/calculateMetrics.d.ts.map +1 -0
- package/dist/src/tools/calculateMetrics.js +347 -0
- package/dist/src/tools/calculateMetrics.js.map +1 -0
- package/dist/src/tools/createBatchConfig.d.ts +25 -0
- package/dist/src/tools/createBatchConfig.d.ts.map +1 -0
- package/dist/src/tools/createBatchConfig.js +128 -0
- package/dist/src/tools/createBatchConfig.js.map +1 -0
- package/dist/src/tools/getBatchStatus.d.ts +23 -0
- package/dist/src/tools/getBatchStatus.d.ts.map +1 -0
- package/dist/src/tools/getBatchStatus.js +194 -0
- package/dist/src/tools/getBatchStatus.js.map +1 -0
- package/dist/src/tools/index.d.ts +67 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +361 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/listBatchModels.d.ts +25 -0
- package/dist/src/tools/listBatchModels.d.ts.map +1 -0
- package/dist/src/tools/listBatchModels.js +86 -0
- package/dist/src/tools/listBatchModels.js.map +1 -0
- package/dist/src/tools/listCsvColumns.d.ts +27 -0
- package/dist/src/tools/listCsvColumns.d.ts.map +1 -0
- package/dist/src/tools/listCsvColumns.js +93 -0
- package/dist/src/tools/listCsvColumns.js.map +1 -0
- package/dist/src/tools/listParameters.d.ts +25 -0
- package/dist/src/tools/listParameters.d.ts.map +1 -0
- package/dist/src/tools/listParameters.js +64 -0
- package/dist/src/tools/listParameters.js.map +1 -0
- package/dist/src/tools/runBatch.d.ts +19 -0
- package/dist/src/tools/runBatch.d.ts.map +1 -0
- package/dist/src/tools/runBatch.js +90 -0
- package/dist/src/tools/runBatch.js.map +1 -0
- package/dist/src/tools/saveParameter.d.ts +23 -0
- package/dist/src/tools/saveParameter.d.ts.map +1 -0
- package/dist/src/tools/saveParameter.js +87 -0
- package/dist/src/tools/saveParameter.js.map +1 -0
- package/dist/src/tools/viewParameter.d.ts +18 -0
- package/dist/src/tools/viewParameter.d.ts.map +1 -0
- package/dist/src/tools/viewParameter.js +51 -0
- package/dist/src/tools/viewParameter.js.map +1 -0
- package/dist/src/utils/batchConfig.d.ts +32 -0
- package/dist/src/utils/batchConfig.d.ts.map +1 -0
- package/dist/src/utils/batchConfig.js +130 -0
- package/dist/src/utils/batchConfig.js.map +1 -0
- package/dist/src/utils/fileLoader.d.ts +21 -0
- package/dist/src/utils/fileLoader.d.ts.map +1 -0
- package/dist/src/utils/fileLoader.js +86 -0
- package/dist/src/utils/fileLoader.js.map +1 -0
- package/package.json +47 -0
- package/wasm/snippets/wasm-bindgen-rayon-38edf6e439f6d70d/src/workerHelpers.no-bundler.js +77 -0
- package/wasm/wasm_version.json +8 -0
- package/wasm/wasm_wrapper.js +1190 -0
- package/wasm/wasm_wrapper_bg.wasm +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* View a specific parameter JSON snippet and its markdown documentation
|
|
5
|
+
*/
|
|
6
|
+
export async function viewParameter(config, args) {
|
|
7
|
+
const { workspace } = config;
|
|
8
|
+
const { category, parameter_id } = args;
|
|
9
|
+
if (!category) {
|
|
10
|
+
throw new Error('category is required');
|
|
11
|
+
}
|
|
12
|
+
if (!parameter_id) {
|
|
13
|
+
throw new Error('parameter_id is required');
|
|
14
|
+
}
|
|
15
|
+
const paramDir = path.join(workspace, 'input', 'batch_parameters', category);
|
|
16
|
+
const jsonPath = path.join(paramDir, `${parameter_id}.json`);
|
|
17
|
+
const markdownPath = path.join(paramDir, `${parameter_id}.md`);
|
|
18
|
+
// Read JSON file
|
|
19
|
+
let jsonContent;
|
|
20
|
+
try {
|
|
21
|
+
const content = await fs.readFile(jsonPath, 'utf-8');
|
|
22
|
+
jsonContent = JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
const err = error;
|
|
26
|
+
if (err.code === 'ENOENT') {
|
|
27
|
+
throw new Error(`Parameter '${parameter_id}' not found in category '${category}'`);
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Failed to read parameter JSON: ${err.message}`);
|
|
30
|
+
}
|
|
31
|
+
// Read markdown file (optional)
|
|
32
|
+
let markdownContent = null;
|
|
33
|
+
try {
|
|
34
|
+
markdownContent = await fs.readFile(markdownPath, 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
// Markdown is optional, so we don't throw if it doesn't exist
|
|
38
|
+
const err = error;
|
|
39
|
+
if (err.code !== 'ENOENT') {
|
|
40
|
+
console.warn(`Failed to read markdown file: ${err.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
category,
|
|
45
|
+
parameter_id,
|
|
46
|
+
json: jsonContent,
|
|
47
|
+
markdown: markdownContent,
|
|
48
|
+
has_markdown: markdownContent !== null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=viewParameter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewParameter.js","sourceRoot":"","sources":["../../../src/tools/viewParameter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAgBxB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAiB,EACjB,IAAuB;IAEvB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC7B,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAExC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,YAAY,OAAO,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC;IAE/D,iBAAiB;IACjB,IAAI,WAAgB,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAA8B,CAAC;QAC3C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,cAAc,YAAY,4BAA4B,QAAQ,GAAG,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,gCAAgC;IAChC,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,eAAe,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8DAA8D;QAC9D,MAAM,GAAG,GAAG,KAA8B,CAAC;QAC3C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,iCAAiC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,eAAe;QACzB,YAAY,EAAE,eAAe,KAAK,IAAI;KACvC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
errors: string[];
|
|
4
|
+
warnings: string[];
|
|
5
|
+
}
|
|
6
|
+
interface MissingFile {
|
|
7
|
+
scenario: string;
|
|
8
|
+
category: string;
|
|
9
|
+
parameter: string;
|
|
10
|
+
path: string;
|
|
11
|
+
}
|
|
12
|
+
interface FileValidationResult {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
errors: string[];
|
|
15
|
+
missingFiles: MissingFile[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Validate batch config structure
|
|
19
|
+
* Returns { valid: boolean, errors: string[], warnings: string[] }
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateBatchConfigStructure(config: any): ValidationResult;
|
|
22
|
+
/**
|
|
23
|
+
* Calculate total permutations for a batch config
|
|
24
|
+
* Returns number or null if calculation fails
|
|
25
|
+
*/
|
|
26
|
+
export declare function calculatePermutations(config: any): number | null;
|
|
27
|
+
/**
|
|
28
|
+
* Validate that all parameter files exist in workspace
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateParameterFilesExist(workspace: string, config: any): Promise<FileValidationResult>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=batchConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchConfig.d.ts","sourceRoot":"","sources":["../../../src/utils/batchConfig.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,GAAG,GAAG,gBAAgB,CA6D1E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI,CAwBhE;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAkD/G"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Validate batch config structure
|
|
5
|
+
* Returns { valid: boolean, errors: string[], warnings: string[] }
|
|
6
|
+
*/
|
|
7
|
+
export function validateBatchConfigStructure(config) {
|
|
8
|
+
const errors = [];
|
|
9
|
+
const warnings = [];
|
|
10
|
+
if (!config || typeof config !== 'object') {
|
|
11
|
+
return { valid: false, errors: ['Config must be an object'], warnings: [] };
|
|
12
|
+
}
|
|
13
|
+
const scenarios = Object.keys(config);
|
|
14
|
+
if (scenarios.length === 0) {
|
|
15
|
+
errors.push('Config must have at least one scenario');
|
|
16
|
+
}
|
|
17
|
+
for (const [scenarioName, scenarioValue] of Object.entries(config)) {
|
|
18
|
+
if (!scenarioValue || typeof scenarioValue !== 'object') {
|
|
19
|
+
errors.push(`Scenario '${scenarioName}' must be an object`);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const scenario = scenarioValue;
|
|
23
|
+
// Check required fields
|
|
24
|
+
if (!scenario.base_json || !Array.isArray(scenario.base_json)) {
|
|
25
|
+
errors.push(`Scenario '${scenarioName}' is missing required 'base_json' field (must be array)`);
|
|
26
|
+
}
|
|
27
|
+
else if (scenario.base_json.length !== 1) {
|
|
28
|
+
errors.push(`Scenario '${scenarioName}' must have exactly one base_json (found ${scenario.base_json.length})`);
|
|
29
|
+
}
|
|
30
|
+
// Check weather_file (required)
|
|
31
|
+
if (!scenario.weather_file && !scenario.weather_files) {
|
|
32
|
+
errors.push(`Scenario '${scenarioName}' is missing required 'weather_file' or 'weather_files' field`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const weatherField = scenario.weather_file || scenario.weather_files;
|
|
36
|
+
if (!Array.isArray(weatherField) || weatherField.length !== 1) {
|
|
37
|
+
errors.push(`Scenario '${scenarioName}' must have exactly one weather_file (found ${weatherField?.length || 0})`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Check for invalid categories
|
|
41
|
+
const validCategories = [
|
|
42
|
+
'base_json', 'weather_file', 'weather_files',
|
|
43
|
+
'model_wrappers', 'simplified_fabric', 'heat_source_wet',
|
|
44
|
+
'hot_water_source', 'space_heat_emitters', 'controls',
|
|
45
|
+
'events', 'internal_gains', 'lighting', 'glazing',
|
|
46
|
+
'orientation', 'location', 'airtightness', 'mechanical_ventilation_unit',
|
|
47
|
+
'solar_systems', 'battery_systems', 'space_cooling_systems',
|
|
48
|
+
'tariff', 'compliance_settings'
|
|
49
|
+
];
|
|
50
|
+
for (const [category, values] of Object.entries(scenario)) {
|
|
51
|
+
if (!Array.isArray(values)) {
|
|
52
|
+
errors.push(`Scenario '${scenarioName}': '${category}' must be an array`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
valid: errors.length === 0,
|
|
58
|
+
errors,
|
|
59
|
+
warnings
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Calculate total permutations for a batch config
|
|
64
|
+
* Returns number or null if calculation fails
|
|
65
|
+
*/
|
|
66
|
+
export function calculatePermutations(config) {
|
|
67
|
+
try {
|
|
68
|
+
let totalPermutations = 0;
|
|
69
|
+
for (const scenarioValue of Object.values(config)) {
|
|
70
|
+
if (!scenarioValue || typeof scenarioValue !== 'object') {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const scenario = scenarioValue;
|
|
74
|
+
let scenarioPermutations = 1;
|
|
75
|
+
for (const [category, values] of Object.entries(scenario)) {
|
|
76
|
+
if (Array.isArray(values)) {
|
|
77
|
+
scenarioPermutations *= values.length;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
totalPermutations += scenarioPermutations;
|
|
81
|
+
}
|
|
82
|
+
return totalPermutations;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Validate that all parameter files exist in workspace
|
|
90
|
+
*/
|
|
91
|
+
export async function validateParameterFilesExist(workspace, config) {
|
|
92
|
+
const errors = [];
|
|
93
|
+
const missingFiles = [];
|
|
94
|
+
for (const [scenarioName, scenarioValue] of Object.entries(config)) {
|
|
95
|
+
if (!scenarioValue || typeof scenarioValue !== 'object') {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const scenario = scenarioValue;
|
|
99
|
+
for (const [category, values] of Object.entries(scenario)) {
|
|
100
|
+
if (!Array.isArray(values)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// Skip weather_files - they're in a different location
|
|
104
|
+
if (category === 'weather_file' || category === 'weather_files') {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
for (const paramId of values) {
|
|
108
|
+
const paramPath = path.join(workspace, 'input', 'batch_parameters', category, `${paramId}.json`);
|
|
109
|
+
try {
|
|
110
|
+
await fs.access(paramPath);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
missingFiles.push({
|
|
114
|
+
scenario: scenarioName,
|
|
115
|
+
category,
|
|
116
|
+
parameter: paramId,
|
|
117
|
+
path: paramPath
|
|
118
|
+
});
|
|
119
|
+
errors.push(`Scenario '${scenarioName}': Parameter '${paramId}' in category '${category}' not found at ${paramPath}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
valid: errors.length === 0,
|
|
126
|
+
errors,
|
|
127
|
+
missingFiles
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=batchConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchConfig.js","sourceRoot":"","sources":["../../../src/utils/batchConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load input.schema.json from workspace
|
|
3
|
+
*/
|
|
4
|
+
export declare function loadSchema(workspace: string): Promise<any>;
|
|
5
|
+
/**
|
|
6
|
+
* Load baseline model (demo_hp_annual.json)
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadBaseline(workspace: string): Promise<any>;
|
|
9
|
+
/**
|
|
10
|
+
* Load simplified fabric compliance example (if category is simplified_fabric)
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadSimplifiedExample(workspace: string, category: string): Promise<any | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Check if a file exists
|
|
15
|
+
*/
|
|
16
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Ensure directory exists
|
|
19
|
+
*/
|
|
20
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=fileLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileLoader.d.ts","sourceRoot":"","sources":["../../../src/utils/fileLoader.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAkBhE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAUlE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAsBpG;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Load input.schema.json from workspace
|
|
5
|
+
*/
|
|
6
|
+
export async function loadSchema(workspace) {
|
|
7
|
+
const schemaPaths = [
|
|
8
|
+
path.join(workspace, 'input.schema.json'),
|
|
9
|
+
path.join(workspace, 'hem_engine', 'schemas', 'input.schema.json'),
|
|
10
|
+
path.join(workspace, 'input', 'hem_engine', 'schemas', 'input.schema.json'),
|
|
11
|
+
];
|
|
12
|
+
for (const schemaPath of schemaPaths) {
|
|
13
|
+
try {
|
|
14
|
+
const content = await fs.readFile(schemaPath, 'utf-8');
|
|
15
|
+
return JSON.parse(content);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
// Try next path
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`Schema file not found. Tried: ${schemaPaths.join(', ')}`);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Load baseline model (demo_hp_annual.json)
|
|
26
|
+
*/
|
|
27
|
+
export async function loadBaseline(workspace) {
|
|
28
|
+
const baselinePath = path.join(workspace, 'input', 'batch_parameters', 'base_json', 'demo_hp_annual.json');
|
|
29
|
+
try {
|
|
30
|
+
const content = await fs.readFile(baselinePath, 'utf-8');
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const err = error;
|
|
35
|
+
throw new Error(`Baseline model not found at ${baselinePath}: ${err.message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Load simplified fabric compliance example (if category is simplified_fabric)
|
|
40
|
+
*/
|
|
41
|
+
export async function loadSimplifiedExample(workspace, category) {
|
|
42
|
+
if (category !== 'simplified_fabric') {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const examplePaths = [
|
|
46
|
+
path.join(workspace, 'input', 'batch_parameters', 'simplified_fabric', 'good_insulation_compliance.json'),
|
|
47
|
+
path.join(workspace, 'input', 'batch_parameters', 'simplified_fabric', 'compliance_example.json'),
|
|
48
|
+
];
|
|
49
|
+
for (const examplePath of examplePaths) {
|
|
50
|
+
try {
|
|
51
|
+
const content = await fs.readFile(examplePath, 'utf-8');
|
|
52
|
+
return JSON.parse(content);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
// Try next path
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Not found - return null (optional)
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if a file exists
|
|
64
|
+
*/
|
|
65
|
+
export async function fileExists(filePath) {
|
|
66
|
+
try {
|
|
67
|
+
await fs.access(filePath);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Ensure directory exists
|
|
76
|
+
*/
|
|
77
|
+
export async function ensureDir(dirPath) {
|
|
78
|
+
try {
|
|
79
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const err = error;
|
|
83
|
+
throw new Error(`Failed to create directory ${dirPath}: ${err.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=fileLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileLoader.js","sourceRoot":"","sources":["../../../src/utils/fileLoader.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vulcan-energy/mcp-helper",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Vulcan MCP Helper Service for Cursor, Claude Desktop, and other local MCP clients",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/server.js",
|
|
7
|
+
"types": "./dist/server.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"vulcan-mcp-helper": "./dist/bin/vulcan-mcp-helper.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsx watch bin/vulcan-mcp-helper.ts",
|
|
14
|
+
"start": "node dist/bin/vulcan-mcp-helper.js",
|
|
15
|
+
"prepublishOnly": "npm run build && npm run clean",
|
|
16
|
+
"clean": "echo 'Package is ready for publishing'"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"model-context-protocol",
|
|
21
|
+
"vulcan",
|
|
22
|
+
"hem",
|
|
23
|
+
"energy-modeling"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
29
|
+
"express": "^4.18.2",
|
|
30
|
+
"zod": "^4.1.12"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/express": "^4.17.21",
|
|
34
|
+
"@types/node": "^20.10.0",
|
|
35
|
+
"tsx": "^4.7.0",
|
|
36
|
+
"typescript": "^5.3.3"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist/",
|
|
43
|
+
"wasm/",
|
|
44
|
+
"package.json",
|
|
45
|
+
"README.md"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 Google Inc. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
* See the License for the specific language governing permissions and
|
|
11
|
+
* limitations under the License.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// This file is kept similar to workerHelpers.js, but intended to be used in
|
|
15
|
+
// a bundlerless ES module environment (which has a few differences).
|
|
16
|
+
|
|
17
|
+
function waitForMsgType(target, type) {
|
|
18
|
+
return new Promise(resolve => {
|
|
19
|
+
target.addEventListener('message', function onMsg({ data }) {
|
|
20
|
+
if (data == null || data.type !== type) return;
|
|
21
|
+
target.removeEventListener('message', onMsg);
|
|
22
|
+
resolve(data);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// We need to wait for a specific message because this file is used both
|
|
28
|
+
// as a Worker and as a regular script, so it might receive unrelated
|
|
29
|
+
// messages on the page.
|
|
30
|
+
waitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {
|
|
31
|
+
const pkg = await import(data.mainJS);
|
|
32
|
+
await pkg.default(data.module, data.memory);
|
|
33
|
+
postMessage({ type: 'wasm_bindgen_worker_ready' });
|
|
34
|
+
pkg.wbg_rayon_start_worker(data.receiver);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Note: this is never used, but necessary to prevent a bug in Firefox
|
|
38
|
+
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1702191) where it collects
|
|
39
|
+
// Web Workers that have a shared WebAssembly memory with the main thread,
|
|
40
|
+
// but are not explicitly rooted via a `Worker` instance.
|
|
41
|
+
//
|
|
42
|
+
// By storing them in a variable, we can keep `Worker` objects around and
|
|
43
|
+
// prevent them from getting GC-d.
|
|
44
|
+
let _workers;
|
|
45
|
+
|
|
46
|
+
export async function startWorkers(module, memory, builder) {
|
|
47
|
+
if (builder.numThreads() === 0) {
|
|
48
|
+
throw new Error(`num_threads must be > 0.`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const workerInit = {
|
|
52
|
+
type: 'wasm_bindgen_worker_init',
|
|
53
|
+
module,
|
|
54
|
+
memory,
|
|
55
|
+
receiver: builder.receiver(),
|
|
56
|
+
mainJS: builder.mainJS()
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
_workers = await Promise.all(
|
|
60
|
+
Array.from({ length: builder.numThreads() }, async () => {
|
|
61
|
+
// Self-spawn into a new Worker.
|
|
62
|
+
// The script is fetched as a blob so it works even if this script is
|
|
63
|
+
// hosted remotely (e.g. on a CDN). This avoids a cross-origin
|
|
64
|
+
// security error.
|
|
65
|
+
let scriptBlob = await fetch(import.meta.url).then(r => r.blob());
|
|
66
|
+
let url = URL.createObjectURL(scriptBlob);
|
|
67
|
+
const worker = new Worker(url, {
|
|
68
|
+
type: 'module'
|
|
69
|
+
});
|
|
70
|
+
worker.postMessage(workerInit);
|
|
71
|
+
await waitForMsgType(worker, 'wasm_bindgen_worker_ready');
|
|
72
|
+
URL.revokeObjectURL(url);
|
|
73
|
+
return worker;
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
builder.build();
|
|
77
|
+
}
|