@celljs/cli 3.8.0 → 4.0.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/README.md +442 -1
- package/agent/guide.md +39 -0
- package/bin/cell.js +2 -0
- package/lib/agent/agent-guide.d.ts +39 -0
- package/lib/agent/agent-guide.d.ts.map +1 -0
- package/lib/agent/agent-guide.js +67 -0
- package/lib/agent/agent-guide.js.map +1 -0
- package/lib/build/executable-compiler.d.ts +44 -0
- package/lib/build/executable-compiler.d.ts.map +1 -0
- package/lib/build/executable-compiler.js +145 -0
- package/lib/build/executable-compiler.js.map +1 -0
- package/lib/build/executable-compiler.spec.d.ts +2 -0
- package/lib/build/executable-compiler.spec.d.ts.map +1 -0
- package/lib/build/executable-compiler.spec.js +71 -0
- package/lib/build/executable-compiler.spec.js.map +1 -0
- package/lib/build/single-compile.spec.d.ts +2 -0
- package/lib/build/single-compile.spec.d.ts.map +1 -0
- package/lib/build/single-compile.spec.js +135 -0
- package/lib/build/single-compile.spec.js.map +1 -0
- package/lib/check/project-checker.d.ts +85 -0
- package/lib/check/project-checker.d.ts.map +1 -0
- package/lib/check/project-checker.js +332 -0
- package/lib/check/project-checker.js.map +1 -0
- package/lib/check/project-checker.spec.d.ts +2 -0
- package/lib/check/project-checker.spec.d.ts.map +1 -0
- package/lib/check/project-checker.spec.js +147 -0
- package/lib/check/project-checker.spec.js.map +1 -0
- package/lib/cli/agent-command.d.ts +15 -0
- package/lib/cli/agent-command.d.ts.map +1 -0
- package/lib/cli/agent-command.js +42 -0
- package/lib/cli/agent-command.js.map +1 -0
- package/lib/cli/build-command.d.ts +84 -0
- package/lib/cli/build-command.d.ts.map +1 -0
- package/lib/cli/build-command.js +170 -0
- package/lib/cli/build-command.js.map +1 -0
- package/lib/cli/cell-cli.d.ts +35 -0
- package/lib/cli/cell-cli.d.ts.map +1 -0
- package/lib/cli/cell-cli.js +159 -0
- package/lib/cli/cell-cli.js.map +1 -0
- package/lib/cli/cell-cli.spec.d.ts +2 -0
- package/lib/cli/cell-cli.spec.d.ts.map +1 -0
- package/lib/cli/cell-cli.spec.js +195 -0
- package/lib/cli/cell-cli.spec.js.map +1 -0
- package/lib/cli/check-command.d.ts +31 -0
- package/lib/cli/check-command.d.ts.map +1 -0
- package/lib/cli/check-command.js +67 -0
- package/lib/cli/check-command.js.map +1 -0
- package/lib/cli/command.d.ts +24 -0
- package/lib/cli/command.d.ts.map +1 -0
- package/lib/cli/command.js +10 -0
- package/lib/cli/command.js.map +1 -0
- package/lib/cli/config-command.d.ts +29 -0
- package/lib/cli/config-command.d.ts.map +1 -0
- package/lib/cli/config-command.js +71 -0
- package/lib/cli/config-command.js.map +1 -0
- package/lib/cli/config-command.spec.d.ts +2 -0
- package/lib/cli/config-command.spec.d.ts.map +1 -0
- package/lib/cli/config-command.spec.js +79 -0
- package/lib/cli/config-command.spec.js.map +1 -0
- package/lib/cli/deploy-command.d.ts +41 -0
- package/lib/cli/deploy-command.d.ts.map +1 -0
- package/lib/cli/deploy-command.js +114 -0
- package/lib/cli/deploy-command.js.map +1 -0
- package/lib/cli/dev-command.d.ts +47 -0
- package/lib/cli/dev-command.d.ts.map +1 -0
- package/lib/cli/dev-command.js +219 -0
- package/lib/cli/dev-command.js.map +1 -0
- package/lib/cli/dev-command.spec.d.ts +2 -0
- package/lib/cli/dev-command.spec.d.ts.map +1 -0
- package/lib/cli/dev-command.spec.js +149 -0
- package/lib/cli/dev-command.spec.js.map +1 -0
- package/lib/cli/docs-command.d.ts +19 -0
- package/lib/cli/docs-command.d.ts.map +1 -0
- package/lib/cli/docs-command.js +47 -0
- package/lib/cli/docs-command.js.map +1 -0
- package/lib/cli/info-command.d.ts +44 -0
- package/lib/cli/info-command.d.ts.map +1 -0
- package/lib/cli/info-command.js +39 -0
- package/lib/cli/info-command.js.map +1 -0
- package/lib/cli/info-command.spec.d.ts +2 -0
- package/lib/cli/info-command.spec.d.ts.map +1 -0
- package/lib/cli/info-command.spec.js +236 -0
- package/lib/cli/info-command.spec.js.map +1 -0
- package/lib/cli/init-command.d.ts +20 -0
- package/lib/cli/init-command.d.ts.map +1 -0
- package/lib/cli/init-command.js +43 -0
- package/lib/cli/init-command.js.map +1 -0
- package/lib/cli/main.d.ts +2 -0
- package/lib/cli/main.d.ts.map +1 -0
- package/lib/cli/main.js +3 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/cli/mcp-command.d.ts +34 -0
- package/lib/cli/mcp-command.d.ts.map +1 -0
- package/lib/cli/mcp-command.js +85 -0
- package/lib/cli/mcp-command.js.map +1 -0
- package/lib/cli/mcp-command.spec.d.ts +2 -0
- package/lib/cli/mcp-command.spec.d.ts.map +1 -0
- package/lib/cli/mcp-command.spec.js +132 -0
- package/lib/cli/mcp-command.spec.js.map +1 -0
- package/lib/cli/preview-command.d.ts +24 -0
- package/lib/cli/preview-command.d.ts.map +1 -0
- package/lib/cli/preview-command.js +91 -0
- package/lib/cli/preview-command.js.map +1 -0
- package/lib/cli/reporter.d.ts +26 -0
- package/lib/cli/reporter.d.ts.map +1 -0
- package/lib/cli/reporter.js +58 -0
- package/lib/cli/reporter.js.map +1 -0
- package/lib/config/config-build.spec.d.ts +2 -0
- package/lib/config/config-build.spec.d.ts.map +1 -0
- package/lib/config/config-build.spec.js +111 -0
- package/lib/config/config-build.spec.js.map +1 -0
- package/lib/config/config-explainer.d.ts +48 -0
- package/lib/config/config-explainer.d.ts.map +1 -0
- package/lib/config/config-explainer.js +130 -0
- package/lib/config/config-explainer.js.map +1 -0
- package/lib/config/config-file-loader.d.ts +22 -0
- package/lib/config/config-file-loader.d.ts.map +1 -0
- package/lib/config/config-file-loader.js +63 -0
- package/lib/config/config-file-loader.js.map +1 -0
- package/lib/config/config-resolver.d.ts +111 -0
- package/lib/config/config-resolver.d.ts.map +1 -0
- package/lib/config/config-resolver.js +215 -0
- package/lib/config/config-resolver.js.map +1 -0
- package/lib/config/config-resolver.spec.d.ts +2 -0
- package/lib/config/config-resolver.spec.d.ts.map +1 -0
- package/lib/config/config-resolver.spec.js +159 -0
- package/lib/config/config-resolver.spec.js.map +1 -0
- package/lib/config/config-validator.d.ts +35 -0
- package/lib/config/config-validator.d.ts.map +1 -0
- package/lib/config/config-validator.js +160 -0
- package/lib/config/config-validator.js.map +1 -0
- package/lib/config/config-validator.spec.d.ts +2 -0
- package/lib/config/config-validator.spec.d.ts.map +1 -0
- package/lib/config/config-validator.spec.js +77 -0
- package/lib/config/config-validator.spec.js.map +1 -0
- package/lib/config/define-config.d.ts +4 -0
- package/lib/config/define-config.d.ts.map +1 -0
- package/lib/config/define-config.js +5 -0
- package/lib/config/define-config.js.map +1 -0
- package/lib/config/types.d.ts +53 -0
- package/lib/config/types.d.ts.map +1 -0
- package/lib/config/types.js +2 -0
- package/lib/config/types.js.map +1 -0
- package/lib/deploy/cloud-api.d.ts +58 -0
- package/lib/deploy/cloud-api.d.ts.map +1 -0
- package/lib/deploy/cloud-api.js +189 -0
- package/lib/deploy/cloud-api.js.map +1 -0
- package/lib/deploy/code-package.d.ts +15 -0
- package/lib/deploy/code-package.d.ts.map +1 -0
- package/lib/deploy/code-package.js +40 -0
- package/lib/deploy/code-package.js.map +1 -0
- package/lib/deploy/deploy-utils.spec.d.ts +2 -0
- package/lib/deploy/deploy-utils.spec.d.ts.map +1 -0
- package/lib/deploy/deploy-utils.spec.js +56 -0
- package/lib/deploy/deploy-utils.spec.js.map +1 -0
- package/lib/deploy/deployer-registry.d.ts +11 -0
- package/lib/deploy/deployer-registry.d.ts.map +1 -0
- package/lib/deploy/deployer-registry.js +40 -0
- package/lib/deploy/deployer-registry.js.map +1 -0
- package/lib/deploy/request-signer.d.ts +51 -0
- package/lib/deploy/request-signer.d.ts.map +1 -0
- package/lib/deploy/request-signer.js +109 -0
- package/lib/deploy/request-signer.js.map +1 -0
- package/lib/deploy/zip-writer.d.ts +32 -0
- package/lib/deploy/zip-writer.d.ts.map +1 -0
- package/lib/deploy/zip-writer.js +114 -0
- package/lib/deploy/zip-writer.js.map +1 -0
- package/lib/docs/docs-index.d.ts +54 -0
- package/lib/docs/docs-index.d.ts.map +1 -0
- package/lib/docs/docs-index.js +140 -0
- package/lib/docs/docs-index.js.map +1 -0
- package/lib/docs/docs-index.spec.d.ts +2 -0
- package/lib/docs/docs-index.spec.d.ts.map +1 -0
- package/lib/docs/docs-index.spec.js +52 -0
- package/lib/docs/docs-index.spec.js.map +1 -0
- package/lib/events/event-bus.d.ts +30 -0
- package/lib/events/event-bus.d.ts.map +1 -0
- package/lib/events/event-bus.js +81 -0
- package/lib/events/event-bus.js.map +1 -0
- package/lib/events/event-bus.spec.d.ts +2 -0
- package/lib/events/event-bus.spec.d.ts.map +1 -0
- package/lib/events/event-bus.spec.js +69 -0
- package/lib/events/event-bus.spec.js.map +1 -0
- package/lib/events/hook-runner.d.ts +27 -0
- package/lib/events/hook-runner.d.ts.map +1 -0
- package/lib/events/hook-runner.js +65 -0
- package/lib/events/hook-runner.js.map +1 -0
- package/lib/events/hook-runner.spec.d.ts +2 -0
- package/lib/events/hook-runner.spec.d.ts.map +1 -0
- package/lib/events/hook-runner.spec.js +36 -0
- package/lib/events/hook-runner.spec.js.map +1 -0
- package/lib/index.d.ts +57 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +57 -2
- package/lib/index.js.map +1 -1
- package/lib/info/project-inspector.d.ts +143 -0
- package/lib/info/project-inspector.d.ts.map +1 -0
- package/lib/info/project-inspector.js +244 -0
- package/lib/info/project-inspector.js.map +1 -0
- package/lib/init/project-initializer.d.ts +44 -0
- package/lib/init/project-initializer.d.ts.map +1 -0
- package/lib/init/project-initializer.js +90 -0
- package/lib/init/project-initializer.js.map +1 -0
- package/lib/init/project-initializer.spec.d.ts +2 -0
- package/lib/init/project-initializer.spec.d.ts.map +1 -0
- package/lib/init/project-initializer.spec.js +88 -0
- package/lib/init/project-initializer.spec.js.map +1 -0
- package/lib/mcp/dev-activity.d.ts +34 -0
- package/lib/mcp/dev-activity.d.ts.map +1 -0
- package/lib/mcp/dev-activity.js +46 -0
- package/lib/mcp/dev-activity.js.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.d.ts +62 -0
- package/lib/mcp/dev-mcp-endpoint.d.ts.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.js +280 -0
- package/lib/mcp/dev-mcp-endpoint.js.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.spec.d.ts +2 -0
- package/lib/mcp/dev-mcp-endpoint.spec.d.ts.map +1 -0
- package/lib/mcp/dev-mcp-endpoint.spec.js +143 -0
- package/lib/mcp/dev-mcp-endpoint.spec.js.map +1 -0
- package/lib/mcp/mcp-server.d.ts +64 -0
- package/lib/mcp/mcp-server.d.ts.map +1 -0
- package/lib/mcp/mcp-server.js +201 -0
- package/lib/mcp/mcp-server.js.map +1 -0
- package/lib/mcp/mcp-server.spec.d.ts +2 -0
- package/lib/mcp/mcp-server.spec.d.ts.map +1 -0
- package/lib/mcp/mcp-server.spec.js +136 -0
- package/lib/mcp/mcp-server.spec.js.map +1 -0
- package/lib/mcp/project-mcp-tools.d.ts +35 -0
- package/lib/mcp/project-mcp-tools.d.ts.map +1 -0
- package/lib/mcp/project-mcp-tools.js +199 -0
- package/lib/mcp/project-mcp-tools.js.map +1 -0
- package/lib/modules/module-host.d.ts +118 -0
- package/lib/modules/module-host.d.ts.map +1 -0
- package/lib/modules/module-host.js +405 -0
- package/lib/modules/module-host.js.map +1 -0
- package/lib/modules/module-host.spec.d.ts +2 -0
- package/lib/modules/module-host.spec.d.ts.map +1 -0
- package/lib/modules/module-host.spec.js +220 -0
- package/lib/modules/module-host.spec.js.map +1 -0
- package/lib/preset/builtin-presets.d.ts +9 -0
- package/lib/preset/builtin-presets.d.ts.map +1 -0
- package/lib/preset/builtin-presets.js +24 -0
- package/lib/preset/builtin-presets.js.map +1 -0
- package/lib/preset/cloudflare/cloudflare-deployer.d.ts +26 -0
- package/lib/preset/cloudflare/cloudflare-deployer.d.ts.map +1 -0
- package/lib/preset/cloudflare/cloudflare-deployer.js +116 -0
- package/lib/preset/cloudflare/cloudflare-deployer.js.map +1 -0
- package/lib/preset/cloudflare/cloudflare-preset.d.ts +16 -0
- package/lib/preset/cloudflare/cloudflare-preset.d.ts.map +1 -0
- package/lib/preset/cloudflare/cloudflare-preset.js +97 -0
- package/lib/preset/cloudflare/cloudflare-preset.js.map +1 -0
- package/lib/preset/cloudflare/cloudflare.spec.d.ts +2 -0
- package/lib/preset/cloudflare/cloudflare.spec.d.ts.map +1 -0
- package/lib/preset/cloudflare/cloudflare.spec.js +212 -0
- package/lib/preset/cloudflare/cloudflare.spec.js.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.d.ts +50 -0
- package/lib/preset/cloudflare/wrangler-config.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.js +160 -0
- package/lib/preset/cloudflare/wrangler-config.js.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.spec.d.ts +2 -0
- package/lib/preset/cloudflare/wrangler-config.spec.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler-config.spec.js +112 -0
- package/lib/preset/cloudflare/wrangler-config.spec.js.map +1 -0
- package/lib/preset/cloudflare/wrangler.d.ts +38 -0
- package/lib/preset/cloudflare/wrangler.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler.js +90 -0
- package/lib/preset/cloudflare/wrangler.js.map +1 -0
- package/lib/preset/cloudflare/wrangler.spec.d.ts +2 -0
- package/lib/preset/cloudflare/wrangler.spec.d.ts.map +1 -0
- package/lib/preset/cloudflare/wrangler.spec.js +64 -0
- package/lib/preset/cloudflare/wrangler.spec.js.map +1 -0
- package/lib/preset/fc/fc-deployer.d.ts +50 -0
- package/lib/preset/fc/fc-deployer.d.ts.map +1 -0
- package/lib/preset/fc/fc-deployer.js +209 -0
- package/lib/preset/fc/fc-deployer.js.map +1 -0
- package/lib/preset/fc/fc-preset.d.ts +20 -0
- package/lib/preset/fc/fc-preset.d.ts.map +1 -0
- package/lib/preset/fc/fc-preset.js +46 -0
- package/lib/preset/fc/fc-preset.js.map +1 -0
- package/lib/preset/lambda/lambda-deployer.d.ts +50 -0
- package/lib/preset/lambda/lambda-deployer.d.ts.map +1 -0
- package/lib/preset/lambda/lambda-deployer.js +274 -0
- package/lib/preset/lambda/lambda-deployer.js.map +1 -0
- package/lib/preset/lambda/lambda-preset.d.ts +14 -0
- package/lib/preset/lambda/lambda-preset.d.ts.map +1 -0
- package/lib/preset/lambda/lambda-preset.js +44 -0
- package/lib/preset/lambda/lambda-preset.js.map +1 -0
- package/lib/preset/preset-output.d.ts +19 -0
- package/lib/preset/preset-output.d.ts.map +1 -0
- package/lib/preset/preset-output.js +45 -0
- package/lib/preset/preset-output.js.map +1 -0
- package/lib/preset/preset-registry.d.ts +16 -0
- package/lib/preset/preset-registry.d.ts.map +1 -0
- package/lib/preset/preset-registry.js +58 -0
- package/lib/preset/preset-registry.js.map +1 -0
- package/lib/preset/preset-registry.spec.d.ts +2 -0
- package/lib/preset/preset-registry.spec.d.ts.map +1 -0
- package/lib/preset/preset-registry.spec.js +28 -0
- package/lib/preset/preset-registry.spec.js.map +1 -0
- package/lib/preset/scf/scf-deployer.d.ts +54 -0
- package/lib/preset/scf/scf-deployer.d.ts.map +1 -0
- package/lib/preset/scf/scf-deployer.js +202 -0
- package/lib/preset/scf/scf-deployer.js.map +1 -0
- package/lib/preset/scf/scf-preset.d.ts +19 -0
- package/lib/preset/scf/scf-preset.d.ts.map +1 -0
- package/lib/preset/scf/scf-preset.js +43 -0
- package/lib/preset/scf/scf-preset.js.map +1 -0
- package/lib/preset/serverless-deployers.spec.d.ts +2 -0
- package/lib/preset/serverless-deployers.spec.d.ts.map +1 -0
- package/lib/preset/serverless-deployers.spec.js +307 -0
- package/lib/preset/serverless-deployers.spec.js.map +1 -0
- package/lib/preset/serverless-presets.spec.d.ts +2 -0
- package/lib/preset/serverless-presets.spec.d.ts.map +1 -0
- package/lib/preset/serverless-presets.spec.js +280 -0
- package/lib/preset/serverless-presets.spec.js.map +1 -0
- package/lib/preset/serverless-scripts.d.ts +29 -0
- package/lib/preset/serverless-scripts.d.ts.map +1 -0
- package/lib/preset/serverless-scripts.js +120 -0
- package/lib/preset/serverless-scripts.js.map +1 -0
- package/lib/preset/vercel/vercel-deployer.d.ts +38 -0
- package/lib/preset/vercel/vercel-deployer.d.ts.map +1 -0
- package/lib/preset/vercel/vercel-deployer.js +160 -0
- package/lib/preset/vercel/vercel-deployer.js.map +1 -0
- package/lib/preset/vercel/vercel-preset.d.ts +19 -0
- package/lib/preset/vercel/vercel-preset.d.ts.map +1 -0
- package/lib/preset/vercel/vercel-preset.js +102 -0
- package/lib/preset/vercel/vercel-preset.js.map +1 -0
- package/lib/test/fixture-project.d.ts +17 -0
- package/lib/test/fixture-project.d.ts.map +1 -0
- package/lib/test/fixture-project.js +43 -0
- package/lib/test/fixture-project.js.map +1 -0
- package/lib/testing/create-test-app.d.ts +27 -0
- package/lib/testing/create-test-app.d.ts.map +1 -0
- package/lib/testing/create-test-app.js +54 -0
- package/lib/testing/create-test-app.js.map +1 -0
- package/lib/testing/create-test-app.spec.d.ts +2 -0
- package/lib/testing/create-test-app.spec.d.ts.map +1 -0
- package/lib/testing/create-test-app.spec.js +66 -0
- package/lib/testing/create-test-app.spec.js.map +1 -0
- package/lib/toolchain/toolchain.d.ts +49 -0
- package/lib/toolchain/toolchain.d.ts.map +1 -0
- package/lib/toolchain/toolchain.js +100 -0
- package/lib/toolchain/toolchain.js.map +1 -0
- package/lib/utils/json-util.d.ts +11 -0
- package/lib/utils/json-util.d.ts.map +1 -0
- package/lib/utils/json-util.js +73 -0
- package/lib/utils/json-util.js.map +1 -0
- package/lib/utils/json-util.spec.d.ts +2 -0
- package/lib/utils/json-util.spec.d.ts.map +1 -0
- package/lib/utils/json-util.spec.js +18 -0
- package/lib/utils/json-util.spec.js.map +1 -0
- package/lib/utils/text-util.d.ts +19 -0
- package/lib/utils/text-util.d.ts.map +1 -0
- package/lib/utils/text-util.js +66 -0
- package/lib/utils/text-util.js.map +1 -0
- package/lib/utils/text-util.spec.d.ts +2 -0
- package/lib/utils/text-util.spec.d.ts.map +1 -0
- package/lib/utils/text-util.spec.js +22 -0
- package/lib/utils/text-util.spec.js.map +1 -0
- package/package.json +28 -30
- package/src/agent/agent-guide.ts +90 -0
- package/src/build/executable-compiler.ts +179 -0
- package/src/check/project-checker.ts +365 -0
- package/src/cli/agent-command.ts +46 -0
- package/src/cli/build-command.ts +189 -0
- package/src/cli/cell-cli.ts +174 -0
- package/src/cli/check-command.ts +74 -0
- package/src/cli/command.ts +29 -0
- package/src/cli/config-command.ts +73 -0
- package/src/cli/deploy-command.ts +122 -0
- package/src/cli/dev-command.ts +232 -0
- package/src/cli/docs-command.ts +53 -0
- package/src/cli/info-command.ts +40 -0
- package/src/cli/init-command.ts +53 -0
- package/src/cli/main.ts +3 -0
- package/src/cli/mcp-command.ts +98 -0
- package/src/cli/preview-command.ts +98 -0
- package/src/cli/reporter.ts +67 -0
- package/src/config/config-explainer.ts +158 -0
- package/src/config/config-file-loader.ts +76 -0
- package/src/config/config-resolver.ts +300 -0
- package/src/config/config-validator.ts +208 -0
- package/src/config/define-config.ts +6 -0
- package/src/config/types.ts +57 -0
- package/src/deploy/cloud-api.ts +194 -0
- package/src/deploy/code-package.ts +44 -0
- package/src/deploy/deployer-registry.ts +44 -0
- package/src/deploy/request-signer.ts +155 -0
- package/src/deploy/zip-writer.ts +132 -0
- package/src/docs/docs-index.ts +174 -0
- package/src/events/event-bus.ts +94 -0
- package/src/events/hook-runner.ts +78 -0
- package/src/index.ts +57 -0
- package/src/info/project-inspector.ts +352 -0
- package/src/init/project-initializer.ts +111 -0
- package/src/mcp/dev-activity.ts +71 -0
- package/src/mcp/dev-mcp-endpoint.ts +323 -0
- package/src/mcp/mcp-server.ts +251 -0
- package/src/mcp/project-mcp-tools.ts +216 -0
- package/src/modules/module-host.ts +489 -0
- package/src/preset/builtin-presets.ts +26 -0
- package/src/preset/cloudflare/cloudflare-deployer.ts +126 -0
- package/src/preset/cloudflare/cloudflare-preset.ts +97 -0
- package/src/preset/cloudflare/wrangler-config.ts +173 -0
- package/src/preset/cloudflare/wrangler.ts +113 -0
- package/src/preset/fc/fc-deployer.ts +237 -0
- package/src/preset/fc/fc-preset.ts +51 -0
- package/src/preset/lambda/lambda-deployer.ts +317 -0
- package/src/preset/lambda/lambda-preset.ts +45 -0
- package/src/preset/preset-output.ts +55 -0
- package/src/preset/preset-registry.ts +65 -0
- package/src/preset/scf/scf-deployer.ts +232 -0
- package/src/preset/scf/scf-preset.ts +45 -0
- package/src/preset/serverless-scripts.ts +132 -0
- package/src/preset/vercel/vercel-deployer.ts +168 -0
- package/src/preset/vercel/vercel-preset.ts +111 -0
- package/src/test/fixture-project.ts +50 -0
- package/src/testing/create-test-app.ts +73 -0
- package/src/toolchain/toolchain.ts +121 -0
- package/src/utils/json-util.ts +67 -0
- package/src/utils/text-util.ts +68 -0
- package/templates/backend/README.md +13 -0
- package/templates/backend/_gitignore +5 -0
- package/templates/backend/cell.yml +3 -0
- package/templates/backend/package.json +23 -0
- package/templates/{file-service/src → backend/src/node}/home-controller.ts +5 -2
- package/templates/{file-service/src → backend/src/node}/module.ts +0 -1
- package/templates/backend/template.json +3 -0
- package/templates/backend/test/app.spec.ts +19 -0
- package/templates/backend/tsconfig.json +25 -0
- package/templates/fullstack/README.md +13 -0
- package/templates/fullstack/_gitignore +5 -0
- package/templates/fullstack/cell.yml +6 -0
- package/templates/fullstack/package.json +27 -0
- package/templates/fullstack/src/browser/home.view.tsx +19 -0
- package/templates/{cell-component/src → fullstack/src/browser}/module.ts +1 -1
- package/templates/fullstack/src/common/greeting-protocol.ts +5 -0
- package/templates/fullstack/src/node/greeting-server.ts +13 -0
- package/templates/{admin-app/src/browser → fullstack/src/node}/module.ts +2 -1
- package/templates/fullstack/template.json +3 -0
- package/templates/fullstack/test/app.spec.ts +18 -0
- package/templates/fullstack/tsconfig.json +27 -0
- package/bin/cell +0 -2
- package/lib/build/build-manager.d.ts +0 -9
- package/lib/build/build-manager.d.ts.map +0 -1
- package/lib/build/build-manager.js +0 -41
- package/lib/build/build-manager.js.map +0 -1
- package/lib/build/build.d.ts +0 -6
- package/lib/build/build.d.ts.map +0 -1
- package/lib/build/build.js +0 -16
- package/lib/build/build.js.map +0 -1
- package/lib/cell-main.d.ts +0 -2
- package/lib/cell-main.d.ts.map +0 -1
- package/lib/cell-main.js +0 -110
- package/lib/cell-main.js.map +0 -1
- package/lib/cell.d.ts +0 -2
- package/lib/cell.d.ts.map +0 -1
- package/lib/cell.js +0 -194
- package/lib/cell.js.map +0 -1
- package/lib/config/config.d.ts +0 -12
- package/lib/config/config.d.ts.map +0 -1
- package/lib/config/config.js +0 -48
- package/lib/config/config.js.map +0 -1
- package/lib/deploy/deploy.d.ts +0 -7
- package/lib/deploy/deploy.d.ts.map +0 -1
- package/lib/deploy/deploy.js +0 -30
- package/lib/deploy/deploy.js.map +0 -1
- package/lib/info/info.d.ts +0 -6
- package/lib/info/info.d.ts.map +0 -1
- package/lib/info/info.js +0 -21
- package/lib/info/info.js.map +0 -1
- package/lib/init/init-manager.d.ts +0 -33
- package/lib/init/init-manager.d.ts.map +0 -1
- package/lib/init/init-manager.js +0 -141
- package/lib/init/init-manager.js.map +0 -1
- package/lib/init/init.d.ts +0 -4
- package/lib/init/init.d.ts.map +0 -1
- package/lib/init/init.js +0 -17
- package/lib/init/init.js.map +0 -1
- package/lib/init/templates.d.ts +0 -2
- package/lib/init/templates.d.ts.map +0 -1
- package/lib/init/templates.js +0 -23
- package/lib/init/templates.js.map +0 -1
- package/lib/package.spec.d.ts +0 -2
- package/lib/package.spec.d.ts.map +0 -1
- package/lib/package.spec.js +0 -7
- package/lib/package.spec.js.map +0 -1
- package/lib/props/props.d.ts +0 -9
- package/lib/props/props.d.ts.map +0 -1
- package/lib/props/props.js +0 -49
- package/lib/props/props.js.map +0 -1
- package/lib/serve/serve-manager.d.ts +0 -8
- package/lib/serve/serve-manager.d.ts.map +0 -1
- package/lib/serve/serve-manager.js +0 -44
- package/lib/serve/serve-manager.js.map +0 -1
- package/lib/serve/serve.d.ts +0 -8
- package/lib/serve/serve.d.ts.map +0 -1
- package/lib/serve/serve.js +0 -25
- package/lib/serve/serve.js.map +0 -1
- package/lib/update/update.d.ts +0 -9
- package/lib/update/update.d.ts.map +0 -1
- package/lib/update/update.js +0 -56
- package/lib/update/update.js.map +0 -1
- package/lib/utils/banner-util.d.ts +0 -6
- package/lib/utils/banner-util.d.ts.map +0 -1
- package/lib/utils/banner-util.js +0 -44
- package/lib/utils/banner-util.js.map +0 -1
- package/lib/utils/index.d.ts +0 -2
- package/lib/utils/index.d.ts.map +0 -1
- package/lib/utils/index.js +0 -18
- package/lib/utils/index.js.map +0 -1
- package/src/build/build-manager.ts +0 -50
- package/src/build/build.ts +0 -17
- package/src/cell-main.ts +0 -125
- package/src/cell.ts +0 -215
- package/src/config/config.ts +0 -56
- package/src/deploy/deploy.ts +0 -31
- package/src/info/info.ts +0 -23
- package/src/init/init-manager.ts +0 -163
- package/src/init/init.ts +0 -15
- package/src/init/templates.ts +0 -19
- package/src/package.spec.ts +0 -5
- package/src/props/props.ts +0 -48
- package/src/serve/serve-manager.ts +0 -51
- package/src/serve/serve.ts +0 -29
- package/src/update/update.ts +0 -61
- package/src/utils/banner-util.ts +0 -41
- package/src/utils/index.ts +0 -1
- package/templates/accounts/README.md +0 -92
- package/templates/accounts/cell-database.yml +0 -17
- package/templates/accounts/cell-locale.yml +0 -17
- package/templates/accounts/cell-oauth2.0.yml +0 -8
- package/templates/accounts/cell-theme.yml +0 -9
- package/templates/accounts/cell.yml +0 -10
- package/templates/accounts/favicon.ico +0 -0
- package/templates/accounts/package.json +0 -48
- package/templates/accounts/src/browser/home.view.tsx +0 -86
- package/templates/accounts/src/browser/index.ts +0 -3
- package/templates/accounts/src/browser/login.view.tsx +0 -78
- package/templates/accounts/src/browser/module.ts +0 -3
- package/templates/accounts/src/common/entity-protocol.ts +0 -7
- package/templates/accounts/src/common/index.ts +0 -1
- package/templates/accounts/src/node/authentication/authentication-success-handler.ts +0 -69
- package/templates/accounts/src/node/authentication/index.ts +0 -1
- package/templates/accounts/src/node/entity/base-entity.ts +0 -13
- package/templates/accounts/src/node/entity/connection.ts +0 -52
- package/templates/accounts/src/node/entity/index.ts +0 -1
- package/templates/accounts/src/node/entity/user.ts +0 -73
- package/templates/accounts/src/node/error/error.ts +0 -14
- package/templates/accounts/src/node/error/index.ts +0 -1
- package/templates/accounts/src/node/index.ts +0 -2
- package/templates/accounts/src/node/module.ts +0 -9
- package/templates/accounts/src/node/user/index.ts +0 -4
- package/templates/accounts/src/node/user/user-protocol.ts +0 -19
- package/templates/accounts/src/node/user/user-repository.ts +0 -72
- package/templates/accounts/src/node/user/user-service.ts +0 -36
- package/templates/accounts/tsconfig.json +0 -32
- package/templates/admin-app/.github/workflows/deploy.yml +0 -25
- package/templates/admin-app/.vscode/launch.json +0 -23
- package/templates/admin-app/README.md +0 -92
- package/templates/admin-app/cell-database.yml +0 -7
- package/templates/admin-app/cell.yml +0 -93
- package/templates/admin-app/package.json +0 -37
- package/templates/admin-app/src/browser/user.view.tsx +0 -40
- package/templates/admin-app/src/common/index.ts +0 -1
- package/templates/admin-app/src/common/user-protocol.ts +0 -23
- package/templates/admin-app/src/node/entity/index.ts +0 -1
- package/templates/admin-app/src/node/entity/user.ts +0 -15
- package/templates/admin-app/src/node/module.ts +0 -8
- package/templates/admin-app/src/node/user-service.ts +0 -41
- package/templates/admin-app/tsconfig.json +0 -32
- package/templates/backend-app/.github/workflows/deploy.yml +0 -25
- package/templates/backend-app/.vscode/launch.json +0 -23
- package/templates/backend-app/README.md +0 -92
- package/templates/backend-app/cell.yml +0 -0
- package/templates/backend-app/package.json +0 -33
- package/templates/backend-app/src/home-controller.ts +0 -11
- package/templates/backend-app/src/module.ts +0 -4
- package/templates/backend-app/src/user-controller.ts +0 -48
- package/templates/backend-app/test/home-controller.spec.ts +0 -19
- package/templates/backend-app/tsconfig.json +0 -32
- package/templates/cell-component/README.md +0 -27
- package/templates/cell-component/cell.yml +0 -0
- package/templates/cell-component/package.json +0 -29
- package/templates/cell-component/src/echo-service.ts +0 -16
- package/templates/cell-component/src/index.ts +0 -1
- package/templates/cell-component/src/package.spec.ts +0 -5
- package/templates/cell-component/tsconfig.json +0 -37
- package/templates/database-app/.github/workflows/deploy.yml +0 -25
- package/templates/database-app/.vscode/launch.json +0 -23
- package/templates/database-app/README.md +0 -92
- package/templates/database-app/cell.yml +0 -17
- package/templates/database-app/package.json +0 -31
- package/templates/database-app/src/entity/index.ts +0 -1
- package/templates/database-app/src/entity/user.ts +0 -13
- package/templates/database-app/src/home-controller.ts +0 -11
- package/templates/database-app/src/module.ts +0 -8
- package/templates/database-app/src/user-controller.ts +0 -43
- package/templates/database-app/tsconfig.json +0 -32
- package/templates/docker-app/.github/workflows/deploy.yml +0 -25
- package/templates/docker-app/.vscode/launch.json +0 -23
- package/templates/docker-app/Dockerfile +0 -27
- package/templates/docker-app/README.md +0 -93
- package/templates/docker-app/cell.yml +0 -0
- package/templates/docker-app/package.json +0 -31
- package/templates/docker-app/src/browser/assets/logo.png +0 -0
- package/templates/docker-app/src/browser/css-shims.d.ts +0 -30
- package/templates/docker-app/src/browser/hello.view.tsx +0 -31
- package/templates/docker-app/src/browser/module.ts +0 -3
- package/templates/docker-app/src/browser/style/hello.module.scss +0 -4
- package/templates/docker-app/src/common/welcome-protocol.ts +0 -5
- package/templates/docker-app/src/node/module.ts +0 -3
- package/templates/docker-app/src/node/welcome-server.ts +0 -9
- package/templates/docker-app/tsconfig.json +0 -33
- package/templates/file-service/.github/workflows/deploy.yml +0 -25
- package/templates/file-service/.vscode/launch.json +0 -23
- package/templates/file-service/README.md +0 -92
- package/templates/file-service/cell.yml +0 -12
- package/templates/file-service/package.json +0 -34
- package/templates/file-service/src/file-controller.ts +0 -47
- package/templates/file-service/tsconfig.json +0 -32
- package/templates/jwt-app/.github/workflows/deploy.yml +0 -25
- package/templates/jwt-app/.vscode/launch.json +0 -23
- package/templates/jwt-app/README.md +0 -92
- package/templates/jwt-app/cell.yml +0 -4
- package/templates/jwt-app/package.json +0 -36
- package/templates/jwt-app/src/context.ts +0 -16
- package/templates/jwt-app/src/error-handler.ts +0 -30
- package/templates/jwt-app/src/error.ts +0 -4
- package/templates/jwt-app/src/home-controller.ts +0 -23
- package/templates/jwt-app/src/index.ts +0 -5
- package/templates/jwt-app/src/jwt-middleware.ts +0 -36
- package/templates/jwt-app/src/module.ts +0 -3
- package/templates/jwt-app/test/home-controller.spec.ts +0 -19
- package/templates/jwt-app/tsconfig.json +0 -32
- package/templates/koa-app/app.js +0 -8
- package/templates/koa-app/package.json +0 -9
- package/templates/microservice/.github/workflows/deploy.yml +0 -28
- package/templates/microservice/.vscode/launch.json +0 -24
- package/templates/microservice/README.md +0 -92
- package/templates/microservice/examples/backend-app/README.md +0 -92
- package/templates/microservice/examples/backend-app/cell-remote.yml +0 -4
- package/templates/microservice/examples/backend-app/cell.yml +0 -3
- package/templates/microservice/examples/backend-app/package.json +0 -32
- package/templates/microservice/examples/backend-app/src/api-controller.ts +0 -31
- package/templates/microservice/examples/backend-app/src/module.ts +0 -3
- package/templates/microservice/examples/backend-app/tsconfig.json +0 -32
- package/templates/microservice/package.json +0 -20
- package/templates/microservice/packages/api/README.md +0 -92
- package/templates/microservice/packages/api/cell.yml +0 -0
- package/templates/microservice/packages/api/package.json +0 -25
- package/templates/microservice/packages/api/src/common/api-protocol.ts +0 -10
- package/templates/microservice/packages/api/src/common/index.ts +0 -1
- package/templates/microservice/packages/api/tsconfig.json +0 -30
- package/templates/microservice/packages/serviceA/.vscode/launch.json +0 -23
- package/templates/microservice/packages/serviceA/README.md +0 -92
- package/templates/microservice/packages/serviceA/cell.yml +0 -6
- package/templates/microservice/packages/serviceA/package.json +0 -29
- package/templates/microservice/packages/serviceA/src/node/module.ts +0 -3
- package/templates/microservice/packages/serviceA/src/node/service-a.ts +0 -9
- package/templates/microservice/packages/serviceA/tsconfig.json +0 -30
- package/templates/microservice/packages/serviceB/README.md +0 -92
- package/templates/microservice/packages/serviceB/cell.yml +0 -5
- package/templates/microservice/packages/serviceB/package.json +0 -29
- package/templates/microservice/packages/serviceB/src/node/module.ts +0 -3
- package/templates/microservice/packages/serviceB/src/node/service-b.ts +0 -9
- package/templates/microservice/packages/serviceB/tsconfig.json +0 -30
- package/templates/microservice/tsconfig.json +0 -32
- package/templates/mycli/.vscode/launch.json +0 -33
- package/templates/mycli/bin/mycli +0 -2
- package/templates/mycli/bin/mycli-deploy +0 -2
- package/templates/mycli/bin/mycli-init +0 -2
- package/templates/mycli/package.json +0 -33
- package/templates/mycli/src/bootstrap.ts +0 -7
- package/templates/mycli/src/constants.ts +0 -1
- package/templates/mycli/src/deploy/deploy-manager.ts +0 -12
- package/templates/mycli/src/deploy/deploy.ts +0 -16
- package/templates/mycli/src/deploy/index.ts +0 -1
- package/templates/mycli/src/index.ts +0 -2
- package/templates/mycli/src/init/index.ts +0 -1
- package/templates/mycli/src/init/init-manager.ts +0 -85
- package/templates/mycli/src/init/init.ts +0 -25
- package/templates/mycli/src/init/templates.ts +0 -3
- package/templates/mycli/src/module.ts +0 -3
- package/templates/mycli/src/mycli.ts +0 -13
- package/templates/mycli/templates/application-template/README.md +0 -0
- package/templates/mycli/tsconfig.json +0 -32
- package/templates/nest-app/.eslintrc.js +0 -25
- package/templates/nest-app/.prettierrc +0 -4
- package/templates/nest-app/README.md +0 -73
- package/templates/nest-app/nest-cli.json +0 -8
- package/templates/nest-app/package.json +0 -69
- package/templates/nest-app/src/app.controller.spec.ts +0 -22
- package/templates/nest-app/src/app.controller.ts +0 -12
- package/templates/nest-app/src/app.module.ts +0 -10
- package/templates/nest-app/src/app.service.ts +0 -8
- package/templates/nest-app/src/main.ts +0 -8
- package/templates/nest-app/test/app.e2e-spec.ts +0 -24
- package/templates/nest-app/test/jest-e2e.json +0 -9
- package/templates/nest-app/tsconfig.build.json +0 -12
- package/templates/nest-app/tsconfig.json +0 -25
- package/templates/nextjs-app/.eslintrc.json +0 -3
- package/templates/nextjs-app/README.md +0 -34
- package/templates/nextjs-app/next.config.js +0 -6
- package/templates/nextjs-app/package.json +0 -20
- package/templates/nextjs-app/pages/_app.js +0 -7
- package/templates/nextjs-app/pages/api/hello.js +0 -5
- package/templates/nextjs-app/pages/index.js +0 -69
- package/templates/nextjs-app/public/favicon.ico +0 -0
- package/templates/nextjs-app/public/vercel.svg +0 -4
- package/templates/nextjs-app/styles/Home.module.css +0 -116
- package/templates/nextjs-app/styles/globals.css +0 -16
- package/templates/sample-app/.github/workflows/deploy.yml +0 -25
- package/templates/sample-app/.vscode/launch.json +0 -23
- package/templates/sample-app/README.md +0 -92
- package/templates/sample-app/cell.yml +0 -0
- package/templates/sample-app/package.json +0 -31
- package/templates/sample-app/src/browser/assets/logo.png +0 -0
- package/templates/sample-app/src/browser/css-shims.d.ts +0 -30
- package/templates/sample-app/src/browser/hello.view.tsx +0 -31
- package/templates/sample-app/src/browser/module.ts +0 -3
- package/templates/sample-app/src/browser/style/hello.module.scss +0 -4
- package/templates/sample-app/src/common/welcome-protocol.ts +0 -5
- package/templates/sample-app/src/node/module.ts +0 -3
- package/templates/sample-app/src/node/welcome-server.ts +0 -9
- package/templates/sample-app/tsconfig.json +0 -32
- package/templates/schedule/.github/workflows/deploy.yml +0 -25
- package/templates/schedule/.vscode/launch.json +0 -23
- package/templates/schedule/README.md +0 -92
- package/templates/schedule/cell.yml +0 -1
- package/templates/schedule/package.json +0 -29
- package/templates/schedule/src/module.ts +0 -3
- package/templates/schedule/src/scheduler.ts +0 -10
- package/templates/schedule/tsconfig.json +0 -32
- package/templates/standalone-app/package.json +0 -17
- package/templates/standalone-app/src/app.service.ts +0 -10
- package/templates/standalone-app/src/main.ts +0 -14
- package/templates/standalone-app/src/module.ts +0 -3
- package/templates/standalone-app/tsconfig.json +0 -30
- package/templates/vue-app/.github/workflows/deploy.yml +0 -25
- package/templates/vue-app/.vscode/launch.json +0 -23
- package/templates/vue-app/README.md +0 -92
- package/templates/vue-app/cell.yml +0 -0
- package/templates/vue-app/package.json +0 -32
- package/templates/vue-app/src/browser/App.vue +0 -32
- package/templates/vue-app/src/browser/app.ts +0 -7
- package/templates/vue-app/src/browser/components/HelloWorld.vue +0 -42
- package/templates/vue-app/src/browser/declare.d.ts +0 -7
- package/templates/vue-app/src/browser/images/logo.png +0 -0
- package/templates/vue-app/src/browser/module.ts +0 -3
- package/templates/vue-app/src/browser/router.ts +0 -13
- package/templates/vue-app/src/browser/shims-vue.d.ts +0 -5
- package/templates/vue-app/src/browser/views/About.vue +0 -5
- package/templates/vue-app/src/browser/views/Root.vue +0 -37
- package/templates/vue-app/src/common/welcome-protocol.ts +0 -5
- package/templates/vue-app/src/node/module.ts +0 -3
- package/templates/vue-app/src/node/welcome-server.ts +0 -9
- package/templates/vue-app/tsconfig.json +0 -32
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { CellError, type McpToolDefinition } from '@celljs/kit';
|
|
3
|
+
import type { CellDevServer } from '@celljs/vite';
|
|
4
|
+
import { DevActivity, type LogLevel } from './dev-activity.js';
|
|
5
|
+
import { McpServer } from './mcp-server.js';
|
|
6
|
+
|
|
7
|
+
/** The parts of an inversify 6 container the endpoint reads. */
|
|
8
|
+
interface ContainerLike {
|
|
9
|
+
get(id: unknown): unknown;
|
|
10
|
+
parent?: ContainerLike | null;
|
|
11
|
+
_bindingDictionary?: { getMap(): Map<unknown, BindingLike[]> };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface BindingLike {
|
|
15
|
+
type?: string;
|
|
16
|
+
scope?: string;
|
|
17
|
+
implementationType?: { name?: string } | null;
|
|
18
|
+
constraint?: { metaData?: { key?: unknown; value?: unknown } };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface RouteLike {
|
|
22
|
+
mapping: Map<string, { path: string | RegExp; controllerMetadata?: { target?: { name?: string } }; methodMetadata?: { key?: unknown } }[]>;
|
|
23
|
+
errorMapping?: Map<{ name?: string }, { controllerMetadata?: { target?: { name?: string } }; methodMetadata?: { key?: unknown } }>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* `POST /_cell/mcp` of `cell dev`: an MCP endpoint (Streamable HTTP, JSON responses) into the running
|
|
28
|
+
* application: errors, routes, DI bindings, configuration, recent requests and logs
|
|
29
|
+
* (docs/design/agent-first.md R8). Only answers same-machine origins.
|
|
30
|
+
*/
|
|
31
|
+
export class DevMcpEndpoint {
|
|
32
|
+
static readonly PATH = '/_cell/mcp';
|
|
33
|
+
static readonly MAX_BODY = 1024 * 1024;
|
|
34
|
+
static readonly LOOPBACK = ['localhost', '127.0.0.1', '[::1]', '::1'];
|
|
35
|
+
/** A key, not an expression: `get_config` evaluates `${key}`. */
|
|
36
|
+
static readonly KEY = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[\d+\])*$/;
|
|
37
|
+
|
|
38
|
+
readonly server: McpServer;
|
|
39
|
+
|
|
40
|
+
constructor(
|
|
41
|
+
protected readonly dev: () => CellDevServer | undefined,
|
|
42
|
+
protected readonly activity: DevActivity,
|
|
43
|
+
version: string,
|
|
44
|
+
) {
|
|
45
|
+
this.server = new McpServer({
|
|
46
|
+
name: 'cell-dev',
|
|
47
|
+
version,
|
|
48
|
+
instructions:
|
|
49
|
+
'The running Cell application of cell dev. Call get_errors first when something fails; list_routes, list_bindings and get_config show what the application really loaded.',
|
|
50
|
+
tools: () => this.tools(),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** A connect-style handler for the dev server. */
|
|
55
|
+
readonly handler = (req: IncomingMessage, res: ServerResponse): void => {
|
|
56
|
+
this.handle(req, res).catch(error => {
|
|
57
|
+
if (!res.headersSent) {
|
|
58
|
+
DevMcpEndpoint.send(res, 500, McpServer.error(null, error));
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
protected async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {
|
|
64
|
+
if (!DevMcpEndpoint.sameMachine(req)) {
|
|
65
|
+
DevMcpEndpoint.send(res, 403, { error: 'Forbidden: the dev MCP endpoint only answers pages and clients of this machine.' });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (req.method !== 'POST') {
|
|
69
|
+
res.setHeader('Allow', 'POST');
|
|
70
|
+
DevMcpEndpoint.send(res, 405, { error: 'Use POST with a JSON-RPC message (MCP Streamable HTTP, JSON responses).' });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const body = await DevMcpEndpoint.read(req);
|
|
74
|
+
if (body === undefined) {
|
|
75
|
+
DevMcpEndpoint.send(res, 413, { error: `The message is larger than ${DevMcpEndpoint.MAX_BODY} bytes.` });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const response = await this.server.handleText(body);
|
|
79
|
+
if (response === undefined) {
|
|
80
|
+
res.statusCode = 202;
|
|
81
|
+
res.end();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
res.statusCode = 200;
|
|
85
|
+
res.setHeader('Content-Type', 'application/json');
|
|
86
|
+
res.end(response);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** No Origin (a CLI client), a loopback origin, or the page of the dev server itself. */
|
|
90
|
+
static sameMachine(req: IncomingMessage): boolean {
|
|
91
|
+
const origin = req.headers.origin;
|
|
92
|
+
if (!origin) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const url = new URL(origin);
|
|
97
|
+
return DevMcpEndpoint.LOOPBACK.includes(url.hostname) || url.host === req.headers.host;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
protected static read(req: IncomingMessage): Promise<string | undefined> {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const chunks: Buffer[] = [];
|
|
106
|
+
let size = 0;
|
|
107
|
+
req.on('data', (chunk: Buffer) => {
|
|
108
|
+
size += chunk.length;
|
|
109
|
+
if (size <= DevMcpEndpoint.MAX_BODY) {
|
|
110
|
+
chunks.push(chunk);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
req.on('end', () => resolve(size > DevMcpEndpoint.MAX_BODY ? undefined : Buffer.concat(chunks).toString('utf8')));
|
|
114
|
+
req.on('error', reject);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected static send(res: ServerResponse, status: number, body: unknown): void {
|
|
119
|
+
res.statusCode = status;
|
|
120
|
+
res.setHeader('Content-Type', 'application/json');
|
|
121
|
+
res.end(JSON.stringify(body));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
tools(): McpToolDefinition[] {
|
|
125
|
+
const object = (properties: Record<string, unknown> = {}, required: string[] = []) => ({
|
|
126
|
+
type: 'object',
|
|
127
|
+
properties,
|
|
128
|
+
...(required.length > 0 ? { required } : {}),
|
|
129
|
+
additionalProperties: false,
|
|
130
|
+
});
|
|
131
|
+
const limit = { type: 'integer', description: 'How many of the latest entries (default 20).' };
|
|
132
|
+
return [
|
|
133
|
+
{
|
|
134
|
+
name: 'get_errors',
|
|
135
|
+
description:
|
|
136
|
+
'Why the application fails: the current backend start error (with file, line and fix), earlier failed reloads, requests answered with 5xx and recent error logs.',
|
|
137
|
+
inputSchema: object(),
|
|
138
|
+
readOnly: true,
|
|
139
|
+
run: () => this.errors(),
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'list_routes',
|
|
143
|
+
description: 'HTTP routes of the running backend (@celljs/mvc): method, path, controller and method name, and error handlers.',
|
|
144
|
+
inputSchema: object({ filter: { type: 'string', description: 'Only routes whose path or controller contains this text.' } }),
|
|
145
|
+
readOnly: true,
|
|
146
|
+
run: input => this.routes(input.filter as string | undefined),
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'list_bindings',
|
|
150
|
+
description: 'DI bindings of the running container: service identifier, implementation, scope and binding type.',
|
|
151
|
+
inputSchema: object({
|
|
152
|
+
filter: { type: 'string', description: 'Only bindings whose identifier or implementation contains this text (case-insensitive).' },
|
|
153
|
+
limit: { type: 'integer', description: 'At most this many (default 200).' },
|
|
154
|
+
}),
|
|
155
|
+
readOnly: true,
|
|
156
|
+
run: input => this.bindings(input.filter as string | undefined, (input.limit as number | undefined) ?? 200),
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'get_config',
|
|
160
|
+
description:
|
|
161
|
+
'A configuration value as the running backend sees it, with ${...} expressions evaluated (e.g. cell.server.port). For where a value comes from, use config_get of cell mcp.',
|
|
162
|
+
inputSchema: object({ key: { type: 'string', description: 'Dotted key, e.g. cell.server.port.' } }, ['key']),
|
|
163
|
+
readOnly: true,
|
|
164
|
+
run: input => this.config(input.key as string),
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'recent_requests',
|
|
168
|
+
description: 'The latest requests the backend answered: time, method, URL, status and duration.',
|
|
169
|
+
inputSchema: object({
|
|
170
|
+
limit,
|
|
171
|
+
minStatus: { type: 'integer', description: 'Only responses with at least this status, e.g. 400.' },
|
|
172
|
+
filter: { type: 'string', description: 'Only URLs containing this text.' },
|
|
173
|
+
}),
|
|
174
|
+
readOnly: true,
|
|
175
|
+
run: input => {
|
|
176
|
+
const min = (input.minStatus as number | undefined) ?? 0;
|
|
177
|
+
const filter = input.filter as string | undefined;
|
|
178
|
+
const requests = this.activity.requests.filter(r => r.status >= min && (!filter || r.url.includes(filter)));
|
|
179
|
+
return { total: requests.length, requests: requests.slice(-((input.limit as number | undefined) ?? 20)) };
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'logs',
|
|
184
|
+
description: 'Console output of the dev process (application, Vite, Cell), newest last.',
|
|
185
|
+
inputSchema: object({
|
|
186
|
+
limit: { type: 'integer', description: 'How many of the latest entries (default 50).' },
|
|
187
|
+
level: { type: 'string', enum: DevActivity.LEVELS, description: 'Minimum level (default debug).' },
|
|
188
|
+
filter: { type: 'string', description: 'Only messages containing this text.' },
|
|
189
|
+
}),
|
|
190
|
+
readOnly: true,
|
|
191
|
+
run: input => {
|
|
192
|
+
const min = DevActivity.LEVELS.indexOf((input.level as LogLevel | undefined) ?? 'debug');
|
|
193
|
+
const filter = input.filter as string | undefined;
|
|
194
|
+
const logs = this.activity.logs.filter(l => DevActivity.LEVELS.indexOf(l.level) >= min && (!filter || l.message.includes(filter)));
|
|
195
|
+
return { total: logs.length, logs: logs.slice(-((input.limit as number | undefined) ?? 50)) };
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
protected errors(): Record<string, unknown> {
|
|
202
|
+
const dev = this.dev();
|
|
203
|
+
return {
|
|
204
|
+
backend: dev?.error?.toJSON() ?? null,
|
|
205
|
+
running: Boolean(dev?.application),
|
|
206
|
+
reloads: this.activity.errors.slice(-5),
|
|
207
|
+
failedRequests: this.activity.requests.filter(r => r.status >= 500).slice(-10),
|
|
208
|
+
errorLogs: this.activity.logs.filter(l => l.level === 'error').slice(-10),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
protected container(): ContainerLike {
|
|
213
|
+
const dev = this.dev();
|
|
214
|
+
const container = dev?.application?.container as ContainerLike | undefined;
|
|
215
|
+
if (!container) {
|
|
216
|
+
throw new CellError({
|
|
217
|
+
code: 'CELL_DEV_BACKEND_NOT_RUNNING',
|
|
218
|
+
message: dev?.error ? `The backend is not running: ${dev.error.message}` : 'The backend is not running.',
|
|
219
|
+
hint: dev?.error
|
|
220
|
+
? 'Call get_errors for the details; the backend starts again when a file is saved.'
|
|
221
|
+
: 'The project has no backend, or it is still starting.',
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return container;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Every binding of the container and its parents, by identifier. */
|
|
228
|
+
protected static entries(container: ContainerLike): [unknown, BindingLike[]][] {
|
|
229
|
+
const entries: [unknown, BindingLike[]][] = [];
|
|
230
|
+
for (let c: ContainerLike | null | undefined = container; c; c = c.parent) {
|
|
231
|
+
const map = c._bindingDictionary?.getMap();
|
|
232
|
+
if (map) {
|
|
233
|
+
entries.push(...map.entries());
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return entries;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static idName(id: unknown): string {
|
|
240
|
+
if (typeof id === 'symbol') {
|
|
241
|
+
return id.description ?? id.toString();
|
|
242
|
+
}
|
|
243
|
+
if (typeof id === 'function') {
|
|
244
|
+
return id.name || '(anonymous class)';
|
|
245
|
+
}
|
|
246
|
+
return String(id);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** A service bound under a symbol of that description, e.g. `RouteProvider` of @celljs/mvc. */
|
|
250
|
+
protected find(description: string): unknown {
|
|
251
|
+
const container = this.container();
|
|
252
|
+
const entry = DevMcpEndpoint.entries(container).find(([id]) => typeof id === 'symbol' && id.description === description);
|
|
253
|
+
return entry && container.get(entry[0]);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
protected bindings(filter: string | undefined, limit: number): Record<string, unknown> {
|
|
257
|
+
const needle = filter?.toLowerCase();
|
|
258
|
+
const rows = DevMcpEndpoint.entries(this.container()).flatMap(([id, bindings]) =>
|
|
259
|
+
bindings.map(binding => ({
|
|
260
|
+
id: DevMcpEndpoint.idName(id),
|
|
261
|
+
...(binding.implementationType?.name ? { implementation: binding.implementationType.name } : {}),
|
|
262
|
+
type: binding.type,
|
|
263
|
+
scope: binding.scope,
|
|
264
|
+
...(binding.constraint?.metaData?.key !== undefined
|
|
265
|
+
? { constraint: `${String(binding.constraint.metaData.key)}=${String(binding.constraint.metaData.value)}` }
|
|
266
|
+
: {}),
|
|
267
|
+
})),
|
|
268
|
+
);
|
|
269
|
+
const matching = needle ? rows.filter(r => r.id.toLowerCase().includes(needle) || r.implementation?.toLowerCase().includes(needle)) : rows;
|
|
270
|
+
return { total: matching.length, bindings: matching.slice(0, limit), ...(matching.length > limit ? { truncated: true } : {}) };
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
protected async routes(filter: string | undefined): Promise<Record<string, unknown>> {
|
|
274
|
+
const provider = this.find('RouteProvider') as { provide(): Promise<RouteLike> } | undefined;
|
|
275
|
+
if (!provider) {
|
|
276
|
+
return { routes: [], errorHandlers: [], note: 'The backend has no @celljs/mvc routes.' };
|
|
277
|
+
}
|
|
278
|
+
const route = await provider.provide();
|
|
279
|
+
const routes = [...route.mapping].flatMap(([method, paths]) =>
|
|
280
|
+
paths.map(p => ({
|
|
281
|
+
method,
|
|
282
|
+
path: typeof p.path === 'string' ? p.path : String(p.path),
|
|
283
|
+
controller: p.controllerMetadata?.target?.name,
|
|
284
|
+
handler: p.methodMetadata?.key === undefined ? undefined : String(p.methodMetadata.key),
|
|
285
|
+
})),
|
|
286
|
+
);
|
|
287
|
+
const errorHandlers = [...(route.errorMapping ?? [])].map(([type, metadata]) => ({
|
|
288
|
+
error: type?.name,
|
|
289
|
+
controller: metadata.controllerMetadata?.target?.name,
|
|
290
|
+
handler: metadata.methodMetadata?.key === undefined ? undefined : String(metadata.methodMetadata.key),
|
|
291
|
+
}));
|
|
292
|
+
const matches = (text?: string) => !filter || (text ?? '').includes(filter);
|
|
293
|
+
return { routes: routes.filter(r => matches(r.path) || matches(r.controller)), errorHandlers };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
protected config(key: string): Record<string, unknown> {
|
|
297
|
+
if (!DevMcpEndpoint.KEY.test(key)) {
|
|
298
|
+
throw new CellError({
|
|
299
|
+
code: 'CELL_ARGUMENT_INVALID',
|
|
300
|
+
message: `Invalid configuration key '${key}'.`,
|
|
301
|
+
hint: 'Pass a dotted key, e.g. cell.server.port or items[0].name.',
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
// ConfigProvider.get() turns 0, false and '' into the default; the expression handler does not.
|
|
305
|
+
const handler = this.find('ExpressionHandler') as { handle(text: string): unknown } | undefined;
|
|
306
|
+
if (!handler) {
|
|
307
|
+
throw new CellError({
|
|
308
|
+
code: 'CELL_DEV_BACKEND_NOT_RUNNING',
|
|
309
|
+
message: 'The backend has no ExpressionHandler.',
|
|
310
|
+
hint: 'Depend on @celljs/core 4 or later.',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const value = handler.handle(`\${${key}}`);
|
|
314
|
+
if (value === undefined) {
|
|
315
|
+
throw new CellError({
|
|
316
|
+
code: 'CELL_CONFIG_KEY_NOT_FOUND',
|
|
317
|
+
message: `'${key}' is not set in the running backend.`,
|
|
318
|
+
hint: `Run cell config get ${key} (or config_get of cell mcp) for the nearest keys and where values come from.`,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return { key, value };
|
|
322
|
+
}
|
|
323
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { CellError, type McpToolDefinition } from '@celljs/kit';
|
|
2
|
+
import { Reporter } from '../cli/reporter.js';
|
|
3
|
+
import { TextUtil } from '../utils/text-util.js';
|
|
4
|
+
|
|
5
|
+
export interface McpServerOptions {
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
/** Told to the client on `initialize`: what the server is for. */
|
|
9
|
+
instructions?: string;
|
|
10
|
+
/** The tools, asked for on every `tools/list` and `tools/call` (they may change with the project). */
|
|
11
|
+
tools(): McpToolDefinition[] | Promise<McpToolDefinition[]>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type JsonRpcId = string | number | null;
|
|
15
|
+
|
|
16
|
+
interface JsonRpcRequest {
|
|
17
|
+
jsonrpc: '2.0';
|
|
18
|
+
id?: JsonRpcId;
|
|
19
|
+
method: string;
|
|
20
|
+
params?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface JsonRpcResponse {
|
|
24
|
+
jsonrpc: '2.0';
|
|
25
|
+
id: JsonRpcId;
|
|
26
|
+
result?: unknown;
|
|
27
|
+
error?: { code: number; message: string; data?: unknown };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A tool result of MCP: the value as JSON text, and as structured content when it is an object. */
|
|
31
|
+
export interface McpToolResult {
|
|
32
|
+
content: { type: 'text'; text: string }[];
|
|
33
|
+
structuredContent?: Record<string, unknown>;
|
|
34
|
+
isError: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class RpcError extends Error {
|
|
38
|
+
constructor(
|
|
39
|
+
readonly code: number,
|
|
40
|
+
message: string,
|
|
41
|
+
readonly data?: unknown,
|
|
42
|
+
) {
|
|
43
|
+
super(message);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The protocol side of an MCP server (JSON-RPC 2.0, tools only), without a transport: `cell mcp`
|
|
49
|
+
* feeds it lines from stdin, `cell dev` the bodies of POST /_cell/mcp. Tool calls run one at a time;
|
|
50
|
+
* a failing tool answers with `isError` and the CellError as JSON (docs/design/agent-first.md R5, R8).
|
|
51
|
+
*/
|
|
52
|
+
export class McpServer {
|
|
53
|
+
static readonly PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'];
|
|
54
|
+
static readonly PARSE_ERROR = -32700;
|
|
55
|
+
static readonly INVALID_REQUEST = -32600;
|
|
56
|
+
static readonly METHOD_NOT_FOUND = -32601;
|
|
57
|
+
static readonly INVALID_PARAMS = -32602;
|
|
58
|
+
|
|
59
|
+
protected queue: Promise<unknown> = Promise.resolve();
|
|
60
|
+
|
|
61
|
+
constructor(protected readonly options: McpServerOptions) {}
|
|
62
|
+
|
|
63
|
+
/** Handles one line or body of JSON; returns the response text, or undefined for a notification. */
|
|
64
|
+
async handleText(text: string): Promise<string | undefined> {
|
|
65
|
+
let message: unknown;
|
|
66
|
+
try {
|
|
67
|
+
message = JSON.parse(text);
|
|
68
|
+
} catch {
|
|
69
|
+
return JSON.stringify(McpServer.error(null, new RpcError(McpServer.PARSE_ERROR, 'Parse error: the message is not JSON.')));
|
|
70
|
+
}
|
|
71
|
+
const response = await this.handle(message);
|
|
72
|
+
return response && JSON.stringify(response);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async handle(message: unknown): Promise<JsonRpcResponse | undefined> {
|
|
76
|
+
const request = message as JsonRpcRequest;
|
|
77
|
+
if (typeof request !== 'object' || request === null || Array.isArray(request) || request.jsonrpc !== '2.0' || typeof request.method !== 'string') {
|
|
78
|
+
// A response from the client (to a request this server never sends) is not an error.
|
|
79
|
+
if (typeof request === 'object' && request !== null && 'id' in request && ('result' in request || 'error' in request)) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
return McpServer.error(null, new RpcError(McpServer.INVALID_REQUEST, 'Invalid request: expected a JSON-RPC 2.0 object with a method.'));
|
|
83
|
+
}
|
|
84
|
+
const notification = !('id' in request);
|
|
85
|
+
try {
|
|
86
|
+
const result = await this.dispatch(request.method, request.params ?? {});
|
|
87
|
+
return notification ? undefined : { jsonrpc: '2.0', id: request.id ?? null, result };
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return notification ? undefined : McpServer.error(request.id ?? null, error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected async dispatch(method: string, params: Record<string, unknown>): Promise<unknown> {
|
|
94
|
+
switch (method) {
|
|
95
|
+
case 'initialize': {
|
|
96
|
+
const requested = params.protocolVersion as string;
|
|
97
|
+
return {
|
|
98
|
+
protocolVersion: McpServer.PROTOCOL_VERSIONS.includes(requested) ? requested : McpServer.PROTOCOL_VERSIONS[0],
|
|
99
|
+
capabilities: { tools: { listChanged: false } },
|
|
100
|
+
serverInfo: { name: this.options.name, version: this.options.version },
|
|
101
|
+
...(this.options.instructions ? { instructions: this.options.instructions } : {}),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
case 'ping':
|
|
105
|
+
return {};
|
|
106
|
+
case 'tools/list':
|
|
107
|
+
return { tools: (await this.options.tools()).map(tool => McpServer.describe(tool)) };
|
|
108
|
+
case 'tools/call':
|
|
109
|
+
return this.serialize(() => this.call(params.name, params.arguments));
|
|
110
|
+
default:
|
|
111
|
+
if (method.startsWith('notifications/')) {
|
|
112
|
+
return {};
|
|
113
|
+
}
|
|
114
|
+
throw new RpcError(McpServer.METHOD_NOT_FOUND, `Method not found: ${method}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected serialize<T>(task: () => Promise<T>): Promise<T> {
|
|
119
|
+
const run = this.queue.then(task, task);
|
|
120
|
+
this.queue = run.catch(() => undefined);
|
|
121
|
+
return run;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
protected async call(name: unknown, args: unknown = {}): Promise<McpToolResult> {
|
|
125
|
+
const tools = await this.options.tools();
|
|
126
|
+
const tool = tools.find(t => t.name === name);
|
|
127
|
+
if (!tool) {
|
|
128
|
+
const suggestion =
|
|
129
|
+
typeof name === 'string'
|
|
130
|
+
? TextUtil.closest(
|
|
131
|
+
name,
|
|
132
|
+
tools.map(t => t.name),
|
|
133
|
+
)
|
|
134
|
+
: undefined;
|
|
135
|
+
throw new RpcError(
|
|
136
|
+
McpServer.INVALID_PARAMS,
|
|
137
|
+
`Unknown tool '${String(name)}'.${suggestion ? ` Did you mean '${suggestion}'?` : ` Tools: ${tools.map(t => t.name).join(', ')}.`}`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args)) {
|
|
141
|
+
throw new RpcError(McpServer.INVALID_PARAMS, `The arguments of '${tool.name}' must be an object.`);
|
|
142
|
+
}
|
|
143
|
+
const problem = McpServer.validate(tool.inputSchema, args as Record<string, unknown>);
|
|
144
|
+
if (problem) {
|
|
145
|
+
return McpServer.result(
|
|
146
|
+
new CellError({
|
|
147
|
+
code: 'CELL_ARGUMENT_INVALID',
|
|
148
|
+
message: `Invalid arguments for '${tool.name}': ${problem}`,
|
|
149
|
+
hint: 'Call tools/list for the input schema.',
|
|
150
|
+
}).toJSON(),
|
|
151
|
+
true,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
return McpServer.result(await tool.run(args as Record<string, unknown>), false);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
return McpServer.result(Reporter.toCellError(error).toJSON(), true);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static describe(tool: McpToolDefinition): Record<string, unknown> {
|
|
162
|
+
return {
|
|
163
|
+
name: tool.name,
|
|
164
|
+
description: tool.description,
|
|
165
|
+
inputSchema: { type: 'object', ...tool.inputSchema },
|
|
166
|
+
annotations: { readOnlyHint: tool.readOnly, destructiveHint: false, openWorldHint: tool.network ?? false },
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Text for every client; objects also as structured content. */
|
|
171
|
+
static result(value: unknown, isError: boolean): McpToolResult {
|
|
172
|
+
const text = typeof value === 'string' ? value : (JSON.stringify(value) ?? 'null');
|
|
173
|
+
const structured = typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
174
|
+
return { content: [{ type: 'text', text }], ...(structured ? { structuredContent: value as Record<string, unknown> } : {}), isError };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Checks the arguments against the top level of the tool's JSON Schema: required properties, the
|
|
179
|
+
* type of each property (and of array items), enums, and unknown properties when
|
|
180
|
+
* `additionalProperties` is false. Returns the first problem, or undefined.
|
|
181
|
+
*/
|
|
182
|
+
static validate(schema: Record<string, unknown>, args: Record<string, unknown>): string | undefined {
|
|
183
|
+
const properties = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;
|
|
184
|
+
for (const key of (schema.required ?? []) as string[]) {
|
|
185
|
+
if (args[key] === undefined) {
|
|
186
|
+
return `'${key}' is required.`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (const [key, value] of Object.entries(args)) {
|
|
190
|
+
const property = properties[key];
|
|
191
|
+
if (!property) {
|
|
192
|
+
if (schema.additionalProperties === false) {
|
|
193
|
+
const suggestion = TextUtil.closest(key, Object.keys(properties));
|
|
194
|
+
return `unknown property '${key}'.${suggestion ? ` Did you mean '${suggestion}'?` : ` Properties: ${Object.keys(properties).join(', ') || 'none'}.`}`;
|
|
195
|
+
}
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const problem = McpServer.checkValue(value, property);
|
|
199
|
+
if (problem) {
|
|
200
|
+
return `'${key}' ${problem}`;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
protected static checkValue(value: unknown, schema: Record<string, unknown>): string | undefined {
|
|
207
|
+
const type = schema.type as string | undefined;
|
|
208
|
+
if (type && !McpServer.hasType(value, type)) {
|
|
209
|
+
return `must be ${type === 'array' || type === 'object' || type === 'integer' ? 'an' : 'a'} ${type}.`;
|
|
210
|
+
}
|
|
211
|
+
if (Array.isArray(schema.enum) && !schema.enum.includes(value)) {
|
|
212
|
+
return `must be one of: ${schema.enum.map(v => JSON.stringify(v)).join(', ')}.`;
|
|
213
|
+
}
|
|
214
|
+
if (type === 'array' && schema.items && Array.isArray(value)) {
|
|
215
|
+
for (const item of value) {
|
|
216
|
+
const problem = McpServer.checkValue(item, schema.items as Record<string, unknown>);
|
|
217
|
+
if (problem) {
|
|
218
|
+
return `items ${problem}`;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
protected static hasType(value: unknown, type: string): boolean {
|
|
226
|
+
switch (type) {
|
|
227
|
+
case 'string':
|
|
228
|
+
return typeof value === 'string';
|
|
229
|
+
case 'boolean':
|
|
230
|
+
return typeof value === 'boolean';
|
|
231
|
+
case 'number':
|
|
232
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
233
|
+
case 'integer':
|
|
234
|
+
return Number.isInteger(value);
|
|
235
|
+
case 'array':
|
|
236
|
+
return Array.isArray(value);
|
|
237
|
+
case 'object':
|
|
238
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
239
|
+
default:
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static error(id: JsonRpcId, error: unknown): JsonRpcResponse {
|
|
245
|
+
if (error instanceof RpcError) {
|
|
246
|
+
return { jsonrpc: '2.0', id, error: { code: error.code, message: error.message, ...(error.data === undefined ? {} : { data: error.data }) } };
|
|
247
|
+
}
|
|
248
|
+
const cellError = Reporter.toCellError(error);
|
|
249
|
+
return { jsonrpc: '2.0', id, error: { code: -32603, message: cellError.message, data: cellError.toJSON() } };
|
|
250
|
+
}
|
|
251
|
+
}
|