mcpmake 0.1.1 → 0.2.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 +88 -635
- package/dist/commands/bundle.d.ts +1 -0
- package/dist/commands/bundle.d.ts.map +1 -0
- package/dist/commands/bundle.js +5 -4
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/ci.d.ts +1 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +3 -2
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +4 -3
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +5 -4
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/from/describe.d.ts +1 -0
- package/dist/commands/from/describe.d.ts.map +1 -0
- package/dist/commands/from/describe.js +11 -10
- package/dist/commands/from/describe.js.map +1 -0
- package/dist/commands/from/har.d.ts +1 -0
- package/dist/commands/from/har.d.ts.map +1 -0
- package/dist/commands/from/har.js +14 -13
- package/dist/commands/from/har.js.map +1 -0
- package/dist/commands/from/openapi.d.ts +1 -0
- package/dist/commands/from/openapi.d.ts.map +1 -0
- package/dist/commands/from/openapi.js +17 -16
- package/dist/commands/from/openapi.js.map +1 -0
- package/dist/commands/from/postman.d.ts +1 -0
- package/dist/commands/from/postman.d.ts.map +1 -0
- package/dist/commands/from/postman.js +13 -12
- package/dist/commands/from/postman.js.map +1 -0
- package/dist/commands/from/stainless.d.ts +110 -0
- package/dist/commands/from/stainless.d.ts.map +1 -0
- package/dist/commands/from/stainless.js +272 -0
- package/dist/commands/from/stainless.js.map +1 -0
- package/dist/commands/from/target-support.d.ts +1 -0
- package/dist/commands/from/target-support.d.ts.map +1 -0
- package/dist/commands/from/target-support.js +2 -1
- package/dist/commands/from/target-support.js.map +1 -0
- package/dist/commands/from/url.d.ts +1 -0
- package/dist/commands/from/url.d.ts.map +1 -0
- package/dist/commands/from/url.js +14 -13
- package/dist/commands/from/url.js.map +1 -0
- package/dist/commands/from/website.d.ts +1 -0
- package/dist/commands/from/website.d.ts.map +1 -0
- package/dist/commands/from/website.js +17 -16
- package/dist/commands/from/website.js.map +1 -0
- package/dist/commands/lint.d.ts +1 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +6 -5
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/merge.d.ts +1 -0
- package/dist/commands/merge.d.ts.map +1 -0
- package/dist/commands/merge.js +3 -2
- package/dist/commands/merge.js.map +1 -0
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +4 -3
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/rescan.d.ts +1 -0
- package/dist/commands/rescan.d.ts.map +1 -0
- package/dist/commands/rescan.js +12 -11
- package/dist/commands/rescan.js.map +1 -0
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +10 -9
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +1 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +7 -6
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -0
- package/dist/registry/official-registry.d.ts +1 -0
- package/dist/registry/official-registry.d.ts.map +1 -0
- package/dist/registry/official-registry.js +1 -0
- package/dist/registry/official-registry.js.map +1 -0
- package/package.json +20 -46
- package/dist/analyzer/auth-detector.d.ts +0 -12
- package/dist/analyzer/auth-detector.js +0 -142
- package/dist/analyzer/dom-parser.d.ts +0 -10
- package/dist/analyzer/dom-parser.js +0 -259
- package/dist/analyzer/goal-crawler.d.ts +0 -25
- package/dist/analyzer/goal-crawler.js +0 -177
- package/dist/analyzer/hybrid-detector.d.ts +0 -28
- package/dist/analyzer/hybrid-detector.js +0 -96
- package/dist/analyzer/index.d.ts +0 -12
- package/dist/analyzer/index.js +0 -8
- package/dist/analyzer/screenshot-capture.d.ts +0 -29
- package/dist/analyzer/screenshot-capture.js +0 -42
- package/dist/analyzer/selector-builder.d.ts +0 -19
- package/dist/analyzer/selector-builder.js +0 -199
- package/dist/analyzer/semantic-analyzer.d.ts +0 -13
- package/dist/analyzer/semantic-analyzer.js +0 -145
- package/dist/analyzer/site-crawler.d.ts +0 -38
- package/dist/analyzer/site-crawler.js +0 -235
- package/dist/cloud/billing/billing-engine.d.ts +0 -44
- package/dist/cloud/billing/billing-engine.js +0 -81
- package/dist/cloud/billing/credit-store.d.ts +0 -64
- package/dist/cloud/billing/credit-store.js +0 -168
- package/dist/cloud/billing/index.d.ts +0 -4
- package/dist/cloud/billing/index.js +0 -2
- package/dist/cloud/billing/usage-store.d.ts +0 -42
- package/dist/cloud/billing/usage-store.js +0 -85
- package/dist/cloud/billing/usage-tracker.d.ts +0 -38
- package/dist/cloud/billing/usage-tracker.js +0 -95
- package/dist/cloud/build-pipeline.d.ts +0 -39
- package/dist/cloud/build-pipeline.js +0 -310
- package/dist/cloud/build-queue.d.ts +0 -30
- package/dist/cloud/build-queue.js +0 -70
- package/dist/cloud/caddy-manager.d.ts +0 -18
- package/dist/cloud/caddy-manager.js +0 -97
- package/dist/cloud/container-backend.d.ts +0 -62
- package/dist/cloud/container-backend.js +0 -59
- package/dist/cloud/container-manager.d.ts +0 -64
- package/dist/cloud/container-manager.js +0 -301
- package/dist/cloud/crypto.d.ts +0 -27
- package/dist/cloud/crypto.js +0 -63
- package/dist/cloud/db/index.d.ts +0 -27
- package/dist/cloud/db/index.js +0 -53
- package/dist/cloud/db/migrations.d.ts +0 -12
- package/dist/cloud/db/migrations.js +0 -329
- package/dist/cloud/db/pg-store.d.ts +0 -45
- package/dist/cloud/db/pg-store.js +0 -336
- package/dist/cloud/failure-tracker.d.ts +0 -51
- package/dist/cloud/failure-tracker.js +0 -102
- package/dist/cloud/idle-monitor.d.ts +0 -30
- package/dist/cloud/idle-monitor.js +0 -70
- package/dist/cloud/mailer.d.ts +0 -21
- package/dist/cloud/mailer.js +0 -193
- package/dist/cloud/mcp-proxy.d.ts +0 -58
- package/dist/cloud/mcp-proxy.js +0 -203
- package/dist/cloud/metric-samples.d.ts +0 -43
- package/dist/cloud/metric-samples.js +0 -85
- package/dist/cloud/metrics.d.ts +0 -26
- package/dist/cloud/metrics.js +0 -59
- package/dist/cloud/multipart.d.ts +0 -26
- package/dist/cloud/multipart.js +0 -132
- package/dist/cloud/observability.d.ts +0 -27
- package/dist/cloud/observability.js +0 -98
- package/dist/cloud/rate-limiter.d.ts +0 -31
- package/dist/cloud/rate-limiter.js +0 -58
- package/dist/cloud/request-security.d.ts +0 -5
- package/dist/cloud/request-security.js +0 -74
- package/dist/cloud/resource-monitor.d.ts +0 -69
- package/dist/cloud/resource-monitor.js +0 -130
- package/dist/cloud/secret-store.d.ts +0 -38
- package/dist/cloud/secret-store.js +0 -103
- package/dist/cloud/security.d.ts +0 -26
- package/dist/cloud/security.js +0 -142
- package/dist/cloud/server.d.ts +0 -21
- package/dist/cloud/server.js +0 -1079
- package/dist/cloud/shared-state.d.ts +0 -72
- package/dist/cloud/shared-state.js +0 -159
- package/dist/cloud/ssrf.d.ts +0 -43
- package/dist/cloud/ssrf.js +0 -150
- package/dist/cloud/store.d.ts +0 -41
- package/dist/cloud/store.js +0 -75
- package/dist/cloud/stripe.d.ts +0 -78
- package/dist/cloud/stripe.js +0 -317
- package/dist/cloud/telemetry-store.d.ts +0 -53
- package/dist/cloud/telemetry-store.js +0 -108
- package/dist/cloud/web/auth.d.ts +0 -225
- package/dist/cloud/web/auth.js +0 -555
- package/dist/cloud/web/charts.d.ts +0 -70
- package/dist/cloud/web/charts.js +0 -178
- package/dist/cloud/web/csrf.d.ts +0 -14
- package/dist/cloud/web/csrf.js +0 -22
- package/dist/cloud/web/docs.d.ts +0 -40
- package/dist/cloud/web/docs.js +0 -174
- package/dist/cloud/web/router.d.ts +0 -25
- package/dist/cloud/web/router.js +0 -1921
- package/dist/cloud/web/static/alpine.min.js +0 -5
- package/dist/cloud/web/static/favicon.svg +0 -4
- package/dist/cloud/web/static/htmx-sse.js +0 -290
- package/dist/cloud/web/static/htmx.min.js +0 -1
- package/dist/cloud/web/static/style.css +0 -2683
- package/dist/cloud/web/static-server.d.ts +0 -13
- package/dist/cloud/web/static-server.js +0 -73
- package/dist/cloud/web/template-engine.d.ts +0 -27
- package/dist/cloud/web/template-engine.js +0 -146
- package/dist/cloud/web/templates/layouts/admin.hbs +0 -57
- package/dist/cloud/web/templates/layouts/auth.hbs +0 -138
- package/dist/cloud/web/templates/layouts/base.hbs +0 -16
- package/dist/cloud/web/templates/layouts/dashboard.hbs +0 -39
- package/dist/cloud/web/templates/layouts/landing.hbs +0 -82
- package/dist/cloud/web/templates/pages/admin/overview.hbs +0 -123
- package/dist/cloud/web/templates/pages/admin/servers.hbs +0 -129
- package/dist/cloud/web/templates/pages/admin/telemetry.hbs +0 -39
- package/dist/cloud/web/templates/pages/admin/user-edit.hbs +0 -91
- package/dist/cloud/web/templates/pages/admin/users.hbs +0 -179
- package/dist/cloud/web/templates/pages/auth/forgot-password.hbs +0 -25
- package/dist/cloud/web/templates/pages/auth/login.hbs +0 -33
- package/dist/cloud/web/templates/pages/auth/register.hbs +0 -32
- package/dist/cloud/web/templates/pages/auth/reset-password.hbs +0 -34
- package/dist/cloud/web/templates/pages/dashboard/billing.hbs +0 -140
- package/dist/cloud/web/templates/pages/dashboard/create.hbs +0 -173
- package/dist/cloud/web/templates/pages/dashboard/index.hbs +0 -8
- package/dist/cloud/web/templates/pages/dashboard/server-detail.hbs +0 -280
- package/dist/cloud/web/templates/pages/dashboard/server-logs.hbs +0 -35
- package/dist/cloud/web/templates/pages/dashboard/server-metrics.hbs +0 -63
- package/dist/cloud/web/templates/pages/dashboard/servers-partial.hbs +0 -21
- package/dist/cloud/web/templates/pages/dashboard/servers.hbs +0 -44
- package/dist/cloud/web/templates/pages/docs/show.hbs +0 -16
- package/dist/cloud/web/templates/pages/errors/404.hbs +0 -9
- package/dist/cloud/web/templates/pages/errors/500.hbs +0 -8
- package/dist/cloud/web/templates/pages/landing/index.hbs +0 -223
- package/dist/cloud/web/templates/pages/legal/privacy.hbs +0 -71
- package/dist/cloud/web/templates/pages/legal/terms.hbs +0 -73
- package/dist/cloud/web/templates/partials/admin-stats.hbs +0 -52
- package/dist/cloud/web/templates/partials/flash-message.hbs +0 -6
- package/dist/cloud/web/templates/partials/pricing-table.hbs +0 -103
- package/dist/cloud/web/templates/partials/server-card.hbs +0 -19
- package/dist/cloud/web/templates/partials/status-badge.hbs +0 -1
- package/dist/config/configurable-command.d.ts +0 -13
- package/dist/config/configurable-command.js +0 -70
- package/dist/config/mcpmake-config.d.ts +0 -68
- package/dist/config/mcpmake-config.js +0 -207
- package/dist/docs/cli.md +0 -400
- package/dist/docs/mcp-2026-07-28-migration.md +0 -78
- package/dist/docs/migrate-from-stainless.md +0 -94
- package/dist/docs/quickstart.md +0 -166
- package/dist/docs/show-hn.md +0 -26
- package/dist/docs/website-servers.md +0 -169
- package/dist/emitter/code-writer.d.ts +0 -8
- package/dist/emitter/code-writer.js +0 -25
- package/dist/emitter/index.d.ts +0 -32
- package/dist/emitter/index.js +0 -280
- package/dist/emitter/mcpb-bundler.d.ts +0 -31
- package/dist/emitter/mcpb-bundler.js +0 -172
- package/dist/emitter/project-scaffolder.d.ts +0 -4
- package/dist/emitter/project-scaffolder.js +0 -89
- package/dist/emitter/python-template-loader.d.ts +0 -4
- package/dist/emitter/python-template-loader.js +0 -30
- package/dist/emitter/python-templates/dockerfile.hbs +0 -14
- package/dist/emitter/python-templates/env.example.hbs +0 -6
- package/dist/emitter/python-templates/requirements.txt.hbs +0 -4
- package/dist/emitter/python-templates/server.py.hbs +0 -77
- package/dist/emitter/site-scaffolder.d.ts +0 -13
- package/dist/emitter/site-scaffolder.js +0 -70
- package/dist/emitter/site-template-loader.d.ts +0 -5
- package/dist/emitter/site-template-loader.js +0 -47
- package/dist/emitter/site-templates/browser-manager.ts.hbs +0 -233
- package/dist/emitter/site-templates/config.ts.hbs +0 -28
- package/dist/emitter/site-templates/dockerfile.hbs +0 -31
- package/dist/emitter/site-templates/env.example.hbs +0 -19
- package/dist/emitter/site-templates/package.json.hbs +0 -26
- package/dist/emitter/site-templates/server-main-http.ts.hbs +0 -108
- package/dist/emitter/site-templates/server-main.ts.hbs +0 -23
- package/dist/emitter/site-templates/tool-handler-action.ts.hbs +0 -86
- package/dist/emitter/site-templates/tool-handler-form.ts.hbs +0 -116
- package/dist/emitter/site-templates/tool-handler-lifecycle.ts.hbs +0 -146
- package/dist/emitter/site-templates/tool-index.ts.hbs +0 -11
- package/dist/emitter/template-loader.d.ts +0 -1
- package/dist/emitter/template-loader.js +0 -27
- package/dist/emitter/templates/auth-provider.ts.hbs +0 -57
- package/dist/emitter/templates/config.ts.hbs +0 -63
- package/dist/emitter/templates/discovery.ts.hbs +0 -301
- package/dist/emitter/templates/dockerfile.hbs +0 -34
- package/dist/emitter/templates/env.example.hbs +0 -28
- package/dist/emitter/templates/gitignore.hbs +0 -5
- package/dist/emitter/templates/http-executor.ts.hbs +0 -117
- package/dist/emitter/templates/oauth.ts.hbs +0 -188
- package/dist/emitter/templates/package.json.hbs +0 -25
- package/dist/emitter/templates/prompts.ts.hbs +0 -22
- package/dist/emitter/templates/readme.md.hbs +0 -123
- package/dist/emitter/templates/resources.ts.hbs +0 -63
- package/dist/emitter/templates/server-main-http.ts.hbs +0 -407
- package/dist/emitter/templates/server-main.ts.hbs +0 -40
- package/dist/emitter/templates/task-handlers.ts.hbs +0 -189
- package/dist/emitter/templates/task-manager.ts.hbs +0 -139
- package/dist/emitter/templates/task-sse.ts.hbs +0 -105
- package/dist/emitter/templates/tool-handler.ts.hbs +0 -124
- package/dist/emitter/templates/tool-index.ts.hbs +0 -11
- package/dist/emitter/templates/tool-test.ts.hbs +0 -57
- package/dist/emitter/templates/trace.ts.hbs +0 -79
- package/dist/emitter/templates/tsconfig.json.hbs +0 -16
- package/dist/emitter/templates/types.ts.hbs +0 -5
- package/dist/emitter/worker-template-loader.d.ts +0 -5
- package/dist/emitter/worker-template-loader.js +0 -33
- package/dist/emitter/worker-templates/config.ts.hbs +0 -54
- package/dist/emitter/worker-templates/dev-vars.example.hbs +0 -10
- package/dist/emitter/worker-templates/gitignore.hbs +0 -6
- package/dist/emitter/worker-templates/package.json.hbs +0 -24
- package/dist/emitter/worker-templates/readme.md.hbs +0 -53
- package/dist/emitter/worker-templates/server.test.ts.hbs +0 -20
- package/dist/emitter/worker-templates/tool-handler.ts.hbs +0 -85
- package/dist/emitter/worker-templates/tool-index.ts.hbs +0 -28
- package/dist/emitter/worker-templates/tsconfig.json.hbs +0 -17
- package/dist/emitter/worker-templates/worker.ts.hbs +0 -242
- package/dist/emitter/worker-templates/wrangler.toml.hbs +0 -19
- package/dist/generator/spec-generator.d.ts +0 -6
- package/dist/generator/spec-generator.js +0 -50
- package/dist/parser/har-filter.d.ts +0 -8
- package/dist/parser/har-filter.js +0 -71
- package/dist/parser/har-loader.d.ts +0 -2
- package/dist/parser/har-loader.js +0 -14
- package/dist/parser/har-normalizer.d.ts +0 -20
- package/dist/parser/har-normalizer.js +0 -78
- package/dist/parser/index.d.ts +0 -10
- package/dist/parser/index.js +0 -6
- package/dist/parser/openapi-loader.d.ts +0 -6
- package/dist/parser/openapi-loader.js +0 -308
- package/dist/parser/operation-extractor.d.ts +0 -13
- package/dist/parser/operation-extractor.js +0 -155
- package/dist/parser/overlay-loader.d.ts +0 -10
- package/dist/parser/overlay-loader.js +0 -184
- package/dist/parser/postman-loader.d.ts +0 -9
- package/dist/parser/postman-loader.js +0 -106
- package/dist/parser/schema-converter.d.ts +0 -12
- package/dist/parser/schema-converter.js +0 -117
- package/dist/plugins/adapter.d.ts +0 -40
- package/dist/plugins/adapter.js +0 -15
- package/dist/plugins/loader.d.ts +0 -25
- package/dist/plugins/loader.js +0 -58
- package/dist/pricing.d.ts +0 -55
- package/dist/pricing.js +0 -133
- package/dist/providers/index.d.ts +0 -15
- package/dist/providers/index.js +0 -56
- package/dist/recorder/browser-recorder.d.ts +0 -22
- package/dist/recorder/browser-recorder.js +0 -205
- package/dist/rescan/diff-engine.d.ts +0 -5
- package/dist/rescan/diff-engine.js +0 -312
- package/dist/rescan/index.d.ts +0 -3
- package/dist/rescan/index.js +0 -2
- package/dist/rescan/rescan-runner.d.ts +0 -42
- package/dist/rescan/rescan-runner.js +0 -69
- package/dist/rescan/rescan-scheduler.d.ts +0 -41
- package/dist/rescan/rescan-scheduler.js +0 -179
- package/dist/site-transformer/browser-tools.d.ts +0 -10
- package/dist/site-transformer/browser-tools.js +0 -59
- package/dist/site-transformer/index.d.ts +0 -2
- package/dist/site-transformer/index.js +0 -2
- package/dist/site-transformer/selector-healer.d.ts +0 -8
- package/dist/site-transformer/selector-healer.js +0 -106
- package/dist/site-transformer/tool-generator.d.ts +0 -13
- package/dist/site-transformer/tool-generator.js +0 -245
- package/dist/transformer/auth-detector.d.ts +0 -13
- package/dist/transformer/auth-detector.js +0 -90
- package/dist/transformer/catalog-builder.d.ts +0 -18
- package/dist/transformer/catalog-builder.js +0 -56
- package/dist/transformer/client-compat.d.ts +0 -6
- package/dist/transformer/client-compat.js +0 -44
- package/dist/transformer/har-clusterer.d.ts +0 -9
- package/dist/transformer/har-clusterer.js +0 -27
- package/dist/transformer/har-dedup.d.ts +0 -10
- package/dist/transformer/har-dedup.js +0 -81
- package/dist/transformer/har-schema-inferrer.d.ts +0 -15
- package/dist/transformer/har-schema-inferrer.js +0 -90
- package/dist/transformer/har-to-operations.d.ts +0 -13
- package/dist/transformer/har-to-operations.js +0 -192
- package/dist/transformer/index.d.ts +0 -8
- package/dist/transformer/index.js +0 -6
- package/dist/transformer/llm-namer.d.ts +0 -6
- package/dist/transformer/llm-namer.js +0 -59
- package/dist/transformer/naming.d.ts +0 -4
- package/dist/transformer/naming.js +0 -30
- package/dist/transformer/operation-filter.d.ts +0 -13
- package/dist/transformer/operation-filter.js +0 -52
- package/dist/transformer/resource-builder.d.ts +0 -12
- package/dist/transformer/resource-builder.js +0 -80
- package/dist/transformer/schema-merger.d.ts +0 -14
- package/dist/transformer/schema-merger.js +0 -65
- package/dist/transformer/tool-builder.d.ts +0 -3
- package/dist/transformer/tool-builder.js +0 -114
- package/dist/types/index.d.ts +0 -131
- package/dist/types/index.js +0 -1
- package/dist/types/site.d.ts +0 -284
- package/dist/types/site.js +0 -8
- package/dist/utils/fail.d.ts +0 -48
- package/dist/utils/fail.js +0 -204
- package/dist/utils/fs.d.ts +0 -5
- package/dist/utils/fs.js +0 -28
- package/dist/utils/interactive.d.ts +0 -6
- package/dist/utils/interactive.js +0 -30
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.js +0 -2
- package/dist/utils/sanitize.d.ts +0 -28
- package/dist/utils/sanitize.js +0 -44
- package/dist/utils/watcher.d.ts +0 -11
- package/dist/utils/watcher.js +0 -36
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { NormalizedEntry } from '../parser/har-normalizer.js';
|
|
2
|
-
export interface EntryCluster {
|
|
3
|
-
signature: string;
|
|
4
|
-
method: string;
|
|
5
|
-
normalizedPath: string;
|
|
6
|
-
baseUrl: string;
|
|
7
|
-
entries: NormalizedEntry[];
|
|
8
|
-
}
|
|
9
|
-
export declare function clusterEntries(entries: NormalizedEntry[]): EntryCluster[];
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export function clusterEntries(entries) {
|
|
2
|
-
const groups = new Map();
|
|
3
|
-
for (const entry of entries) {
|
|
4
|
-
const method = entry.entry.request.method.toUpperCase();
|
|
5
|
-
const signature = `${method} ${entry.normalizedPath}`;
|
|
6
|
-
const existing = groups.get(signature);
|
|
7
|
-
if (existing) {
|
|
8
|
-
existing.push(entry);
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
groups.set(signature, [entry]);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
const clusters = [];
|
|
15
|
-
for (const [signature, clusterEntries] of groups) {
|
|
16
|
-
const [method, ...pathParts] = signature.split(' ');
|
|
17
|
-
const normalizedPath = pathParts.join(' ');
|
|
18
|
-
clusters.push({
|
|
19
|
-
signature,
|
|
20
|
-
method: method.toLowerCase(),
|
|
21
|
-
normalizedPath,
|
|
22
|
-
baseUrl: clusterEntries[0].baseUrl,
|
|
23
|
-
entries: clusterEntries,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return clusters;
|
|
27
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { NormalizedEntry } from '../parser/har-normalizer.js';
|
|
2
|
-
/**
|
|
3
|
-
* Deduplicate HAR entries that are likely pagination or retries.
|
|
4
|
-
*
|
|
5
|
-
* Strategy:
|
|
6
|
-
* - Group by method + normalizedPath (same as clustering)
|
|
7
|
-
* - Within each group, detect pagination patterns (same URL with different page/offset/cursor params)
|
|
8
|
-
* - Remove retries: consecutive requests to the same URL within 5s with same method
|
|
9
|
-
*/
|
|
10
|
-
export declare function deduplicateEntries(entries: NormalizedEntry[]): NormalizedEntry[];
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deduplicate HAR entries that are likely pagination or retries.
|
|
3
|
-
*
|
|
4
|
-
* Strategy:
|
|
5
|
-
* - Group by method + normalizedPath (same as clustering)
|
|
6
|
-
* - Within each group, detect pagination patterns (same URL with different page/offset/cursor params)
|
|
7
|
-
* - Remove retries: consecutive requests to the same URL within 5s with same method
|
|
8
|
-
*/
|
|
9
|
-
export function deduplicateEntries(entries) {
|
|
10
|
-
const result = [];
|
|
11
|
-
const seenSignatures = new Map();
|
|
12
|
-
for (const entry of entries) {
|
|
13
|
-
const url = entry.entry.request.url;
|
|
14
|
-
const method = entry.entry.request.method;
|
|
15
|
-
const signature = `${method} ${stripPaginationParams(url)}`;
|
|
16
|
-
const timestamp = new Date(entry.entry.startedDateTime).getTime();
|
|
17
|
-
const seen = seenSignatures.get(signature);
|
|
18
|
-
if (seen) {
|
|
19
|
-
// Skip retries: same signature within 5 seconds
|
|
20
|
-
if (timestamp - seen.lastTime < 5000) {
|
|
21
|
-
seen.lastTime = timestamp;
|
|
22
|
-
seen.count++;
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
// Skip excessive pagination: keep at most 3 examples per endpoint
|
|
26
|
-
if (isPaginationVariant(url, entries, entry) && seen.count >= 3) {
|
|
27
|
-
seen.lastTime = timestamp;
|
|
28
|
-
seen.count++;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
seenSignatures.set(signature, {
|
|
33
|
-
lastTime: timestamp,
|
|
34
|
-
count: (seen?.count ?? 0) + 1,
|
|
35
|
-
});
|
|
36
|
-
result.push(entry);
|
|
37
|
-
}
|
|
38
|
-
return result;
|
|
39
|
-
}
|
|
40
|
-
const PAGINATION_PARAMS = new Set([
|
|
41
|
-
'page',
|
|
42
|
-
'offset',
|
|
43
|
-
'limit',
|
|
44
|
-
'cursor',
|
|
45
|
-
'after',
|
|
46
|
-
'before',
|
|
47
|
-
'skip',
|
|
48
|
-
'take',
|
|
49
|
-
'per_page',
|
|
50
|
-
'page_size',
|
|
51
|
-
'pagesize',
|
|
52
|
-
'start',
|
|
53
|
-
'count',
|
|
54
|
-
'from',
|
|
55
|
-
'next_token',
|
|
56
|
-
'continuation',
|
|
57
|
-
]);
|
|
58
|
-
function stripPaginationParams(url) {
|
|
59
|
-
try {
|
|
60
|
-
const parsed = new URL(url);
|
|
61
|
-
for (const key of [...parsed.searchParams.keys()]) {
|
|
62
|
-
if (PAGINATION_PARAMS.has(key.toLowerCase())) {
|
|
63
|
-
parsed.searchParams.delete(key);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return `${parsed.origin}${parsed.pathname}${parsed.search}`;
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
return url;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function isPaginationVariant(url, allEntries, current) {
|
|
73
|
-
try {
|
|
74
|
-
const parsed = new URL(url);
|
|
75
|
-
const paramKeys = [...parsed.searchParams.keys()].map((k) => k.toLowerCase());
|
|
76
|
-
return paramKeys.some((k) => PAGINATION_PARAMS.has(k));
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { JsonSchema } from '../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Infer a JSON Schema from a sample JSON value.
|
|
4
|
-
* Handles objects, arrays, and primitives.
|
|
5
|
-
*/
|
|
6
|
-
export declare function inferJsonSchema(value: unknown, depth?: number): JsonSchema;
|
|
7
|
-
/**
|
|
8
|
-
* Try to parse a response body as JSON and infer its schema.
|
|
9
|
-
* Returns undefined if not JSON or parsing fails.
|
|
10
|
-
*/
|
|
11
|
-
export declare function inferResponseSchema(body: string | undefined, mimeType: string): JsonSchema | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* Try to parse a request body and infer its schema.
|
|
14
|
-
*/
|
|
15
|
-
export declare function inferRequestBodySchema(text: string | undefined, mimeType: string): JsonSchema | undefined;
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { isDangerousKey } from '../utils/sanitize.js';
|
|
2
|
-
const MAX_INFERENCE_DEPTH = 20;
|
|
3
|
-
/**
|
|
4
|
-
* Infer a JSON Schema from a sample JSON value.
|
|
5
|
-
* Handles objects, arrays, and primitives.
|
|
6
|
-
*/
|
|
7
|
-
export function inferJsonSchema(value, depth = 0) {
|
|
8
|
-
if (depth > MAX_INFERENCE_DEPTH) {
|
|
9
|
-
return { type: 'object' };
|
|
10
|
-
}
|
|
11
|
-
if (value === null || value === undefined) {
|
|
12
|
-
return { type: 'string' };
|
|
13
|
-
}
|
|
14
|
-
if (Array.isArray(value)) {
|
|
15
|
-
if (value.length === 0) {
|
|
16
|
-
return { type: 'array', items: {} };
|
|
17
|
-
}
|
|
18
|
-
return { type: 'array', items: inferJsonSchema(value[0], depth + 1) };
|
|
19
|
-
}
|
|
20
|
-
if (typeof value === 'object') {
|
|
21
|
-
const properties = {};
|
|
22
|
-
const required = [];
|
|
23
|
-
for (const [key, val] of Object.entries(value)) {
|
|
24
|
-
if (isDangerousKey(key))
|
|
25
|
-
continue;
|
|
26
|
-
properties[key] = inferJsonSchema(val, depth + 1);
|
|
27
|
-
if (val !== null && val !== undefined) {
|
|
28
|
-
required.push(key);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
type: 'object',
|
|
33
|
-
properties,
|
|
34
|
-
...(required.length > 0 ? { required } : {}),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
if (typeof value === 'number') {
|
|
38
|
-
return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' };
|
|
39
|
-
}
|
|
40
|
-
if (typeof value === 'boolean') {
|
|
41
|
-
return { type: 'boolean' };
|
|
42
|
-
}
|
|
43
|
-
return { type: 'string' };
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Try to parse a response body as JSON and infer its schema.
|
|
47
|
-
* Returns undefined if not JSON or parsing fails.
|
|
48
|
-
*/
|
|
49
|
-
export function inferResponseSchema(body, mimeType) {
|
|
50
|
-
if (!body || !mimeType.includes('json'))
|
|
51
|
-
return undefined;
|
|
52
|
-
try {
|
|
53
|
-
const parsed = JSON.parse(body);
|
|
54
|
-
return inferJsonSchema(parsed);
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Try to parse a request body and infer its schema.
|
|
62
|
-
*/
|
|
63
|
-
export function inferRequestBodySchema(text, mimeType) {
|
|
64
|
-
if (!text)
|
|
65
|
-
return undefined;
|
|
66
|
-
if (mimeType.includes('json')) {
|
|
67
|
-
try {
|
|
68
|
-
return inferJsonSchema(JSON.parse(text));
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (mimeType.includes('x-www-form-urlencoded')) {
|
|
75
|
-
const params = new URLSearchParams(text);
|
|
76
|
-
const properties = {};
|
|
77
|
-
const required = [];
|
|
78
|
-
for (const [key, value] of params) {
|
|
79
|
-
properties[key] = { type: 'string' };
|
|
80
|
-
required.push(key);
|
|
81
|
-
// Try to detect numbers/booleans
|
|
82
|
-
if (/^\d+$/.test(value))
|
|
83
|
-
properties[key] = { type: 'integer' };
|
|
84
|
-
else if (value === 'true' || value === 'false')
|
|
85
|
-
properties[key] = { type: 'boolean' };
|
|
86
|
-
}
|
|
87
|
-
return { type: 'object', properties, required };
|
|
88
|
-
}
|
|
89
|
-
return undefined;
|
|
90
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { OperationDescriptor } from '../types/index.js';
|
|
2
|
-
import type { EntryCluster } from './har-clusterer.js';
|
|
3
|
-
export interface HarConversionResult {
|
|
4
|
-
operations: OperationDescriptor[];
|
|
5
|
-
baseUrl: string;
|
|
6
|
-
detectedAuth: DetectedAuth[];
|
|
7
|
-
}
|
|
8
|
-
export interface DetectedAuth {
|
|
9
|
-
type: 'bearer' | 'basic' | 'apiKey';
|
|
10
|
-
headerName: string;
|
|
11
|
-
exampleValue?: string;
|
|
12
|
-
}
|
|
13
|
-
export declare function clustersToOperations(clusters: EntryCluster[]): HarConversionResult;
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import { mergeRequestBodySchemas } from './schema-merger.js';
|
|
2
|
-
const AUTH_HEADER_PATTERNS = [
|
|
3
|
-
{ pattern: /^Bearer\s+/i, schemeName: 'bearer' },
|
|
4
|
-
{ pattern: /^Basic\s+/i, schemeName: 'basic' },
|
|
5
|
-
{ pattern: /^Token\s+/i, schemeName: 'token' },
|
|
6
|
-
];
|
|
7
|
-
const CUSTOM_AUTH_HEADERS = [
|
|
8
|
-
'x-api-key',
|
|
9
|
-
'api-key',
|
|
10
|
-
'authorization-token',
|
|
11
|
-
'x-auth-token',
|
|
12
|
-
'x-access-token',
|
|
13
|
-
'x-csrf-token',
|
|
14
|
-
'x-session-token',
|
|
15
|
-
];
|
|
16
|
-
const SESSION_COOKIE_PATTERNS = [
|
|
17
|
-
/^sess/i,
|
|
18
|
-
/^sid$/i,
|
|
19
|
-
/^session/i,
|
|
20
|
-
/^token/i,
|
|
21
|
-
/^auth/i,
|
|
22
|
-
/^jwt/i,
|
|
23
|
-
/^connect\.sid$/i,
|
|
24
|
-
];
|
|
25
|
-
export function clustersToOperations(clusters) {
|
|
26
|
-
const operations = [];
|
|
27
|
-
const allAuth = new Map();
|
|
28
|
-
let baseUrl = '';
|
|
29
|
-
for (const cluster of clusters) {
|
|
30
|
-
if (!baseUrl)
|
|
31
|
-
baseUrl = cluster.baseUrl;
|
|
32
|
-
const canonical = pickCanonicalEntry(cluster.entries);
|
|
33
|
-
const entry = canonical.entry;
|
|
34
|
-
const auth = detectAuth(entry);
|
|
35
|
-
for (const a of auth) {
|
|
36
|
-
allAuth.set(a.headerName.toLowerCase(), a);
|
|
37
|
-
}
|
|
38
|
-
const operationId = generateOperationId(cluster.method, cluster.normalizedPath);
|
|
39
|
-
const parameters = [];
|
|
40
|
-
// Path params from normalization
|
|
41
|
-
for (const pp of canonical.pathParams) {
|
|
42
|
-
const schemaType = pp.inferredType === 'integer' ? 'integer' : 'string';
|
|
43
|
-
const schema = pp.inferredType === 'uuid' ? { type: 'string', format: 'uuid' } : { type: schemaType };
|
|
44
|
-
parameters.push({
|
|
45
|
-
name: pp.name,
|
|
46
|
-
in: 'path',
|
|
47
|
-
required: true,
|
|
48
|
-
description: pp.name,
|
|
49
|
-
schema,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
// Query params merged across all entries in cluster
|
|
53
|
-
const queryMap = new Map();
|
|
54
|
-
for (const ne of cluster.entries) {
|
|
55
|
-
for (const qp of ne.queryParams) {
|
|
56
|
-
const existing = queryMap.get(qp.name);
|
|
57
|
-
if (existing) {
|
|
58
|
-
existing.values.add(qp.exampleValue);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
queryMap.set(qp.name, { values: new Set([qp.exampleValue]), type: qp.inferredType });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
for (const [name, info] of queryMap) {
|
|
66
|
-
parameters.push({
|
|
67
|
-
name,
|
|
68
|
-
in: 'query',
|
|
69
|
-
required: false,
|
|
70
|
-
schema: { type: info.type },
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
// Request body — merge schemas across all entries in the cluster
|
|
74
|
-
let requestBody;
|
|
75
|
-
const bodyEntries = cluster.entries
|
|
76
|
-
.map((ne) => ne.entry.request.postData)
|
|
77
|
-
.filter((pd) => !!pd?.text)
|
|
78
|
-
.map((pd) => ({ text: pd.text, mimeType: pd.mimeType }));
|
|
79
|
-
if (bodyEntries.length > 0) {
|
|
80
|
-
const mergedSchema = mergeRequestBodySchemas(bodyEntries);
|
|
81
|
-
if (mergedSchema) {
|
|
82
|
-
requestBody = {
|
|
83
|
-
required: true,
|
|
84
|
-
contentType: bodyEntries[0].mimeType.split(';')[0].trim(),
|
|
85
|
-
schema: mergedSchema,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// Security
|
|
90
|
-
const security = auth.map((a) => ({
|
|
91
|
-
schemeName: a.type,
|
|
92
|
-
scopes: [],
|
|
93
|
-
}));
|
|
94
|
-
operations.push({
|
|
95
|
-
operationId,
|
|
96
|
-
method: cluster.method,
|
|
97
|
-
path: cluster.normalizedPath,
|
|
98
|
-
summary: `${cluster.method.toUpperCase()} ${cluster.normalizedPath}`,
|
|
99
|
-
tags: [extractTag(cluster.normalizedPath)],
|
|
100
|
-
parameters,
|
|
101
|
-
requestBody,
|
|
102
|
-
responses: [],
|
|
103
|
-
security,
|
|
104
|
-
deprecated: false,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
operations,
|
|
109
|
-
baseUrl,
|
|
110
|
-
detectedAuth: [...allAuth.values()],
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function pickCanonicalEntry(entries) {
|
|
114
|
-
// Prefer entries with 2xx responses
|
|
115
|
-
const successful = entries.filter((e) => e.entry.response.status >= 200 && e.entry.response.status < 300);
|
|
116
|
-
return successful[0] ?? entries[0];
|
|
117
|
-
}
|
|
118
|
-
function detectAuth(entry) {
|
|
119
|
-
const result = [];
|
|
120
|
-
for (const header of entry.request.headers) {
|
|
121
|
-
const name = header.name.toLowerCase();
|
|
122
|
-
if (name === 'authorization') {
|
|
123
|
-
for (const { pattern, schemeName } of AUTH_HEADER_PATTERNS) {
|
|
124
|
-
if (pattern.test(header.value)) {
|
|
125
|
-
result.push({
|
|
126
|
-
type: schemeName,
|
|
127
|
-
headerName: 'Authorization',
|
|
128
|
-
exampleValue: '[REDACTED]',
|
|
129
|
-
});
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
if (CUSTOM_AUTH_HEADERS.includes(name)) {
|
|
135
|
-
result.push({
|
|
136
|
-
type: 'apiKey',
|
|
137
|
-
headerName: header.name,
|
|
138
|
-
exampleValue: '[REDACTED]',
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
// Detect cookie-based session auth
|
|
142
|
-
if (name === 'cookie') {
|
|
143
|
-
const cookies = header.value.split(';').map((c) => c.trim().split('=')[0]);
|
|
144
|
-
for (const cookieName of cookies) {
|
|
145
|
-
if (SESSION_COOKIE_PATTERNS.some((p) => p.test(cookieName))) {
|
|
146
|
-
result.push({
|
|
147
|
-
type: 'apiKey',
|
|
148
|
-
headerName: 'Cookie',
|
|
149
|
-
exampleValue: '[REDACTED]',
|
|
150
|
-
});
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return result;
|
|
157
|
-
}
|
|
158
|
-
function generateOperationId(method, path) {
|
|
159
|
-
const segments = path
|
|
160
|
-
.replace(/\{[^}]+\}/g, '')
|
|
161
|
-
.split('/')
|
|
162
|
-
.filter(Boolean);
|
|
163
|
-
const resource = segments[segments.length - 1] ?? 'resource';
|
|
164
|
-
switch (method.toLowerCase()) {
|
|
165
|
-
case 'get':
|
|
166
|
-
return path.includes('{') ? `get_${singularize(resource)}` : `list_${resource}`;
|
|
167
|
-
case 'post':
|
|
168
|
-
return `create_${singularize(resource)}`;
|
|
169
|
-
case 'put':
|
|
170
|
-
case 'patch':
|
|
171
|
-
return `update_${singularize(resource)}`;
|
|
172
|
-
case 'delete':
|
|
173
|
-
return `delete_${singularize(resource)}`;
|
|
174
|
-
default:
|
|
175
|
-
return `${method.toLowerCase()}_${resource}`;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
function extractTag(path) {
|
|
179
|
-
const segments = path.split('/').filter((s) => s && !s.startsWith('{'));
|
|
180
|
-
// Skip api/v1/v2 prefixes
|
|
181
|
-
const meaningful = segments.filter((s) => !/^(api|v\d+)$/i.test(s));
|
|
182
|
-
return meaningful[0] ?? 'default';
|
|
183
|
-
}
|
|
184
|
-
function singularize(word) {
|
|
185
|
-
if (word.endsWith('ies'))
|
|
186
|
-
return word.slice(0, -3) + 'y';
|
|
187
|
-
if (word.endsWith('ses') || word.endsWith('xes') || word.endsWith('zes'))
|
|
188
|
-
return word.slice(0, -2);
|
|
189
|
-
if (word.endsWith('s') && !word.endsWith('ss'))
|
|
190
|
-
return word.slice(0, -1);
|
|
191
|
-
return word;
|
|
192
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { toToolName, toToolTitle, toFileName, toFunctionName } from './naming.js';
|
|
2
|
-
export { detectAuthSchemes } from './auth-detector.js';
|
|
3
|
-
export { buildToolDefinition, buildAllTools } from './tool-builder.js';
|
|
4
|
-
export { clusterEntries } from './har-clusterer.js';
|
|
5
|
-
export type { EntryCluster } from './har-clusterer.js';
|
|
6
|
-
export { clustersToOperations } from './har-to-operations.js';
|
|
7
|
-
export type { HarConversionResult, DetectedAuth } from './har-to-operations.js';
|
|
8
|
-
export { inferJsonSchema, inferResponseSchema, inferRequestBodySchema, } from './har-schema-inferrer.js';
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { toToolName, toToolTitle, toFileName, toFunctionName } from './naming.js';
|
|
2
|
-
export { detectAuthSchemes } from './auth-detector.js';
|
|
3
|
-
export { buildToolDefinition, buildAllTools } from './tool-builder.js';
|
|
4
|
-
export { clusterEntries } from './har-clusterer.js';
|
|
5
|
-
export { clustersToOperations } from './har-to-operations.js';
|
|
6
|
-
export { inferJsonSchema, inferResponseSchema, inferRequestBodySchema, } from './har-schema-inferrer.js';
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { OperationDescriptor } from '../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Use Claude to generate better tool names and descriptions
|
|
4
|
-
* from HAR-captured request/response patterns.
|
|
5
|
-
*/
|
|
6
|
-
export declare function improveToolNames(operations: OperationDescriptor[], model?: string): Promise<OperationDescriptor[]>;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import { logger } from '../utils/logger.js';
|
|
3
|
-
/**
|
|
4
|
-
* Use Claude to generate better tool names and descriptions
|
|
5
|
-
* from HAR-captured request/response patterns.
|
|
6
|
-
*/
|
|
7
|
-
export async function improveToolNames(operations, model) {
|
|
8
|
-
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
9
|
-
if (!apiKey) {
|
|
10
|
-
logger.warn('ANTHROPIC_API_KEY not set — skipping LLM tool naming');
|
|
11
|
-
return operations;
|
|
12
|
-
}
|
|
13
|
-
const client = new Anthropic({ apiKey });
|
|
14
|
-
const operationSummaries = operations.map((op) => ({
|
|
15
|
-
method: op.method,
|
|
16
|
-
path: op.path,
|
|
17
|
-
currentId: op.operationId,
|
|
18
|
-
summary: op.summary,
|
|
19
|
-
paramNames: op.parameters.map((p) => p.name),
|
|
20
|
-
hasBody: !!op.requestBody,
|
|
21
|
-
tags: op.tags,
|
|
22
|
-
}));
|
|
23
|
-
const prompt = `Given these API operations captured from network traffic, suggest better operationId names and descriptions. Return a JSON array with one object per operation: { "index": number, "operationId": "camelCase name", "summary": "one-line description" }. Keep names concise (camelCase, under 40 chars). Only output JSON, no explanation.
|
|
24
|
-
|
|
25
|
-
Operations:
|
|
26
|
-
${JSON.stringify(operationSummaries, null, 2)}`;
|
|
27
|
-
try {
|
|
28
|
-
logger.info('Improving tool names with Claude...');
|
|
29
|
-
const message = await client.messages.create({
|
|
30
|
-
model: model ?? 'claude-sonnet-4-20250514',
|
|
31
|
-
max_tokens: 2048,
|
|
32
|
-
messages: [{ role: 'user', content: prompt }],
|
|
33
|
-
});
|
|
34
|
-
const content = message.content[0];
|
|
35
|
-
if (content.type !== 'text')
|
|
36
|
-
return operations;
|
|
37
|
-
let json = content.text.trim();
|
|
38
|
-
if (json.startsWith('```')) {
|
|
39
|
-
json = json.replace(/^```(?:json)?\n?/, '').replace(/\n?```$/, '');
|
|
40
|
-
}
|
|
41
|
-
const improvements = JSON.parse(json);
|
|
42
|
-
const result = operations.map((op, i) => {
|
|
43
|
-
const improvement = improvements.find((imp) => imp.index === i);
|
|
44
|
-
if (!improvement)
|
|
45
|
-
return op;
|
|
46
|
-
return {
|
|
47
|
-
...op,
|
|
48
|
-
operationId: improvement.operationId || op.operationId,
|
|
49
|
-
summary: improvement.summary || op.summary,
|
|
50
|
-
};
|
|
51
|
-
});
|
|
52
|
-
logger.info(`Improved ${improvements.length} tool names`);
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
55
|
-
catch (err) {
|
|
56
|
-
logger.warn(`LLM naming failed, using defaults: ${err instanceof Error ? err.message : err}`);
|
|
57
|
-
return operations;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export function toToolName(operationId) {
|
|
2
|
-
return toSnakeCase(operationId);
|
|
3
|
-
}
|
|
4
|
-
export function toToolTitle(operationId) {
|
|
5
|
-
const snake = toSnakeCase(operationId);
|
|
6
|
-
return snake
|
|
7
|
-
.split('_')
|
|
8
|
-
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
9
|
-
.join(' ');
|
|
10
|
-
}
|
|
11
|
-
export function toFileName(operationId) {
|
|
12
|
-
return toSnakeCase(operationId)
|
|
13
|
-
.replace(/_/g, '-')
|
|
14
|
-
.replace(/\.\./g, '')
|
|
15
|
-
.replace(/[/\\]/g, '')
|
|
16
|
-
.replace(/[^a-z0-9\-]/g, '');
|
|
17
|
-
}
|
|
18
|
-
export function toFunctionName(operationId) {
|
|
19
|
-
const snake = toSnakeCase(operationId);
|
|
20
|
-
return snake.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
21
|
-
}
|
|
22
|
-
function toSnakeCase(str) {
|
|
23
|
-
return str
|
|
24
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
25
|
-
.replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
|
|
26
|
-
.replace(/[\s\-]+/g, '_')
|
|
27
|
-
.toLowerCase()
|
|
28
|
-
.replace(/^_+|_+$/g, '')
|
|
29
|
-
.replace(/_+/g, '_');
|
|
30
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { OperationDescriptor } from '../types/index.js';
|
|
2
|
-
export interface FilterOptions {
|
|
3
|
-
include?: string[];
|
|
4
|
-
exclude?: string[];
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Filter operations by tag or path pattern.
|
|
8
|
-
* Patterns can be:
|
|
9
|
-
* - A tag name: "pets" matches operations tagged with "pets"
|
|
10
|
-
* - A path prefix: "/users*" matches /users, /users/{id}, etc.
|
|
11
|
-
* - A glob-like pattern: "*admin*" matches any operation with "admin" in path or tags
|
|
12
|
-
*/
|
|
13
|
-
export declare function filterOperations(operations: OperationDescriptor[], options: FilterOptions): OperationDescriptor[];
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Filter operations by tag or path pattern.
|
|
3
|
-
* Patterns can be:
|
|
4
|
-
* - A tag name: "pets" matches operations tagged with "pets"
|
|
5
|
-
* - A path prefix: "/users*" matches /users, /users/{id}, etc.
|
|
6
|
-
* - A glob-like pattern: "*admin*" matches any operation with "admin" in path or tags
|
|
7
|
-
*/
|
|
8
|
-
export function filterOperations(operations, options) {
|
|
9
|
-
let result = operations;
|
|
10
|
-
if (options.include?.length) {
|
|
11
|
-
result = result.filter((op) => options.include.some((pattern) => matchesOperation(op, pattern)));
|
|
12
|
-
}
|
|
13
|
-
if (options.exclude?.length) {
|
|
14
|
-
result = result.filter((op) => !options.exclude.some((pattern) => matchesOperation(op, pattern)));
|
|
15
|
-
}
|
|
16
|
-
return result;
|
|
17
|
-
}
|
|
18
|
-
function matchesOperation(op, pattern) {
|
|
19
|
-
const lowerPattern = pattern.toLowerCase();
|
|
20
|
-
// Check tag match
|
|
21
|
-
if (op.tags.some((t) => t.toLowerCase() === lowerPattern))
|
|
22
|
-
return true;
|
|
23
|
-
// Check path match with simple glob support
|
|
24
|
-
if (matchGlob(op.path.toLowerCase(), lowerPattern))
|
|
25
|
-
return true;
|
|
26
|
-
// Check operationId match
|
|
27
|
-
if (op.operationId.toLowerCase().includes(lowerPattern))
|
|
28
|
-
return true;
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
function matchGlob(str, pattern) {
|
|
32
|
-
// Simple glob matching without regex to avoid ReDoS.
|
|
33
|
-
// Split pattern by '*' and check that all parts appear in order.
|
|
34
|
-
const parts = pattern.split('*');
|
|
35
|
-
let pos = 0;
|
|
36
|
-
for (let i = 0; i < parts.length; i++) {
|
|
37
|
-
const part = parts[i];
|
|
38
|
-
if (part === '')
|
|
39
|
-
continue;
|
|
40
|
-
const idx = str.indexOf(part, pos);
|
|
41
|
-
if (idx === -1)
|
|
42
|
-
return false;
|
|
43
|
-
// First segment must match at start, last at end
|
|
44
|
-
if (i === 0 && idx !== 0)
|
|
45
|
-
return false;
|
|
46
|
-
pos = idx + part.length;
|
|
47
|
-
}
|
|
48
|
-
// If pattern doesn't end with *, the string must end at pos
|
|
49
|
-
if (!pattern.endsWith('*') && pos !== str.length)
|
|
50
|
-
return false;
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { OperationDescriptor } from '../types/index.js';
|
|
2
|
-
import type { ResourceDefinition, PromptDefinition } from '../types/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Generate MCP resources from GET operations.
|
|
5
|
-
* - List endpoints (no path params) → static resources
|
|
6
|
-
* - Detail endpoints (with path params) → URI template resources
|
|
7
|
-
*/
|
|
8
|
-
export declare function buildResources(operations: OperationDescriptor[]): ResourceDefinition[];
|
|
9
|
-
/**
|
|
10
|
-
* Generate MCP prompts — one per tag as a "workflow" prompt.
|
|
11
|
-
*/
|
|
12
|
-
export declare function buildPrompts(operations: OperationDescriptor[]): PromptDefinition[];
|