@cyanheads/mcp-ts-core 0.13.9 → 0.13.11
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/AGENTS.md +41 -15
- package/CLAUDE.md +41 -15
- package/README.md +37 -11
- package/biome.json +1 -1
- package/changelog/0.13.x/0.13.10.md +118 -0
- package/changelog/0.13.x/0.13.11.md +113 -0
- package/dist/cli/app-render.d.ts +11 -0
- package/dist/cli/app-render.d.ts.map +1 -0
- package/dist/cli/app-render.js +150 -0
- package/dist/cli/app-render.js.map +1 -0
- package/dist/cli/init.d.ts +2 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +10 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +15 -1
- package/dist/core/app.js.map +1 -1
- package/dist/core/context.d.ts +92 -22
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +65 -16
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/worker.d.ts +6 -0
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +1 -0
- package/dist/core/worker.js.map +1 -1
- package/dist/linter/rules/error-contract-rules.d.ts +3 -44
- package/dist/linter/rules/error-contract-rules.d.ts.map +1 -1
- package/dist/linter/rules/error-contract-rules.js +8 -144
- package/dist/linter/rules/error-contract-rules.js.map +1 -1
- package/dist/linter/rules/index.d.ts +1 -1
- package/dist/linter/rules/index.d.ts.map +1 -1
- package/dist/linter/rules/index.js +1 -1
- package/dist/linter/rules/index.js.map +1 -1
- package/dist/linter/rules/resource-rules.d.ts.map +1 -1
- package/dist/linter/rules/resource-rules.js +1 -2
- package/dist/linter/rules/resource-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +1 -2
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/mcp-server/handlerContext.d.ts +26 -13
- package/dist/mcp-server/handlerContext.d.ts.map +1 -1
- package/dist/mcp-server/handlerContext.js +32 -17
- package/dist/mcp-server/handlerContext.js.map +1 -1
- package/dist/mcp-server/inputRequired.d.ts +120 -8
- package/dist/mcp-server/inputRequired.d.ts.map +1 -1
- package/dist/mcp-server/inputRequired.js +177 -12
- package/dist/mcp-server/inputRequired.js.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.d.ts +10 -2
- package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.js +49 -11
- package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts +4 -2
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +6 -4
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +4 -3
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +60 -21
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/server.d.ts +9 -0
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +14 -13
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts +7 -3
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +9 -5
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +17 -9
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +91 -50
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js +7 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
- package/dist/services/mirror/sqlite/handle.d.ts +11 -5
- package/dist/services/mirror/sqlite/handle.d.ts.map +1 -1
- package/dist/services/mirror/sqlite/handle.js +46 -8
- package/dist/services/mirror/sqlite/handle.js.map +1 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.d.ts +6 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.d.ts.map +1 -1
- package/dist/services/mirror/sqlite/sqliteMirrorStore.js.map +1 -1
- package/dist/testing/apps/browser.d.ts +27 -0
- package/dist/testing/apps/browser.d.ts.map +1 -0
- package/dist/testing/apps/browser.js +162 -0
- package/dist/testing/apps/browser.js.map +1 -0
- package/dist/testing/apps/cdp-pipe.d.ts +79 -0
- package/dist/testing/apps/cdp-pipe.d.ts.map +1 -0
- package/dist/testing/apps/cdp-pipe.js +200 -0
- package/dist/testing/apps/cdp-pipe.js.map +1 -0
- package/dist/testing/apps/csp.d.ts +17 -0
- package/dist/testing/apps/csp.d.ts.map +1 -0
- package/dist/testing/apps/csp.js +50 -0
- package/dist/testing/apps/csp.js.map +1 -0
- package/dist/testing/apps/host-pages.d.ts +47 -0
- package/dist/testing/apps/host-pages.d.ts.map +1 -0
- package/dist/testing/apps/host-pages.js +138 -0
- package/dist/testing/apps/host-pages.js.map +1 -0
- package/dist/testing/apps/index.d.ts +167 -0
- package/dist/testing/apps/index.d.ts.map +1 -0
- package/dist/testing/apps/index.js +36 -0
- package/dist/testing/apps/index.js.map +1 -0
- package/dist/testing/apps/partial-json.d.ts +14 -0
- package/dist/testing/apps/partial-json.d.ts.map +1 -0
- package/dist/testing/apps/partial-json.js +71 -0
- package/dist/testing/apps/partial-json.js.map +1 -0
- package/dist/testing/apps/run.d.ts +13 -0
- package/dist/testing/apps/run.d.ts.map +1 -0
- package/dist/testing/apps/run.js +659 -0
- package/dist/testing/apps/run.js.map +1 -0
- package/dist/testing/index.d.ts +17 -2
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +21 -7
- package/dist/testing/index.js.map +1 -1
- package/dist/types-global/errors.d.ts +18 -15
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts +5 -4
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +9 -7
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +3 -1
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/logger.d.ts +21 -1
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +31 -14
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/performance.d.ts +7 -3
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +16 -9
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/internal/telemetryMessages.d.ts +0 -1
- package/dist/utils/internal/telemetryMessages.d.ts.map +1 -1
- package/dist/utils/internal/telemetryMessages.js +0 -1
- package/dist/utils/internal/telemetryMessages.js.map +1 -1
- package/dist/utils/security/sanitization.d.ts +16 -13
- package/dist/utils/security/sanitization.d.ts.map +1 -1
- package/dist/utils/security/sanitization.js +74 -33
- package/dist/utils/security/sanitization.js.map +1 -1
- package/dist/utils/telemetry/attributes.d.ts +12 -5
- package/dist/utils/telemetry/attributes.d.ts.map +1 -1
- package/dist/utils/telemetry/attributes.js +12 -5
- package/dist/utils/telemetry/attributes.js.map +1 -1
- package/framework-skills/add-app-tool/SKILL.md +2 -1
- package/framework-skills/add-service/SKILL.md +3 -12
- package/framework-skills/add-test/SKILL.md +20 -17
- package/framework-skills/add-tool/SKILL.md +30 -34
- package/framework-skills/api-config/SKILL.md +12 -2
- package/framework-skills/api-context/SKILL.md +156 -41
- package/framework-skills/api-errors/SKILL.md +43 -47
- package/framework-skills/api-linter/SKILL.md +5 -29
- package/framework-skills/api-mirror/SKILL.md +4 -3
- package/framework-skills/api-telemetry/SKILL.md +16 -10
- package/framework-skills/api-testing/SKILL.md +47 -11
- package/framework-skills/api-utils/SKILL.md +3 -3
- package/framework-skills/api-workers/SKILL.md +3 -1
- package/framework-skills/code-simplifier/SKILL.md +2 -2
- package/framework-skills/design-mcp-server/SKILL.md +5 -5
- package/framework-skills/field-test/SKILL.md +53 -8
- package/framework-skills/git-wrapup/SKILL.md +2 -2
- package/framework-skills/orchestrations/SKILL.md +1 -1
- package/framework-skills/orchestrations/workflows/greenfield-build.md +2 -2
- package/framework-skills/polish-docs-meta/SKILL.md +4 -3
- package/framework-skills/polish-docs-meta/references/server-json.md +24 -26
- package/framework-skills/release-and-publish/SKILL.md +3 -3
- package/framework-skills/release-pr-review/SKILL.md +6 -6
- package/framework-skills/security-pass/SKILL.md +8 -7
- package/framework-skills/setup/SKILL.md +2 -2
- package/package.json +38 -22
- package/scripts/devcheck.ts +43 -21
- package/scripts/install-otel.ts +84 -0
- package/scripts/lint-packaging.ts +279 -28
- package/scripts/prune-musl-packages.ts +146 -0
- package/templates/.env.example +2 -0
- package/templates/.github/workflows/codeql.yml +10 -1
- package/templates/AGENTS.md +5 -4
- package/templates/CLAUDE.md +5 -4
- package/templates/Dockerfile +76 -50
- package/templates/_.dockerignore +3 -5
- package/templates/_.gitignore +4 -4
- package/templates/package.json +4 -4
- package/templates/server.json +7 -21
- package/templates/src/mcp-server/tools/definitions/echo.tool.ts +3 -8
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Post-init orientation for an MCP server built on @cyanheads/mcp-ts-core. Use after running `@cyanheads/mcp-ts-core init` to understand the project structure, conventions, and skill sync model. Also use when onboarding to an existing project for the first time.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.12"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
@@ -40,7 +40,7 @@ Dockerfile # Starter multi-stage image
|
|
|
40
40
|
.vscode/ # Recommended extensions + editor settings
|
|
41
41
|
server.json # MCP Registry publishing metadata
|
|
42
42
|
changelog/template.md # Format reference for per-version changelog files
|
|
43
|
-
scripts/ # build,
|
|
43
|
+
scripts/ # Framework scripts (build, devcheck and its checks, lint-mcp, lint-packaging, Docker install-otel and prune-musl-packages, release-github, …), re-synced by `maintenance`
|
|
44
44
|
framework-skills/ # External skills copied from the package (source of truth)
|
|
45
45
|
src/
|
|
46
46
|
index.ts # createApp() entry point
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/mcp-ts-core",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.11",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-core",
|
|
5
5
|
"description": "Agent-native TypeScript framework for MCP servers. Includes runtime infrastructure and agent skills for building, testing, and shipping servers.",
|
|
6
6
|
"files": [
|
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
"scripts/clean-mcpb.ts",
|
|
17
17
|
"scripts/clean.ts",
|
|
18
18
|
"scripts/devcheck.ts",
|
|
19
|
+
"scripts/install-otel.ts",
|
|
19
20
|
"scripts/lint-mcp.ts",
|
|
20
21
|
"scripts/lint-packaging.ts",
|
|
21
22
|
"scripts/list-skills.ts",
|
|
23
|
+
"scripts/prune-musl-packages.ts",
|
|
22
24
|
"scripts/release-github.ts",
|
|
23
25
|
"scripts/tree.ts",
|
|
24
26
|
"framework-skills/",
|
|
@@ -113,6 +115,11 @@
|
|
|
113
115
|
"import": "./dist/testing/index.js",
|
|
114
116
|
"default": "./dist/testing/index.js"
|
|
115
117
|
},
|
|
118
|
+
"./testing/apps": {
|
|
119
|
+
"types": "./dist/testing/apps/index.d.ts",
|
|
120
|
+
"import": "./dist/testing/apps/index.js",
|
|
121
|
+
"default": "./dist/testing/apps/index.js"
|
|
122
|
+
},
|
|
116
123
|
"./testing/fuzz": {
|
|
117
124
|
"types": "./dist/testing/fuzz.d.ts",
|
|
118
125
|
"import": "./dist/testing/fuzz.js",
|
|
@@ -196,12 +203,13 @@
|
|
|
196
203
|
"publish-mcp": "mcp-publisher login github -token \"$(security find-generic-password -a \"$USER\" -s mcp-publisher-github-pat -w)\" && mcp-publisher publish"
|
|
197
204
|
},
|
|
198
205
|
"devDependencies": {
|
|
199
|
-
"@biomejs/biome": "2.5.
|
|
206
|
+
"@biomejs/biome": "2.5.15",
|
|
200
207
|
"@cloudflare/vitest-pool-workers": "^0.22.0",
|
|
201
|
-
"@cloudflare/workers-types": "5.
|
|
202
|
-
"@duckdb/node-api": "^1.5.
|
|
203
|
-
"@hono/otel": "^1.
|
|
204
|
-
"@modelcontextprotocol/client": "^2.
|
|
208
|
+
"@cloudflare/workers-types": "5.20260930.2",
|
|
209
|
+
"@duckdb/node-api": "^1.5.6-r.1",
|
|
210
|
+
"@hono/otel": "^1.2.0",
|
|
211
|
+
"@modelcontextprotocol/client": "^2.2.0",
|
|
212
|
+
"@modelcontextprotocol/ext-apps": "^2.0.3",
|
|
205
213
|
"@opentelemetry/api-logs": "^0.222.0",
|
|
206
214
|
"@opentelemetry/exporter-logs-otlp-http": "^0.222.0",
|
|
207
215
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.222.0",
|
|
@@ -215,11 +223,11 @@
|
|
|
215
223
|
"@opentelemetry/sdk-trace-node": "^2.11.0",
|
|
216
224
|
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
217
225
|
"@socketsecurity/bun-security-scanner": "^1.1.3",
|
|
218
|
-
"@supabase/supabase-js": "^2.117.
|
|
226
|
+
"@supabase/supabase-js": "^2.117.2",
|
|
219
227
|
"@types/bun": "^1.4.2",
|
|
220
|
-
"@types/node": "26.6.
|
|
228
|
+
"@types/node": "26.6.3",
|
|
221
229
|
"@types/papaparse": "^5.5.2",
|
|
222
|
-
"@types/sanitize-html": "^2.16.
|
|
230
|
+
"@types/sanitize-html": "^2.16.2",
|
|
223
231
|
"@vitest/coverage-istanbul": "4.1.11",
|
|
224
232
|
"@vitest/ui": "4.1.11",
|
|
225
233
|
"better-sqlite3": "^13.0.3",
|
|
@@ -230,24 +238,24 @@
|
|
|
230
238
|
"diff": "^9.0.0",
|
|
231
239
|
"execa": "^10.0.1",
|
|
232
240
|
"fast-check": "^4.10.2",
|
|
233
|
-
"fast-xml-parser": "^5.11.
|
|
234
|
-
"ignore": "^7.0.
|
|
241
|
+
"fast-xml-parser": "^5.11.2",
|
|
242
|
+
"ignore": "^7.0.11",
|
|
235
243
|
"js-yaml": "^5.4.2",
|
|
236
244
|
"linkedom": "^0.18.13",
|
|
237
245
|
"node-cron": "^4.6.0",
|
|
238
|
-
"openai": "^7.
|
|
246
|
+
"openai": "^7.25.0",
|
|
239
247
|
"papaparse": "^5.7.0",
|
|
240
248
|
"partial-json": "^0.1.7",
|
|
241
249
|
"pdf-lib": "^1.17.1",
|
|
242
250
|
"pino-pretty": "^13.1.3",
|
|
243
251
|
"repomix": "^1.18.1",
|
|
244
|
-
"sanitize-html": "^2.
|
|
245
|
-
"tsc-alias": "^1.9.
|
|
252
|
+
"sanitize-html": "^2.18.0",
|
|
253
|
+
"tsc-alias": "^1.9.7",
|
|
246
254
|
"typedoc": "^0.28.20",
|
|
247
255
|
"typescript": "^7.0.2",
|
|
248
256
|
"typescript-v6": "npm:typescript@^6.0.3",
|
|
249
257
|
"unpdf": "^1.8.1",
|
|
250
|
-
"vite": "8.3.
|
|
258
|
+
"vite": "8.3.1",
|
|
251
259
|
"vitest": "^4.1.11"
|
|
252
260
|
},
|
|
253
261
|
"keywords": [
|
|
@@ -289,17 +297,19 @@
|
|
|
289
297
|
"access": "public"
|
|
290
298
|
},
|
|
291
299
|
"dependencies": {
|
|
292
|
-
"@hono/node-server": "^2.1.
|
|
293
|
-
"@modelcontextprotocol/server": "^2.
|
|
300
|
+
"@hono/node-server": "^2.1.3",
|
|
301
|
+
"@modelcontextprotocol/server": "^2.2.0",
|
|
294
302
|
"@opentelemetry/api": "^1.9.1",
|
|
295
|
-
"hono": "^4.13.
|
|
303
|
+
"hono": "^4.13.12",
|
|
296
304
|
"jose": "^6.2.12",
|
|
297
305
|
"pino": "^10.3.1",
|
|
298
306
|
"zod": "^4.6.5"
|
|
299
307
|
},
|
|
300
308
|
"peerDependencies": {
|
|
301
|
-
"@duckdb/node-api": "^1.5.5-r.1",
|
|
309
|
+
"@duckdb/node-api": "^1.5.5-r.1 || ^1.5.6-r.1",
|
|
302
310
|
"@hono/otel": "^1.1.2",
|
|
311
|
+
"@modelcontextprotocol/client": "^2.1.0",
|
|
312
|
+
"@modelcontextprotocol/ext-apps": "^2.0.0",
|
|
303
313
|
"@opentelemetry/api-logs": "^0.222.0",
|
|
304
314
|
"@opentelemetry/exporter-logs-otlp-http": "^0.222.0",
|
|
305
315
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.222.0",
|
|
@@ -338,6 +348,12 @@
|
|
|
338
348
|
"@hono/otel": {
|
|
339
349
|
"optional": true
|
|
340
350
|
},
|
|
351
|
+
"@modelcontextprotocol/client": {
|
|
352
|
+
"optional": true
|
|
353
|
+
},
|
|
354
|
+
"@modelcontextprotocol/ext-apps": {
|
|
355
|
+
"optional": true
|
|
356
|
+
},
|
|
341
357
|
"@opentelemetry/api-logs": {
|
|
342
358
|
"optional": true
|
|
343
359
|
},
|
|
@@ -427,12 +443,12 @@
|
|
|
427
443
|
}
|
|
428
444
|
},
|
|
429
445
|
"overrides": {
|
|
430
|
-
"brace-expansion": "^2.1.
|
|
446
|
+
"brace-expansion": "^2.1.7",
|
|
431
447
|
"postcss": "^8.5.23",
|
|
432
448
|
"protobufjs": "^7.6.5",
|
|
433
449
|
"sharp": "^0.35.3",
|
|
434
|
-
"fast-uri": "^3.1.
|
|
435
|
-
"ip-address": "^10.
|
|
450
|
+
"fast-uri": "^3.1.8",
|
|
451
|
+
"ip-address": "^10.7.1",
|
|
436
452
|
"nanoid": "^3.3.18"
|
|
437
453
|
}
|
|
438
454
|
}
|
package/scripts/devcheck.ts
CHANGED
|
@@ -639,15 +639,25 @@ const ALL_CHECKS: Check[] = [
|
|
|
639
639
|
canFix: false,
|
|
640
640
|
getCommand: (ctx) => {
|
|
641
641
|
if (!isGitRepo()) return null; // no repo to grep — fresh scaffold before `git init`
|
|
642
|
-
// git
|
|
643
|
-
|
|
644
|
-
//
|
|
642
|
+
// -w is git's own whole-word test: macOS's regex library reads `\b` in an
|
|
643
|
+
// extended regex as a literal `b`. Case-sensitive, so a lowercase `todo`
|
|
644
|
+
// variable or stop word is not a marker.
|
|
645
|
+
const baseCmd = ['git', 'grep', '-nwE', '(TODO|FIXME)'];
|
|
646
|
+
// Exclude files where TODO/FIXME appears as prose or intentional stubs:
|
|
647
|
+
// changelogs, tests, this script, and the framework's skill prose wherever
|
|
648
|
+
// the maintenance sync copies it.
|
|
645
649
|
const excludes = [
|
|
646
650
|
':!CHANGELOG.md',
|
|
647
651
|
':!changelog/',
|
|
648
652
|
':!*.lock',
|
|
649
653
|
':!scripts/devcheck.ts',
|
|
650
654
|
':!tests/',
|
|
655
|
+
':!framework-skills/',
|
|
656
|
+
':!.claude/skills/',
|
|
657
|
+
':!.agents/skills/',
|
|
658
|
+
':!.codex/skills/',
|
|
659
|
+
':!.cursor/skills/',
|
|
660
|
+
':!.windsurf/skills/',
|
|
651
661
|
];
|
|
652
662
|
if (ctx.isHuskyHook && ctx.stagedFiles.length > 0) {
|
|
653
663
|
// Check only staged files in the working tree
|
|
@@ -670,28 +680,38 @@ const ALL_CHECKS: Check[] = [
|
|
|
670
680
|
name: 'Tracked Secrets',
|
|
671
681
|
flag: '--no-secrets',
|
|
672
682
|
canFix: false,
|
|
673
|
-
// Check if common sensitive files are tracked by git.
|
|
683
|
+
// Check if common sensitive files are tracked by git. `:(glob)` makes `**/`
|
|
684
|
+
// match zero or more directories, so each shape is caught at the repository
|
|
685
|
+
// root too; under it `*` stops at `/`, so the two name-prefix shapes carry a
|
|
686
|
+
// `/**` twin for the files inside a directory of that name (`secrets/`,
|
|
687
|
+
// `.env.d/`).
|
|
674
688
|
getCommand: () => {
|
|
675
689
|
if (!isGitRepo()) return null; // no repo — `git ls-files` would exit 128, not a finding
|
|
676
690
|
return [
|
|
677
691
|
'git',
|
|
678
692
|
'ls-files',
|
|
679
|
-
'
|
|
680
|
-
'
|
|
681
|
-
'**/.
|
|
682
|
-
'
|
|
683
|
-
'
|
|
684
|
-
'**/*.
|
|
685
|
-
'
|
|
686
|
-
'
|
|
693
|
+
':(glob)**/*.env*',
|
|
694
|
+
':(glob)**/*.env*/**',
|
|
695
|
+
':(glob)**/.npmrc',
|
|
696
|
+
':(glob)**/.netrc',
|
|
697
|
+
':(glob)**/credentials.json',
|
|
698
|
+
':(glob)**/*.pem',
|
|
699
|
+
':(glob)**/*.key',
|
|
700
|
+
':(glob)**/secret*',
|
|
701
|
+
':(glob)**/secret*/**',
|
|
702
|
+
':(glob)**/.htpasswd',
|
|
687
703
|
];
|
|
688
704
|
},
|
|
689
|
-
// Success if output is empty OR only contains safe
|
|
705
|
+
// Success if output is empty OR only contains safe files: `.env` templates
|
|
706
|
+
// anywhere, and GitHub's secret scanning config at the one path it reads.
|
|
690
707
|
isSuccess: (result, _mode) => {
|
|
691
708
|
if (result.exitCode !== 0) return false;
|
|
692
|
-
const
|
|
709
|
+
const SAFE_SUFFIXES = ['.env.example', '.env.template', '.env.sample'];
|
|
710
|
+
const SAFE_PATHS = ['.github/secret_scanning.yml'];
|
|
693
711
|
const files = result.stdout.trim().split('\n').filter(Boolean);
|
|
694
|
-
const dangerous = files.filter(
|
|
712
|
+
const dangerous = files.filter(
|
|
713
|
+
(f) => !SAFE_PATHS.includes(f) && !SAFE_SUFFIXES.some((safe) => f.endsWith(safe)),
|
|
714
|
+
);
|
|
695
715
|
return dangerous.length === 0;
|
|
696
716
|
},
|
|
697
717
|
tip: (c) =>
|
|
@@ -712,11 +732,12 @@ const ALL_CHECKS: Check[] = [
|
|
|
712
732
|
// Validates env var alignment between manifest.json (MCPB bundle) and
|
|
713
733
|
// server.json (MCP Registry), plus plugin marketplace manifests (#240), the
|
|
714
734
|
// bundle-content guards on .mcpbignore (#343), the README version badge
|
|
715
|
-
// (#418),
|
|
716
|
-
//
|
|
717
|
-
//
|
|
718
|
-
//
|
|
719
|
-
//
|
|
735
|
+
// (#418), the Dockerfile build platform, and the launch shape of server.json
|
|
736
|
+
// npm entries (#622). Runs when any of those inputs is present; skipped
|
|
737
|
+
// cleanly when none exist — consumers on an HTTP-only deploy are unaffected.
|
|
738
|
+
// README.md, Dockerfile, and server.json are triggers in their own right:
|
|
739
|
+
// each check must gate a project that carries no bundle or plugin metadata
|
|
740
|
+
// at all, which the other inputs only covered incidentally.
|
|
720
741
|
getCommand: () => {
|
|
721
742
|
const inputs = [
|
|
722
743
|
'manifest.json',
|
|
@@ -726,12 +747,13 @@ const ALL_CHECKS: Check[] = [
|
|
|
726
747
|
'.mcpbignore',
|
|
727
748
|
'README.md',
|
|
728
749
|
'Dockerfile',
|
|
750
|
+
'server.json',
|
|
729
751
|
];
|
|
730
752
|
if (!inputs.some((input) => existsSync(path.join(ROOT_DIR, input)))) return null;
|
|
731
753
|
return ['bun', 'run', 'scripts/lint-packaging.ts'];
|
|
732
754
|
},
|
|
733
755
|
tip: (c) =>
|
|
734
|
-
`
|
|
756
|
+
`Each ${c.bold('✗')} line above names the file and the change that fixes it; ${c.bold('scripts/lint-packaging.ts')} documents every check.`,
|
|
735
757
|
},
|
|
736
758
|
{
|
|
737
759
|
name: 'Framework Antipatterns',
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Installs the OpenTelemetry packages the framework loads at
|
|
4
|
+
* runtime into a production dependency tree — the Dockerfile's OTel step.
|
|
5
|
+
*
|
|
6
|
+
* The list is every `peerDependencies` entry named `@opentelemetry/*`, plus
|
|
7
|
+
* `@hono/otel`, in `@cyanheads/mcp-ts-core/package.json` resolved from the
|
|
8
|
+
* project root: the installed framework in a server, the package itself (by
|
|
9
|
+
* self-reference) in the framework. Each package moves into the project's
|
|
10
|
+
* `dependencies` at its declared peer range, out of `peerDependencies`,
|
|
11
|
+
* `peerDependenciesMeta`, and `devDependencies`, so `--omit=peer` keeps it
|
|
12
|
+
* while every other optional peer stays out. Then `bun install --omit=dev
|
|
13
|
+
* --omit=peer --ignore-scripts` runs with every argument given to this script
|
|
14
|
+
* appended, under the project's `bunfig.toml`, and its exit code is this
|
|
15
|
+
* script's. Not `--production`: it implies `--frozen-lockfile`, which fails
|
|
16
|
+
* once the manifest gains packages the lockfile lacks.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // In a Dockerfile stage on $BUILDPLATFORM, cross-installing for the target:
|
|
20
|
+
* // bun scripts/install-otel.ts --os=linux --cpu=x64
|
|
21
|
+
* @module scripts/install-otel
|
|
22
|
+
*/
|
|
23
|
+
import { spawnSync } from 'node:child_process';
|
|
24
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
25
|
+
import { createRequire } from 'node:module';
|
|
26
|
+
import { join, resolve } from 'node:path';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
28
|
+
|
|
29
|
+
interface Manifest {
|
|
30
|
+
dependencies?: Record<string, string>;
|
|
31
|
+
devDependencies?: Record<string, string>;
|
|
32
|
+
peerDependencies?: Record<string, string>;
|
|
33
|
+
peerDependenciesMeta?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The OTel optional peers a framework manifest declares, keyed by name, at their declared ranges. */
|
|
37
|
+
export function otelPeers(framework: Manifest): Record<string, string> {
|
|
38
|
+
return Object.fromEntries(
|
|
39
|
+
Object.entries(framework.peerDependencies ?? {}).filter(
|
|
40
|
+
([name]) => name.startsWith('@opentelemetry/') || name === '@hono/otel',
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function main(args: string[]): number {
|
|
46
|
+
const manifestPath = join(process.cwd(), 'package.json');
|
|
47
|
+
const frameworkPath = createRequire(manifestPath).resolve('@cyanheads/mcp-ts-core/package.json');
|
|
48
|
+
const peers = otelPeers(JSON.parse(readFileSync(frameworkPath, 'utf8')) as Manifest);
|
|
49
|
+
const names = Object.keys(peers);
|
|
50
|
+
if (names.length === 0) {
|
|
51
|
+
console.error(
|
|
52
|
+
`install-otel: ${frameworkPath} declares no @opentelemetry/* or @hono/otel peerDependencies — nothing to install.`,
|
|
53
|
+
);
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as Manifest;
|
|
58
|
+
manifest.dependencies = { ...manifest.dependencies, ...peers };
|
|
59
|
+
for (const name of names) {
|
|
60
|
+
delete manifest.peerDependencies?.[name];
|
|
61
|
+
delete manifest.peerDependenciesMeta?.[name];
|
|
62
|
+
delete manifest.devDependencies?.[name];
|
|
63
|
+
}
|
|
64
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
65
|
+
console.log(
|
|
66
|
+
`install-otel: ${names.length} OpenTelemetry packages from ${frameworkPath}: ` +
|
|
67
|
+
names.map((name) => `${name}@${peers[name]}`).join(' '),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const install = spawnSync(
|
|
71
|
+
'bun',
|
|
72
|
+
['install', '--omit=dev', '--omit=peer', '--ignore-scripts', ...args],
|
|
73
|
+
{ stdio: 'inherit' },
|
|
74
|
+
);
|
|
75
|
+
if (install.error) {
|
|
76
|
+
console.error(`install-otel: could not run bun install: ${install.error.message}`);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
return install.status ?? 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
83
|
+
process.exit(main(process.argv.slice(2)));
|
|
84
|
+
}
|