@mcpmake/core 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/dom-parser.d.ts +28 -0
- package/dist/analyzer/dom-parser.d.ts.map +1 -1
- package/dist/analyzer/dom-parser.js +77 -2
- package/dist/analyzer/dom-parser.js.map +1 -1
- package/dist/analyzer/goal-crawler.d.ts +2 -1
- package/dist/analyzer/goal-crawler.d.ts.map +1 -1
- package/dist/analyzer/goal-crawler.js +66 -17
- package/dist/analyzer/goal-crawler.js.map +1 -1
- package/dist/analyzer/semantic-analyzer.d.ts +1 -1
- package/dist/analyzer/semantic-analyzer.d.ts.map +1 -1
- package/dist/analyzer/semantic-analyzer.js +15 -16
- package/dist/analyzer/semantic-analyzer.js.map +1 -1
- package/dist/analyzer/site-crawler.d.ts.map +1 -1
- package/dist/analyzer/site-crawler.js +86 -12
- package/dist/analyzer/site-crawler.js.map +1 -1
- package/dist/config/mcpmake-config.d.ts.map +1 -1
- package/dist/config/mcpmake-config.js +5 -0
- package/dist/config/mcpmake-config.js.map +1 -1
- package/dist/emitter/code-writer.d.ts +1 -0
- package/dist/emitter/code-writer.d.ts.map +1 -1
- package/dist/emitter/code-writer.js +79 -12
- package/dist/emitter/code-writer.js.map +1 -1
- package/dist/emitter/index.d.ts +8 -0
- package/dist/emitter/index.d.ts.map +1 -1
- package/dist/emitter/index.js.map +1 -1
- package/dist/emitter/python-templates/dockerfile.hbs +4 -1
- package/dist/emitter/python-templates/server.py.hbs +4 -0
- package/dist/emitter/site-scaffolder.d.ts.map +1 -1
- package/dist/emitter/site-scaffolder.js +28 -1
- package/dist/emitter/site-scaffolder.js.map +1 -1
- package/dist/emitter/site-templates/browser-manager.ts.hbs +24 -3
- package/dist/emitter/site-templates/dockerfile.hbs +13 -4
- package/dist/emitter/site-templates/env.example.hbs +8 -0
- package/dist/emitter/site-templates/server-main-http.ts.hbs +53 -0
- package/dist/emitter/site-templates/telemetry.ts.hbs +117 -0
- package/dist/emitter/templates/auth-provider.ts.hbs +9 -5
- package/dist/emitter/templates/config.ts.hbs +22 -0
- package/dist/emitter/templates/dockerfile.hbs +12 -4
- package/dist/emitter/templates/oauth.ts.hbs +19 -65
- package/dist/emitter/templates/server-main-http.ts.hbs +33 -8
- package/dist/emitter/templates/task-handlers.ts.hbs +40 -1
- package/dist/emitter/worker-templates/worker.ts.hbs +88 -25
- package/dist/generator/spec-generator.d.ts.map +1 -1
- package/dist/generator/spec-generator.js +9 -54
- package/dist/generator/spec-generator.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/anthropic-provider.d.ts +14 -0
- package/dist/llm/anthropic-provider.d.ts.map +1 -0
- package/dist/llm/anthropic-provider.js +50 -0
- package/dist/llm/anthropic-provider.js.map +1 -0
- package/dist/llm/index.d.ts +19 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +73 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/openai-provider.d.ts +46 -0
- package/dist/llm/openai-provider.d.ts.map +1 -0
- package/dist/llm/openai-provider.js +221 -0
- package/dist/llm/openai-provider.js.map +1 -0
- package/dist/llm/types.d.ts +61 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +16 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/parser/har-filter.d.ts +7 -0
- package/dist/parser/har-filter.d.ts.map +1 -1
- package/dist/parser/har-filter.js +107 -1
- package/dist/parser/har-filter.js.map +1 -1
- package/dist/parser/index.d.ts +1 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +1 -1
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/openapi-loader.d.ts.map +1 -1
- package/dist/parser/openapi-loader.js +36 -2
- package/dist/parser/openapi-loader.js.map +1 -1
- package/dist/parser/postman-loader.d.ts.map +1 -1
- package/dist/parser/postman-loader.js +6 -1
- package/dist/parser/postman-loader.js.map +1 -1
- package/dist/parser/schema-converter.d.ts.map +1 -1
- package/dist/parser/schema-converter.js +34 -23
- package/dist/parser/schema-converter.js.map +1 -1
- package/dist/plugins/loader.d.ts +5 -1
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +39 -10
- package/dist/plugins/loader.js.map +1 -1
- package/dist/recorder/browser-recorder.d.ts.map +1 -1
- package/dist/recorder/browser-recorder.js +50 -5
- package/dist/recorder/browser-recorder.js.map +1 -1
- package/dist/rescan/rescan-scheduler.d.ts.map +1 -1
- package/dist/rescan/rescan-scheduler.js +22 -7
- package/dist/rescan/rescan-scheduler.js.map +1 -1
- package/dist/site-transformer/selector-healer.d.ts +1 -1
- package/dist/site-transformer/selector-healer.d.ts.map +1 -1
- package/dist/site-transformer/selector-healer.js +17 -18
- package/dist/site-transformer/selector-healer.js.map +1 -1
- package/dist/transformer/auth-detector.d.ts.map +1 -1
- package/dist/transformer/auth-detector.js +13 -1
- package/dist/transformer/auth-detector.js.map +1 -1
- package/dist/transformer/har-schema-inferrer.d.ts.map +1 -1
- package/dist/transformer/har-schema-inferrer.js +2 -0
- package/dist/transformer/har-schema-inferrer.js.map +1 -1
- package/dist/transformer/har-to-operations.d.ts +1 -0
- package/dist/transformer/har-to-operations.d.ts.map +1 -1
- package/dist/transformer/har-to-operations.js +42 -10
- package/dist/transformer/har-to-operations.js.map +1 -1
- package/dist/transformer/llm-namer.d.ts.map +1 -1
- package/dist/transformer/llm-namer.js +10 -13
- package/dist/transformer/llm-namer.js.map +1 -1
- package/dist/transformer/tool-builder.d.ts.map +1 -1
- package/dist/transformer/tool-builder.js +30 -1
- package/dist/transformer/tool-builder.js.map +1 -1
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/fail.d.ts.map +1 -1
- package/dist/utils/fail.js +22 -4
- package/dist/utils/fail.js.map +1 -1
- package/dist/utils/json-extract.d.ts +21 -0
- package/dist/utils/json-extract.d.ts.map +1 -0
- package/dist/utils/json-extract.js +67 -0
- package/dist/utils/json-extract.js.map +1 -0
- package/dist/utils/model-resolver.d.ts.map +1 -1
- package/dist/utils/model-resolver.js +6 -0
- package/dist/utils/model-resolver.js.map +1 -1
- package/dist/utils/sanitize.d.ts +1 -1
- package/dist/utils/sanitize.d.ts.map +1 -1
- package/dist/utils/sanitize.js +6 -2
- package/dist/utils/sanitize.js.map +1 -1
- package/dist/utils/ssrf-guard.d.ts +10 -0
- package/dist/utils/ssrf-guard.d.ts.map +1 -0
- package/dist/utils/ssrf-guard.js +130 -0
- package/dist/utils/ssrf-guard.js.map +1 -0
- package/dist/utils/watcher.d.ts +17 -1
- package/dist/utils/watcher.d.ts.map +1 -1
- package/dist/utils/watcher.js +53 -21
- package/dist/utils/watcher.js.map +1 -1
- package/package.json +2 -1
|
@@ -56,8 +56,14 @@ export async function resolveModel(client, tier, override) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
catch (err) {
|
|
59
|
+
// Transient Models API failure: return the fallback for this call WITHOUT
|
|
60
|
+
// caching it, so a later call retries once the API recovers (a poisoned
|
|
61
|
+
// cache would pin the whole process to the fallback alias).
|
|
59
62
|
logger.warn(`Could not list models (${err instanceof Error ? err.message : err}); using "${preferred}"`);
|
|
63
|
+
return preferred;
|
|
60
64
|
}
|
|
65
|
+
// Only successful resolutions are cached — the served-model list rarely
|
|
66
|
+
// changes mid-run, so one API round-trip per tier is enough.
|
|
61
67
|
cache.set(tier, choice);
|
|
62
68
|
return choice;
|
|
63
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/utils/model-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AASrC;;;;GAIG;AACH,MAAM,SAAS,GAA8B;IAC3C,QAAQ,EAAE,mBAAmB;IAC7B,IAAI,EAAE,kBAAkB;CACzB,CAAC;AAEF,MAAM,YAAY,GAA8B;IAC9C,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAiB,EACjB,IAAe,EACf,QAAiB;IAEjB,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,SAAS,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,MAAM,GAA+D,EAAE,CAAC;QAC9E,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM;iBAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;gBAClE,yEAAyE;iBACxE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,oBAAoB,SAAS,yBAAyB,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;gBAChF,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CACT,oBAAoB,SAAS,wBAAwB,IAAI,gCAAgC,CAC1F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CACT,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,SAAS,GAAG,CAC5F,CAAC;
|
|
1
|
+
{"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/utils/model-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AASrC;;;;GAIG;AACH,MAAM,SAAS,GAA8B;IAC3C,QAAQ,EAAE,mBAAmB;IAC7B,IAAI,EAAE,kBAAkB;CACzB,CAAC;AAEF,MAAM,YAAY,GAA8B;IAC9C,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAiB,EACjB,IAAe,EACf,QAAiB;IAEjB,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,SAAS,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,MAAM,GAA+D,EAAE,CAAC;QAC9E,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM;iBAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;gBAClE,yEAAyE;iBACxE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,oBAAoB,SAAS,yBAAyB,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;gBAChF,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CACT,oBAAoB,SAAS,wBAAwB,IAAI,gCAAgC,CAC1F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0EAA0E;QAC1E,wEAAwE;QACxE,4DAA4D;QAC5D,MAAM,CAAC,IAAI,CACT,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,aAAa,SAAS,GAAG,CAC5F,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,wEAAwE;IACxE,6DAA6D;IAC7D,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/utils/sanitize.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sanitize a string for safe embedding in a JavaScript/TypeScript single-quoted string literal.
|
|
3
|
-
* Escapes backslashes, single quotes, and
|
|
3
|
+
* Escapes backslashes, single quotes, and CR/LF.
|
|
4
4
|
*/
|
|
5
5
|
export declare function escapeStringLiteral(str: string): string;
|
|
6
6
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,GAC3D,MAAM,CAUR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAStD;AAMD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMlD;AA0CD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKpD;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|
package/dist/utils/sanitize.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sanitize a string for safe embedding in a JavaScript/TypeScript single-quoted string literal.
|
|
3
|
-
* Escapes backslashes, single quotes, and
|
|
3
|
+
* Escapes backslashes, single quotes, and CR/LF.
|
|
4
4
|
*/
|
|
5
5
|
export function escapeStringLiteral(str) {
|
|
6
|
-
return str
|
|
6
|
+
return str
|
|
7
|
+
.replace(/\\/g, '\\\\')
|
|
8
|
+
.replace(/'/g, "\\'")
|
|
9
|
+
.replace(/\n/g, '\\n')
|
|
10
|
+
.replace(/\r/g, '\\r');
|
|
7
11
|
}
|
|
8
12
|
/**
|
|
9
13
|
* Sanitize a string for safe embedding in a JavaScript/TypeScript template literal.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function privateHostsAllowed(): boolean;
|
|
2
|
+
/** Whether `ip` (a literal IPv4 or IPv6 address) is private, loopback, or reserved. */
|
|
3
|
+
export declare function isPrivateOrReservedIp(ip: string): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Throw if `urlString` is not a public http(s) URL. Resolves the host via DNS and
|
|
6
|
+
* rejects when any resolved address is private/loopback/link-local/reserved.
|
|
7
|
+
* Honors the `MCPMAKE_ALLOW_PRIVATE_HOSTS` escape hatch.
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertPublicUrl(urlString: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=ssrf-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssrf-guard.d.ts","sourceRoot":"","sources":["../../src/utils/ssrf-guard.ts"],"names":[],"mappings":"AAyBA,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AA0CD,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CtE"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { isIP } from 'node:net';
|
|
2
|
+
import { lookup } from 'node:dns/promises';
|
|
3
|
+
/**
|
|
4
|
+
* SSRF guard for outbound requests driven by untrusted input — crawled links,
|
|
5
|
+
* recorded navigations, and remote OpenAPI spec/`$ref` URLs.
|
|
6
|
+
*
|
|
7
|
+
* The browser crawler/recorder and the spec loader all fetch URLs that originate
|
|
8
|
+
* from user input or from an LLM/page following links. Without a host check they
|
|
9
|
+
* can be steered at `localhost`, RFC1918 intranets, or the cloud metadata
|
|
10
|
+
* endpoint (`169.254.169.254`). This module resolves a URL's host and rejects
|
|
11
|
+
* any that points at a private, loopback, link-local, or otherwise reserved
|
|
12
|
+
* address.
|
|
13
|
+
*
|
|
14
|
+
* Residual limitation (documented, not closed here): this checks at request time
|
|
15
|
+
* but does not pin DNS at the socket, so a TOCTOU/DNS-rebinding attacker who
|
|
16
|
+
* flips a record between this lookup and the browser's own connect can still slip
|
|
17
|
+
* through. Full DNS-pinning would require intercepting at the socket layer.
|
|
18
|
+
*
|
|
19
|
+
* Escape hatch: set `MCPMAKE_ALLOW_PRIVATE_HOSTS=1` to allow private/loopback
|
|
20
|
+
* targets (local development against `localhost` test servers).
|
|
21
|
+
*/
|
|
22
|
+
const ALLOW_ENV = 'MCPMAKE_ALLOW_PRIVATE_HOSTS';
|
|
23
|
+
export function privateHostsAllowed() {
|
|
24
|
+
return process.env[ALLOW_ENV] === '1' || process.env[ALLOW_ENV] === 'true';
|
|
25
|
+
}
|
|
26
|
+
/** Parse a dotted-quad IPv4 string into its four octets, or null if malformed. */
|
|
27
|
+
function ipv4Octets(ip) {
|
|
28
|
+
const parts = ip.split('.');
|
|
29
|
+
if (parts.length !== 4)
|
|
30
|
+
return null;
|
|
31
|
+
const nums = parts.map((p) => Number(p));
|
|
32
|
+
if (nums.some((n) => !Number.isInteger(n) || n < 0 || n > 255))
|
|
33
|
+
return null;
|
|
34
|
+
return nums;
|
|
35
|
+
}
|
|
36
|
+
function isPrivateIpv4(ip) {
|
|
37
|
+
const o = ipv4Octets(ip);
|
|
38
|
+
if (!o)
|
|
39
|
+
return false;
|
|
40
|
+
const [a, b] = o;
|
|
41
|
+
if (a === 0)
|
|
42
|
+
return true; // 0.0.0.0/8 "this network"
|
|
43
|
+
if (a === 10)
|
|
44
|
+
return true; // 10.0.0.0/8 private
|
|
45
|
+
if (a === 127)
|
|
46
|
+
return true; // 127.0.0.0/8 loopback
|
|
47
|
+
if (a === 169 && b === 254)
|
|
48
|
+
return true; // 169.254.0.0/16 link-local (cloud metadata)
|
|
49
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
50
|
+
return true; // 172.16.0.0/12 private
|
|
51
|
+
if (a === 192 && b === 168)
|
|
52
|
+
return true; // 192.168.0.0/16 private
|
|
53
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
54
|
+
return true; // 100.64.0.0/10 CGNAT
|
|
55
|
+
if (a === 192 && b === 0 && o[2] === 0)
|
|
56
|
+
return true; // 192.0.0.0/24 IETF protocol
|
|
57
|
+
if (a >= 224)
|
|
58
|
+
return true; // 224.0.0.0/4 multicast + 240.0.0.0/4 reserved + 255.* broadcast
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function isPrivateIpv6(raw) {
|
|
62
|
+
const ip = raw.toLowerCase();
|
|
63
|
+
if (ip === '::1' || ip === '::')
|
|
64
|
+
return true; // loopback / unspecified
|
|
65
|
+
// IPv4-mapped (::ffff:a.b.c.d) and IPv4-compatible / NAT64 — re-check embedded v4.
|
|
66
|
+
const mapped = ip.match(/(?:::ffff:|::ffff:0:|64:ff9b::)(\d+\.\d+\.\d+\.\d+)$/);
|
|
67
|
+
if (mapped)
|
|
68
|
+
return isPrivateIpv4(mapped[1]);
|
|
69
|
+
if (ip.startsWith('fe8') || ip.startsWith('fe9') || ip.startsWith('fea') || ip.startsWith('feb'))
|
|
70
|
+
return true; // fe80::/10 link-local
|
|
71
|
+
if (ip.startsWith('fc') || ip.startsWith('fd'))
|
|
72
|
+
return true; // fc00::/7 unique-local
|
|
73
|
+
if (ip.startsWith('fec') || ip.startsWith('fed') || ip.startsWith('fee') || ip.startsWith('fef'))
|
|
74
|
+
return true; // fec0::/10 deprecated site-local
|
|
75
|
+
if (ip.startsWith('ff'))
|
|
76
|
+
return true; // ff00::/8 multicast
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
/** Whether `ip` (a literal IPv4 or IPv6 address) is private, loopback, or reserved. */
|
|
80
|
+
export function isPrivateOrReservedIp(ip) {
|
|
81
|
+
const kind = isIP(ip);
|
|
82
|
+
if (kind === 4)
|
|
83
|
+
return isPrivateIpv4(ip);
|
|
84
|
+
if (kind === 6)
|
|
85
|
+
return isPrivateIpv6(ip);
|
|
86
|
+
return false; // not an IP literal
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Throw if `urlString` is not a public http(s) URL. Resolves the host via DNS and
|
|
90
|
+
* rejects when any resolved address is private/loopback/link-local/reserved.
|
|
91
|
+
* Honors the `MCPMAKE_ALLOW_PRIVATE_HOSTS` escape hatch.
|
|
92
|
+
*/
|
|
93
|
+
export async function assertPublicUrl(urlString) {
|
|
94
|
+
let url;
|
|
95
|
+
try {
|
|
96
|
+
url = new URL(urlString);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
throw new Error(`Invalid URL: ${urlString}`);
|
|
100
|
+
}
|
|
101
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
102
|
+
throw new Error(`Refusing non-http(s) URL: ${urlString}`);
|
|
103
|
+
}
|
|
104
|
+
if (privateHostsAllowed())
|
|
105
|
+
return;
|
|
106
|
+
// Strip IPv6 brackets from the hostname for literal checks.
|
|
107
|
+
const host = url.hostname.replace(/^\[/, '').replace(/\]$/, '');
|
|
108
|
+
// Literal IP host — check directly, no DNS needed.
|
|
109
|
+
if (isIP(host)) {
|
|
110
|
+
if (isPrivateOrReservedIp(host)) {
|
|
111
|
+
throw new Error(`Refusing to access private/reserved address ${host} (set ${ALLOW_ENV}=1 to allow).`);
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Hostname — resolve every address it maps to and reject if ANY is private.
|
|
116
|
+
let addresses;
|
|
117
|
+
try {
|
|
118
|
+
addresses = await lookup(host, { all: true });
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
throw new Error(`Cannot resolve host "${host}" to verify it is public; refusing request.`);
|
|
122
|
+
}
|
|
123
|
+
for (const { address } of addresses) {
|
|
124
|
+
if (isPrivateOrReservedIp(address)) {
|
|
125
|
+
throw new Error(`Refusing request: host "${host}" resolves to private/reserved address ${address} ` +
|
|
126
|
+
`(set ${ALLOW_ENV}=1 to allow).`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=ssrf-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssrf-guard.js","sourceRoot":"","sources":["../../src/utils/ssrf-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,SAAS,GAAG,6BAA6B,CAAC;AAEhD,MAAM,UAAU,mBAAmB;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC;AAC7E,CAAC;AAED,kFAAkF;AAClF,SAAS,UAAU,CAAC,EAAU;IAC5B,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5E,OAAO,IAAwC,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,MAAM,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACjB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,2BAA2B;IACrD,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC,CAAC,qBAAqB;IAChD,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,uBAAuB;IACnD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,6CAA6C;IACtF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC,CAAC,wBAAwB;IAC1E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,yBAAyB;IAClE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,sBAAsB;IACzE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,6BAA6B;IAClF,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,iEAAiE;IAC5F,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC7B,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC,yBAAyB;IACvE,mFAAmF;IACnF,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAChF,IAAI,MAAM;QAAE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAC9F,OAAO,IAAI,CAAC,CAAC,uBAAuB;IACtC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,wBAAwB;IACrF,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAC9F,OAAO,IAAI,CAAC,CAAC,kCAAkC;IACjD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,qBAAqB;IAC3D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;IACzC,OAAO,KAAK,CAAC,CAAC,oBAAoB;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,mBAAmB,EAAE;QAAE,OAAO;IAElC,4DAA4D;IAC5D,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEhE,mDAAmD;IACnD,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACf,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,+CAA+C,IAAI,SAAS,SAAS,eAAe,CACrF,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,4EAA4E;IAC5E,IAAI,SAAgC,CAAC;IACrC,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,6CAA6C,CAAC,CAAC;IAC7F,CAAC;IACD,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,EAAE,CAAC;QACpC,IAAI,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,2BAA2B,IAAI,0CAA0C,OAAO,GAAG;gBACjF,QAAQ,SAAS,eAAe,CACnC,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/utils/watcher.d.ts
CHANGED
|
@@ -4,9 +4,25 @@ export interface WatchOptions {
|
|
|
4
4
|
onChange: () => Promise<void>;
|
|
5
5
|
debounceMs?: number;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Debounce + coalesce change notifications into regeneration runs.
|
|
9
|
+
*
|
|
10
|
+
* - Rapid bursts before a run are debounced into one run.
|
|
11
|
+
* - A change that arrives *while* a run is in flight sets a single `pending`
|
|
12
|
+
* flag, so exactly one trailing run fires afterwards. The flag (not a queue)
|
|
13
|
+
* caps the backlog at one regardless of how many events land mid-run, which
|
|
14
|
+
* avoids an unbounded backlog / memory growth.
|
|
15
|
+
*
|
|
16
|
+
* Exposed (and exported) separately from the fs binding so the coalescing logic
|
|
17
|
+
* is testable without relying on platform fs.watch event timing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createChangeHandler(onChange: () => Promise<void>, debounceMs: number): {
|
|
20
|
+
notify: () => void;
|
|
21
|
+
};
|
|
7
22
|
/**
|
|
8
23
|
* Watch a file for changes and invoke a callback.
|
|
9
|
-
* Debounces rapid successive changes (e.g., editor save + format)
|
|
24
|
+
* Debounces rapid successive changes (e.g., editor save + format) and coalesces
|
|
25
|
+
* changes that arrive during a regeneration into a single trailing run.
|
|
10
26
|
*/
|
|
11
27
|
export declare function watchFile(options: WatchOptions): FSWatcher;
|
|
12
28
|
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/utils/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAGhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/utils/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAGhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB;IAAE,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAmCxB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAa1D"}
|
package/dist/utils/watcher.js
CHANGED
|
@@ -1,34 +1,66 @@
|
|
|
1
1
|
import { watch } from 'node:fs';
|
|
2
2
|
import { logger } from './logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Debounce + coalesce change notifications into regeneration runs.
|
|
5
|
+
*
|
|
6
|
+
* - Rapid bursts before a run are debounced into one run.
|
|
7
|
+
* - A change that arrives *while* a run is in flight sets a single `pending`
|
|
8
|
+
* flag, so exactly one trailing run fires afterwards. The flag (not a queue)
|
|
9
|
+
* caps the backlog at one regardless of how many events land mid-run, which
|
|
10
|
+
* avoids an unbounded backlog / memory growth.
|
|
11
|
+
*
|
|
12
|
+
* Exposed (and exported) separately from the fs binding so the coalescing logic
|
|
13
|
+
* is testable without relying on platform fs.watch event timing.
|
|
14
|
+
*/
|
|
15
|
+
export function createChangeHandler(onChange, debounceMs) {
|
|
16
|
+
let timer;
|
|
17
|
+
let running = false;
|
|
18
|
+
let pending = false;
|
|
19
|
+
async function regenerate() {
|
|
20
|
+
running = true;
|
|
21
|
+
try {
|
|
22
|
+
do {
|
|
23
|
+
pending = false;
|
|
24
|
+
logger.info('Spec file changed, regenerating...');
|
|
25
|
+
try {
|
|
26
|
+
await onChange();
|
|
27
|
+
logger.success('Regeneration complete');
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
logger.error(`Regeneration failed: ${err instanceof Error ? err.message : err}`);
|
|
31
|
+
}
|
|
32
|
+
} while (pending);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
running = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
notify() {
|
|
40
|
+
if (running) {
|
|
41
|
+
pending = true;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (timer)
|
|
45
|
+
clearTimeout(timer);
|
|
46
|
+
timer = setTimeout(() => {
|
|
47
|
+
void regenerate();
|
|
48
|
+
}, debounceMs);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
3
52
|
/**
|
|
4
53
|
* Watch a file for changes and invoke a callback.
|
|
5
|
-
* Debounces rapid successive changes (e.g., editor save + format)
|
|
54
|
+
* Debounces rapid successive changes (e.g., editor save + format) and coalesces
|
|
55
|
+
* changes that arrive during a regeneration into a single trailing run.
|
|
6
56
|
*/
|
|
7
57
|
export function watchFile(options) {
|
|
8
58
|
const debounceMs = options.debounceMs ?? 500;
|
|
9
|
-
|
|
10
|
-
let running = false;
|
|
59
|
+
const handler = createChangeHandler(options.onChange, debounceMs);
|
|
11
60
|
const watcher = watch(options.filePath, (eventType) => {
|
|
12
61
|
if (eventType !== 'change')
|
|
13
62
|
return;
|
|
14
|
-
|
|
15
|
-
return;
|
|
16
|
-
if (timer)
|
|
17
|
-
clearTimeout(timer);
|
|
18
|
-
timer = setTimeout(async () => {
|
|
19
|
-
running = true;
|
|
20
|
-
logger.info('Spec file changed, regenerating...');
|
|
21
|
-
try {
|
|
22
|
-
await options.onChange();
|
|
23
|
-
logger.success('Regeneration complete');
|
|
24
|
-
}
|
|
25
|
-
catch (err) {
|
|
26
|
-
logger.error(`Regeneration failed: ${err instanceof Error ? err.message : err}`);
|
|
27
|
-
}
|
|
28
|
-
finally {
|
|
29
|
-
running = false;
|
|
30
|
-
}
|
|
31
|
-
}, debounceMs);
|
|
63
|
+
handler.notify();
|
|
32
64
|
});
|
|
33
65
|
logger.info(`Watching for changes: ${options.filePath}`);
|
|
34
66
|
logger.info('Press Ctrl+C to stop');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/utils/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/utils/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA6B,EAC7B,UAAkB;IAElB,IAAI,KAAgD,CAAC;IACrD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,UAAU,UAAU;QACvB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,CAAC;YACH,GAAG,CAAC;gBACF,OAAO,GAAG,KAAK,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;gBAClD,IAAI,CAAC;oBACH,MAAM,QAAQ,EAAE,CAAC;oBACjB,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;gBAC1C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnF,CAAC;YACH,CAAC,QAAQ,OAAO,EAAE;QACpB,CAAC;gBAAS,CAAC;YACT,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM;YACJ,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO;YACT,CAAC;YACD,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBACtB,KAAK,UAAU,EAAE,CAAC;YACpB,CAAC,EAAE,UAAU,CAAC,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,OAAqB;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC;IAC7C,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE;QACpD,IAAI,SAAS,KAAK,QAAQ;YAAE,OAAO;QACnC,OAAO,CAAC,MAAM,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,yBAAyB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAEpC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcpmake/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared generation library for mcpmake — parse APIs (OpenAPI/HAR/Postman/websites) and emit MCP servers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"handlebars": "^4.7.8",
|
|
36
36
|
"json-schema-to-zod": "^2.4.1",
|
|
37
37
|
"marked": "^12.0.2",
|
|
38
|
+
"openai": "^6.44.0",
|
|
38
39
|
"openapi-types": "^12.1.3",
|
|
39
40
|
"playwright": "^1.59.1",
|
|
40
41
|
"yaml": "^2.7.0"
|