@aws/nx-plugin 1.0.0-rc.79 → 1.0.0-rc.80
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/generators.json +10 -0
- package/migrations.json +1 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/agent-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/agent-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/agent-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/agent-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/attach-upstream.js.map +1 -1
- package/src/agentcore-gateway/gateway-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/gateway-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/gateway-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/generator.d.ts +3 -3
- package/src/agentcore-gateway/generator.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/mcp-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/react-connection/generator.d.ts +1 -1
- package/src/agentcore-gateway/react-connection/generator.js.map +1 -1
- package/src/agentcore-gateway/react-connection/schema.d.js.map +1 -1
- package/src/agentcore-gateway/react-connection/schema.d.ts +1 -1
- package/src/agentcore-gateway/schema.d.js.map +1 -1
- package/src/agentcore-gateway/schema.d.ts +1 -1
- package/src/agentcore-harness/generator.d.ts +4 -4
- package/src/agentcore-harness/generator.js.map +1 -1
- package/src/agentcore-harness/schema.d.js.map +1 -1
- package/src/agentcore-harness/schema.d.ts +1 -1
- package/src/connection/agent-local-dev.d.ts +1 -1
- package/src/connection/agent-local-dev.js.map +1 -1
- package/src/connection/agent-runtime-config.js.map +1 -1
- package/src/connection/gateway-runtime-config.js.map +1 -1
- package/src/connection/generator.d.ts +2 -2
- package/src/connection/generator.js.map +1 -1
- package/src/connection/local-dev.js.map +1 -1
- package/src/connection/scaffold-catalog.d.ts +1 -1
- package/src/connection/scaffold-catalog.js +6 -6
- package/src/connection/scaffold-catalog.js.map +1 -1
- package/src/connection/schema-resolver.d.ts +1 -1
- package/src/connection/schema-resolver.js.map +1 -1
- package/src/index.d.ts +1 -1
- package/src/index.js.map +1 -1
- package/src/infra/app/generator.d.ts +7 -7
- package/src/infra/app/generator.js.map +1 -1
- package/src/init/generator.d.ts +3 -3
- package/src/init/generator.js.map +1 -1
- package/src/init/schema.d.js.map +1 -1
- package/src/init/schema.d.ts +2 -2
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/license/config-types.d.ts +2 -2
- package/src/license/config-types.js.map +1 -1
- package/src/license/config.d.ts +2 -2
- package/src/license/config.js.map +1 -1
- package/src/license/dependency-check/check.d.ts +2 -2
- package/src/license/dependency-check/check.js.map +1 -1
- package/src/license/dependency-check/collectors/collector.js.map +1 -1
- package/src/license/dependency-check/collectors/python-collector.js.map +1 -1
- package/src/license/dependency-check/evaluator.d.ts +1 -1
- package/src/license/dependency-check/evaluator.js.map +1 -1
- package/src/license/dependency-check/executor.js.map +1 -1
- package/src/license/dependency-check/pre-approved.d.ts +1 -1
- package/src/license/dependency-check/pre-approved.js.map +1 -1
- package/src/license/dependency-check/types.d.ts +1 -1
- package/src/license/dependency-check/types.js.map +1 -1
- package/src/license/generator.d.ts +1 -1
- package/src/license/generator.js.map +1 -1
- package/src/license/index.d.ts +4 -4
- package/src/license/index.js.map +1 -1
- package/src/license/known-exceptions.d.ts +1 -1
- package/src/license/known-exceptions.js.map +1 -1
- package/src/license/sync/generator.js.map +1 -1
- package/src/license/sync/project-file-sync.d.ts +1 -1
- package/src/license/sync/project-file-sync.js.map +1 -1
- package/src/mcp-server/dev-server.js.map +1 -1
- package/src/mcp-server/generator-info.d.ts +3 -3
- package/src/mcp-server/generator-info.js.map +1 -1
- package/src/mcp-server/guide-pipeline.d.ts +1 -1
- package/src/mcp-server/guide-pipeline.js.map +1 -1
- package/src/mcp-server/guide-render.js.map +1 -1
- package/src/mcp-server/index.js.map +1 -1
- package/src/mcp-server/mdx-ast.js.map +1 -1
- package/src/mcp-server/server.js.map +1 -1
- package/src/mcp-server/tools/add-to-existing-project.d.ts +1 -1
- package/src/mcp-server/tools/add-to-existing-project.js.map +1 -1
- package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
- package/src/mcp-server/tools/general-guidance.d.ts +1 -1
- package/src/mcp-server/tools/general-guidance.js +1 -1
- package/src/mcp-server/tools/general-guidance.js.map +1 -1
- package/src/mcp-server/tools/generator-guide.d.ts +1 -1
- package/src/mcp-server/tools/generator-guide.js.map +1 -1
- package/src/mcp-server/tools/list-generators.d.ts +1 -1
- package/src/mcp-server/tools/list-generators.js.map +1 -1
- package/src/mcp-server/tools/upgrade-workspace.d.ts +1 -1
- package/src/mcp-server/tools/upgrade-workspace.js.map +1 -1
- package/src/migrations/latest/apt-security-updates-in-container-images/migration.js.map +1 -1
- package/src/migrations/latest/dynamodb-configurable-encryption/migration.js.map +1 -1
- package/src/migrations/latest/py-agent-ag-ui-hooks/migration.js.map +1 -1
- package/src/migrations/latest/py-agent-session-id-middleware-extraction/migration.js.map +1 -1
- package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js.map +1 -1
- package/src/migrations/latest/static-website-configurable-waf-encryption/migration.js.map +1 -1
- package/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.js.map +1 -1
- package/src/migrations/latest/user-identity-configurable-mfa/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.50/0001-modernize-function-props-cast/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.50/0002-restrict-cors-to-custom-domains/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.50/0003-terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.52/0001-user-identity-waf-allow-localhost-callback/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.54/0001-order-access-log-delivery-after-bucket-policy/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.d.ts +1 -1
- package/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.56/0001-dynamodb-local-remove-optimize-flag/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.57/0001-ts-agent-session-management-support/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.58/0001-smithy-ssdk-bundle-pins/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.59/0001-gateway-agent-targets/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.60/0001-gateway-cognito-passthrough/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.60/0002-waf-log-group-removal/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.60/0003-strip-pip-from-python-images/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.61/0001-py-agent-lifespan-construction/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.62/0001-rename-load-runtime-config-target/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.63/0001-add-deploy-sandbox-target/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.64/0001-smithy-build-without-docker/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.65/0001-vite-config-import-meta-dirname/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.65/0002-rolldown-code-splitting/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.67/0001-smithy-server-package-rename/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.68/0001-translate-script-whole-file-writes/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.js.map +1 -1
- package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js.map +1 -1
- package/src/open-api/ts-client/generator.d.ts +1 -1
- package/src/open-api/ts-client/generator.js.map +1 -1
- package/src/open-api/ts-hooks/generator.d.ts +1 -1
- package/src/open-api/ts-hooks/generator.js.map +1 -1
- package/src/open-api/ts-hooks/generator.spec.tsx +6 -6
- package/src/open-api/ts-metadata/generator.d.ts +1 -1
- package/src/open-api/ts-metadata/generator.js.map +1 -1
- package/src/open-api/utils/codegen-data/languages.d.ts +1 -1
- package/src/open-api/utils/codegen-data/languages.js.map +1 -1
- package/src/open-api/utils/codegen-data.d.ts +2 -2
- package/src/open-api/utils/codegen-data.js.map +1 -1
- package/src/open-api/utils/normalise.d.ts +1 -1
- package/src/open-api/utils/normalise.js.map +1 -1
- package/src/open-api/utils/parse.d.ts +1 -1
- package/src/open-api/utils/parse.js.map +1 -1
- package/src/open-api/utils/parser.d.ts +2 -2
- package/src/open-api/utils/parser.js.map +1 -1
- package/src/open-api/utils/refs.d.ts +1 -1
- package/src/open-api/utils/refs.js.map +1 -1
- package/src/preset/generator.d.ts +3 -3
- package/src/preset/generator.js.map +1 -1
- package/src/preset/schema.d.js.map +1 -1
- package/src/preset/schema.d.ts +3 -3
- package/src/py/agent/a2a-connection/generator.d.ts +3 -3
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/a2a-connection/schema.d.js.map +1 -1
- package/src/py/agent/a2a-connection/schema.d.ts +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +3 -3
- package/src/py/agent/gateway-connection/generator.js.map +1 -1
- package/src/py/agent/gateway-connection/schema.d.js.map +1 -1
- package/src/py/agent/gateway-connection/schema.d.ts +1 -1
- package/src/py/agent/generator.d.ts +3 -3
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/generator.d.ts +3 -3
- package/src/py/agent/mcp-connection/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/schema.d.js.map +1 -1
- package/src/py/agent/mcp-connection/schema.d.ts +1 -1
- package/src/py/agent/react-connection/generator.d.ts +12 -12
- package/src/py/agent/react-connection/generator.js.map +1 -1
- package/src/py/agent/react-connection/local-dev.d.ts +1 -1
- package/src/py/agent/react-connection/local-dev.js.map +1 -1
- package/src/py/agent/react-connection/schema.d.js.map +1 -1
- package/src/py/agent/react-connection/schema.d.ts +1 -1
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +1 -1
- package/src/py/api/generator.d.ts +1 -1
- package/src/py/api/generator.js.map +1 -1
- package/src/py/api/schema.d.js.map +1 -1
- package/src/py/api/schema.d.ts +1 -1
- package/src/py/dynamodb/agent-connection/generator.d.ts +1 -1
- package/src/py/dynamodb/agent-connection/generator.js.map +1 -1
- package/src/py/dynamodb/agent-connection/schema.d.js.map +1 -1
- package/src/py/dynamodb/agent-connection/schema.d.ts +1 -1
- package/src/py/dynamodb/fast-api-connection/generator.d.ts +1 -1
- package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -1
- package/src/py/dynamodb/generator.d.ts +4 -4
- package/src/py/dynamodb/generator.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/generator.d.ts +1 -1
- package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/py/dynamodb/mcp-server-connection/schema.d.ts +1 -1
- package/src/py/dynamodb/schema.d.js.map +1 -1
- package/src/py/dynamodb/schema.d.ts +1 -1
- package/src/py/fast-api/generator.d.ts +3 -3
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/fast-api/react/generator.d.ts +3 -3
- package/src/py/fast-api/react/generator.js.map +1 -1
- package/src/py/fast-api/react/open-api.js.map +1 -1
- package/src/py/fast-api/schema.d.js.map +1 -1
- package/src/py/fast-api/schema.d.ts +1 -1
- package/src/py/lambda-function/files/handler/__lambdaFunctionSnakeCase__.py.template +1 -1
- package/src/py/lambda-function/generator.d.ts +10 -4
- package/src/py/lambda-function/generator.js +8 -1
- package/src/py/lambda-function/generator.js.map +1 -1
- package/src/py/lambda-function/schema.d.js.map +1 -1
- package/src/py/lambda-function/schema.d.ts +2 -2
- package/src/py/lambda-function/schema.json +1 -1
- package/src/py/mcp-server/generator.d.ts +3 -3
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/mcp-server/schema.d.js.map +1 -1
- package/src/py/mcp-server/schema.d.ts +1 -1
- package/src/py/project/generator.d.ts +2 -2
- package/src/py/project/generator.js.map +1 -1
- package/src/py/project/schema.json +1 -0
- package/src/py/rdb/agent-connection/generator.d.ts +1 -1
- package/src/py/rdb/agent-connection/generator.js.map +1 -1
- package/src/py/rdb/agent-connection/schema.d.js.map +1 -1
- package/src/py/rdb/agent-connection/schema.d.ts +1 -1
- package/src/py/rdb/fast-api-connection/generator.d.ts +1 -1
- package/src/py/rdb/fast-api-connection/generator.js.map +1 -1
- package/src/py/rdb/generator.d.ts +3 -3
- package/src/py/rdb/generator.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/generator.d.ts +1 -1
- package/src/py/rdb/mcp-server-connection/generator.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/py/rdb/mcp-server-connection/schema.d.ts +1 -1
- package/src/sdk/agentcore-gateway.d.ts +1 -1
- package/src/sdk/agentcore-gateway.js.map +1 -1
- package/src/sdk/agentcore-harness.d.ts +1 -1
- package/src/sdk/agentcore-harness.js.map +1 -1
- package/src/sdk/connection.d.ts +1 -1
- package/src/sdk/connection.js.map +1 -1
- package/src/sdk/license.d.ts +3 -3
- package/src/sdk/license.js.map +1 -1
- package/src/sdk/open-api.d.ts +3 -3
- package/src/sdk/open-api.js.map +1 -1
- package/src/sdk/py.d.ts +7 -7
- package/src/sdk/py.js.map +1 -1
- package/src/sdk/smithy.d.ts +1 -1
- package/src/sdk/smithy.js.map +1 -1
- package/src/sdk/terraform.d.ts +1 -1
- package/src/sdk/terraform.js.map +1 -1
- package/src/sdk/ts.d.ts +18 -18
- package/src/sdk/ts.js.map +1 -1
- package/src/sdk/utils/ast.d.ts +1 -1
- package/src/sdk/utils/ast.js.map +1 -1
- package/src/sdk/utils/format.d.ts +1 -1
- package/src/sdk/utils/format.js.map +1 -1
- package/src/sdk/utils/test.d.ts +1 -1
- package/src/sdk/utils/test.js.map +1 -1
- package/src/smithy/project/generator.d.ts +4 -4
- package/src/smithy/project/generator.js.map +1 -1
- package/src/smithy/react-connection/generator.d.ts +3 -3
- package/src/smithy/react-connection/generator.js.map +1 -1
- package/src/smithy/ts/api/generator.d.ts +3 -3
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/smithy/ts/api/schema.d.js.map +1 -1
- package/src/smithy/ts/api/schema.d.ts +1 -1
- package/src/terraform/project/generator.d.ts +5 -5
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/generator.d.ts +3 -3
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/backend/schema.d.js.map +1 -1
- package/src/trpc/backend/schema.d.ts +1 -1
- package/src/trpc/react/generator.d.ts +3 -3
- package/src/trpc/react/generator.js.map +1 -1
- package/src/ts/agent/a2a-connection/generator.d.ts +3 -3
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/a2a-connection/schema.d.js.map +1 -1
- package/src/ts/agent/a2a-connection/schema.d.ts +1 -1
- package/src/ts/agent/gateway-connection/generator.d.ts +3 -3
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/gateway-connection/schema.d.js.map +1 -1
- package/src/ts/agent/gateway-connection/schema.d.ts +1 -1
- package/src/ts/agent/generator.d.ts +3 -3
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/generator.d.ts +3 -3
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/schema.d.js.map +1 -1
- package/src/ts/agent/mcp-connection/schema.d.ts +1 -1
- package/src/ts/agent/react-connection/generator.d.ts +11 -11
- package/src/ts/agent/react-connection/generator.js.map +1 -1
- package/src/ts/agent/react-connection/local-dev.d.ts +1 -1
- package/src/ts/agent/react-connection/local-dev.js.map +1 -1
- package/src/ts/agent/react-connection/schema.d.js.map +1 -1
- package/src/ts/agent/react-connection/schema.d.ts +1 -1
- package/src/ts/agent/schema.d.js.map +1 -1
- package/src/ts/agent/schema.d.ts +1 -1
- package/src/ts/api/generator.d.ts +1 -1
- package/src/ts/api/generator.js.map +1 -1
- package/src/ts/api/schema.d.js.map +1 -1
- package/src/ts/api/schema.d.ts +1 -1
- package/src/ts/astro-docs/generator.d.ts +3 -3
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/dcr-proxy/generator.d.ts +5 -5
- package/src/ts/dcr-proxy/generator.js.map +1 -1
- package/src/ts/dcr-proxy/schema.d.js.map +1 -1
- package/src/ts/dcr-proxy/schema.d.ts +1 -1
- package/src/ts/docs/generator.d.ts +1 -1
- package/src/ts/docs/generator.js.map +1 -1
- package/src/ts/dynamodb/agent-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/agent-connection/schema.d.js.map +1 -1
- package/src/ts/dynamodb/agent-connection/schema.d.ts +1 -1
- package/src/ts/dynamodb/generator.d.ts +5 -5
- package/src/ts/dynamodb/generator.js +1 -0
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +1 -1
- package/src/ts/dynamodb/schema.d.js.map +1 -1
- package/src/ts/dynamodb/schema.d.ts +1 -1
- package/src/ts/dynamodb/smithy-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
- package/src/ts/dynamodb/trpc-connection/generator.d.ts +1 -1
- package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
- package/src/ts/lambda-function/generator.d.ts +5 -5
- package/src/ts/lambda-function/generator.js.map +1 -1
- package/src/ts/lambda-function/schema.d.js.map +1 -1
- package/src/ts/lambda-function/schema.d.ts +1 -1
- package/src/ts/lib/biome.d.ts +1 -1
- package/src/ts/lib/biome.js.map +1 -1
- package/src/ts/lib/generator.d.ts +3 -3
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/ts-project-utils.d.ts +3 -3
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/vitest.d.ts +2 -2
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/ts/mcp-server/generator.d.ts +3 -3
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.d.js.map +1 -1
- package/src/ts/mcp-server/schema.d.ts +1 -1
- package/src/ts/nx-generator/generator.d.ts +2 -2
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-migration/generator.d.ts +3 -3
- package/src/ts/nx-migration/generator.js.map +1 -1
- package/src/ts/nx-plugin/generator.d.ts +3 -3
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/nx-plugin/utils.d.ts +1 -1
- package/src/ts/nx-plugin/utils.js.map +1 -1
- package/src/ts/rdb/agent-connection/generator.d.ts +1 -1
- package/src/ts/rdb/agent-connection/generator.js.map +1 -1
- package/src/ts/rdb/agent-connection/schema.d.js.map +1 -1
- package/src/ts/rdb/agent-connection/schema.d.ts +1 -1
- package/src/ts/rdb/generator.d.ts +4 -4
- package/src/ts/rdb/generator.js +1 -0
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/generator.d.ts +1 -1
- package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/schema.d.js.map +1 -1
- package/src/ts/rdb/mcp-server-connection/schema.d.ts +1 -1
- package/src/ts/rdb/schema.d.js.map +1 -1
- package/src/ts/rdb/schema.d.ts +1 -1
- package/src/ts/rdb/smithy-connection/generator.d.ts +1 -1
- package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
- package/src/ts/rdb/trpc-connection/generator.d.ts +1 -1
- package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
- package/src/ts/react-website/agui/generator.d.ts +2 -2
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/ts/react-website/app/generator.d.ts +3 -3
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/app/schema.d.js.map +1 -1
- package/src/ts/react-website/app/schema.d.ts +2 -2
- package/src/ts/react-website/cognito-auth/generator.d.ts +5 -5
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/schema.d.js.map +1 -1
- package/src/ts/react-website/cognito-auth/schema.d.ts +1 -1
- package/src/ts/react-website/cognito-auth/utils.js.map +1 -1
- package/src/ts/react-website/runtime-config/generator.d.ts +1 -1
- package/src/ts/react-website/runtime-config/generator.js.map +1 -1
- package/src/ts/sync/generator.d.ts +1 -1
- package/src/ts/sync/generator.js.map +1 -1
- package/src/ts/website/app/generator.d.ts +1 -1
- package/src/ts/website/app/generator.js.map +1 -1
- package/src/ts/website/app/schema.d.js.map +1 -1
- package/src/ts/website/app/schema.d.ts +2 -2
- package/src/ts/website/auth/generator.d.ts +1 -1
- package/src/ts/website/auth/generator.js.map +1 -1
- package/src/ts/website/auth/schema.d.js.map +1 -1
- package/src/ts/website/auth/schema.d.ts +1 -1
- package/src/utils/add-dependencies.d.ts +1 -1
- package/src/utils/add-dependencies.js.map +1 -1
- package/src/utils/agent-chat/agent-chat.js.map +1 -1
- package/src/utils/agent-connection/agent-connection.d.ts +2 -2
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +4 -4
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/api-constructs/api-constructs.d.ts +3 -3
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/open-api-metadata.d.ts +1 -1
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/ast/website.js.map +1 -1
- package/src/utils/ast.js +6 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/bundle/bundle.d.ts +1 -1
- package/src/utils/bundle/bundle.js.map +1 -1
- package/src/utils/commands.d.ts +1 -1
- package/src/utils/commands.js.map +1 -1
- package/src/utils/config/index.d.ts +6 -6
- package/src/utils/config/index.js.map +1 -1
- package/src/utils/config/utils.d.ts +1 -1
- package/src/utils/config/utils.js.map +1 -1
- package/src/utils/connection/open-api/react.d.ts +1 -1
- package/src/utils/connection/open-api/react.js.map +1 -1
- package/src/utils/containers.js.map +1 -1
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.d.ts +1 -1
- package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -1
- package/src/utils/declared-dependencies.d.ts +1 -1
- package/src/utils/declared-dependencies.js.map +1 -1
- package/src/utils/dependencies.js.map +1 -1
- package/src/utils/docker.d.ts +1 -1
- package/src/utils/docker.js.map +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
- package/src/utils/format.js.map +1 -1
- package/src/utils/fs.d.ts +1 -1
- package/src/utils/fs.js.map +1 -1
- package/src/utils/function-constructs/function-constructs.d.ts +1 -1
- package/src/utils/function-constructs/function-constructs.js.map +1 -1
- package/src/utils/iac.d.ts +2 -2
- package/src/utils/iac.js.map +1 -1
- package/src/utils/identity-constructs/identity-constructs.d.ts +2 -2
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/init.d.ts +3 -3
- package/src/utils/init.js.map +1 -1
- package/src/utils/install.d.ts +1 -1
- package/src/utils/install.js.map +1 -1
- package/src/utils/mcp.js.map +1 -1
- package/src/utils/metrics.d.ts +1 -1
- package/src/utils/metrics.js.map +1 -1
- package/src/utils/migration-manifest.d.ts +1 -1
- package/src/utils/migration-manifest.js.map +1 -1
- package/src/utils/nx.d.ts +3 -3
- package/src/utils/nx.js.map +1 -1
- package/src/utils/paths.js.map +1 -1
- package/src/utils/pkg-manager.d.ts +1 -1
- package/src/utils/pkg-manager.js.map +1 -1
- package/src/utils/pnpm-workspace.js.map +1 -1
- package/src/utils/project-package-json.js.map +1 -1
- package/src/utils/py.d.ts +2 -2
- package/src/utils/py.js.map +1 -1
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +2 -2
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/shared-constructs.d.ts +3 -3
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/shared-dynamodb-scripts.d.ts +1 -1
- package/src/utils/shared-dynamodb-scripts.js.map +1 -1
- package/src/utils/shared-infra-config.js.map +1 -1
- package/src/utils/shared-infra-scripts.d.ts +2 -2
- package/src/utils/shared-infra-scripts.js.map +1 -1
- package/src/utils/shared-rdb-scripts.d.ts +1 -1
- package/src/utils/shared-rdb-scripts.js.map +1 -1
- package/src/utils/shared-scripts.js.map +1 -1
- package/src/utils/shared-shadcn.d.ts +1 -1
- package/src/utils/shared-shadcn.js.map +1 -1
- package/src/utils/smithy.js.map +1 -1
- package/src/utils/test.js.map +1 -1
- package/src/utils/version-upgrade-migration/migration.js.map +1 -1
- package/src/utils/version-upgrade-migration/nx-package-updates.js.map +1 -1
- package/src/utils/version-upgrade-migration/owned-dependencies.d.ts +1 -1
- package/src/utils/version-upgrade-migration/owned-dependencies.js.map +1 -1
- package/src/utils/version-upgrade-migration/register.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-embedded-versions.d.ts +1 -1
- package/src/utils/version-upgrade-migration/sync-embedded-versions.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-metrics-version.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js.map +1 -1
- package/src/utils/website-constructs/website-constructs.d.ts +2 -2
- package/src/utils/website-constructs/website-constructs.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/guide-render.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Shared rendering helpers used by the unified/remark-mdx guide pipeline.\n * Kept in their own module so `generator-info.ts` (which still exports\n * `renderGeneratorInfo` for list-generators) and the pipeline both render\n * identical command strings without either re-implementing the other.\n */\nimport { buildPackageManagerExecCommand } from '../utils/commands';\n\n/**\n * Build an nx command, optionally prefixed by the package manager's exec\n * wrapper. A bare `nx <command>` is returned when no package manager is\n * passed, matching the legacy regex-based post-processor's behaviour.\n */\nexport const buildNxCommand = (command: string, pm?: string) =>\n pm ? buildPackageManagerExecCommand(pm, `nx ${command}`) : `nx ${command}`;\n\n/**\n * Serialise a generator schema's `properties` map to the bullet list\n * `<GeneratorParameters>` expands to.\n */\nexport const renderSchema = (schema: {\n properties?: Record<string, unknown>;\n required?: string[];\n}): string => {\n const required = new Set(schema.required ?? []);\n return Object.entries(schema.properties ?? {})\n .map(([parameter, raw]) => {\n const p = raw as {\n type?: string;\n enum?: unknown[];\n description?: string;\n };\n const enumPart = p.enum ? ` [options: ${p.enum.join(', ')}]` : '';\n const requiredPart = required.has(parameter) ? ` (required)` : '';\n return `- ${parameter} [type: ${p.type}]${enumPart}${requiredPart} ${p.description}`;\n })\n .join('\\n');\n};\n\n/**\n * Build the fenced-code invocation that `<RunGenerator>` expands to.\n */\nexport const renderGeneratorCommand = (\n generatorId: string,\n schema: { properties?: Record<string, unknown>; required?: string[] },\n packageManager?: string,\n): string => {\n const required = new Set(schema.required ?? []);\n const args = Object.keys(schema.properties ?? {})\n .filter((k) => required.has(k))\n .map((k) => `--${k}=<${k}>`)\n .join(' ');\n return `\\`\\`\\`bash\\n${buildNxCommand(\n `g @aws/nx-plugin:${generatorId} --no-interactive ${args}`,\n packageManager,\n )}\\n\\`\\`\\``;\n};\n"],"names":["buildPackageManagerExecCommand","buildNxCommand","command","pm","renderSchema","schema","required","Set","Object","entries","properties","map","parameter","raw","p","enumPart","enum","join","requiredPart","has","type","description","renderGeneratorCommand","generatorId","packageManager","args","keys","filter","k"],"mappings":"AAAA;;;CAGC,GAED;;;;;CAKC,GACD,SAASA,8BAA8B,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/guide-render.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Shared rendering helpers used by the unified/remark-mdx guide pipeline.\n * Kept in their own module so `generator-info.ts` (which still exports\n * `renderGeneratorInfo` for list-generators) and the pipeline both render\n * identical command strings without either re-implementing the other.\n */\nimport { buildPackageManagerExecCommand } from '../utils/commands.js';\n\n/**\n * Build an nx command, optionally prefixed by the package manager's exec\n * wrapper. A bare `nx <command>` is returned when no package manager is\n * passed, matching the legacy regex-based post-processor's behaviour.\n */\nexport const buildNxCommand = (command: string, pm?: string) =>\n pm ? buildPackageManagerExecCommand(pm, `nx ${command}`) : `nx ${command}`;\n\n/**\n * Serialise a generator schema's `properties` map to the bullet list\n * `<GeneratorParameters>` expands to.\n */\nexport const renderSchema = (schema: {\n properties?: Record<string, unknown>;\n required?: string[];\n}): string => {\n const required = new Set(schema.required ?? []);\n return Object.entries(schema.properties ?? {})\n .map(([parameter, raw]) => {\n const p = raw as {\n type?: string;\n enum?: unknown[];\n description?: string;\n };\n const enumPart = p.enum ? ` [options: ${p.enum.join(', ')}]` : '';\n const requiredPart = required.has(parameter) ? ` (required)` : '';\n return `- ${parameter} [type: ${p.type}]${enumPart}${requiredPart} ${p.description}`;\n })\n .join('\\n');\n};\n\n/**\n * Build the fenced-code invocation that `<RunGenerator>` expands to.\n */\nexport const renderGeneratorCommand = (\n generatorId: string,\n schema: { properties?: Record<string, unknown>; required?: string[] },\n packageManager?: string,\n): string => {\n const required = new Set(schema.required ?? []);\n const args = Object.keys(schema.properties ?? {})\n .filter((k) => required.has(k))\n .map((k) => `--${k}=<${k}>`)\n .join(' ');\n return `\\`\\`\\`bash\\n${buildNxCommand(\n `g @aws/nx-plugin:${generatorId} --no-interactive ${args}`,\n packageManager,\n )}\\n\\`\\`\\``;\n};\n"],"names":["buildPackageManagerExecCommand","buildNxCommand","command","pm","renderSchema","schema","required","Set","Object","entries","properties","map","parameter","raw","p","enumPart","enum","join","requiredPart","has","type","description","renderGeneratorCommand","generatorId","packageManager","args","keys","filter","k"],"mappings":"AAAA;;;CAGC,GAED;;;;;CAKC,GACD,SAASA,8BAA8B,QAAQ,uBAAuB;AAEtE;;;;CAIC,GACD,OAAO,MAAMC,iBAAiB,CAACC,SAAiBC,KAC9CA,KAAKH,+BAA+BG,IAAI,CAAC,GAAG,EAAED,SAAS,IAAI,CAAC,GAAG,EAAEA,SAAS,CAAC;AAE7E;;;CAGC,GACD,OAAO,MAAME,eAAe,CAACC;IAI3B,MAAMC,WAAW,IAAIC,IAAIF,OAAOC,QAAQ,IAAI,EAAE;IAC9C,OAAOE,OAAOC,OAAO,CAACJ,OAAOK,UAAU,IAAI,CAAC,GACzCC,GAAG,CAAC,CAAC,CAACC,WAAWC,IAAI;QACpB,MAAMC,IAAID;QAKV,MAAME,WAAWD,EAAEE,IAAI,GAAG,CAAC,WAAW,EAAEF,EAAEE,IAAI,CAACC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG;QAC/D,MAAMC,eAAeZ,SAASa,GAAG,CAACP,aAAa,CAAC,WAAW,CAAC,GAAG;QAC/D,OAAO,CAAC,EAAE,EAAEA,UAAU,QAAQ,EAAEE,EAAEM,IAAI,CAAC,CAAC,EAAEL,WAAWG,aAAa,CAAC,EAAEJ,EAAEO,WAAW,EAAE;IACtF,GACCJ,IAAI,CAAC;AACV,EAAE;AAEF;;CAEC,GACD,OAAO,MAAMK,yBAAyB,CACpCC,aACAlB,QACAmB;IAEA,MAAMlB,WAAW,IAAIC,IAAIF,OAAOC,QAAQ,IAAI,EAAE;IAC9C,MAAMmB,OAAOjB,OAAOkB,IAAI,CAACrB,OAAOK,UAAU,IAAI,CAAC,GAC5CiB,MAAM,CAAC,CAACC,IAAMtB,SAASa,GAAG,CAACS,IAC3BjB,GAAG,CAAC,CAACiB,IAAM,CAAC,EAAE,EAAEA,EAAE,EAAE,EAAEA,EAAE,CAAC,CAAC,EAC1BX,IAAI,CAAC;IACR,OAAO,CAAC,YAAY,EAAEhB,eACpB,CAAC,iBAAiB,EAAEsB,YAAY,kBAAkB,EAAEE,MAAM,EAC1DD,gBACA,QAAQ,CAAC;AACb,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/index.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createServer } from './server';\n\nexport const startMcpServer = async () => {\n const transport = new StdioServerTransport();\n await createServer().connect(transport);\n console.error('Nx Plugin for AWS MCP Server listening on STDIO');\n};\n"],"names":["StdioServerTransport","createServer","startMcpServer","transport","connect","console","error"],"mappings":"AAAA;;;CAGC,GACD,SAASA,oBAAoB,QAAQ,4CAA4C;AACjF,SAASC,YAAY,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/index.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createServer } from './server.js';\n\nexport const startMcpServer = async () => {\n const transport = new StdioServerTransport();\n await createServer().connect(transport);\n console.error('Nx Plugin for AWS MCP Server listening on STDIO');\n};\n"],"names":["StdioServerTransport","createServer","startMcpServer","transport","connect","console","error"],"mappings":"AAAA;;;CAGC,GACD,SAASA,oBAAoB,QAAQ,4CAA4C;AACjF,SAASC,YAAY,QAAQ,cAAc;AAE3C,OAAO,MAAMC,iBAAiB;IAC5B,MAAMC,YAAY,IAAIH;IACtB,MAAMC,eAAeG,OAAO,CAACD;IAC7BE,QAAQC,KAAK,CAAC;AAChB,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/mdx-ast.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport yaml from 'js-yaml';\nimport type { Root, RootContent, Yaml } from 'mdast';\nimport type {\n MdxJsxAttribute,\n MdxJsxAttributeValueExpression,\n MdxJsxFlowElement,\n MdxJsxTextElement,\n} from 'mdast-util-mdx-jsx';\nimport { parseWhenExpression } from './option-filter';\n\nexport type JsxParent = Root | MdxJsxFlowElement | MdxJsxTextElement;\nexport type JsxElement = MdxJsxFlowElement | MdxJsxTextElement;\n\nexport const isJsxElement = (node: RootContent): node is JsxElement =>\n node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement';\n\nconst findAttr = (\n node: JsxElement,\n name: string,\n): MdxJsxAttribute | undefined =>\n node.attributes.find(\n (a): a is MdxJsxAttribute =>\n a.type === 'mdxJsxAttribute' && a.name === name,\n );\n\nexport const readStringAttr = (\n node: JsxElement,\n name: string,\n): string | undefined => {\n const attr = findAttr(node, name);\n return typeof attr?.value === 'string' ? attr.value : undefined;\n};\n\nexport const readExpressionAttr = (\n node: JsxElement,\n name: string,\n): string | undefined => {\n const attr = findAttr(node, name);\n if (attr && typeof attr.value === 'object' && attr.value !== null) {\n return (attr.value as MdxJsxAttributeValueExpression).value;\n }\n return undefined;\n};\n\nexport const readEstreeAttr = (\n node: JsxElement,\n name: string,\n): unknown | undefined => {\n const attr = findAttr(node, name);\n if (attr && typeof attr.value === 'object' && attr.value !== null) {\n return (attr.value as MdxJsxAttributeValueExpression).data?.estree;\n }\n return undefined;\n};\n\nexport const hasBareAttr = (node: JsxElement, name: string): boolean =>\n node.attributes.some((a) => a.type === 'mdxJsxAttribute' && a.name === name);\n\n/** Walk every JSX element in the subtree, pre-order. */\nexport const walkJsx = (\n parent: JsxParent,\n visit: (node: JsxElement, parent: JsxParent) => void,\n): void => {\n const children = parent.children as RootContent[];\n for (const child of children) {\n if (!isJsxElement(child)) continue;\n visit(child, parent);\n walkJsx(child, visit);\n }\n};\n\n/**\n * Every option key referenced by `<OptionFilter when>` or\n * `<TabItem _filter>` in the subtree. Malformed predicates are skipped.\n */\nexport const collectFilterableKeysFromJsx = (tree: Root): Set<string> => {\n const keys = new Set<string>();\n walkJsx(tree, (node) => {\n const attrName =\n node.name === 'OptionFilter'\n ? 'when'\n : node.name === 'TabItem'\n ? '_filter'\n : undefined;\n if (!attrName) return;\n const estree = readEstreeAttr(node, attrName);\n if (!estree) return;\n try {\n for (const key of Object.keys(parseWhenExpression(estree as never))) {\n keys.add(key);\n }\n } catch {\n // Malformed / partially-typed — skip.\n }\n });\n return keys;\n};\n\n/**\n * Parse the leading `---…---` YAML frontmatter from an mdast Root produced\n * with `remark-frontmatter`. Returns `{ data, bodyOffset }` where\n * `bodyOffset` is the character index after the closing `---` — slice the\n * original source from it to get the body without re-stringifying the tree.\n */\nexport const extractFrontmatter = (\n tree: Root,\n): { data: Record<string, unknown>; bodyOffset: number } => {\n const node = tree.children.find((c): c is Yaml => c.type === 'yaml');\n if (!node) return { data: {}, bodyOffset: 0 };\n let parsed: unknown;\n try {\n parsed = yaml.load(node.value);\n } catch {\n return { data: {}, bodyOffset: node.position?.end.offset ?? 0 };\n }\n const data =\n parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n return { data, bodyOffset: node.position?.end.offset ?? 0 };\n};\n"],"names":["yaml","parseWhenExpression","isJsxElement","node","type","findAttr","name","attributes","find","a","readStringAttr","attr","value","undefined","readExpressionAttr","readEstreeAttr","data","estree","hasBareAttr","some","walkJsx","parent","visit","children","child","collectFilterableKeysFromJsx","tree","keys","Set","attrName","key","Object","add","extractFrontmatter","c","bodyOffset","parsed","load","position","end","offset","Array","isArray"],"mappings":"AAAA;;;CAGC,GAED,OAAOA,UAAU,UAAU;AAQ3B,SAASC,mBAAmB,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/mdx-ast.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport yaml from 'js-yaml';\nimport type { Root, RootContent, Yaml } from 'mdast';\nimport type {\n MdxJsxAttribute,\n MdxJsxAttributeValueExpression,\n MdxJsxFlowElement,\n MdxJsxTextElement,\n} from 'mdast-util-mdx-jsx';\nimport { parseWhenExpression } from './option-filter.js';\n\nexport type JsxParent = Root | MdxJsxFlowElement | MdxJsxTextElement;\nexport type JsxElement = MdxJsxFlowElement | MdxJsxTextElement;\n\nexport const isJsxElement = (node: RootContent): node is JsxElement =>\n node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement';\n\nconst findAttr = (\n node: JsxElement,\n name: string,\n): MdxJsxAttribute | undefined =>\n node.attributes.find(\n (a): a is MdxJsxAttribute =>\n a.type === 'mdxJsxAttribute' && a.name === name,\n );\n\nexport const readStringAttr = (\n node: JsxElement,\n name: string,\n): string | undefined => {\n const attr = findAttr(node, name);\n return typeof attr?.value === 'string' ? attr.value : undefined;\n};\n\nexport const readExpressionAttr = (\n node: JsxElement,\n name: string,\n): string | undefined => {\n const attr = findAttr(node, name);\n if (attr && typeof attr.value === 'object' && attr.value !== null) {\n return (attr.value as MdxJsxAttributeValueExpression).value;\n }\n return undefined;\n};\n\nexport const readEstreeAttr = (\n node: JsxElement,\n name: string,\n): unknown | undefined => {\n const attr = findAttr(node, name);\n if (attr && typeof attr.value === 'object' && attr.value !== null) {\n return (attr.value as MdxJsxAttributeValueExpression).data?.estree;\n }\n return undefined;\n};\n\nexport const hasBareAttr = (node: JsxElement, name: string): boolean =>\n node.attributes.some((a) => a.type === 'mdxJsxAttribute' && a.name === name);\n\n/** Walk every JSX element in the subtree, pre-order. */\nexport const walkJsx = (\n parent: JsxParent,\n visit: (node: JsxElement, parent: JsxParent) => void,\n): void => {\n const children = parent.children as RootContent[];\n for (const child of children) {\n if (!isJsxElement(child)) continue;\n visit(child, parent);\n walkJsx(child, visit);\n }\n};\n\n/**\n * Every option key referenced by `<OptionFilter when>` or\n * `<TabItem _filter>` in the subtree. Malformed predicates are skipped.\n */\nexport const collectFilterableKeysFromJsx = (tree: Root): Set<string> => {\n const keys = new Set<string>();\n walkJsx(tree, (node) => {\n const attrName =\n node.name === 'OptionFilter'\n ? 'when'\n : node.name === 'TabItem'\n ? '_filter'\n : undefined;\n if (!attrName) return;\n const estree = readEstreeAttr(node, attrName);\n if (!estree) return;\n try {\n for (const key of Object.keys(parseWhenExpression(estree as never))) {\n keys.add(key);\n }\n } catch {\n // Malformed / partially-typed — skip.\n }\n });\n return keys;\n};\n\n/**\n * Parse the leading `---…---` YAML frontmatter from an mdast Root produced\n * with `remark-frontmatter`. Returns `{ data, bodyOffset }` where\n * `bodyOffset` is the character index after the closing `---` — slice the\n * original source from it to get the body without re-stringifying the tree.\n */\nexport const extractFrontmatter = (\n tree: Root,\n): { data: Record<string, unknown>; bodyOffset: number } => {\n const node = tree.children.find((c): c is Yaml => c.type === 'yaml');\n if (!node) return { data: {}, bodyOffset: 0 };\n let parsed: unknown;\n try {\n parsed = yaml.load(node.value);\n } catch {\n return { data: {}, bodyOffset: node.position?.end.offset ?? 0 };\n }\n const data =\n parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n return { data, bodyOffset: node.position?.end.offset ?? 0 };\n};\n"],"names":["yaml","parseWhenExpression","isJsxElement","node","type","findAttr","name","attributes","find","a","readStringAttr","attr","value","undefined","readExpressionAttr","readEstreeAttr","data","estree","hasBareAttr","some","walkJsx","parent","visit","children","child","collectFilterableKeysFromJsx","tree","keys","Set","attrName","key","Object","add","extractFrontmatter","c","bodyOffset","parsed","load","position","end","offset","Array","isArray"],"mappings":"AAAA;;;CAGC,GAED,OAAOA,UAAU,UAAU;AAQ3B,SAASC,mBAAmB,QAAQ,qBAAqB;AAKzD,OAAO,MAAMC,eAAe,CAACC,OAC3BA,KAAKC,IAAI,KAAK,uBAAuBD,KAAKC,IAAI,KAAK,oBAAoB;AAEzE,MAAMC,WAAW,CACfF,MACAG,OAEAH,KAAKI,UAAU,CAACC,IAAI,CAClB,CAACC,IACCA,EAAEL,IAAI,KAAK,qBAAqBK,EAAEH,IAAI,KAAKA;AAGjD,OAAO,MAAMI,iBAAiB,CAC5BP,MACAG;IAEA,MAAMK,OAAON,SAASF,MAAMG;IAC5B,OAAO,OAAOK,MAAMC,UAAU,WAAWD,KAAKC,KAAK,GAAGC;AACxD,EAAE;AAEF,OAAO,MAAMC,qBAAqB,CAChCX,MACAG;IAEA,MAAMK,OAAON,SAASF,MAAMG;IAC5B,IAAIK,QAAQ,OAAOA,KAAKC,KAAK,KAAK,YAAYD,KAAKC,KAAK,KAAK,MAAM;QACjE,OAAO,AAACD,KAAKC,KAAK,CAAoCA,KAAK;IAC7D;IACA,OAAOC;AACT,EAAE;AAEF,OAAO,MAAME,iBAAiB,CAC5BZ,MACAG;IAEA,MAAMK,OAAON,SAASF,MAAMG;IAC5B,IAAIK,QAAQ,OAAOA,KAAKC,KAAK,KAAK,YAAYD,KAAKC,KAAK,KAAK,MAAM;QACjE,OAAO,AAACD,KAAKC,KAAK,CAAoCI,IAAI,EAAEC;IAC9D;IACA,OAAOJ;AACT,EAAE;AAEF,OAAO,MAAMK,cAAc,CAACf,MAAkBG,OAC5CH,KAAKI,UAAU,CAACY,IAAI,CAAC,CAACV,IAAMA,EAAEL,IAAI,KAAK,qBAAqBK,EAAEH,IAAI,KAAKA,MAAM;AAE/E,sDAAsD,GACtD,OAAO,MAAMc,UAAU,CACrBC,QACAC;IAEA,MAAMC,WAAWF,OAAOE,QAAQ;IAChC,KAAK,MAAMC,SAASD,SAAU;QAC5B,IAAI,CAACrB,aAAasB,QAAQ;QAC1BF,MAAME,OAAOH;QACbD,QAAQI,OAAOF;IACjB;AACF,EAAE;AAEF;;;CAGC,GACD,OAAO,MAAMG,+BAA+B,CAACC;IAC3C,MAAMC,OAAO,IAAIC;IACjBR,QAAQM,MAAM,CAACvB;QACb,MAAM0B,WACJ1B,KAAKG,IAAI,KAAK,iBACV,SACAH,KAAKG,IAAI,KAAK,YACZ,YACAO;QACR,IAAI,CAACgB,UAAU;QACf,MAAMZ,SAASF,eAAeZ,MAAM0B;QACpC,IAAI,CAACZ,QAAQ;QACb,IAAI;YACF,KAAK,MAAMa,OAAOC,OAAOJ,IAAI,CAAC1B,oBAAoBgB,SAAmB;gBACnEU,KAAKK,GAAG,CAACF;YACX;QACF,EAAE,OAAM;QACN,sCAAsC;QACxC;IACF;IACA,OAAOH;AACT,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAMM,qBAAqB,CAChCP;IAEA,MAAMvB,OAAOuB,KAAKH,QAAQ,CAACf,IAAI,CAAC,CAAC0B,IAAiBA,EAAE9B,IAAI,KAAK;IAC7D,IAAI,CAACD,MAAM,OAAO;QAAEa,MAAM,CAAC;QAAGmB,YAAY;IAAE;IAC5C,IAAIC;IACJ,IAAI;QACFA,SAASpC,KAAKqC,IAAI,CAAClC,KAAKS,KAAK;IAC/B,EAAE,OAAM;QACN,OAAO;YAAEI,MAAM,CAAC;YAAGmB,YAAYhC,KAAKmC,QAAQ,EAAEC,IAAIC,UAAU;QAAE;IAChE;IACA,MAAMxB,OACJoB,UAAU,OAAOA,WAAW,YAAY,CAACK,MAAMC,OAAO,CAACN,UAClDA,SACD,CAAC;IACP,OAAO;QAAEpB;QAAMmB,YAAYhC,KAAKmC,QAAQ,EAAEC,IAAIC,UAAU;IAAE;AAC5D,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/server.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport PackageJson from '../../package.json' with { type: 'json' };\nimport { listGenerators } from '../utils/nx';\nimport { addToExistingProjectTool } from './tools/add-to-existing-project';\nimport { addCreateWorkspaceCommandTool } from './tools/create-workspace-command';\nimport {\n addGeneralGuidanceTool,\n TOOL_SELECTION_GUIDE,\n} from './tools/general-guidance';\nimport { addGeneratorGuideTool } from './tools/generator-guide';\nimport { addListGeneratorsTool } from './tools/list-generators';\nimport { addUpgradeWorkspaceTool } from './tools/upgrade-workspace';\n\n/**\n * Create the MCP Server\n */\nexport const createServer = () => {\n const generators = listGenerators();\n\n const server = new McpServer(\n {\n name: 'nx-plugin-for-aws',\n version: PackageJson.version,\n },\n {\n instructions: `# Nx Plugin for AWS MCP Server\n\nThis server provides resources and tools for quickly scaffolding AWS projects within an Nx workspace (monorepo), using the Nx Plugin for AWS (@aws/nx-plugin).\n\nThe Nx Plugin for AWS provides \"generators\" to add projects or functionality to your workspace. Use this to build the foundations of any project you are building\non AWS, if the generators apply to your use case.\n\n${TOOL_SELECTION_GUIDE}\n`,\n },\n );\n\n addGeneralGuidanceTool(server, generators);\n addCreateWorkspaceCommandTool(server);\n addListGeneratorsTool(server, generators);\n addGeneratorGuideTool(server, generators);\n addToExistingProjectTool(server, generators);\n addUpgradeWorkspaceTool(server, generators);\n\n return server;\n};\n"],"names":["McpServer","PackageJson","type","listGenerators","addToExistingProjectTool","addCreateWorkspaceCommandTool","addGeneralGuidanceTool","TOOL_SELECTION_GUIDE","addGeneratorGuideTool","addListGeneratorsTool","addUpgradeWorkspaceTool","createServer","generators","server","name","version","instructions"],"mappings":"AAAA;;;CAGC,GACD,SAASA,SAAS,QAAQ,0CAA0C;AACpE,OAAOC,iBAAiB,0BAA0B;IAAEC,MAAM;AAAO,EAAE;AACnE,SAASC,cAAc,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/mcp-server/server.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport PackageJson from '../../package.json' with { type: 'json' };\nimport { listGenerators } from '../utils/nx.js';\nimport { addToExistingProjectTool } from './tools/add-to-existing-project.js';\nimport { addCreateWorkspaceCommandTool } from './tools/create-workspace-command.js';\nimport {\n addGeneralGuidanceTool,\n TOOL_SELECTION_GUIDE,\n} from './tools/general-guidance.js';\nimport { addGeneratorGuideTool } from './tools/generator-guide.js';\nimport { addListGeneratorsTool } from './tools/list-generators.js';\nimport { addUpgradeWorkspaceTool } from './tools/upgrade-workspace.js';\n\n/**\n * Create the MCP Server\n */\nexport const createServer = () => {\n const generators = listGenerators();\n\n const server = new McpServer(\n {\n name: 'nx-plugin-for-aws',\n version: PackageJson.version,\n },\n {\n instructions: `# Nx Plugin for AWS MCP Server\n\nThis server provides resources and tools for quickly scaffolding AWS projects within an Nx workspace (monorepo), using the Nx Plugin for AWS (@aws/nx-plugin).\n\nThe Nx Plugin for AWS provides \"generators\" to add projects or functionality to your workspace. Use this to build the foundations of any project you are building\non AWS, if the generators apply to your use case.\n\n${TOOL_SELECTION_GUIDE}\n`,\n },\n );\n\n addGeneralGuidanceTool(server, generators);\n addCreateWorkspaceCommandTool(server);\n addListGeneratorsTool(server, generators);\n addGeneratorGuideTool(server, generators);\n addToExistingProjectTool(server, generators);\n addUpgradeWorkspaceTool(server, generators);\n\n return server;\n};\n"],"names":["McpServer","PackageJson","type","listGenerators","addToExistingProjectTool","addCreateWorkspaceCommandTool","addGeneralGuidanceTool","TOOL_SELECTION_GUIDE","addGeneratorGuideTool","addListGeneratorsTool","addUpgradeWorkspaceTool","createServer","generators","server","name","version","instructions"],"mappings":"AAAA;;;CAGC,GACD,SAASA,SAAS,QAAQ,0CAA0C;AACpE,OAAOC,iBAAiB,0BAA0B;IAAEC,MAAM;AAAO,EAAE;AACnE,SAASC,cAAc,QAAQ,iBAAiB;AAChD,SAASC,wBAAwB,QAAQ,qCAAqC;AAC9E,SAASC,6BAA6B,QAAQ,sCAAsC;AACpF,SACEC,sBAAsB,EACtBC,oBAAoB,QACf,8BAA8B;AACrC,SAASC,qBAAqB,QAAQ,6BAA6B;AACnE,SAASC,qBAAqB,QAAQ,6BAA6B;AACnE,SAASC,uBAAuB,QAAQ,+BAA+B;AAEvE;;CAEC,GACD,OAAO,MAAMC,eAAe;IAC1B,MAAMC,aAAaT;IAEnB,MAAMU,SAAS,IAAIb,UACjB;QACEc,MAAM;QACNC,SAASd,YAAYc,OAAO;IAC9B,GACA;QACEC,cAAc,CAAC;;;;;;;AAOrB,EAAET,qBAAqB;AACvB,CAAC;IACG;IAGFD,uBAAuBO,QAAQD;IAC/BP,8BAA8BQ;IAC9BJ,sBAAsBI,QAAQD;IAC9BJ,sBAAsBK,QAAQD;IAC9BR,yBAAyBS,QAAQD;IACjCF,wBAAwBG,QAAQD;IAEhC,OAAOC;AACT,EAAE"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
-
import type { NxGeneratorInfo } from '../../utils/generators';
|
|
6
|
+
import type { NxGeneratorInfo } from '../../utils/generators.js';
|
|
7
7
|
/**
|
|
8
8
|
* Add a tool which guides an agent through adding @aws/nx-plugin to an
|
|
9
9
|
* existing Nx or non-Nx workspace. Returns the `existing-project` docs page,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/add-to-existing-project.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport { fetchGuidePages } from '../generator-info';\nimport { PackageManagerSchema } from '../schema';\n\n/**\n * The guide page (under `get_started/`) that backs this tool, so the tool and\n * the published docs never drift.\n */\nconst EXISTING_PROJECT_GUIDE = 'existing-project';\n\n/**\n * Add a tool which guides an agent through adding @aws/nx-plugin to an\n * existing Nx or non-Nx workspace. Returns the `existing-project` docs page,\n * which includes the full adoption steps and troubleshooting reference.\n */\nexport const addToExistingProjectTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'add-to-existing-project',\n {\n title: 'Add to Existing Project',\n description:\n 'Tool for adding the Nx Plugin for AWS to an existing Nx workspace or non-Nx monorepo. Use this when a user wants to adopt @aws/nx-plugin in a project that was not created with the plugin preset, or hits configuration errors when running generators in such a workspace.',\n inputSchema: {\n packageManager: PackageManagerSchema.optional(),\n },\n },\n async ({ packageManager }) => {\n const guide = await fetchGuidePages(\n [EXISTING_PROJECT_GUIDE],\n generators,\n packageManager,\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: guide,\n },\n ],\n };\n },\n );\n};\n"],"names":["fetchGuidePages","PackageManagerSchema","EXISTING_PROJECT_GUIDE","addToExistingProjectTool","server","generators","registerTool","title","description","inputSchema","packageManager","optional","guide","content","type","text"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,eAAe,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/add-to-existing-project.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators.js';\nimport { fetchGuidePages } from '../generator-info.js';\nimport { PackageManagerSchema } from '../schema.js';\n\n/**\n * The guide page (under `get_started/`) that backs this tool, so the tool and\n * the published docs never drift.\n */\nconst EXISTING_PROJECT_GUIDE = 'existing-project';\n\n/**\n * Add a tool which guides an agent through adding @aws/nx-plugin to an\n * existing Nx or non-Nx workspace. Returns the `existing-project` docs page,\n * which includes the full adoption steps and troubleshooting reference.\n */\nexport const addToExistingProjectTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'add-to-existing-project',\n {\n title: 'Add to Existing Project',\n description:\n 'Tool for adding the Nx Plugin for AWS to an existing Nx workspace or non-Nx monorepo. Use this when a user wants to adopt @aws/nx-plugin in a project that was not created with the plugin preset, or hits configuration errors when running generators in such a workspace.',\n inputSchema: {\n packageManager: PackageManagerSchema.optional(),\n },\n },\n async ({ packageManager }) => {\n const guide = await fetchGuidePages(\n [EXISTING_PROJECT_GUIDE],\n generators,\n packageManager,\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: guide,\n },\n ],\n };\n },\n );\n};\n"],"names":["fetchGuidePages","PackageManagerSchema","EXISTING_PROJECT_GUIDE","addToExistingProjectTool","server","generators","registerTool","title","description","inputSchema","packageManager","optional","guide","content","type","text"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,eAAe,QAAQ,uBAAuB;AACvD,SAASC,oBAAoB,QAAQ,eAAe;AAEpD;;;CAGC,GACD,MAAMC,yBAAyB;AAE/B;;;;CAIC,GACD,OAAO,MAAMC,2BAA2B,CACtCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,2BACA;QACEC,OAAO;QACPC,aACE;QACFC,aAAa;YACXC,gBAAgBT,qBAAqBU,QAAQ;QAC/C;IACF,GACA,OAAO,EAAED,cAAc,EAAE;QACvB,MAAME,QAAQ,MAAMZ,gBAClB;YAACE;SAAuB,EACxBG,YACAK;QAEF,OAAO;YACLG,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAMH;gBACR;aACD;QACH;IACF;AAEJ,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/create-workspace-command.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { buildCreateNxWorkspaceCommand } from '../../utils/commands';\nimport { IAC_PROVIDERS } from '../../utils/iac-providers';\nimport { PackageManagerSchema } from '../schema';\n\n/**\n * Add a tool which tells a model how to create an Nx workspace\n */\nexport const addCreateWorkspaceCommandTool = (server: McpServer) => {\n server.registerTool(\n 'create-workspace-command',\n {\n description:\n 'Tool to discover how to create a workspace to start a new project.',\n inputSchema: {\n packageManager: PackageManagerSchema,\n },\n },\n ({ packageManager }) => ({\n content: [\n {\n type: 'text' as const,\n text: `Run the following command to create a workspace:\n\n\\`\\`\\`bash\n${buildCreateNxWorkspaceCommand(packageManager, '<workspace-name>')} --no-interactive\n\\`\\`\\`\n\nThis will create a new workspace within the \\`<workspace-name>\\` directory.\n\nIf you are already inside an empty directory intended for this project, you can pass \\`.\\` as the workspace name to create the workspace in the current directory:\n\n\\`\\`\\`bash\n${buildCreateNxWorkspaceCommand(packageManager, '.')} --no-interactive\n\\`\\`\\`\n\nNote that this will prompt for an Infrastructure as Code provider (${IAC_PROVIDERS.join(', ')}).\nIf you know the preferred option, pass ${IAC_PROVIDERS.map((iac) => `\\`--iac=${iac}\\``).join(' or ')} to the above command to skip the prompt.\n\nAdditional options:\n- \\`--no-gitSecrets\\`: Opt out of the default git-secrets pre-commit hook (prevents committing AWS credentials)\n\nRefer to the \\`general-guidance\\` tool for full workspace documentation including structure, common commands, and configuration.\n `,\n },\n ],\n }),\n );\n};\n"],"names":["buildCreateNxWorkspaceCommand","IAC_PROVIDERS","PackageManagerSchema","addCreateWorkspaceCommandTool","server","registerTool","description","inputSchema","packageManager","content","type","text","join","map","iac"],"mappings":"AAAA;;;CAGC,GAED,SAASA,6BAA6B,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/create-workspace-command.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { buildCreateNxWorkspaceCommand } from '../../utils/commands.js';\nimport { IAC_PROVIDERS } from '../../utils/iac-providers.js';\nimport { PackageManagerSchema } from '../schema.js';\n\n/**\n * Add a tool which tells a model how to create an Nx workspace\n */\nexport const addCreateWorkspaceCommandTool = (server: McpServer) => {\n server.registerTool(\n 'create-workspace-command',\n {\n description:\n 'Tool to discover how to create a workspace to start a new project.',\n inputSchema: {\n packageManager: PackageManagerSchema,\n },\n },\n ({ packageManager }) => ({\n content: [\n {\n type: 'text' as const,\n text: `Run the following command to create a workspace:\n\n\\`\\`\\`bash\n${buildCreateNxWorkspaceCommand(packageManager, '<workspace-name>')} --no-interactive\n\\`\\`\\`\n\nThis will create a new workspace within the \\`<workspace-name>\\` directory.\n\nIf you are already inside an empty directory intended for this project, you can pass \\`.\\` as the workspace name to create the workspace in the current directory:\n\n\\`\\`\\`bash\n${buildCreateNxWorkspaceCommand(packageManager, '.')} --no-interactive\n\\`\\`\\`\n\nNote that this will prompt for an Infrastructure as Code provider (${IAC_PROVIDERS.join(', ')}).\nIf you know the preferred option, pass ${IAC_PROVIDERS.map((iac) => `\\`--iac=${iac}\\``).join(' or ')} to the above command to skip the prompt.\n\nAdditional options:\n- \\`--no-gitSecrets\\`: Opt out of the default git-secrets pre-commit hook (prevents committing AWS credentials)\n\nRefer to the \\`general-guidance\\` tool for full workspace documentation including structure, common commands, and configuration.\n `,\n },\n ],\n }),\n );\n};\n"],"names":["buildCreateNxWorkspaceCommand","IAC_PROVIDERS","PackageManagerSchema","addCreateWorkspaceCommandTool","server","registerTool","description","inputSchema","packageManager","content","type","text","join","map","iac"],"mappings":"AAAA;;;CAGC,GAED,SAASA,6BAA6B,QAAQ,0BAA0B;AACxE,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,oBAAoB,QAAQ,eAAe;AAEpD;;CAEC,GACD,OAAO,MAAMC,gCAAgC,CAACC;IAC5CA,OAAOC,YAAY,CACjB,4BACA;QACEC,aACE;QACFC,aAAa;YACXC,gBAAgBN;QAClB;IACF,GACA,CAAC,EAAEM,cAAc,EAAE,GAAM,CAAA;YACvBC,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC;;;AAGjB,EAAEX,8BAA8BQ,gBAAgB,oBAAoB;;;;;;;;AAQpE,EAAER,8BAA8BQ,gBAAgB,KAAK;;;mEAGc,EAAEP,cAAcW,IAAI,CAAC,MAAM;uCACvD,EAAEX,cAAcY,GAAG,CAAC,CAACC,MAAQ,CAAC,QAAQ,EAAEA,IAAI,EAAE,CAAC,EAAEF,IAAI,CAAC,QAAQ;;;;;;EAMnG,CAAC;gBACK;aACD;QACH,CAAA;AAEJ,EAAE"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
-
import type { NxGeneratorInfo } from '../../utils/generators';
|
|
6
|
+
import type { NxGeneratorInfo } from '../../utils/generators.js';
|
|
7
7
|
export declare const TOOL_SELECTION_GUIDE = "## Tool Selection Guide\n\n- Use the `general-guidance` tool for guidance and best practices for working with Nx and the Nx Plugin for AWS.\n- Use the `create-workspace-command` tool to discover how to create a workspace to start a new project.\n- Use the `add-to-existing-project` tool when adding the plugin to an existing Nx workspace or non-Nx monorepo, or when troubleshooting configuration errors in such a workspace.\n- Use the `upgrade-workspace` tool when upgrading Nx or the Nx Plugin for AWS to a newer version.\n- Use the `list-generators` tool to discover the available generators and how to run them.\n- Use the `generator-guide` tool to retrieve detailed information about a specific generator.";
|
|
8
8
|
/**
|
|
9
9
|
* Add a tool which provides general guidance for using Nx and the Nx Plugin for AWS
|
|
@@ -74,7 +74,7 @@ When scaffolding several projects in one go, chain generators to avoid a slow de
|
|
|
74
74
|
- **Chain generators** with \`&&\` in a single command. Pass \`--prefer-install-dependencies=false\` on each generator except the last so dependencies install once at the end, for example:
|
|
75
75
|
|
|
76
76
|
${PACKAGE_MANAGERS.map((pm)=>` \`\`\`bash
|
|
77
|
-
${buildNxCommand('g @aws/nx-plugin:ts#trpc-api --no-interactive --name=my-app-api --auth=
|
|
77
|
+
${buildNxCommand('g @aws/nx-plugin:ts#trpc-api --no-interactive --name=my-app-api --auth=iam --prefer-install-dependencies=false', pm)} && \\
|
|
78
78
|
${buildNxCommand('g @aws/nx-plugin:ts#react-website --no-interactive --name=my-app-website --prefer-install-dependencies=false', pm)} && \\
|
|
79
79
|
${buildNxCommand('g @aws/nx-plugin:connection --no-interactive --sourceProject=@my-app/my-app-website --targetProject=@my-app/my-app-api --prefer-install-dependencies=false', pm)} && \\
|
|
80
80
|
${buildNxCommand('g @aws/nx-plugin:ts#infra --no-interactive --name=infra', pm)} && \\
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/general-guidance.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport { IAC_PROVIDERS } from '../../utils/iac-providers';\nimport { buildNxCommand, fetchGuidePages } from '../generator-info';\nimport { PACKAGE_MANAGERS } from '../schema';\n\nexport const TOOL_SELECTION_GUIDE = `## Tool Selection Guide\n\n- Use the \\`general-guidance\\` tool for guidance and best practices for working with Nx and the Nx Plugin for AWS.\n- Use the \\`create-workspace-command\\` tool to discover how to create a workspace to start a new project.\n- Use the \\`add-to-existing-project\\` tool when adding the plugin to an existing Nx workspace or non-Nx monorepo, or when troubleshooting configuration errors in such a workspace.\n- Use the \\`upgrade-workspace\\` tool when upgrading Nx or the Nx Plugin for AWS to a newer version.\n- Use the \\`list-generators\\` tool to discover the available generators and how to run them.\n- Use the \\`generator-guide\\` tool to retrieve detailed information about a specific generator.`;\n\n/**\n * Add a tool which provides general guidance for using Nx and the Nx Plugin for AWS\n */\nexport const addGeneralGuidanceTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'general-guidance',\n {\n title: 'General Guidance',\n description:\n 'Tool for guidance and best practices for working with Nx and the Nx Plugin for AWS',\n },\n async () => ({\n content: [\n {\n type: 'text' as const,\n text: `# Nx Plugin for AWS Guidance\n\n${TOOL_SELECTION_GUIDE}\n\n## Getting Started\n\n- Choose a package manager first. You can choose between ${PACKAGE_MANAGERS.join(', ')}. It's recommended to use \"pnpm\" if the user has no preference\n- Choose an infrastructure as code (IaC) provider next. You can choose between ${IAC_PROVIDERS.join(', ')}. It's recommended to use CDK if the user has no preference\n- Next, you must create an Nx workspace. Use the \\`create-workspace-command\\` tool for more details, and provide it with your chosen package manager\n- After this, you can start scaffolding the main components of your application using generators. Use the \\`list-generators\\` tool to discover available generators, and the \\`generator-guide\\` tool for more detailed information about a specific generator\n\n## Nx Primer\n\n- Prefix nx commands with the appropriate prefix for your package manager, for example:\n${PACKAGE_MANAGERS.map((pm) => buildNxCommand('<options>', pm)).join(' - \\n')}\n- Each project in your workspace has a file named \\`project.json\\` which contains important project information such as its name, and defines the \"targets\" which can be run for that project, for example building or testing the project\n- Use the command \\`nx reset\\` to reset the Nx daemon when unexpected issues arise\n- After adding dependencies between TypeScript projects, use \\`nx sync\\` to ensure project references are set up correctly\n\n## General Instructions\n\n- Each project declares the third-party runtime dependencies its source imports in its own \\`package.json\\`; shared build/test tooling (test runners, bundlers, etc.) is declared in the root \\`package.json\\` \\`devDependencies\\`. Versions follow a single version policy, recorded in the package manager's dependency catalog where supported (referenced as \\`catalog:\\`). Install with the appropriate command for your package manager:\n - Add a project runtime dependency: \\`pnpm add <package> --filter <project>\\` / \\`yarn workspace <project> add <package>\\` / \\`npm install <package> -w <project>\\` / \\`bun add <package> --cwd <project-directory>\\`\n - Add a shared dev tool at the root: \\`pnpm add -Dw <package>\\` / \\`yarn add -D <package>\\` / \\`npm install --legacy-peer-deps -D <package>\\` / \\`bun install -D <package>\\`\n- The \\`noUndeclaredDependencies\\` lint rule enforces that a project's source only imports packages declared in its own \\`package.json\\`\n- Projects in the same workspace can import one another directly by package name (eg \\`@workspace-name/project-name\\`) without declaring a dependency in \\`package.json\\` — TypeScript path aliases in \\`tsconfig.base.json\\` resolve these imports\n- When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example \\`@workspace-name/project-name\\`. Check the \\`project.json\\` file for the specific package to find its fully qualified name\n- When no generator exists for a specific framework required, use the base \\`ts#project\\` and \\`py#project\\` generators and build on top.\n- Leave the \\`--infra\\` option at its default value unless the user has explicitly instructed otherwise. Generators choose a sensible default type of infrastructure to deploy the project with, so only override \\`--infra\\` when the user has specified a particular requirement.\n\n## Useful Commands\n\n- Fix lint issues with \\`nx run-many --target lint --configuration=fix --all --output-style=stream\\`\n- Build all projects with \\`nx run-many --target build --all --output-style=stream\\`\n- Prefer importing the CDK constructs vended by generators in \\`packages/common/constructs\\` over writing your own\n\n## Best Practices\n\n- After running a generator, use the \\`nx show projects\\` command to check which projects have been added (if any)\n- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project\n- Generate all projects into the \\`packages/\\` directory\n- After making changes to your projects, fix linting issues, then run a full build\n- When it's time to start testing a project, suggest to the user that infrastructure is deployed to AWS. For websites, if a runtime-config.json is needed, use the load-runtime-config target after a deployment to point a local website at a sandbox stack.\n- For CDK infrastructure projects, deploy the sandbox stage with the \\`deploy-sandbox\\` target (eg \\`nx deploy-sandbox infra\\`) rather than passing a stage pattern to \\`deploy\\` — it already targets the sandbox stage declared in \\`main.ts\\`.\n\n## Batching Generators\n\nWhen scaffolding several projects in one go, chain generators to avoid a slow dependency install after every generator:\n\n- **Chain generators** with \\`&&\\` in a single command. Pass \\`--prefer-install-dependencies=false\\` on each generator except the last so dependencies install once at the end, for example:\n\n${PACKAGE_MANAGERS.map(\n (pm) => ` \\`\\`\\`bash\n ${buildNxCommand('g @aws/nx-plugin:ts#trpc-api --no-interactive --name=my-app-api --auth=
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/general-guidance.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators.js';\nimport { IAC_PROVIDERS } from '../../utils/iac-providers.js';\nimport { buildNxCommand, fetchGuidePages } from '../generator-info.js';\nimport { PACKAGE_MANAGERS } from '../schema.js';\n\nexport const TOOL_SELECTION_GUIDE = `## Tool Selection Guide\n\n- Use the \\`general-guidance\\` tool for guidance and best practices for working with Nx and the Nx Plugin for AWS.\n- Use the \\`create-workspace-command\\` tool to discover how to create a workspace to start a new project.\n- Use the \\`add-to-existing-project\\` tool when adding the plugin to an existing Nx workspace or non-Nx monorepo, or when troubleshooting configuration errors in such a workspace.\n- Use the \\`upgrade-workspace\\` tool when upgrading Nx or the Nx Plugin for AWS to a newer version.\n- Use the \\`list-generators\\` tool to discover the available generators and how to run them.\n- Use the \\`generator-guide\\` tool to retrieve detailed information about a specific generator.`;\n\n/**\n * Add a tool which provides general guidance for using Nx and the Nx Plugin for AWS\n */\nexport const addGeneralGuidanceTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'general-guidance',\n {\n title: 'General Guidance',\n description:\n 'Tool for guidance and best practices for working with Nx and the Nx Plugin for AWS',\n },\n async () => ({\n content: [\n {\n type: 'text' as const,\n text: `# Nx Plugin for AWS Guidance\n\n${TOOL_SELECTION_GUIDE}\n\n## Getting Started\n\n- Choose a package manager first. You can choose between ${PACKAGE_MANAGERS.join(', ')}. It's recommended to use \"pnpm\" if the user has no preference\n- Choose an infrastructure as code (IaC) provider next. You can choose between ${IAC_PROVIDERS.join(', ')}. It's recommended to use CDK if the user has no preference\n- Next, you must create an Nx workspace. Use the \\`create-workspace-command\\` tool for more details, and provide it with your chosen package manager\n- After this, you can start scaffolding the main components of your application using generators. Use the \\`list-generators\\` tool to discover available generators, and the \\`generator-guide\\` tool for more detailed information about a specific generator\n\n## Nx Primer\n\n- Prefix nx commands with the appropriate prefix for your package manager, for example:\n${PACKAGE_MANAGERS.map((pm) => buildNxCommand('<options>', pm)).join(' - \\n')}\n- Each project in your workspace has a file named \\`project.json\\` which contains important project information such as its name, and defines the \"targets\" which can be run for that project, for example building or testing the project\n- Use the command \\`nx reset\\` to reset the Nx daemon when unexpected issues arise\n- After adding dependencies between TypeScript projects, use \\`nx sync\\` to ensure project references are set up correctly\n\n## General Instructions\n\n- Each project declares the third-party runtime dependencies its source imports in its own \\`package.json\\`; shared build/test tooling (test runners, bundlers, etc.) is declared in the root \\`package.json\\` \\`devDependencies\\`. Versions follow a single version policy, recorded in the package manager's dependency catalog where supported (referenced as \\`catalog:\\`). Install with the appropriate command for your package manager:\n - Add a project runtime dependency: \\`pnpm add <package> --filter <project>\\` / \\`yarn workspace <project> add <package>\\` / \\`npm install <package> -w <project>\\` / \\`bun add <package> --cwd <project-directory>\\`\n - Add a shared dev tool at the root: \\`pnpm add -Dw <package>\\` / \\`yarn add -D <package>\\` / \\`npm install --legacy-peer-deps -D <package>\\` / \\`bun install -D <package>\\`\n- The \\`noUndeclaredDependencies\\` lint rule enforces that a project's source only imports packages declared in its own \\`package.json\\`\n- Projects in the same workspace can import one another directly by package name (eg \\`@workspace-name/project-name\\`) without declaring a dependency in \\`package.json\\` — TypeScript path aliases in \\`tsconfig.base.json\\` resolve these imports\n- When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example \\`@workspace-name/project-name\\`. Check the \\`project.json\\` file for the specific package to find its fully qualified name\n- When no generator exists for a specific framework required, use the base \\`ts#project\\` and \\`py#project\\` generators and build on top.\n- Leave the \\`--infra\\` option at its default value unless the user has explicitly instructed otherwise. Generators choose a sensible default type of infrastructure to deploy the project with, so only override \\`--infra\\` when the user has specified a particular requirement.\n\n## Useful Commands\n\n- Fix lint issues with \\`nx run-many --target lint --configuration=fix --all --output-style=stream\\`\n- Build all projects with \\`nx run-many --target build --all --output-style=stream\\`\n- Prefer importing the CDK constructs vended by generators in \\`packages/common/constructs\\` over writing your own\n\n## Best Practices\n\n- After running a generator, use the \\`nx show projects\\` command to check which projects have been added (if any)\n- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project\n- Generate all projects into the \\`packages/\\` directory\n- After making changes to your projects, fix linting issues, then run a full build\n- When it's time to start testing a project, suggest to the user that infrastructure is deployed to AWS. For websites, if a runtime-config.json is needed, use the load-runtime-config target after a deployment to point a local website at a sandbox stack.\n- For CDK infrastructure projects, deploy the sandbox stage with the \\`deploy-sandbox\\` target (eg \\`nx deploy-sandbox infra\\`) rather than passing a stage pattern to \\`deploy\\` — it already targets the sandbox stage declared in \\`main.ts\\`.\n\n## Batching Generators\n\nWhen scaffolding several projects in one go, chain generators to avoid a slow dependency install after every generator:\n\n- **Chain generators** with \\`&&\\` in a single command. Pass \\`--prefer-install-dependencies=false\\` on each generator except the last so dependencies install once at the end, for example:\n\n${PACKAGE_MANAGERS.map(\n (pm) => ` \\`\\`\\`bash\n ${buildNxCommand('g @aws/nx-plugin:ts#trpc-api --no-interactive --name=my-app-api --auth=iam --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:ts#react-website --no-interactive --name=my-app-website --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:connection --no-interactive --sourceProject=@my-app/my-app-website --targetProject=@my-app/my-app-api --prefer-install-dependencies=false', pm)} && \\\\\n ${buildNxCommand('g @aws/nx-plugin:ts#infra --no-interactive --name=infra', pm)} && \\\\\n ${buildNxCommand('sync', pm)}\n \\`\\`\\``,\n).join('\\n')}\n\n- **\\`--prefer-install-dependencies=false\\`** asks a generator to defer its dependency install so the batch installs once at the end (the final generator above omits the flag and installs everything).\n- **\\`nx sync\\`** is required before building — generators modify TypeScript project references.\n\n## Detailed Guides\n\nPlease refer to the below documentation for important details regarding workspaces and working with TypeScript or Python projects.\n\n${await fetchGuidePages(['workspace', 'typescript-project', 'python-project'], generators)}\n\n `,\n },\n ],\n }),\n );\n};\n"],"names":["IAC_PROVIDERS","buildNxCommand","fetchGuidePages","PACKAGE_MANAGERS","TOOL_SELECTION_GUIDE","addGeneralGuidanceTool","server","generators","registerTool","title","description","content","type","text","join","map","pm"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,cAAc,EAAEC,eAAe,QAAQ,uBAAuB;AACvE,SAASC,gBAAgB,QAAQ,eAAe;AAEhD,OAAO,MAAMC,uBAAuB,CAAC;;;;;;;+FAO0D,CAAC,CAAC;AAEjG;;CAEC,GACD,OAAO,MAAMC,yBAAyB,CACpCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,oBACA;QACEC,OAAO;QACPC,aACE;IACJ,GACA,UAAa,CAAA;YACXC,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC;;AAEjB,EAAET,qBAAqB;;;;yDAIkC,EAAED,iBAAiBW,IAAI,CAAC,MAAM;+EACR,EAAEd,cAAcc,IAAI,CAAC,MAAM;;;;;;;AAO1G,EAAEX,iBAAiBY,GAAG,CAAC,CAACC,KAAOf,eAAe,aAAae,KAAKF,IAAI,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqC9E,EAAEX,iBAAiBY,GAAG,CACpB,CAACC,KAAO,CAAC;EACT,EAAEf,eAAe,kHAAkHe,IAAI;IACrI,EAAEf,eAAe,gHAAgHe,IAAI;IACrI,EAAEf,eAAe,8JAA8Je,IAAI;IACnL,EAAEf,eAAe,2DAA2De,IAAI;IAChF,EAAEf,eAAe,QAAQe,IAAI;QACzB,CAAC,EACPF,IAAI,CAAC,MAAM;;;;;;;;;AASb,EAAE,MAAMZ,gBAAgB;wBAAC;wBAAa;wBAAsB;qBAAiB,EAAEK,YAAY;;IAEvF,CAAC;gBACG;aACD;QACH,CAAA;AAEJ,EAAE"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
-
import type { NxGeneratorInfo } from '../../utils/generators';
|
|
6
|
+
import type { NxGeneratorInfo } from '../../utils/generators.js';
|
|
7
7
|
/**
|
|
8
8
|
* Add a tool which provides a detailed guide for an individual generator.
|
|
9
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/generator-guide.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport {\n fetchGuidePagesForGenerator,\n renderGeneratorInfo,\n} from '../generator-info';\nimport { PackageManagerSchema } from '../schema';\n\n/**\n * Add a tool which provides a detailed guide for an individual generator.\n *\n * `fetchGuidePagesForGenerator` handles both the \"narrow by `options`\"\n * case — reading each page's frontmatter `when:` to pick matching variants\n * — and the \"unsupported combination\" case, where it returns an explicit\n * warning instead of empty guide content. The tool description points\n * agents at `list-generators` for the list of filterable options.\n */\nexport const addGeneratorGuideTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'generator-guide',\n {\n description:\n 'Tool to retrieve detailed information about a specific generator. ' +\n 'Pass `options` with the values you intend to use for any filterable option ' +\n '(e.g. infra, iac, auth, ux, protocol, sourceType, targetType) ' +\n 'to receive only the guide content relevant to those choices — this cuts noise ' +\n 'and avoids suggesting configuration from a different branch. The filterable keys ' +\n 'and their valid values for each generator are listed by the `list-generators` ' +\n 'tool; call it first if you are not sure which keys to pass. When the combination ' +\n 'you pick is not supported by the generator (e.g. connection from ts#trpc-api ' +\n 'to smithy), the tool returns an \"Unsupported combination\" warning with the ' +\n 'list of supported pairs. When `options` is omitted, every conditional section ' +\n 'is included and prefixed with a `> [!NOTE] Only when …` marker so you can see ' +\n 'the branching condition.',\n inputSchema: {\n packageManager: PackageManagerSchema,\n generator: z.enum(generators.map((g) => g.id)),\n options: z\n .record(z.string(), z.string())\n .optional()\n .describe(\n 'Optional map of generator option values (e.g. { infra: \"rest-lambda\", iac: \"cdk\" }) used to filter the guide to content that applies to those choices.',\n ),\n },\n },\n async ({ packageManager, generator: generatorId, options }) => {\n const generator = generators.find((g) => g.id === generatorId);\n if (!generator) {\n throw new Error(\n `No generator found with id ${generatorId}. Available generators: ${generators.map((g) => g.id).join(' ,')}`,\n );\n }\n\n const guide = await fetchGuidePagesForGenerator(\n generator,\n generators,\n packageManager,\n undefined,\n options,\n );\n\n // An unsupported combination renders its own self-contained warning\n // (leads with `## <id>` and lists the supported predicates), so\n // return it directly without the usual guide header.\n if (guide.kind === 'unsupported') {\n return { content: [{ type: 'text' as const, text: guide.content }] };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `## ${renderGeneratorInfo(packageManager, generator)}\n\n# Guide\n\n${guide.content}\n`,\n },\n ],\n };\n },\n );\n};\n"],"names":["z","fetchGuidePagesForGenerator","renderGeneratorInfo","PackageManagerSchema","addGeneratorGuideTool","server","generators","registerTool","description","inputSchema","packageManager","generator","enum","map","g","id","options","record","string","optional","describe","generatorId","find","Error","join","guide","undefined","kind","content","type","text"],"mappings":"AAAA;;;CAGC,GAED,SAASA,CAAC,QAAQ,MAAM;AAExB,SACEC,2BAA2B,EAC3BC,mBAAmB,QACd,
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/generator-guide.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport type { NxGeneratorInfo } from '../../utils/generators.js';\nimport {\n fetchGuidePagesForGenerator,\n renderGeneratorInfo,\n} from '../generator-info.js';\nimport { PackageManagerSchema } from '../schema.js';\n\n/**\n * Add a tool which provides a detailed guide for an individual generator.\n *\n * `fetchGuidePagesForGenerator` handles both the \"narrow by `options`\"\n * case — reading each page's frontmatter `when:` to pick matching variants\n * — and the \"unsupported combination\" case, where it returns an explicit\n * warning instead of empty guide content. The tool description points\n * agents at `list-generators` for the list of filterable options.\n */\nexport const addGeneratorGuideTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'generator-guide',\n {\n description:\n 'Tool to retrieve detailed information about a specific generator. ' +\n 'Pass `options` with the values you intend to use for any filterable option ' +\n '(e.g. infra, iac, auth, ux, protocol, sourceType, targetType) ' +\n 'to receive only the guide content relevant to those choices — this cuts noise ' +\n 'and avoids suggesting configuration from a different branch. The filterable keys ' +\n 'and their valid values for each generator are listed by the `list-generators` ' +\n 'tool; call it first if you are not sure which keys to pass. When the combination ' +\n 'you pick is not supported by the generator (e.g. connection from ts#trpc-api ' +\n 'to smithy), the tool returns an \"Unsupported combination\" warning with the ' +\n 'list of supported pairs. When `options` is omitted, every conditional section ' +\n 'is included and prefixed with a `> [!NOTE] Only when …` marker so you can see ' +\n 'the branching condition.',\n inputSchema: {\n packageManager: PackageManagerSchema,\n generator: z.enum(generators.map((g) => g.id)),\n options: z\n .record(z.string(), z.string())\n .optional()\n .describe(\n 'Optional map of generator option values (e.g. { infra: \"rest-lambda\", iac: \"cdk\" }) used to filter the guide to content that applies to those choices.',\n ),\n },\n },\n async ({ packageManager, generator: generatorId, options }) => {\n const generator = generators.find((g) => g.id === generatorId);\n if (!generator) {\n throw new Error(\n `No generator found with id ${generatorId}. Available generators: ${generators.map((g) => g.id).join(' ,')}`,\n );\n }\n\n const guide = await fetchGuidePagesForGenerator(\n generator,\n generators,\n packageManager,\n undefined,\n options,\n );\n\n // An unsupported combination renders its own self-contained warning\n // (leads with `## <id>` and lists the supported predicates), so\n // return it directly without the usual guide header.\n if (guide.kind === 'unsupported') {\n return { content: [{ type: 'text' as const, text: guide.content }] };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `## ${renderGeneratorInfo(packageManager, generator)}\n\n# Guide\n\n${guide.content}\n`,\n },\n ],\n };\n },\n );\n};\n"],"names":["z","fetchGuidePagesForGenerator","renderGeneratorInfo","PackageManagerSchema","addGeneratorGuideTool","server","generators","registerTool","description","inputSchema","packageManager","generator","enum","map","g","id","options","record","string","optional","describe","generatorId","find","Error","join","guide","undefined","kind","content","type","text"],"mappings":"AAAA;;;CAGC,GAED,SAASA,CAAC,QAAQ,MAAM;AAExB,SACEC,2BAA2B,EAC3BC,mBAAmB,QACd,uBAAuB;AAC9B,SAASC,oBAAoB,QAAQ,eAAe;AAEpD;;;;;;;;CAQC,GACD,OAAO,MAAMC,wBAAwB,CACnCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,mBACA;QACEC,aACE,uEACA,gFACA,mEACA,mFACA,sFACA,mFACA,sFACA,kFACA,gFACA,mFACA,mFACA;QACFC,aAAa;YACXC,gBAAgBP;YAChBQ,WAAWX,EAAEY,IAAI,CAACN,WAAWO,GAAG,CAAC,CAACC,IAAMA,EAAEC,EAAE;YAC5CC,SAAShB,EACNiB,MAAM,CAACjB,EAAEkB,MAAM,IAAIlB,EAAEkB,MAAM,IAC3BC,QAAQ,GACRC,QAAQ,CACP;QAEN;IACF,GACA,OAAO,EAAEV,cAAc,EAAEC,WAAWU,WAAW,EAAEL,OAAO,EAAE;QACxD,MAAML,YAAYL,WAAWgB,IAAI,CAAC,CAACR,IAAMA,EAAEC,EAAE,KAAKM;QAClD,IAAI,CAACV,WAAW;YACd,MAAM,IAAIY,MACR,CAAC,2BAA2B,EAAEF,YAAY,wBAAwB,EAAEf,WAAWO,GAAG,CAAC,CAACC,IAAMA,EAAEC,EAAE,EAAES,IAAI,CAAC,OAAO;QAEhH;QAEA,MAAMC,QAAQ,MAAMxB,4BAClBU,WACAL,YACAI,gBACAgB,WACAV;QAGF,oEAAoE;QACpE,gEAAgE;QAChE,qDAAqD;QACrD,IAAIS,MAAME,IAAI,KAAK,eAAe;YAChC,OAAO;gBAAEC,SAAS;oBAAC;wBAAEC,MAAM;wBAAiBC,MAAML,MAAMG,OAAO;oBAAC;iBAAE;YAAC;QACrE;QAEA,OAAO;YACLA,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC,GAAG,EAAE5B,oBAAoBQ,gBAAgBC,WAAW;;;;AAIvE,EAAEc,MAAMG,OAAO,CAAC;AAChB,CAAC;gBACS;aACD;QACH;IACF;AAEJ,EAAE"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
-
import type { NxGeneratorInfo } from '../../utils/generators';
|
|
6
|
+
import type { NxGeneratorInfo } from '../../utils/generators.js';
|
|
7
7
|
/**
|
|
8
8
|
* Adds a tool which lists details about the available generators.
|
|
9
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/list-generators.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport {\n renderFilterableOptionsAsync,\n renderGeneratorInfo,\n} from '../generator-info';\nimport { PackageManagerSchema } from '../schema';\n\n/**\n * Adds a tool which lists details about the available generators.\n *\n * Each entry carries a \"Filterable options\" section that tells the agent\n * which keys it can pass to `generator-guide` to narrow the guide response\n * to only the branches relevant to its selection. The keys come from two\n * sources, merged transparently:\n * - Enum properties from the generator's JSON schema.\n * - The union of `when:` frontmatter keys across the generator's guide\n * pages (lets multi-variant generators like `connection` surface\n * `sourceType` / `targetType` / `protocol` without any bespoke config).\n */\nexport const addListGeneratorsTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'list-generators',\n {\n description:\n 'Tool to discover the available generators and how to run them. ' +\n 'Each entry includes a \"Filterable options\" section — pass those ' +\n 'keys to `generator-guide` before invoking a generator so the guide ' +\n 'is narrowed to the variant you intend to scaffold.',\n inputSchema: { packageManager: PackageManagerSchema },\n },\n async ({ packageManager }) => {\n const entries = await Promise.all(\n generators.map(async (g) => {\n const info = renderGeneratorInfo(packageManager, g);\n const filterable = await renderFilterableOptionsAsync(g);\n return `### ${info}${filterable ? `\\n${filterable}\\n` : ''}`;\n }),\n );\n const guidance =\n 'Before running any generator below, call `generator-guide` with the ' +\n \"generator's id and `options` populated from its `generator-guide options` \" +\n 'list — the guide is returned narrowed to the branches that apply to ' +\n 'those choices, which keeps you from mixing configuration from a ' +\n 'different variant.';\n return {\n content: [\n {\n type: 'text' as const,\n text: `## Available Generators\\n\\n${guidance}\\n\\n${entries.join('\\n\\n')}\\n`,\n },\n ],\n };\n },\n );\n};\n"],"names":["renderFilterableOptionsAsync","renderGeneratorInfo","PackageManagerSchema","addListGeneratorsTool","server","generators","registerTool","description","inputSchema","packageManager","entries","Promise","all","map","g","info","filterable","guidance","content","type","text","join"],"mappings":"AAAA;;;CAGC,GAGD,SACEA,4BAA4B,EAC5BC,mBAAmB,QACd,
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/list-generators.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators.js';\nimport {\n renderFilterableOptionsAsync,\n renderGeneratorInfo,\n} from '../generator-info.js';\nimport { PackageManagerSchema } from '../schema.js';\n\n/**\n * Adds a tool which lists details about the available generators.\n *\n * Each entry carries a \"Filterable options\" section that tells the agent\n * which keys it can pass to `generator-guide` to narrow the guide response\n * to only the branches relevant to its selection. The keys come from two\n * sources, merged transparently:\n * - Enum properties from the generator's JSON schema.\n * - The union of `when:` frontmatter keys across the generator's guide\n * pages (lets multi-variant generators like `connection` surface\n * `sourceType` / `targetType` / `protocol` without any bespoke config).\n */\nexport const addListGeneratorsTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'list-generators',\n {\n description:\n 'Tool to discover the available generators and how to run them. ' +\n 'Each entry includes a \"Filterable options\" section — pass those ' +\n 'keys to `generator-guide` before invoking a generator so the guide ' +\n 'is narrowed to the variant you intend to scaffold.',\n inputSchema: { packageManager: PackageManagerSchema },\n },\n async ({ packageManager }) => {\n const entries = await Promise.all(\n generators.map(async (g) => {\n const info = renderGeneratorInfo(packageManager, g);\n const filterable = await renderFilterableOptionsAsync(g);\n return `### ${info}${filterable ? `\\n${filterable}\\n` : ''}`;\n }),\n );\n const guidance =\n 'Before running any generator below, call `generator-guide` with the ' +\n \"generator's id and `options` populated from its `generator-guide options` \" +\n 'list — the guide is returned narrowed to the branches that apply to ' +\n 'those choices, which keeps you from mixing configuration from a ' +\n 'different variant.';\n return {\n content: [\n {\n type: 'text' as const,\n text: `## Available Generators\\n\\n${guidance}\\n\\n${entries.join('\\n\\n')}\\n`,\n },\n ],\n };\n },\n );\n};\n"],"names":["renderFilterableOptionsAsync","renderGeneratorInfo","PackageManagerSchema","addListGeneratorsTool","server","generators","registerTool","description","inputSchema","packageManager","entries","Promise","all","map","g","info","filterable","guidance","content","type","text","join"],"mappings":"AAAA;;;CAGC,GAGD,SACEA,4BAA4B,EAC5BC,mBAAmB,QACd,uBAAuB;AAC9B,SAASC,oBAAoB,QAAQ,eAAe;AAEpD;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,wBAAwB,CACnCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,mBACA;QACEC,aACE,oEACA,qEACA,wEACA;QACFC,aAAa;YAAEC,gBAAgBP;QAAqB;IACtD,GACA,OAAO,EAAEO,cAAc,EAAE;QACvB,MAAMC,UAAU,MAAMC,QAAQC,GAAG,CAC/BP,WAAWQ,GAAG,CAAC,OAAOC;YACpB,MAAMC,OAAOd,oBAAoBQ,gBAAgBK;YACjD,MAAME,aAAa,MAAMhB,6BAA6Bc;YACtD,OAAO,CAAC,IAAI,EAAEC,OAAOC,aAAa,CAAC,EAAE,EAAEA,WAAW,EAAE,CAAC,GAAG,IAAI;QAC9D;QAEF,MAAMC,WACJ,yEACA,+EACA,yEACA,qEACA;QACF,OAAO;YACLC,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAM,CAAC,2BAA2B,EAAEH,SAAS,IAAI,EAAEP,QAAQW,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC7E;aACD;QACH;IACF;AAEJ,EAAE"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
-
import type { NxGeneratorInfo } from '../../utils/generators';
|
|
6
|
+
import type { NxGeneratorInfo } from '../../utils/generators.js';
|
|
7
7
|
/**
|
|
8
8
|
* Add a tool which guides an agent through upgrading Nx and @aws/nx-plugin in a
|
|
9
9
|
* workspace, returning the `upgrading` docs page.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/upgrade-workspace.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators';\nimport { fetchGuidePages } from '../generator-info';\nimport { PackageManagerSchema } from '../schema';\n\n/** The guide page backing this tool, so it never drifts from the docs. */\nconst UPGRADING_GUIDE = 'upgrading';\n\n/**\n * Add a tool which guides an agent through upgrading Nx and @aws/nx-plugin in a\n * workspace, returning the `upgrading` docs page.\n */\nexport const addUpgradeWorkspaceTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'upgrade-workspace',\n {\n title: 'Upgrade Workspace',\n description:\n 'Tool for upgrading Nx and the Nx Plugin for AWS in a workspace. Use this when a user wants to update @aws/nx-plugin or Nx to a newer version, or asks how to run migrations with nx migrate.',\n inputSchema: {\n packageManager: PackageManagerSchema.optional(),\n },\n },\n async ({ packageManager }) => {\n const guide = await fetchGuidePages(\n [UPGRADING_GUIDE],\n generators,\n packageManager,\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: guide,\n },\n ],\n };\n },\n );\n};\n"],"names":["fetchGuidePages","PackageManagerSchema","UPGRADING_GUIDE","addUpgradeWorkspaceTool","server","generators","registerTool","title","description","inputSchema","packageManager","optional","guide","content","type","text"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,eAAe,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/mcp-server/tools/upgrade-workspace.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { NxGeneratorInfo } from '../../utils/generators.js';\nimport { fetchGuidePages } from '../generator-info.js';\nimport { PackageManagerSchema } from '../schema.js';\n\n/** The guide page backing this tool, so it never drifts from the docs. */\nconst UPGRADING_GUIDE = 'upgrading';\n\n/**\n * Add a tool which guides an agent through upgrading Nx and @aws/nx-plugin in a\n * workspace, returning the `upgrading` docs page.\n */\nexport const addUpgradeWorkspaceTool = (\n server: McpServer,\n generators: NxGeneratorInfo[],\n) => {\n server.registerTool(\n 'upgrade-workspace',\n {\n title: 'Upgrade Workspace',\n description:\n 'Tool for upgrading Nx and the Nx Plugin for AWS in a workspace. Use this when a user wants to update @aws/nx-plugin or Nx to a newer version, or asks how to run migrations with nx migrate.',\n inputSchema: {\n packageManager: PackageManagerSchema.optional(),\n },\n },\n async ({ packageManager }) => {\n const guide = await fetchGuidePages(\n [UPGRADING_GUIDE],\n generators,\n packageManager,\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: guide,\n },\n ],\n };\n },\n );\n};\n"],"names":["fetchGuidePages","PackageManagerSchema","UPGRADING_GUIDE","addUpgradeWorkspaceTool","server","generators","registerTool","title","description","inputSchema","packageManager","optional","guide","content","type","text"],"mappings":"AAAA;;;CAGC,GAGD,SAASA,eAAe,QAAQ,uBAAuB;AACvD,SAASC,oBAAoB,QAAQ,eAAe;AAEpD,wEAAwE,GACxE,MAAMC,kBAAkB;AAExB;;;CAGC,GACD,OAAO,MAAMC,0BAA0B,CACrCC,QACAC;IAEAD,OAAOE,YAAY,CACjB,qBACA;QACEC,OAAO;QACPC,aACE;QACFC,aAAa;YACXC,gBAAgBT,qBAAqBU,QAAQ;QAC/C;IACF,GACA,OAAO,EAAED,cAAc,EAAE;QACvB,MAAME,QAAQ,MAAMZ,gBAClB;YAACE;SAAgB,EACjBG,YACAK;QAEF,OAAO;YACLG,SAAS;gBACP;oBACEC,MAAM;oBACNC,MAAMH;gBACR;aACD;QACH;IACF;AAEJ,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/apt-security-updates-in-container-images/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type ProjectConfiguration,\n type Tree,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport type { ComponentMetadata } from '../../../utils/nx';\n\n/**\n * Apply the distribution's security updates in the vended agent / MCP server\n * images.\n *\n * A base image tag lags behind its distribution's security suite, so the OS\n * packages it ships carry vulnerabilities that already have a fixed version\n * published — which the image scan flags as HIGH/CRITICAL. Upgrading them in the\n * image build clears those findings whenever the scan runs, rather than waiting\n * for the base image to be rebuilt. New workspaces get this from the generator\n * templates; this brings existing ones up to date.\n *\n * Only the Dockerfiles of the components whose images the generators vend are\n * touched, located from their project metadata. The Dockerfile is generated\n * `KeepExisting`, so it is edited in place: the upgrade is inserted right after\n * the `FROM` line, ahead of every other instruction, so later layers install\n * against the upgraded packages. One that already runs `apt-get upgrade`, or\n * which has been re-based onto an image `apt-get` can't upgrade, is left alone.\n */\n\n/**\n * The generators whose runtime images the vended Dockerfiles build. Hardcoded\n * rather than imported from the generators: a migration matches the ids\n * workspaces recorded at generation time, which must stay fixed even if the\n * generators' current ids change later.\n */\nconst RUNTIME_IMAGE_GENERATOR_IDS = [\n 'py#agent',\n 'py#mcp-server',\n 'ts#agent',\n 'ts#mcp-server',\n];\n\nconst APT_UPGRADE = `# Apply the distribution's security updates: base image tags lag behind the\n# security suite, so its OS packages carry fixed HIGH/CRITICAL vulnerabilities\n# flagged by the image scan.\nRUN apt-get update && \\\\\n apt-get upgrade -y --no-install-recommends && \\\\\n rm -rf /var/lib/apt/lists/*`;\n\n/** The apt command this migration adds; used to detect an applied fix. */\nconst APT_UPGRADE_COMMAND = 'apt-get upgrade';\n\n/**\n * The Debian-derived base images the generators vend, whose packages `apt-get`\n * upgrades. A user who has re-based onto another image (Alpine, distroless,\n * Amazon Linux) needs a different command, so theirs is left as they wrote it.\n */\nconst DEBIAN_BASE_IMAGE = /^FROM\\s+\\S*(?:node|python):\\S*\\n/m;\n\n/**\n * The Dockerfiles of every runtime image component, located from each project's\n * recorded component metadata (`path` is the component directory relative to\n * the project root).\n */\nconst runtimeImageDockerfiles = (tree: Tree): string[] => {\n const paths: string[] = [];\n for (const project of getProjects(tree).values()) {\n const components = ((\n project.metadata as { components?: ComponentMetadata[] }\n )?.components ?? []) as ComponentMetadata[];\n for (const component of components) {\n if (\n !RUNTIME_IMAGE_GENERATOR_IDS.includes(component.generator) ||\n !component.path\n ) {\n continue;\n }\n const dockerfile = joinPathFragments(\n projectRoot(project),\n component.path,\n 'Dockerfile',\n );\n if (tree.exists(dockerfile)) {\n paths.push(dockerfile);\n }\n }\n }\n return paths;\n};\n\n/** A project's root, falling back to sourceRoot for the TS-solution layout. */\nconst projectRoot = (project: ProjectConfiguration): string =>\n project.root ?? project.sourceRoot ?? '';\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n for (const filePath of runtimeImageDockerfiles(tree)) {\n const content = tree.read(filePath, 'utf-8');\n if (!content) {\n continue;\n }\n if (content.includes(APT_UPGRADE_COMMAND)) {\n continue; // Already upgrading (migrated or user-added).\n }\n\n const from = content.match(DEBIAN_BASE_IMAGE);\n if (from?.index === undefined) {\n continue; // The user has re-based the image; theirs to patch, not ours.\n }\n\n // Insert the upgrade after the FROM line, ahead of every other instruction\n // so later layers install against the upgraded packages, with the spacing a\n // freshly generated Dockerfile has.\n const insertAt = from.index + from[0].length;\n tree.write(\n filePath,\n `${content.slice(0, insertAt)}\\n${APT_UPGRADE}\\n${content.slice(insertAt)}`,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return {};\n}\n"],"names":["getProjects","joinPathFragments","formatFilesInSubtree","RUNTIME_IMAGE_GENERATOR_IDS","APT_UPGRADE","APT_UPGRADE_COMMAND","DEBIAN_BASE_IMAGE","runtimeImageDockerfiles","tree","paths","project","values","components","metadata","component","includes","generator","path","dockerfile","projectRoot","exists","push","root","sourceRoot","migration","filePath","content","read","from","match","index","undefined","insertAt","length","write","slice"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAIZ,aAAa;AACpB,SAASC,oBAAoB,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/apt-security-updates-in-container-images/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type ProjectConfiguration,\n type Tree,\n} from '@nx/devkit';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport type { ComponentMetadata } from '../../../utils/nx.js';\n\n/**\n * Apply the distribution's security updates in the vended agent / MCP server\n * images.\n *\n * A base image tag lags behind its distribution's security suite, so the OS\n * packages it ships carry vulnerabilities that already have a fixed version\n * published — which the image scan flags as HIGH/CRITICAL. Upgrading them in the\n * image build clears those findings whenever the scan runs, rather than waiting\n * for the base image to be rebuilt. New workspaces get this from the generator\n * templates; this brings existing ones up to date.\n *\n * Only the Dockerfiles of the components whose images the generators vend are\n * touched, located from their project metadata. The Dockerfile is generated\n * `KeepExisting`, so it is edited in place: the upgrade is inserted right after\n * the `FROM` line, ahead of every other instruction, so later layers install\n * against the upgraded packages. One that already runs `apt-get upgrade`, or\n * which has been re-based onto an image `apt-get` can't upgrade, is left alone.\n */\n\n/**\n * The generators whose runtime images the vended Dockerfiles build. Hardcoded\n * rather than imported from the generators: a migration matches the ids\n * workspaces recorded at generation time, which must stay fixed even if the\n * generators' current ids change later.\n */\nconst RUNTIME_IMAGE_GENERATOR_IDS = [\n 'py#agent',\n 'py#mcp-server',\n 'ts#agent',\n 'ts#mcp-server',\n];\n\nconst APT_UPGRADE = `# Apply the distribution's security updates: base image tags lag behind the\n# security suite, so its OS packages carry fixed HIGH/CRITICAL vulnerabilities\n# flagged by the image scan.\nRUN apt-get update && \\\\\n apt-get upgrade -y --no-install-recommends && \\\\\n rm -rf /var/lib/apt/lists/*`;\n\n/** The apt command this migration adds; used to detect an applied fix. */\nconst APT_UPGRADE_COMMAND = 'apt-get upgrade';\n\n/**\n * The Debian-derived base images the generators vend, whose packages `apt-get`\n * upgrades. A user who has re-based onto another image (Alpine, distroless,\n * Amazon Linux) needs a different command, so theirs is left as they wrote it.\n */\nconst DEBIAN_BASE_IMAGE = /^FROM\\s+\\S*(?:node|python):\\S*\\n/m;\n\n/**\n * The Dockerfiles of every runtime image component, located from each project's\n * recorded component metadata (`path` is the component directory relative to\n * the project root).\n */\nconst runtimeImageDockerfiles = (tree: Tree): string[] => {\n const paths: string[] = [];\n for (const project of getProjects(tree).values()) {\n const components = ((\n project.metadata as { components?: ComponentMetadata[] }\n )?.components ?? []) as ComponentMetadata[];\n for (const component of components) {\n if (\n !RUNTIME_IMAGE_GENERATOR_IDS.includes(component.generator) ||\n !component.path\n ) {\n continue;\n }\n const dockerfile = joinPathFragments(\n projectRoot(project),\n component.path,\n 'Dockerfile',\n );\n if (tree.exists(dockerfile)) {\n paths.push(dockerfile);\n }\n }\n }\n return paths;\n};\n\n/** A project's root, falling back to sourceRoot for the TS-solution layout. */\nconst projectRoot = (project: ProjectConfiguration): string =>\n project.root ?? project.sourceRoot ?? '';\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n for (const filePath of runtimeImageDockerfiles(tree)) {\n const content = tree.read(filePath, 'utf-8');\n if (!content) {\n continue;\n }\n if (content.includes(APT_UPGRADE_COMMAND)) {\n continue; // Already upgrading (migrated or user-added).\n }\n\n const from = content.match(DEBIAN_BASE_IMAGE);\n if (from?.index === undefined) {\n continue; // The user has re-based the image; theirs to patch, not ours.\n }\n\n // Insert the upgrade after the FROM line, ahead of every other instruction\n // so later layers install against the upgraded packages, with the spacing a\n // freshly generated Dockerfile has.\n const insertAt = from.index + from[0].length;\n tree.write(\n filePath,\n `${content.slice(0, insertAt)}\\n${APT_UPGRADE}\\n${content.slice(insertAt)}`,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return {};\n}\n"],"names":["getProjects","joinPathFragments","formatFilesInSubtree","RUNTIME_IMAGE_GENERATOR_IDS","APT_UPGRADE","APT_UPGRADE_COMMAND","DEBIAN_BASE_IMAGE","runtimeImageDockerfiles","tree","paths","project","values","components","metadata","component","includes","generator","path","dockerfile","projectRoot","exists","push","root","sourceRoot","migration","filePath","content","read","from","match","index","undefined","insertAt","length","write","slice"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAIZ,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAA2B;AAGhE;;;;;;;;;;;;;;;;;CAiBC,GAED;;;;;CAKC,GACD,MAAMC,8BAA8B;IAClC;IACA;IACA;IACA;CACD;AAED,MAAMC,cAAc,CAAC;;;;;+BAKU,CAAC;AAEhC,wEAAwE,GACxE,MAAMC,sBAAsB;AAE5B;;;;CAIC,GACD,MAAMC,oBAAoB;AAE1B;;;;CAIC,GACD,MAAMC,0BAA0B,CAACC;IAC/B,MAAMC,QAAkB,EAAE;IAC1B,KAAK,MAAMC,WAAWV,YAAYQ,MAAMG,MAAM,GAAI;QAChD,MAAMC,aAAc,AAClBF,QAAQG,QAAQ,EACfD,cAAc,EAAE;QACnB,KAAK,MAAME,aAAaF,WAAY;YAClC,IACE,CAACT,4BAA4BY,QAAQ,CAACD,UAAUE,SAAS,KACzD,CAACF,UAAUG,IAAI,EACf;gBACA;YACF;YACA,MAAMC,aAAajB,kBACjBkB,YAAYT,UACZI,UAAUG,IAAI,EACd;YAEF,IAAIT,KAAKY,MAAM,CAACF,aAAa;gBAC3BT,MAAMY,IAAI,CAACH;YACb;QACF;IACF;IACA,OAAOT;AACT;AAEA,6EAA6E,GAC7E,MAAMU,cAAc,CAACT,UACnBA,QAAQY,IAAI,IAAIZ,QAAQa,UAAU,IAAI;AAExC,eAAe,eAAeC,UAC5BhB,IAAU;IAEV,KAAK,MAAMiB,YAAYlB,wBAAwBC,MAAO;QACpD,MAAMkB,UAAUlB,KAAKmB,IAAI,CAACF,UAAU;QACpC,IAAI,CAACC,SAAS;YACZ;QACF;QACA,IAAIA,QAAQX,QAAQ,CAACV,sBAAsB;YACzC,UAAU,8CAA8C;QAC1D;QAEA,MAAMuB,OAAOF,QAAQG,KAAK,CAACvB;QAC3B,IAAIsB,MAAME,UAAUC,WAAW;YAC7B,UAAU,8DAA8D;QAC1E;QAEA,2EAA2E;QAC3E,4EAA4E;QAC5E,oCAAoC;QACpC,MAAMC,WAAWJ,KAAKE,KAAK,GAAGF,IAAI,CAAC,EAAE,CAACK,MAAM;QAC5CzB,KAAK0B,KAAK,CACRT,UACA,GAAGC,QAAQS,KAAK,CAAC,GAAGH,UAAU,EAAE,EAAE5B,YAAY,EAAE,EAAEsB,QAAQS,KAAK,CAACH,WAAW;IAE/E;IAEA,MAAM9B,qBAAqBM;IAE3B,OAAO,CAAC;AACV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/dynamodb-configurable-encryption/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport {\n addDestructuredImport,\n applyGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Bring existing workspaces up to the generators' current DynamoDBTable\n * configurability:\n *\n * - The vended `DynamoDBTable` CDK construct gains `encryption` and\n * `encryptionKey` props. The KMS key is only created when `encryption` is\n * `TableEncryption.CUSTOMER_MANAGED` and no `encryptionKey` is supplied.\n * `enableKeyRotation` (already present) only applies to that auto-created\n * key.\n * - The generated per-table CDK app construct already forwards an optional\n * `props` parameter through to `DynamoDBTable`, so no change is needed\n * there.\n * - The vended Terraform dynamodb core module gains the equivalent\n * `encryption`, `kms_key_arn` and `create_kms_key` variables (`encryption`\n * also accepts `DEFAULT`, the AWS owned key, which CDK already supports for\n * free via `TableEncryption.DEFAULT`), with the KMS key made conditional on\n * `create_kms_key` (not on `kms_key_arn`'s nullness, which `count` can't\n * depend on when the ARN comes from another resource) and\n * `server_side_encryption.enabled` tied to `encryption`. `AWS_MANAGED`\n * resolves to the explicit `alias/aws/dynamodb` ARN rather than `null`,\n * since the provider's `kms_key_arn` is Optional+Computed and a `null`\n * there means \"leave whatever is there\", not \"clear it\".\n * - The vended Terraform per-table app module (`app/dynamodb/<name>/<name>.tf`)\n * gains pass-through `encryption`, `kms_key_arn` and `create_kms_key`\n * variables forwarded to the core module call, matching its existing\n * `enable_key_rotation` pass-through.\n *\n * These files are generated with `KeepExisting`, so without this an upgraded\n * workspace has generators that support this configuration but vended files\n * that don't. Diverged files are left untouched and reported via `nextSteps`.\n */\n\nconst CDK_DYNAMODB_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/dynamodb.ts`;\nconst TERRAFORM_DYNAMODB_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/dynamodb/dynamodb.tf`;\nconst TERRAFORM_DYNAMODB_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/dynamodb`;\n\nconst CDK_DIVERGED_MESSAGE = `${CDK_DYNAMODB_FILE}: has diverged from the generated shape - left untouched. To pick up the encryption and encryptionKey props, manually port them from the vended core/dynamodb.ts template (see the ts#dynamodb generator's DynamoDBTable construct).`;\n\nconst TERRAFORM_DIVERGED_MESSAGE = `${TERRAFORM_DYNAMODB_FILE}: has diverged from the generated shape - left untouched. To pick up the encryption and kms_key_arn variables, manually port them from the vended dynamodb.tf template (see the ts#dynamodb generator's dynamodb module).`;\n\nconst terraformAppDivergedMessage = (filePath: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. To make encryption and kms_key_arn configurable from your root Terraform configuration, add pass-through variables here and forward them to the dynamodb_table module call (see the ts#dynamodb generator's dynamodb app template).`;\n\n/**\n * Surface encryption/encryptionKey on the vended DynamoDBTable CDK\n * construct.\n */\nconst migrateCdkConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(CDK_DYNAMODB_FILE)) {\n return; // This workspace has no CDK DynamoDBTable construct.\n }\n\n if (\n await matchGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n '`readonly encryption?: TableEncryption`',\n )\n ) {\n return; // Already migrated.\n }\n\n const ENABLE_KEY_ROTATION_FIELD = '`readonly enableKeyRotation?: boolean`';\n // Matched as a literal so the new fields can be inserted *before* it (see\n // below) — GritQL doesn't include a leading comment in the span it matches\n // for the field itself, so anchoring on the field would strand this\n // comment above the newly-inserted fields instead of above the field it\n // actually documents.\n const ENABLE_KEY_ROTATION_COMMENT = `\\`/**\n * Whether to enable automatic key rotation on the KMS key used to encrypt the table.\n *\n * @default true\n */\\``;\n const DESTRUCTURE_OLD = `\\`{\n tableName,\n runtimeConfigKey,\n billingMode = BillingMode.PAY_PER_REQUEST,\n pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true },\n deletionProtection = true,\n removalPolicy = RemovalPolicy.RETAIN,\n enableKeyRotation = true,\n ...rest\n }: DynamoDBTableProps\\``;\n const KEY_CREATION_OLD =\n \"`const key = new Key(this, 'EncryptionKey', { enableKeyRotation });`\";\n const TABLE_ENCRYPTION_OLD = '`encryption: TableEncryption.CUSTOMER_MANAGED`';\n\n const anchors = [\n ENABLE_KEY_ROTATION_FIELD,\n ENABLE_KEY_ROTATION_COMMENT,\n DESTRUCTURE_OLD,\n KEY_CREATION_OLD,\n TABLE_ENCRYPTION_OLD,\n ];\n\n const allPresent = (\n await Promise.all(\n anchors.map((pattern) => matchGritQL(tree, CDK_DYNAMODB_FILE, pattern)),\n )\n ).every(Boolean);\n\n if (!allPresent) {\n nextSteps.push(CDK_DIVERGED_MESSAGE);\n return;\n }\n\n await addDestructuredImport(\n tree,\n CDK_DYNAMODB_FILE,\n ['IKey'],\n 'aws-cdk-lib/aws-kms',\n );\n\n // Inserted before the enableKeyRotation field's own leading comment (rather\n // than before the bare field) so that comment stays directly above the\n // field it documents, instead of being stranded above the new fields.\n await insertViaGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${ENABLE_KEY_ROTATION_COMMENT} as $comment => \\`${GRIT_INSERT_PLACEHOLDER}\n $comment\\``,\n `/**\n * Server-side encryption for the table.\n *\n * @default TableEncryption.CUSTOMER_MANAGED\n */\n readonly encryption?: TableEncryption;\n\n /**\n * KMS key used to encrypt the table. Only used when \\`encryption\\` is\n * \\`TableEncryption.CUSTOMER_MANAGED\\`. When not provided, a new key is created.\n */\n readonly encryptionKey?: IKey;\n\n `,\n );\n\n // Update the enableKeyRotation field's own comment to note it now only\n // applies to the auto-created key, matching the vended template exactly.\n // Routed through the insert placeholder (rather than embedding the text\n // directly in the GritQL rewrite) since the comment's own backticks would\n // otherwise be parsed as GritQL code-block delimiters.\n await insertViaGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${ENABLE_KEY_ROTATION_COMMENT} => \\`${GRIT_INSERT_PLACEHOLDER}\\``,\n `/**\n * Whether to enable automatic key rotation on the KMS key used to encrypt the table.\n * Only applies when \\`encryption\\` is \\`TableEncryption.CUSTOMER_MANAGED\\` and no\n * \\`encryptionKey\\` is supplied.\n *\n * @default true\n */`,\n );\n\n await applyGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${DESTRUCTURE_OLD} => \\`{\n tableName,\n runtimeConfigKey,\n billingMode = BillingMode.PAY_PER_REQUEST,\n pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true },\n deletionProtection = true,\n removalPolicy = RemovalPolicy.RETAIN,\n encryption = TableEncryption.CUSTOMER_MANAGED,\n encryptionKey,\n enableKeyRotation = true,\n ...rest\n }: DynamoDBTableProps\\``,\n );\n\n await applyGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${KEY_CREATION_OLD} => \\`const key: IKey | undefined =\n encryption === TableEncryption.CUSTOMER_MANAGED\n ? (encryptionKey ?? new Key(this, 'EncryptionKey', { enableKeyRotation }))\n : undefined;\\``,\n );\n\n await applyGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${TABLE_ENCRYPTION_OLD} => \\`encryption\\``,\n );\n};\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\nconst NEW_TERRAFORM_VARIABLES_TEXT = [\n 'variable \"encryption\" {',\n ' description = \"Server-side encryption for the table. One of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT (the AWS owned key, at no cost and with no key to manage). Changing this on an already-deployed table away from CUSTOMER_MANAGED requires a manual step first - see the ts#dynamodb generator docs.\"',\n ' type = string',\n ' default = \"CUSTOMER_MANAGED\"',\n '',\n ' validation {',\n ' condition = contains([\"CUSTOMER_MANAGED\", \"AWS_MANAGED\", \"DEFAULT\"], var.encryption)',\n ' error_message = \"encryption must be one of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT.\"',\n ' }',\n '}',\n '',\n 'variable \"kms_key_arn\" {',\n ' description = \"ARN of an existing KMS key used to encrypt the table when encryption is CUSTOMER_MANAGED. When not provided and create_kms_key is true, a new key is created. Note that a customer-supplied key must already grant the DynamoDB service the necessary permissions in its own key policy.\"',\n ' type = string',\n ' default = null',\n '}',\n '',\n 'variable \"create_kms_key\" {',\n ' description = \"Whether to create a KMS key for the table. Only applies when encryption is CUSTOMER_MANAGED. Set to false when supplying kms_key_arn.\"',\n ' type = bool',\n ' default = true',\n '}',\n '',\n 'variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table. Only applies when encryption is CUSTOMER_MANAGED and create_kms_key is true.\"',\n ' type = bool',\n ' default = true',\n '}',\n].join('\\n');\n\n/**\n * Surface encryption/kms_key_arn on the vended Terraform dynamodb core\n * module.\n */\nconst migrateTerraformModule = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(TERRAFORM_DYNAMODB_FILE)) {\n return; // This workspace has no Terraform dynamodb module.\n }\n\n if (\n await matchGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl('`variable \"encryption\" { $_ }`'),\n )\n ) {\n return; // Already migrated.\n }\n\n const OLD_ENABLE_KEY_ROTATION_VAR = hcl(\n [\n '`variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table.\"',\n ' type = bool',\n ' default = true',\n '}`',\n ].join('\\n'),\n );\n const LOCALS_BLOCK = hcl('`locals { $_ }`');\n const DATA_PARTITION_LINE = hcl('`data \"aws_partition\" \"current\" {}`');\n const KMS_KEY_BLOCK = hcl('`resource \"aws_kms_key\" \"table\" { $_ }`');\n const SSE_ENABLED_LINE = hcl('`enabled = true`');\n const SSE_KMS_KEY_LINE = hcl('`kms_key_arn = aws_kms_key.table.arn`');\n const OUTPUT_VALUE_LINE = hcl('`value = aws_kms_key.table.arn`');\n const OUTPUT_DESCRIPTION_LINE = hcl(\n '`description = \"ARN of the KMS key used to encrypt the DynamoDB table.\"`',\n );\n\n const anchors = [\n OLD_ENABLE_KEY_ROTATION_VAR,\n LOCALS_BLOCK,\n DATA_PARTITION_LINE,\n KMS_KEY_BLOCK,\n SSE_ENABLED_LINE,\n SSE_KMS_KEY_LINE,\n OUTPUT_VALUE_LINE,\n OUTPUT_DESCRIPTION_LINE,\n ];\n\n const allPresent = (\n await Promise.all(\n anchors.map((pattern) =>\n matchGritQL(tree, TERRAFORM_DYNAMODB_FILE, pattern),\n ),\n )\n ).every(Boolean);\n\n if (!allPresent) {\n nextSteps.push(TERRAFORM_DIVERGED_MESSAGE);\n return;\n }\n\n // 1. Replace the enable_key_rotation variable with the new variables plus\n // an updated enable_key_rotation description, in the same position.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${OLD_ENABLE_KEY_ROTATION_VAR} => \\`${NEW_TERRAFORM_VARIABLES_TEXT.replace(/`/g, '\\\\`')}\\``,\n );\n\n // 2. New locals, appended into the existing locals block.\n await insertViaGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl(\n `\\`locals { $body }\\` => \\`locals {\\n $body\\n\\n ${GRIT_INSERT_PLACEHOLDER}\\n}\\``,\n ),\n [\n 'create_table_key = var.encryption == \"CUSTOMER_MANAGED\" && var.create_kms_key',\n 'table_kms_key_arn = (',\n ' var.encryption == \"CUSTOMER_MANAGED\" ? (local.create_table_key ? aws_kms_key.table[0].arn : var.kms_key_arn) :',\n ' var.encryption == \"AWS_MANAGED\" ? \"arn:${data.aws_partition.current.partition}:kms:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:alias/aws/dynamodb\" :',\n ' null',\n ')',\n ].join('\\n '),\n );\n\n // 2b. Region is needed to resolve the AWS_MANAGED key's alias ARN above.\n await insertViaGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${DATA_PARTITION_LINE} => \\`data \"aws_partition\" \"current\" {}\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n 'data \"aws_region\" \"current\" {}',\n );\n\n // 3. Make the KMS key conditional on encryption/kms_key_arn.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl(`\\`resource \"aws_kms_key\" \"table\" { $body }\\` => \\`resource \"aws_kms_key\" \"table\" {\n count = local.create_table_key ? 1 : 0\n\n $body\n}\\``),\n );\n\n // 4. Only enable KMS-backed encryption when not using the AWS owned key.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${SSE_ENABLED_LINE} => \\`enabled = var.encryption != \"DEFAULT\"\\``,\n );\n\n // 4b. Checkov's CKV_AWS_119 only passes when server_side_encryption.enabled\n // is the literal `true` — it can't resolve the conditional above, even\n // though CUSTOMER_MANAGED (the default) always uses a real CMK. Same\n // false-positive shape as CKV_AWS_139 on the vended RDS module.\n await insertViaGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl(\n `\\`resource \"aws_dynamodb_table\" \"table\" { $body }\\` => \\`resource \"aws_dynamodb_table\" \"table\" {\\n ${GRIT_INSERT_PLACEHOLDER}\\n $body\\n}\\``,\n ),\n '#checkov:skip=CKV_AWS_119:Encryption is configurable via var.encryption; checkov cannot resolve the conditional server_side_encryption.enabled expression',\n );\n\n // 5. Resolve the key ARN through the new local everywhere it's consumed.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${SSE_KMS_KEY_LINE} => \\`kms_key_arn = local.table_kms_key_arn\\``,\n );\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${OUTPUT_VALUE_LINE} => \\`value = local.table_kms_key_arn\\``,\n );\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${OUTPUT_DESCRIPTION_LINE} => \\`description = \"ARN of the KMS key used to encrypt the DynamoDB table, or null when using the AWS owned key (encryption = DEFAULT).\"\\``,\n );\n};\n\nconst NEW_APP_MODULE_VARIABLES_TEXT = [\n 'variable \"encryption\" {',\n ' description = \"Server-side encryption for the table. One of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT (the AWS owned key, at no cost and with no key to manage). Changing this on an already-deployed table away from CUSTOMER_MANAGED requires a manual step first - see the ts#dynamodb generator docs.\"',\n ' type = string',\n ' default = \"CUSTOMER_MANAGED\"',\n '',\n ' validation {',\n ' condition = contains([\"CUSTOMER_MANAGED\", \"AWS_MANAGED\", \"DEFAULT\"], var.encryption)',\n ' error_message = \"encryption must be one of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT.\"',\n ' }',\n '}',\n '',\n 'variable \"kms_key_arn\" {',\n ' description = \"ARN of an existing KMS key used to encrypt the table when encryption is CUSTOMER_MANAGED. When not provided and create_kms_key is true, a new key is created. Note that a customer-supplied key must already grant the DynamoDB service the necessary permissions in its own key policy.\"',\n ' type = string',\n ' default = null',\n '}',\n '',\n 'variable \"create_kms_key\" {',\n ' description = \"Whether to create a KMS key for the table. Only applies when encryption is CUSTOMER_MANAGED. Set to false when supplying kms_key_arn.\"',\n ' type = bool',\n ' default = true',\n '}',\n '',\n 'variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table. Only applies when encryption is CUSTOMER_MANAGED and create_kms_key is true.\"',\n ' type = bool',\n ' default = true',\n '}',\n].join('\\n');\n\n/**\n * Surface the same configuration as pass-through variables on each vended\n * per-table Terraform app module, matching its existing pass-through\n * convention for enable_key_rotation.\n */\nconst migrateTerraformAppModules = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(TERRAFORM_DYNAMODB_APP_DIR)) {\n return;\n }\n\n for (const dirName of tree.children(TERRAFORM_DYNAMODB_APP_DIR)) {\n const filePath = joinPathFragments(\n TERRAFORM_DYNAMODB_APP_DIR,\n dirName,\n `${dirName}.tf`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a dynamodb app module directory.\n }\n\n if (\n await matchGritQL(tree, filePath, hcl('`variable \"encryption\" { $_ }`'))\n ) {\n continue; // Already migrated.\n }\n\n const OLD_ENABLE_KEY_ROTATION_VAR = hcl(\n [\n '`variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table.\"',\n ' type = bool',\n ' default = true',\n '}`',\n ].join('\\n'),\n );\n const MODULE_BLOCK = hcl('`module \"dynamodb_table\" { $_ }`');\n const DELETION_PROTECTION_LINE = hcl(\n '`deletion_protection_enabled = var.deletion_protection_enabled`',\n );\n\n const ready = (\n await Promise.all(\n [\n OLD_ENABLE_KEY_ROTATION_VAR,\n MODULE_BLOCK,\n DELETION_PROTECTION_LINE,\n ].map((pattern) => matchGritQL(tree, filePath, pattern)),\n )\n ).every(Boolean);\n\n if (!ready) {\n nextSteps.push(terraformAppDivergedMessage(filePath));\n continue;\n }\n\n await applyGritQL(\n tree,\n filePath,\n `${OLD_ENABLE_KEY_ROTATION_VAR} => \\`${NEW_APP_MODULE_VARIABLES_TEXT.replace(/`/g, '\\\\`')}\\``,\n );\n\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`deletion_protection_enabled = var.deletion_protection_enabled\\` => \\`deletion_protection_enabled = var.deletion_protection_enabled\\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n [\n 'encryption = var.encryption',\n 'kms_key_arn = var.kms_key_arn',\n 'create_kms_key = var.create_kms_key',\n ].join('\\n '),\n );\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateCdkConstruct(tree, nextSteps);\n await migrateTerraformModule(tree, nextSteps);\n await migrateTerraformAppModules(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","addDestructuredImport","applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","CDK_DYNAMODB_FILE","TERRAFORM_DYNAMODB_FILE","TERRAFORM_DYNAMODB_APP_DIR","CDK_DIVERGED_MESSAGE","TERRAFORM_DIVERGED_MESSAGE","terraformAppDivergedMessage","filePath","migrateCdkConstruct","tree","nextSteps","exists","ENABLE_KEY_ROTATION_FIELD","ENABLE_KEY_ROTATION_COMMENT","DESTRUCTURE_OLD","KEY_CREATION_OLD","TABLE_ENCRYPTION_OLD","anchors","allPresent","Promise","all","map","pattern","every","Boolean","push","hcl","NEW_TERRAFORM_VARIABLES_TEXT","join","migrateTerraformModule","OLD_ENABLE_KEY_ROTATION_VAR","LOCALS_BLOCK","DATA_PARTITION_LINE","KMS_KEY_BLOCK","SSE_ENABLED_LINE","SSE_KMS_KEY_LINE","OUTPUT_VALUE_LINE","OUTPUT_DESCRIPTION_LINE","replace","NEW_APP_MODULE_VARIABLES_TEXT","migrateTerraformAppModules","dirName","children","MODULE_BLOCK","DELETION_PROTECTION_LINE","ready","migration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/dynamodb-configurable-encryption/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport {\n addDestructuredImport,\n applyGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Bring existing workspaces up to the generators' current DynamoDBTable\n * configurability:\n *\n * - The vended `DynamoDBTable` CDK construct gains `encryption` and\n * `encryptionKey` props. The KMS key is only created when `encryption` is\n * `TableEncryption.CUSTOMER_MANAGED` and no `encryptionKey` is supplied.\n * `enableKeyRotation` (already present) only applies to that auto-created\n * key.\n * - The generated per-table CDK app construct already forwards an optional\n * `props` parameter through to `DynamoDBTable`, so no change is needed\n * there.\n * - The vended Terraform dynamodb core module gains the equivalent\n * `encryption`, `kms_key_arn` and `create_kms_key` variables (`encryption`\n * also accepts `DEFAULT`, the AWS owned key, which CDK already supports for\n * free via `TableEncryption.DEFAULT`), with the KMS key made conditional on\n * `create_kms_key` (not on `kms_key_arn`'s nullness, which `count` can't\n * depend on when the ARN comes from another resource) and\n * `server_side_encryption.enabled` tied to `encryption`. `AWS_MANAGED`\n * resolves to the explicit `alias/aws/dynamodb` ARN rather than `null`,\n * since the provider's `kms_key_arn` is Optional+Computed and a `null`\n * there means \"leave whatever is there\", not \"clear it\".\n * - The vended Terraform per-table app module (`app/dynamodb/<name>/<name>.tf`)\n * gains pass-through `encryption`, `kms_key_arn` and `create_kms_key`\n * variables forwarded to the core module call, matching its existing\n * `enable_key_rotation` pass-through.\n *\n * These files are generated with `KeepExisting`, so without this an upgraded\n * workspace has generators that support this configuration but vended files\n * that don't. Diverged files are left untouched and reported via `nextSteps`.\n */\n\nconst CDK_DYNAMODB_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/dynamodb.ts`;\nconst TERRAFORM_DYNAMODB_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/dynamodb/dynamodb.tf`;\nconst TERRAFORM_DYNAMODB_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/dynamodb`;\n\nconst CDK_DIVERGED_MESSAGE = `${CDK_DYNAMODB_FILE}: has diverged from the generated shape - left untouched. To pick up the encryption and encryptionKey props, manually port them from the vended core/dynamodb.ts template (see the ts#dynamodb generator's DynamoDBTable construct).`;\n\nconst TERRAFORM_DIVERGED_MESSAGE = `${TERRAFORM_DYNAMODB_FILE}: has diverged from the generated shape - left untouched. To pick up the encryption and kms_key_arn variables, manually port them from the vended dynamodb.tf template (see the ts#dynamodb generator's dynamodb module).`;\n\nconst terraformAppDivergedMessage = (filePath: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. To make encryption and kms_key_arn configurable from your root Terraform configuration, add pass-through variables here and forward them to the dynamodb_table module call (see the ts#dynamodb generator's dynamodb app template).`;\n\n/**\n * Surface encryption/encryptionKey on the vended DynamoDBTable CDK\n * construct.\n */\nconst migrateCdkConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(CDK_DYNAMODB_FILE)) {\n return; // This workspace has no CDK DynamoDBTable construct.\n }\n\n if (\n await matchGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n '`readonly encryption?: TableEncryption`',\n )\n ) {\n return; // Already migrated.\n }\n\n const ENABLE_KEY_ROTATION_FIELD = '`readonly enableKeyRotation?: boolean`';\n // Matched as a literal so the new fields can be inserted *before* it (see\n // below) — GritQL doesn't include a leading comment in the span it matches\n // for the field itself, so anchoring on the field would strand this\n // comment above the newly-inserted fields instead of above the field it\n // actually documents.\n const ENABLE_KEY_ROTATION_COMMENT = `\\`/**\n * Whether to enable automatic key rotation on the KMS key used to encrypt the table.\n *\n * @default true\n */\\``;\n const DESTRUCTURE_OLD = `\\`{\n tableName,\n runtimeConfigKey,\n billingMode = BillingMode.PAY_PER_REQUEST,\n pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true },\n deletionProtection = true,\n removalPolicy = RemovalPolicy.RETAIN,\n enableKeyRotation = true,\n ...rest\n }: DynamoDBTableProps\\``;\n const KEY_CREATION_OLD =\n \"`const key = new Key(this, 'EncryptionKey', { enableKeyRotation });`\";\n const TABLE_ENCRYPTION_OLD = '`encryption: TableEncryption.CUSTOMER_MANAGED`';\n\n const anchors = [\n ENABLE_KEY_ROTATION_FIELD,\n ENABLE_KEY_ROTATION_COMMENT,\n DESTRUCTURE_OLD,\n KEY_CREATION_OLD,\n TABLE_ENCRYPTION_OLD,\n ];\n\n const allPresent = (\n await Promise.all(\n anchors.map((pattern) => matchGritQL(tree, CDK_DYNAMODB_FILE, pattern)),\n )\n ).every(Boolean);\n\n if (!allPresent) {\n nextSteps.push(CDK_DIVERGED_MESSAGE);\n return;\n }\n\n await addDestructuredImport(\n tree,\n CDK_DYNAMODB_FILE,\n ['IKey'],\n 'aws-cdk-lib/aws-kms',\n );\n\n // Inserted before the enableKeyRotation field's own leading comment (rather\n // than before the bare field) so that comment stays directly above the\n // field it documents, instead of being stranded above the new fields.\n await insertViaGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${ENABLE_KEY_ROTATION_COMMENT} as $comment => \\`${GRIT_INSERT_PLACEHOLDER}\n $comment\\``,\n `/**\n * Server-side encryption for the table.\n *\n * @default TableEncryption.CUSTOMER_MANAGED\n */\n readonly encryption?: TableEncryption;\n\n /**\n * KMS key used to encrypt the table. Only used when \\`encryption\\` is\n * \\`TableEncryption.CUSTOMER_MANAGED\\`. When not provided, a new key is created.\n */\n readonly encryptionKey?: IKey;\n\n `,\n );\n\n // Update the enableKeyRotation field's own comment to note it now only\n // applies to the auto-created key, matching the vended template exactly.\n // Routed through the insert placeholder (rather than embedding the text\n // directly in the GritQL rewrite) since the comment's own backticks would\n // otherwise be parsed as GritQL code-block delimiters.\n await insertViaGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${ENABLE_KEY_ROTATION_COMMENT} => \\`${GRIT_INSERT_PLACEHOLDER}\\``,\n `/**\n * Whether to enable automatic key rotation on the KMS key used to encrypt the table.\n * Only applies when \\`encryption\\` is \\`TableEncryption.CUSTOMER_MANAGED\\` and no\n * \\`encryptionKey\\` is supplied.\n *\n * @default true\n */`,\n );\n\n await applyGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${DESTRUCTURE_OLD} => \\`{\n tableName,\n runtimeConfigKey,\n billingMode = BillingMode.PAY_PER_REQUEST,\n pointInTimeRecoverySpecification = { pointInTimeRecoveryEnabled: true },\n deletionProtection = true,\n removalPolicy = RemovalPolicy.RETAIN,\n encryption = TableEncryption.CUSTOMER_MANAGED,\n encryptionKey,\n enableKeyRotation = true,\n ...rest\n }: DynamoDBTableProps\\``,\n );\n\n await applyGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${KEY_CREATION_OLD} => \\`const key: IKey | undefined =\n encryption === TableEncryption.CUSTOMER_MANAGED\n ? (encryptionKey ?? new Key(this, 'EncryptionKey', { enableKeyRotation }))\n : undefined;\\``,\n );\n\n await applyGritQL(\n tree,\n CDK_DYNAMODB_FILE,\n `${TABLE_ENCRYPTION_OLD} => \\`encryption\\``,\n );\n};\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\nconst NEW_TERRAFORM_VARIABLES_TEXT = [\n 'variable \"encryption\" {',\n ' description = \"Server-side encryption for the table. One of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT (the AWS owned key, at no cost and with no key to manage). Changing this on an already-deployed table away from CUSTOMER_MANAGED requires a manual step first - see the ts#dynamodb generator docs.\"',\n ' type = string',\n ' default = \"CUSTOMER_MANAGED\"',\n '',\n ' validation {',\n ' condition = contains([\"CUSTOMER_MANAGED\", \"AWS_MANAGED\", \"DEFAULT\"], var.encryption)',\n ' error_message = \"encryption must be one of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT.\"',\n ' }',\n '}',\n '',\n 'variable \"kms_key_arn\" {',\n ' description = \"ARN of an existing KMS key used to encrypt the table when encryption is CUSTOMER_MANAGED. When not provided and create_kms_key is true, a new key is created. Note that a customer-supplied key must already grant the DynamoDB service the necessary permissions in its own key policy.\"',\n ' type = string',\n ' default = null',\n '}',\n '',\n 'variable \"create_kms_key\" {',\n ' description = \"Whether to create a KMS key for the table. Only applies when encryption is CUSTOMER_MANAGED. Set to false when supplying kms_key_arn.\"',\n ' type = bool',\n ' default = true',\n '}',\n '',\n 'variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table. Only applies when encryption is CUSTOMER_MANAGED and create_kms_key is true.\"',\n ' type = bool',\n ' default = true',\n '}',\n].join('\\n');\n\n/**\n * Surface encryption/kms_key_arn on the vended Terraform dynamodb core\n * module.\n */\nconst migrateTerraformModule = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(TERRAFORM_DYNAMODB_FILE)) {\n return; // This workspace has no Terraform dynamodb module.\n }\n\n if (\n await matchGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl('`variable \"encryption\" { $_ }`'),\n )\n ) {\n return; // Already migrated.\n }\n\n const OLD_ENABLE_KEY_ROTATION_VAR = hcl(\n [\n '`variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table.\"',\n ' type = bool',\n ' default = true',\n '}`',\n ].join('\\n'),\n );\n const LOCALS_BLOCK = hcl('`locals { $_ }`');\n const DATA_PARTITION_LINE = hcl('`data \"aws_partition\" \"current\" {}`');\n const KMS_KEY_BLOCK = hcl('`resource \"aws_kms_key\" \"table\" { $_ }`');\n const SSE_ENABLED_LINE = hcl('`enabled = true`');\n const SSE_KMS_KEY_LINE = hcl('`kms_key_arn = aws_kms_key.table.arn`');\n const OUTPUT_VALUE_LINE = hcl('`value = aws_kms_key.table.arn`');\n const OUTPUT_DESCRIPTION_LINE = hcl(\n '`description = \"ARN of the KMS key used to encrypt the DynamoDB table.\"`',\n );\n\n const anchors = [\n OLD_ENABLE_KEY_ROTATION_VAR,\n LOCALS_BLOCK,\n DATA_PARTITION_LINE,\n KMS_KEY_BLOCK,\n SSE_ENABLED_LINE,\n SSE_KMS_KEY_LINE,\n OUTPUT_VALUE_LINE,\n OUTPUT_DESCRIPTION_LINE,\n ];\n\n const allPresent = (\n await Promise.all(\n anchors.map((pattern) =>\n matchGritQL(tree, TERRAFORM_DYNAMODB_FILE, pattern),\n ),\n )\n ).every(Boolean);\n\n if (!allPresent) {\n nextSteps.push(TERRAFORM_DIVERGED_MESSAGE);\n return;\n }\n\n // 1. Replace the enable_key_rotation variable with the new variables plus\n // an updated enable_key_rotation description, in the same position.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${OLD_ENABLE_KEY_ROTATION_VAR} => \\`${NEW_TERRAFORM_VARIABLES_TEXT.replace(/`/g, '\\\\`')}\\``,\n );\n\n // 2. New locals, appended into the existing locals block.\n await insertViaGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl(\n `\\`locals { $body }\\` => \\`locals {\\n $body\\n\\n ${GRIT_INSERT_PLACEHOLDER}\\n}\\``,\n ),\n [\n 'create_table_key = var.encryption == \"CUSTOMER_MANAGED\" && var.create_kms_key',\n 'table_kms_key_arn = (',\n ' var.encryption == \"CUSTOMER_MANAGED\" ? (local.create_table_key ? aws_kms_key.table[0].arn : var.kms_key_arn) :',\n ' var.encryption == \"AWS_MANAGED\" ? \"arn:${data.aws_partition.current.partition}:kms:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:alias/aws/dynamodb\" :',\n ' null',\n ')',\n ].join('\\n '),\n );\n\n // 2b. Region is needed to resolve the AWS_MANAGED key's alias ARN above.\n await insertViaGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${DATA_PARTITION_LINE} => \\`data \"aws_partition\" \"current\" {}\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n 'data \"aws_region\" \"current\" {}',\n );\n\n // 3. Make the KMS key conditional on encryption/kms_key_arn.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl(`\\`resource \"aws_kms_key\" \"table\" { $body }\\` => \\`resource \"aws_kms_key\" \"table\" {\n count = local.create_table_key ? 1 : 0\n\n $body\n}\\``),\n );\n\n // 4. Only enable KMS-backed encryption when not using the AWS owned key.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${SSE_ENABLED_LINE} => \\`enabled = var.encryption != \"DEFAULT\"\\``,\n );\n\n // 4b. Checkov's CKV_AWS_119 only passes when server_side_encryption.enabled\n // is the literal `true` — it can't resolve the conditional above, even\n // though CUSTOMER_MANAGED (the default) always uses a real CMK. Same\n // false-positive shape as CKV_AWS_139 on the vended RDS module.\n await insertViaGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n hcl(\n `\\`resource \"aws_dynamodb_table\" \"table\" { $body }\\` => \\`resource \"aws_dynamodb_table\" \"table\" {\\n ${GRIT_INSERT_PLACEHOLDER}\\n $body\\n}\\``,\n ),\n '#checkov:skip=CKV_AWS_119:Encryption is configurable via var.encryption; checkov cannot resolve the conditional server_side_encryption.enabled expression',\n );\n\n // 5. Resolve the key ARN through the new local everywhere it's consumed.\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${SSE_KMS_KEY_LINE} => \\`kms_key_arn = local.table_kms_key_arn\\``,\n );\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${OUTPUT_VALUE_LINE} => \\`value = local.table_kms_key_arn\\``,\n );\n await applyGritQL(\n tree,\n TERRAFORM_DYNAMODB_FILE,\n `${OUTPUT_DESCRIPTION_LINE} => \\`description = \"ARN of the KMS key used to encrypt the DynamoDB table, or null when using the AWS owned key (encryption = DEFAULT).\"\\``,\n );\n};\n\nconst NEW_APP_MODULE_VARIABLES_TEXT = [\n 'variable \"encryption\" {',\n ' description = \"Server-side encryption for the table. One of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT (the AWS owned key, at no cost and with no key to manage). Changing this on an already-deployed table away from CUSTOMER_MANAGED requires a manual step first - see the ts#dynamodb generator docs.\"',\n ' type = string',\n ' default = \"CUSTOMER_MANAGED\"',\n '',\n ' validation {',\n ' condition = contains([\"CUSTOMER_MANAGED\", \"AWS_MANAGED\", \"DEFAULT\"], var.encryption)',\n ' error_message = \"encryption must be one of CUSTOMER_MANAGED, AWS_MANAGED or DEFAULT.\"',\n ' }',\n '}',\n '',\n 'variable \"kms_key_arn\" {',\n ' description = \"ARN of an existing KMS key used to encrypt the table when encryption is CUSTOMER_MANAGED. When not provided and create_kms_key is true, a new key is created. Note that a customer-supplied key must already grant the DynamoDB service the necessary permissions in its own key policy.\"',\n ' type = string',\n ' default = null',\n '}',\n '',\n 'variable \"create_kms_key\" {',\n ' description = \"Whether to create a KMS key for the table. Only applies when encryption is CUSTOMER_MANAGED. Set to false when supplying kms_key_arn.\"',\n ' type = bool',\n ' default = true',\n '}',\n '',\n 'variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table. Only applies when encryption is CUSTOMER_MANAGED and create_kms_key is true.\"',\n ' type = bool',\n ' default = true',\n '}',\n].join('\\n');\n\n/**\n * Surface the same configuration as pass-through variables on each vended\n * per-table Terraform app module, matching its existing pass-through\n * convention for enable_key_rotation.\n */\nconst migrateTerraformAppModules = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(TERRAFORM_DYNAMODB_APP_DIR)) {\n return;\n }\n\n for (const dirName of tree.children(TERRAFORM_DYNAMODB_APP_DIR)) {\n const filePath = joinPathFragments(\n TERRAFORM_DYNAMODB_APP_DIR,\n dirName,\n `${dirName}.tf`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a dynamodb app module directory.\n }\n\n if (\n await matchGritQL(tree, filePath, hcl('`variable \"encryption\" { $_ }`'))\n ) {\n continue; // Already migrated.\n }\n\n const OLD_ENABLE_KEY_ROTATION_VAR = hcl(\n [\n '`variable \"enable_key_rotation\" {',\n ' description = \"Whether to enable automatic key rotation on the KMS key used to encrypt the table.\"',\n ' type = bool',\n ' default = true',\n '}`',\n ].join('\\n'),\n );\n const MODULE_BLOCK = hcl('`module \"dynamodb_table\" { $_ }`');\n const DELETION_PROTECTION_LINE = hcl(\n '`deletion_protection_enabled = var.deletion_protection_enabled`',\n );\n\n const ready = (\n await Promise.all(\n [\n OLD_ENABLE_KEY_ROTATION_VAR,\n MODULE_BLOCK,\n DELETION_PROTECTION_LINE,\n ].map((pattern) => matchGritQL(tree, filePath, pattern)),\n )\n ).every(Boolean);\n\n if (!ready) {\n nextSteps.push(terraformAppDivergedMessage(filePath));\n continue;\n }\n\n await applyGritQL(\n tree,\n filePath,\n `${OLD_ENABLE_KEY_ROTATION_VAR} => \\`${NEW_APP_MODULE_VARIABLES_TEXT.replace(/`/g, '\\\\`')}\\``,\n );\n\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`deletion_protection_enabled = var.deletion_protection_enabled\\` => \\`deletion_protection_enabled = var.deletion_protection_enabled\\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n [\n 'encryption = var.encryption',\n 'kms_key_arn = var.kms_key_arn',\n 'create_kms_key = var.create_kms_key',\n ].join('\\n '),\n );\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateCdkConstruct(tree, nextSteps);\n await migrateTerraformModule(tree, nextSteps);\n await migrateTerraformAppModules(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","addDestructuredImport","applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","CDK_DYNAMODB_FILE","TERRAFORM_DYNAMODB_FILE","TERRAFORM_DYNAMODB_APP_DIR","CDK_DIVERGED_MESSAGE","TERRAFORM_DIVERGED_MESSAGE","terraformAppDivergedMessage","filePath","migrateCdkConstruct","tree","nextSteps","exists","ENABLE_KEY_ROTATION_FIELD","ENABLE_KEY_ROTATION_COMMENT","DESTRUCTURE_OLD","KEY_CREATION_OLD","TABLE_ENCRYPTION_OLD","anchors","allPresent","Promise","all","map","pattern","every","Boolean","push","hcl","NEW_TERRAFORM_VARIABLES_TEXT","join","migrateTerraformModule","OLD_ENABLE_KEY_ROTATION_VAR","LOCALS_BLOCK","DATA_PARTITION_LINE","KMS_KEY_BLOCK","SSE_ENABLED_LINE","SSE_KMS_KEY_LINE","OUTPUT_VALUE_LINE","OUTPUT_DESCRIPTION_LINE","replace","NEW_APP_MODULE_VARIABLES_TEXT","migrateTerraformAppModules","dirName","children","MODULE_BLOCK","DELETION_PROTECTION_LINE","ready","migration"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/py-agent-ag-ui-hooks/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { PY_AGENT_GENERATOR_INFO } from '../../../py/agent/generator';\nimport {\n addPythonDestructuredImport,\n applyGritQL,\n captureGritQLVariable,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport type { ComponentMetadata } from '../../../utils/nx';\n\n/**\n * Forward a Strands py#agent's hooks to the AG-UI adapter.\n *\n * `StrandsAgent` builds a fresh `Agent` per `thread_id` by copying the template\n * Agent's kwargs, but deliberately skips `hooks` - Strands keeps only the built\n * `HookRegistry`, so the providers can't be read back off it. An AG-UI agent's\n * `log_model_errors` / `log_tool_errors` therefore never fired for served\n * requests, and model/tool failures were reported as successful runs.\n *\n * The fix hoists the hooks list out of the `Agent(...)` call into an\n * `AGENT_HOOKS` module constant in `agent.py` - whatever the user has put in it,\n * so custom hooks come along - and passes that to `StrandsAgent(...)` in\n * `main.py` as well. `agent.py` is hoisted for every protocol so the constant\n * matches what the generator vends today; only AG-UI needs the `main.py` half.\n */\n\n// `Agent`'s `hooks` list is invariant, so the hoisted constant has to declare\n// the parameter's own type - an inline literal was inferred from it instead.\nconst HOOKS_TYPE = 'list[HookProvider | HookCallback]';\nconst HOOKS_MODULE = 'strands.hooks';\n\n// Anchored on the `get_agent` context manager - the one shape shared by every\n// generated protocol and connection combination - so the constant lands\n// directly above its only use, where the generator vends it.\nconst HOIST_HOOKS_PATTERN = `language python\n\\`@contextmanager\ndef get_agent($params):\n $body\\` => raw\\`AGENT_HOOKS: ${HOOKS_TYPE} = ${GRIT_INSERT_PLACEHOLDER}\n\n\n@contextmanager\ndef get_agent($params):\n $body\\` where { $program <: not contains \\`AGENT_HOOKS\\` }`;\n\n// Scoped to the Agent constructor so a hooks list the user passes elsewhere in\n// agent.py is left alone.\nconst HOOKS_LIST_CAPTURE_PATTERN =\n 'language python\\n`hooks=[$hooks]` where { $hooks <: within `Agent($_)` }';\nconst HOOKS_LIST_REWRITE_PATTERN =\n 'language python\\n`hooks=[$_]` as $kwarg where { $kwarg <: within `Agent($_)`, $kwarg => `hooks=AGENT_HOOKS` }';\n\nconst AGUI_CONSTRUCTOR_MATCH_PATTERN =\n 'language python\\n`StrandsAgent($args)` where { $args <: contains `agent=$_` }';\nconst AGUI_HOOKS_WIRED_PATTERN =\n 'language python\\n`StrandsAgent($args)` where { $args <: contains `agent=$_`, $args <: contains `hooks=$_` }';\n// Appends after the last argument rather than re-emitting the argument list,\n// both to land `hooks=` where the template puts it and to leave the other\n// arguments' formatting and comments untouched.\nconst AGUI_HOOKS_APPEND_PATTERN =\n 'language python\\n`StrandsAgent($args)` where { $args <: contains `agent=$_`, $args <: not contains `hooks=$_`, $args <: [$..., $last], $last += `, hooks=AGENT_HOOKS` }';\n\nconst findAgentComponents = (\n components: ComponentMetadata[] | undefined,\n): ComponentMetadata[] =>\n (components ?? []).filter(\n (component) => component.generator === PY_AGENT_GENERATOR_INFO.id,\n );\n\n/**\n * Hoists `agent.py`'s `hooks=[...]` list into an `AGENT_HOOKS` module constant,\n * returning whether the file ends up exporting one.\n */\nconst hoistAgentHooks = async (\n tree: Tree,\n agentPath: string,\n): Promise<boolean> => {\n if ((tree.read(agentPath, 'utf-8') ?? '').includes('AGENT_HOOKS')) {\n return true;\n }\n\n // Nothing to hoist unless the Agent is constructed with an inline hooks list.\n const hooks = await captureGritQLVariable(\n tree,\n agentPath,\n HOOKS_LIST_CAPTURE_PATTERN,\n 'hooks',\n );\n if (!hooks) return false;\n\n if (\n !(await insertViaGritQL(tree, agentPath, HOIST_HOOKS_PATTERN, `[${hooks}]`))\n ) {\n return false;\n }\n await applyGritQL(tree, agentPath, HOOKS_LIST_REWRITE_PATTERN);\n await addPythonDestructuredImport(\n tree,\n agentPath,\n ['HookCallback', 'HookProvider'],\n HOOKS_MODULE,\n );\n return true;\n};\n\nconst migrateAgent = async (\n tree: Tree,\n agentDir: string,\n component: ComponentMetadata,\n nextSteps: string[],\n): Promise<void> => {\n // LangChain agents pass no hooks - their AG-UI adapter is handed the graph\n // itself rather than rebuilding one, so nothing is dropped.\n if (component.framework === 'langchain') return;\n\n const agentPath = joinPathFragments(agentDir, 'agent.py');\n const mainPath = joinPathFragments(agentDir, 'main.py');\n const isAgUi = component.protocol === 'ag-ui';\n\n if (!tree.exists(agentPath)) return;\n\n if (!(await hoistAgentHooks(tree, agentPath))) {\n if (isAgUi) {\n nextSteps.push(\n `${agentPath}: the hooks passed to \\`Agent(...)\\` have diverged from the generated shape - left untouched. Hoist them into an \\`AGENT_HOOKS\\` module constant and pass it to \\`StrandsAgent(...)\\` in ${mainPath} too, or AG-UI will not register them (see the py#agent generator's template).`,\n );\n }\n return;\n }\n\n // Only AG-UI rebuilds the Agent, so only its main.py needs the hooks.\n if (!isAgUi || !tree.exists(mainPath)) return;\n\n // Already passing hooks, whether from a previous run or the user's own wiring.\n if (await matchGritQL(tree, mainPath, AGUI_HOOKS_WIRED_PATTERN)) return;\n\n if (!(await matchGritQL(tree, mainPath, AGUI_CONSTRUCTOR_MATCH_PATTERN))) {\n nextSteps.push(\n `${mainPath}: the \\`StrandsAgent(...)\\` constructor has diverged from the generated shape - left untouched. Pass \\`hooks=AGENT_HOOKS\\` to it, importing \\`AGENT_HOOKS\\` from \\`.agent\\`, or AG-UI will not register the agent's hooks (see the py#agent generator's template).`,\n );\n return;\n }\n\n await applyGritQL(tree, mainPath, AGUI_HOOKS_APPEND_PATTERN);\n await addPythonDestructuredImport(tree, mainPath, ['AGENT_HOOKS'], '.agent');\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const project of getProjects(tree).values()) {\n const components = findAgentComponents(\n (project.metadata as { components?: ComponentMetadata[] })?.components,\n );\n\n for (const component of components) {\n if (!component.path) continue;\n\n // Legacy component paths point at agent.py rather than its directory.\n const componentDir = component.path.endsWith('/agent.py')\n ? component.path.slice(0, -'/agent.py'.length)\n : component.path;\n\n await migrateAgent(\n tree,\n joinPathFragments(project.root, componentDir),\n component,\n nextSteps,\n );\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","PY_AGENT_GENERATOR_INFO","addPythonDestructuredImport","applyGritQL","captureGritQLVariable","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","HOOKS_TYPE","HOOKS_MODULE","HOIST_HOOKS_PATTERN","HOOKS_LIST_CAPTURE_PATTERN","HOOKS_LIST_REWRITE_PATTERN","AGUI_CONSTRUCTOR_MATCH_PATTERN","AGUI_HOOKS_WIRED_PATTERN","AGUI_HOOKS_APPEND_PATTERN","findAgentComponents","components","filter","component","generator","id","hoistAgentHooks","tree","agentPath","read","includes","hooks","migrateAgent","agentDir","nextSteps","framework","mainPath","isAgUi","protocol","exists","push","migration","project","values","metadata","path","componentDir","endsWith","slice","length","root"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/py-agent-ag-ui-hooks/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { PY_AGENT_GENERATOR_INFO } from '../../../py/agent/generator.js';\nimport {\n addPythonDestructuredImport,\n applyGritQL,\n captureGritQLVariable,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport type { ComponentMetadata } from '../../../utils/nx.js';\n\n/**\n * Forward a Strands py#agent's hooks to the AG-UI adapter.\n *\n * `StrandsAgent` builds a fresh `Agent` per `thread_id` by copying the template\n * Agent's kwargs, but deliberately skips `hooks` - Strands keeps only the built\n * `HookRegistry`, so the providers can't be read back off it. An AG-UI agent's\n * `log_model_errors` / `log_tool_errors` therefore never fired for served\n * requests, and model/tool failures were reported as successful runs.\n *\n * The fix hoists the hooks list out of the `Agent(...)` call into an\n * `AGENT_HOOKS` module constant in `agent.py` - whatever the user has put in it,\n * so custom hooks come along - and passes that to `StrandsAgent(...)` in\n * `main.py` as well. `agent.py` is hoisted for every protocol so the constant\n * matches what the generator vends today; only AG-UI needs the `main.py` half.\n */\n\n// `Agent`'s `hooks` list is invariant, so the hoisted constant has to declare\n// the parameter's own type - an inline literal was inferred from it instead.\nconst HOOKS_TYPE = 'list[HookProvider | HookCallback]';\nconst HOOKS_MODULE = 'strands.hooks';\n\n// Anchored on the `get_agent` context manager - the one shape shared by every\n// generated protocol and connection combination - so the constant lands\n// directly above its only use, where the generator vends it.\nconst HOIST_HOOKS_PATTERN = `language python\n\\`@contextmanager\ndef get_agent($params):\n $body\\` => raw\\`AGENT_HOOKS: ${HOOKS_TYPE} = ${GRIT_INSERT_PLACEHOLDER}\n\n\n@contextmanager\ndef get_agent($params):\n $body\\` where { $program <: not contains \\`AGENT_HOOKS\\` }`;\n\n// Scoped to the Agent constructor so a hooks list the user passes elsewhere in\n// agent.py is left alone.\nconst HOOKS_LIST_CAPTURE_PATTERN =\n 'language python\\n`hooks=[$hooks]` where { $hooks <: within `Agent($_)` }';\nconst HOOKS_LIST_REWRITE_PATTERN =\n 'language python\\n`hooks=[$_]` as $kwarg where { $kwarg <: within `Agent($_)`, $kwarg => `hooks=AGENT_HOOKS` }';\n\nconst AGUI_CONSTRUCTOR_MATCH_PATTERN =\n 'language python\\n`StrandsAgent($args)` where { $args <: contains `agent=$_` }';\nconst AGUI_HOOKS_WIRED_PATTERN =\n 'language python\\n`StrandsAgent($args)` where { $args <: contains `agent=$_`, $args <: contains `hooks=$_` }';\n// Appends after the last argument rather than re-emitting the argument list,\n// both to land `hooks=` where the template puts it and to leave the other\n// arguments' formatting and comments untouched.\nconst AGUI_HOOKS_APPEND_PATTERN =\n 'language python\\n`StrandsAgent($args)` where { $args <: contains `agent=$_`, $args <: not contains `hooks=$_`, $args <: [$..., $last], $last += `, hooks=AGENT_HOOKS` }';\n\nconst findAgentComponents = (\n components: ComponentMetadata[] | undefined,\n): ComponentMetadata[] =>\n (components ?? []).filter(\n (component) => component.generator === PY_AGENT_GENERATOR_INFO.id,\n );\n\n/**\n * Hoists `agent.py`'s `hooks=[...]` list into an `AGENT_HOOKS` module constant,\n * returning whether the file ends up exporting one.\n */\nconst hoistAgentHooks = async (\n tree: Tree,\n agentPath: string,\n): Promise<boolean> => {\n if ((tree.read(agentPath, 'utf-8') ?? '').includes('AGENT_HOOKS')) {\n return true;\n }\n\n // Nothing to hoist unless the Agent is constructed with an inline hooks list.\n const hooks = await captureGritQLVariable(\n tree,\n agentPath,\n HOOKS_LIST_CAPTURE_PATTERN,\n 'hooks',\n );\n if (!hooks) return false;\n\n if (\n !(await insertViaGritQL(tree, agentPath, HOIST_HOOKS_PATTERN, `[${hooks}]`))\n ) {\n return false;\n }\n await applyGritQL(tree, agentPath, HOOKS_LIST_REWRITE_PATTERN);\n await addPythonDestructuredImport(\n tree,\n agentPath,\n ['HookCallback', 'HookProvider'],\n HOOKS_MODULE,\n );\n return true;\n};\n\nconst migrateAgent = async (\n tree: Tree,\n agentDir: string,\n component: ComponentMetadata,\n nextSteps: string[],\n): Promise<void> => {\n // LangChain agents pass no hooks - their AG-UI adapter is handed the graph\n // itself rather than rebuilding one, so nothing is dropped.\n if (component.framework === 'langchain') return;\n\n const agentPath = joinPathFragments(agentDir, 'agent.py');\n const mainPath = joinPathFragments(agentDir, 'main.py');\n const isAgUi = component.protocol === 'ag-ui';\n\n if (!tree.exists(agentPath)) return;\n\n if (!(await hoistAgentHooks(tree, agentPath))) {\n if (isAgUi) {\n nextSteps.push(\n `${agentPath}: the hooks passed to \\`Agent(...)\\` have diverged from the generated shape - left untouched. Hoist them into an \\`AGENT_HOOKS\\` module constant and pass it to \\`StrandsAgent(...)\\` in ${mainPath} too, or AG-UI will not register them (see the py#agent generator's template).`,\n );\n }\n return;\n }\n\n // Only AG-UI rebuilds the Agent, so only its main.py needs the hooks.\n if (!isAgUi || !tree.exists(mainPath)) return;\n\n // Already passing hooks, whether from a previous run or the user's own wiring.\n if (await matchGritQL(tree, mainPath, AGUI_HOOKS_WIRED_PATTERN)) return;\n\n if (!(await matchGritQL(tree, mainPath, AGUI_CONSTRUCTOR_MATCH_PATTERN))) {\n nextSteps.push(\n `${mainPath}: the \\`StrandsAgent(...)\\` constructor has diverged from the generated shape - left untouched. Pass \\`hooks=AGENT_HOOKS\\` to it, importing \\`AGENT_HOOKS\\` from \\`.agent\\`, or AG-UI will not register the agent's hooks (see the py#agent generator's template).`,\n );\n return;\n }\n\n await applyGritQL(tree, mainPath, AGUI_HOOKS_APPEND_PATTERN);\n await addPythonDestructuredImport(tree, mainPath, ['AGENT_HOOKS'], '.agent');\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const project of getProjects(tree).values()) {\n const components = findAgentComponents(\n (project.metadata as { components?: ComponentMetadata[] })?.components,\n );\n\n for (const component of components) {\n if (!component.path) continue;\n\n // Legacy component paths point at agent.py rather than its directory.\n const componentDir = component.path.endsWith('/agent.py')\n ? component.path.slice(0, -'/agent.py'.length)\n : component.path;\n\n await migrateAgent(\n tree,\n joinPathFragments(project.root, componentDir),\n component,\n nextSteps,\n );\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","PY_AGENT_GENERATOR_INFO","addPythonDestructuredImport","applyGritQL","captureGritQLVariable","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","HOOKS_TYPE","HOOKS_MODULE","HOIST_HOOKS_PATTERN","HOOKS_LIST_CAPTURE_PATTERN","HOOKS_LIST_REWRITE_PATTERN","AGUI_CONSTRUCTOR_MATCH_PATTERN","AGUI_HOOKS_WIRED_PATTERN","AGUI_HOOKS_APPEND_PATTERN","findAgentComponents","components","filter","component","generator","id","hoistAgentHooks","tree","agentPath","read","includes","hooks","migrateAgent","agentDir","nextSteps","framework","mainPath","isAgUi","protocol","exists","push","migration","project","values","metadata","path","componentDir","endsWith","slice","length","root"],"mappings":"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"}
|