@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.
Files changed (469) hide show
  1. package/generators.json +10 -0
  2. package/migrations.json +1 -1
  3. package/package.json +1 -1
  4. package/src/agentcore-gateway/agent-connection/generator.d.ts +1 -1
  5. package/src/agentcore-gateway/agent-connection/generator.js.map +1 -1
  6. package/src/agentcore-gateway/agent-connection/schema.d.js.map +1 -1
  7. package/src/agentcore-gateway/agent-connection/schema.d.ts +1 -1
  8. package/src/agentcore-gateway/attach-upstream.js.map +1 -1
  9. package/src/agentcore-gateway/gateway-connection/generator.d.ts +1 -1
  10. package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -1
  11. package/src/agentcore-gateway/gateway-connection/schema.d.js.map +1 -1
  12. package/src/agentcore-gateway/gateway-connection/schema.d.ts +1 -1
  13. package/src/agentcore-gateway/generator.d.ts +3 -3
  14. package/src/agentcore-gateway/generator.js.map +1 -1
  15. package/src/agentcore-gateway/mcp-connection/generator.d.ts +1 -1
  16. package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
  17. package/src/agentcore-gateway/mcp-connection/schema.d.js.map +1 -1
  18. package/src/agentcore-gateway/mcp-connection/schema.d.ts +1 -1
  19. package/src/agentcore-gateway/react-connection/generator.d.ts +1 -1
  20. package/src/agentcore-gateway/react-connection/generator.js.map +1 -1
  21. package/src/agentcore-gateway/react-connection/schema.d.js.map +1 -1
  22. package/src/agentcore-gateway/react-connection/schema.d.ts +1 -1
  23. package/src/agentcore-gateway/schema.d.js.map +1 -1
  24. package/src/agentcore-gateway/schema.d.ts +1 -1
  25. package/src/agentcore-harness/generator.d.ts +4 -4
  26. package/src/agentcore-harness/generator.js.map +1 -1
  27. package/src/agentcore-harness/schema.d.js.map +1 -1
  28. package/src/agentcore-harness/schema.d.ts +1 -1
  29. package/src/connection/agent-local-dev.d.ts +1 -1
  30. package/src/connection/agent-local-dev.js.map +1 -1
  31. package/src/connection/agent-runtime-config.js.map +1 -1
  32. package/src/connection/gateway-runtime-config.js.map +1 -1
  33. package/src/connection/generator.d.ts +2 -2
  34. package/src/connection/generator.js.map +1 -1
  35. package/src/connection/local-dev.js.map +1 -1
  36. package/src/connection/scaffold-catalog.d.ts +1 -1
  37. package/src/connection/scaffold-catalog.js +6 -6
  38. package/src/connection/scaffold-catalog.js.map +1 -1
  39. package/src/connection/schema-resolver.d.ts +1 -1
  40. package/src/connection/schema-resolver.js.map +1 -1
  41. package/src/index.d.ts +1 -1
  42. package/src/index.js.map +1 -1
  43. package/src/infra/app/generator.d.ts +7 -7
  44. package/src/infra/app/generator.js.map +1 -1
  45. package/src/init/generator.d.ts +3 -3
  46. package/src/init/generator.js.map +1 -1
  47. package/src/init/schema.d.js.map +1 -1
  48. package/src/init/schema.d.ts +2 -2
  49. package/src/internal/test-matrix/generator.js.map +1 -1
  50. package/src/license/config-types.d.ts +2 -2
  51. package/src/license/config-types.js.map +1 -1
  52. package/src/license/config.d.ts +2 -2
  53. package/src/license/config.js.map +1 -1
  54. package/src/license/dependency-check/check.d.ts +2 -2
  55. package/src/license/dependency-check/check.js.map +1 -1
  56. package/src/license/dependency-check/collectors/collector.js.map +1 -1
  57. package/src/license/dependency-check/collectors/python-collector.js.map +1 -1
  58. package/src/license/dependency-check/evaluator.d.ts +1 -1
  59. package/src/license/dependency-check/evaluator.js.map +1 -1
  60. package/src/license/dependency-check/executor.js.map +1 -1
  61. package/src/license/dependency-check/pre-approved.d.ts +1 -1
  62. package/src/license/dependency-check/pre-approved.js.map +1 -1
  63. package/src/license/dependency-check/types.d.ts +1 -1
  64. package/src/license/dependency-check/types.js.map +1 -1
  65. package/src/license/generator.d.ts +1 -1
  66. package/src/license/generator.js.map +1 -1
  67. package/src/license/index.d.ts +4 -4
  68. package/src/license/index.js.map +1 -1
  69. package/src/license/known-exceptions.d.ts +1 -1
  70. package/src/license/known-exceptions.js.map +1 -1
  71. package/src/license/sync/generator.js.map +1 -1
  72. package/src/license/sync/project-file-sync.d.ts +1 -1
  73. package/src/license/sync/project-file-sync.js.map +1 -1
  74. package/src/mcp-server/dev-server.js.map +1 -1
  75. package/src/mcp-server/generator-info.d.ts +3 -3
  76. package/src/mcp-server/generator-info.js.map +1 -1
  77. package/src/mcp-server/guide-pipeline.d.ts +1 -1
  78. package/src/mcp-server/guide-pipeline.js.map +1 -1
  79. package/src/mcp-server/guide-render.js.map +1 -1
  80. package/src/mcp-server/index.js.map +1 -1
  81. package/src/mcp-server/mdx-ast.js.map +1 -1
  82. package/src/mcp-server/server.js.map +1 -1
  83. package/src/mcp-server/tools/add-to-existing-project.d.ts +1 -1
  84. package/src/mcp-server/tools/add-to-existing-project.js.map +1 -1
  85. package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
  86. package/src/mcp-server/tools/general-guidance.d.ts +1 -1
  87. package/src/mcp-server/tools/general-guidance.js +1 -1
  88. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  89. package/src/mcp-server/tools/generator-guide.d.ts +1 -1
  90. package/src/mcp-server/tools/generator-guide.js.map +1 -1
  91. package/src/mcp-server/tools/list-generators.d.ts +1 -1
  92. package/src/mcp-server/tools/list-generators.js.map +1 -1
  93. package/src/mcp-server/tools/upgrade-workspace.d.ts +1 -1
  94. package/src/mcp-server/tools/upgrade-workspace.js.map +1 -1
  95. package/src/migrations/latest/apt-security-updates-in-container-images/migration.js.map +1 -1
  96. package/src/migrations/latest/dynamodb-configurable-encryption/migration.js.map +1 -1
  97. package/src/migrations/latest/py-agent-ag-ui-hooks/migration.js.map +1 -1
  98. package/src/migrations/latest/py-agent-session-id-middleware-extraction/migration.js.map +1 -1
  99. package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js.map +1 -1
  100. package/src/migrations/latest/static-website-configurable-waf-encryption/migration.js.map +1 -1
  101. package/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.js.map +1 -1
  102. package/src/migrations/latest/user-identity-configurable-mfa/migration.js.map +1 -1
  103. package/src/migrations/v1.0.0-rc.50/0001-modernize-function-props-cast/migration.js.map +1 -1
  104. package/src/migrations/v1.0.0-rc.50/0002-restrict-cors-to-custom-domains/migration.js.map +1 -1
  105. package/src/migrations/v1.0.0-rc.50/0003-terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -1
  106. package/src/migrations/v1.0.0-rc.52/0001-user-identity-waf-allow-localhost-callback/migration.js.map +1 -1
  107. package/src/migrations/v1.0.0-rc.54/0001-order-access-log-delivery-after-bucket-policy/migration.js.map +1 -1
  108. package/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.d.ts +1 -1
  109. package/src/migrations/v1.0.0-rc.55/0001-backfill-generator-metadata/migration.js.map +1 -1
  110. package/src/migrations/v1.0.0-rc.56/0001-dynamodb-local-remove-optimize-flag/migration.js.map +1 -1
  111. package/src/migrations/v1.0.0-rc.57/0001-ts-agent-session-management-support/migration.js.map +1 -1
  112. package/src/migrations/v1.0.0-rc.58/0001-smithy-ssdk-bundle-pins/migration.js.map +1 -1
  113. package/src/migrations/v1.0.0-rc.59/0001-gateway-agent-targets/migration.js.map +1 -1
  114. package/src/migrations/v1.0.0-rc.60/0001-gateway-cognito-passthrough/migration.js.map +1 -1
  115. package/src/migrations/v1.0.0-rc.60/0002-waf-log-group-removal/migration.js.map +1 -1
  116. package/src/migrations/v1.0.0-rc.60/0003-strip-pip-from-python-images/migration.js.map +1 -1
  117. package/src/migrations/v1.0.0-rc.61/0001-py-agent-lifespan-construction/migration.js.map +1 -1
  118. package/src/migrations/v1.0.0-rc.62/0001-rename-load-runtime-config-target/migration.js.map +1 -1
  119. package/src/migrations/v1.0.0-rc.63/0001-add-deploy-sandbox-target/migration.js.map +1 -1
  120. package/src/migrations/v1.0.0-rc.64/0001-smithy-build-without-docker/migration.js.map +1 -1
  121. package/src/migrations/v1.0.0-rc.65/0001-vite-config-import-meta-dirname/migration.js.map +1 -1
  122. package/src/migrations/v1.0.0-rc.65/0002-rolldown-code-splitting/migration.js.map +1 -1
  123. package/src/migrations/v1.0.0-rc.67/0001-smithy-server-package-rename/migration.js.map +1 -1
  124. package/src/migrations/v1.0.0-rc.68/0001-translate-script-whole-file-writes/migration.js.map +1 -1
  125. package/src/migrations/v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction/migration.js.map +1 -1
  126. package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.js.map +1 -1
  127. package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js.map +1 -1
  128. package/src/open-api/ts-client/generator.d.ts +1 -1
  129. package/src/open-api/ts-client/generator.js.map +1 -1
  130. package/src/open-api/ts-hooks/generator.d.ts +1 -1
  131. package/src/open-api/ts-hooks/generator.js.map +1 -1
  132. package/src/open-api/ts-hooks/generator.spec.tsx +6 -6
  133. package/src/open-api/ts-metadata/generator.d.ts +1 -1
  134. package/src/open-api/ts-metadata/generator.js.map +1 -1
  135. package/src/open-api/utils/codegen-data/languages.d.ts +1 -1
  136. package/src/open-api/utils/codegen-data/languages.js.map +1 -1
  137. package/src/open-api/utils/codegen-data.d.ts +2 -2
  138. package/src/open-api/utils/codegen-data.js.map +1 -1
  139. package/src/open-api/utils/normalise.d.ts +1 -1
  140. package/src/open-api/utils/normalise.js.map +1 -1
  141. package/src/open-api/utils/parse.d.ts +1 -1
  142. package/src/open-api/utils/parse.js.map +1 -1
  143. package/src/open-api/utils/parser.d.ts +2 -2
  144. package/src/open-api/utils/parser.js.map +1 -1
  145. package/src/open-api/utils/refs.d.ts +1 -1
  146. package/src/open-api/utils/refs.js.map +1 -1
  147. package/src/preset/generator.d.ts +3 -3
  148. package/src/preset/generator.js.map +1 -1
  149. package/src/preset/schema.d.js.map +1 -1
  150. package/src/preset/schema.d.ts +3 -3
  151. package/src/py/agent/a2a-connection/generator.d.ts +3 -3
  152. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  153. package/src/py/agent/a2a-connection/schema.d.js.map +1 -1
  154. package/src/py/agent/a2a-connection/schema.d.ts +1 -1
  155. package/src/py/agent/gateway-connection/generator.d.ts +3 -3
  156. package/src/py/agent/gateway-connection/generator.js.map +1 -1
  157. package/src/py/agent/gateway-connection/schema.d.js.map +1 -1
  158. package/src/py/agent/gateway-connection/schema.d.ts +1 -1
  159. package/src/py/agent/generator.d.ts +3 -3
  160. package/src/py/agent/generator.js.map +1 -1
  161. package/src/py/agent/mcp-connection/generator.d.ts +3 -3
  162. package/src/py/agent/mcp-connection/generator.js.map +1 -1
  163. package/src/py/agent/mcp-connection/schema.d.js.map +1 -1
  164. package/src/py/agent/mcp-connection/schema.d.ts +1 -1
  165. package/src/py/agent/react-connection/generator.d.ts +12 -12
  166. package/src/py/agent/react-connection/generator.js.map +1 -1
  167. package/src/py/agent/react-connection/local-dev.d.ts +1 -1
  168. package/src/py/agent/react-connection/local-dev.js.map +1 -1
  169. package/src/py/agent/react-connection/schema.d.js.map +1 -1
  170. package/src/py/agent/react-connection/schema.d.ts +1 -1
  171. package/src/py/agent/schema.d.js.map +1 -1
  172. package/src/py/agent/schema.d.ts +1 -1
  173. package/src/py/api/generator.d.ts +1 -1
  174. package/src/py/api/generator.js.map +1 -1
  175. package/src/py/api/schema.d.js.map +1 -1
  176. package/src/py/api/schema.d.ts +1 -1
  177. package/src/py/dynamodb/agent-connection/generator.d.ts +1 -1
  178. package/src/py/dynamodb/agent-connection/generator.js.map +1 -1
  179. package/src/py/dynamodb/agent-connection/schema.d.js.map +1 -1
  180. package/src/py/dynamodb/agent-connection/schema.d.ts +1 -1
  181. package/src/py/dynamodb/fast-api-connection/generator.d.ts +1 -1
  182. package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -1
  183. package/src/py/dynamodb/generator.d.ts +4 -4
  184. package/src/py/dynamodb/generator.js.map +1 -1
  185. package/src/py/dynamodb/mcp-server-connection/generator.d.ts +1 -1
  186. package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -1
  187. package/src/py/dynamodb/mcp-server-connection/schema.d.js.map +1 -1
  188. package/src/py/dynamodb/mcp-server-connection/schema.d.ts +1 -1
  189. package/src/py/dynamodb/schema.d.js.map +1 -1
  190. package/src/py/dynamodb/schema.d.ts +1 -1
  191. package/src/py/fast-api/generator.d.ts +3 -3
  192. package/src/py/fast-api/generator.js.map +1 -1
  193. package/src/py/fast-api/react/generator.d.ts +3 -3
  194. package/src/py/fast-api/react/generator.js.map +1 -1
  195. package/src/py/fast-api/react/open-api.js.map +1 -1
  196. package/src/py/fast-api/schema.d.js.map +1 -1
  197. package/src/py/fast-api/schema.d.ts +1 -1
  198. package/src/py/lambda-function/files/handler/__lambdaFunctionSnakeCase__.py.template +1 -1
  199. package/src/py/lambda-function/generator.d.ts +10 -4
  200. package/src/py/lambda-function/generator.js +8 -1
  201. package/src/py/lambda-function/generator.js.map +1 -1
  202. package/src/py/lambda-function/schema.d.js.map +1 -1
  203. package/src/py/lambda-function/schema.d.ts +2 -2
  204. package/src/py/lambda-function/schema.json +1 -1
  205. package/src/py/mcp-server/generator.d.ts +3 -3
  206. package/src/py/mcp-server/generator.js.map +1 -1
  207. package/src/py/mcp-server/schema.d.js.map +1 -1
  208. package/src/py/mcp-server/schema.d.ts +1 -1
  209. package/src/py/project/generator.d.ts +2 -2
  210. package/src/py/project/generator.js.map +1 -1
  211. package/src/py/project/schema.json +1 -0
  212. package/src/py/rdb/agent-connection/generator.d.ts +1 -1
  213. package/src/py/rdb/agent-connection/generator.js.map +1 -1
  214. package/src/py/rdb/agent-connection/schema.d.js.map +1 -1
  215. package/src/py/rdb/agent-connection/schema.d.ts +1 -1
  216. package/src/py/rdb/fast-api-connection/generator.d.ts +1 -1
  217. package/src/py/rdb/fast-api-connection/generator.js.map +1 -1
  218. package/src/py/rdb/generator.d.ts +3 -3
  219. package/src/py/rdb/generator.js.map +1 -1
  220. package/src/py/rdb/mcp-server-connection/generator.d.ts +1 -1
  221. package/src/py/rdb/mcp-server-connection/generator.js.map +1 -1
  222. package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -1
  223. package/src/py/rdb/mcp-server-connection/schema.d.ts +1 -1
  224. package/src/sdk/agentcore-gateway.d.ts +1 -1
  225. package/src/sdk/agentcore-gateway.js.map +1 -1
  226. package/src/sdk/agentcore-harness.d.ts +1 -1
  227. package/src/sdk/agentcore-harness.js.map +1 -1
  228. package/src/sdk/connection.d.ts +1 -1
  229. package/src/sdk/connection.js.map +1 -1
  230. package/src/sdk/license.d.ts +3 -3
  231. package/src/sdk/license.js.map +1 -1
  232. package/src/sdk/open-api.d.ts +3 -3
  233. package/src/sdk/open-api.js.map +1 -1
  234. package/src/sdk/py.d.ts +7 -7
  235. package/src/sdk/py.js.map +1 -1
  236. package/src/sdk/smithy.d.ts +1 -1
  237. package/src/sdk/smithy.js.map +1 -1
  238. package/src/sdk/terraform.d.ts +1 -1
  239. package/src/sdk/terraform.js.map +1 -1
  240. package/src/sdk/ts.d.ts +18 -18
  241. package/src/sdk/ts.js.map +1 -1
  242. package/src/sdk/utils/ast.d.ts +1 -1
  243. package/src/sdk/utils/ast.js.map +1 -1
  244. package/src/sdk/utils/format.d.ts +1 -1
  245. package/src/sdk/utils/format.js.map +1 -1
  246. package/src/sdk/utils/test.d.ts +1 -1
  247. package/src/sdk/utils/test.js.map +1 -1
  248. package/src/smithy/project/generator.d.ts +4 -4
  249. package/src/smithy/project/generator.js.map +1 -1
  250. package/src/smithy/react-connection/generator.d.ts +3 -3
  251. package/src/smithy/react-connection/generator.js.map +1 -1
  252. package/src/smithy/ts/api/generator.d.ts +3 -3
  253. package/src/smithy/ts/api/generator.js.map +1 -1
  254. package/src/smithy/ts/api/schema.d.js.map +1 -1
  255. package/src/smithy/ts/api/schema.d.ts +1 -1
  256. package/src/terraform/project/generator.d.ts +5 -5
  257. package/src/terraform/project/generator.js.map +1 -1
  258. package/src/trpc/backend/generator.d.ts +3 -3
  259. package/src/trpc/backend/generator.js.map +1 -1
  260. package/src/trpc/backend/schema.d.js.map +1 -1
  261. package/src/trpc/backend/schema.d.ts +1 -1
  262. package/src/trpc/react/generator.d.ts +3 -3
  263. package/src/trpc/react/generator.js.map +1 -1
  264. package/src/ts/agent/a2a-connection/generator.d.ts +3 -3
  265. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  266. package/src/ts/agent/a2a-connection/schema.d.js.map +1 -1
  267. package/src/ts/agent/a2a-connection/schema.d.ts +1 -1
  268. package/src/ts/agent/gateway-connection/generator.d.ts +3 -3
  269. package/src/ts/agent/gateway-connection/generator.js.map +1 -1
  270. package/src/ts/agent/gateway-connection/schema.d.js.map +1 -1
  271. package/src/ts/agent/gateway-connection/schema.d.ts +1 -1
  272. package/src/ts/agent/generator.d.ts +3 -3
  273. package/src/ts/agent/generator.js.map +1 -1
  274. package/src/ts/agent/mcp-connection/generator.d.ts +3 -3
  275. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  276. package/src/ts/agent/mcp-connection/schema.d.js.map +1 -1
  277. package/src/ts/agent/mcp-connection/schema.d.ts +1 -1
  278. package/src/ts/agent/react-connection/generator.d.ts +11 -11
  279. package/src/ts/agent/react-connection/generator.js.map +1 -1
  280. package/src/ts/agent/react-connection/local-dev.d.ts +1 -1
  281. package/src/ts/agent/react-connection/local-dev.js.map +1 -1
  282. package/src/ts/agent/react-connection/schema.d.js.map +1 -1
  283. package/src/ts/agent/react-connection/schema.d.ts +1 -1
  284. package/src/ts/agent/schema.d.js.map +1 -1
  285. package/src/ts/agent/schema.d.ts +1 -1
  286. package/src/ts/api/generator.d.ts +1 -1
  287. package/src/ts/api/generator.js.map +1 -1
  288. package/src/ts/api/schema.d.js.map +1 -1
  289. package/src/ts/api/schema.d.ts +1 -1
  290. package/src/ts/astro-docs/generator.d.ts +3 -3
  291. package/src/ts/astro-docs/generator.js.map +1 -1
  292. package/src/ts/dcr-proxy/generator.d.ts +5 -5
  293. package/src/ts/dcr-proxy/generator.js.map +1 -1
  294. package/src/ts/dcr-proxy/schema.d.js.map +1 -1
  295. package/src/ts/dcr-proxy/schema.d.ts +1 -1
  296. package/src/ts/docs/generator.d.ts +1 -1
  297. package/src/ts/docs/generator.js.map +1 -1
  298. package/src/ts/dynamodb/agent-connection/generator.d.ts +1 -1
  299. package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
  300. package/src/ts/dynamodb/agent-connection/schema.d.js.map +1 -1
  301. package/src/ts/dynamodb/agent-connection/schema.d.ts +1 -1
  302. package/src/ts/dynamodb/generator.d.ts +5 -5
  303. package/src/ts/dynamodb/generator.js +1 -0
  304. package/src/ts/dynamodb/generator.js.map +1 -1
  305. package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +1 -1
  306. package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
  307. package/src/ts/dynamodb/mcp-server-connection/schema.d.js.map +1 -1
  308. package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +1 -1
  309. package/src/ts/dynamodb/schema.d.js.map +1 -1
  310. package/src/ts/dynamodb/schema.d.ts +1 -1
  311. package/src/ts/dynamodb/smithy-connection/generator.d.ts +1 -1
  312. package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
  313. package/src/ts/dynamodb/trpc-connection/generator.d.ts +1 -1
  314. package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
  315. package/src/ts/lambda-function/generator.d.ts +5 -5
  316. package/src/ts/lambda-function/generator.js.map +1 -1
  317. package/src/ts/lambda-function/schema.d.js.map +1 -1
  318. package/src/ts/lambda-function/schema.d.ts +1 -1
  319. package/src/ts/lib/biome.d.ts +1 -1
  320. package/src/ts/lib/biome.js.map +1 -1
  321. package/src/ts/lib/generator.d.ts +3 -3
  322. package/src/ts/lib/generator.js.map +1 -1
  323. package/src/ts/lib/ts-project-utils.d.ts +3 -3
  324. package/src/ts/lib/ts-project-utils.js.map +1 -1
  325. package/src/ts/lib/vitest.d.ts +2 -2
  326. package/src/ts/lib/vitest.js.map +1 -1
  327. package/src/ts/mcp-server/generator.d.ts +3 -3
  328. package/src/ts/mcp-server/generator.js.map +1 -1
  329. package/src/ts/mcp-server/schema.d.js.map +1 -1
  330. package/src/ts/mcp-server/schema.d.ts +1 -1
  331. package/src/ts/nx-generator/generator.d.ts +2 -2
  332. package/src/ts/nx-generator/generator.js.map +1 -1
  333. package/src/ts/nx-migration/generator.d.ts +3 -3
  334. package/src/ts/nx-migration/generator.js.map +1 -1
  335. package/src/ts/nx-plugin/generator.d.ts +3 -3
  336. package/src/ts/nx-plugin/generator.js.map +1 -1
  337. package/src/ts/nx-plugin/utils.d.ts +1 -1
  338. package/src/ts/nx-plugin/utils.js.map +1 -1
  339. package/src/ts/rdb/agent-connection/generator.d.ts +1 -1
  340. package/src/ts/rdb/agent-connection/generator.js.map +1 -1
  341. package/src/ts/rdb/agent-connection/schema.d.js.map +1 -1
  342. package/src/ts/rdb/agent-connection/schema.d.ts +1 -1
  343. package/src/ts/rdb/generator.d.ts +4 -4
  344. package/src/ts/rdb/generator.js +1 -0
  345. package/src/ts/rdb/generator.js.map +1 -1
  346. package/src/ts/rdb/mcp-server-connection/generator.d.ts +1 -1
  347. package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
  348. package/src/ts/rdb/mcp-server-connection/schema.d.js.map +1 -1
  349. package/src/ts/rdb/mcp-server-connection/schema.d.ts +1 -1
  350. package/src/ts/rdb/schema.d.js.map +1 -1
  351. package/src/ts/rdb/schema.d.ts +1 -1
  352. package/src/ts/rdb/smithy-connection/generator.d.ts +1 -1
  353. package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
  354. package/src/ts/rdb/trpc-connection/generator.d.ts +1 -1
  355. package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
  356. package/src/ts/react-website/agui/generator.d.ts +2 -2
  357. package/src/ts/react-website/agui/generator.js.map +1 -1
  358. package/src/ts/react-website/app/generator.d.ts +3 -3
  359. package/src/ts/react-website/app/generator.js.map +1 -1
  360. package/src/ts/react-website/app/schema.d.js.map +1 -1
  361. package/src/ts/react-website/app/schema.d.ts +2 -2
  362. package/src/ts/react-website/cognito-auth/generator.d.ts +5 -5
  363. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  364. package/src/ts/react-website/cognito-auth/schema.d.js.map +1 -1
  365. package/src/ts/react-website/cognito-auth/schema.d.ts +1 -1
  366. package/src/ts/react-website/cognito-auth/utils.js.map +1 -1
  367. package/src/ts/react-website/runtime-config/generator.d.ts +1 -1
  368. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  369. package/src/ts/sync/generator.d.ts +1 -1
  370. package/src/ts/sync/generator.js.map +1 -1
  371. package/src/ts/website/app/generator.d.ts +1 -1
  372. package/src/ts/website/app/generator.js.map +1 -1
  373. package/src/ts/website/app/schema.d.js.map +1 -1
  374. package/src/ts/website/app/schema.d.ts +2 -2
  375. package/src/ts/website/auth/generator.d.ts +1 -1
  376. package/src/ts/website/auth/generator.js.map +1 -1
  377. package/src/ts/website/auth/schema.d.js.map +1 -1
  378. package/src/ts/website/auth/schema.d.ts +1 -1
  379. package/src/utils/add-dependencies.d.ts +1 -1
  380. package/src/utils/add-dependencies.js.map +1 -1
  381. package/src/utils/agent-chat/agent-chat.js.map +1 -1
  382. package/src/utils/agent-connection/agent-connection.d.ts +2 -2
  383. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  384. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +4 -4
  385. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  386. package/src/utils/api-constructs/api-constructs.d.ts +3 -3
  387. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  388. package/src/utils/api-constructs/open-api-metadata.d.ts +1 -1
  389. package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
  390. package/src/utils/ast/website.js.map +1 -1
  391. package/src/utils/ast.js +6 -0
  392. package/src/utils/ast.js.map +1 -1
  393. package/src/utils/bundle/bundle.d.ts +1 -1
  394. package/src/utils/bundle/bundle.js.map +1 -1
  395. package/src/utils/commands.d.ts +1 -1
  396. package/src/utils/commands.js.map +1 -1
  397. package/src/utils/config/index.d.ts +6 -6
  398. package/src/utils/config/index.js.map +1 -1
  399. package/src/utils/config/utils.d.ts +1 -1
  400. package/src/utils/config/utils.js.map +1 -1
  401. package/src/utils/connection/open-api/react.d.ts +1 -1
  402. package/src/utils/connection/open-api/react.js.map +1 -1
  403. package/src/utils/containers.js.map +1 -1
  404. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.d.ts +1 -1
  405. package/src/utils/dcr-proxy-constructs/dcr-proxy-constructs.js.map +1 -1
  406. package/src/utils/declared-dependencies.d.ts +1 -1
  407. package/src/utils/declared-dependencies.js.map +1 -1
  408. package/src/utils/dependencies.js.map +1 -1
  409. package/src/utils/docker.d.ts +1 -1
  410. package/src/utils/docker.js.map +1 -1
  411. package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +1 -1
  412. package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
  413. package/src/utils/format.js.map +1 -1
  414. package/src/utils/fs.d.ts +1 -1
  415. package/src/utils/fs.js.map +1 -1
  416. package/src/utils/function-constructs/function-constructs.d.ts +1 -1
  417. package/src/utils/function-constructs/function-constructs.js.map +1 -1
  418. package/src/utils/iac.d.ts +2 -2
  419. package/src/utils/iac.js.map +1 -1
  420. package/src/utils/identity-constructs/identity-constructs.d.ts +2 -2
  421. package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
  422. package/src/utils/init.d.ts +3 -3
  423. package/src/utils/init.js.map +1 -1
  424. package/src/utils/install.d.ts +1 -1
  425. package/src/utils/install.js.map +1 -1
  426. package/src/utils/mcp.js.map +1 -1
  427. package/src/utils/metrics.d.ts +1 -1
  428. package/src/utils/metrics.js.map +1 -1
  429. package/src/utils/migration-manifest.d.ts +1 -1
  430. package/src/utils/migration-manifest.js.map +1 -1
  431. package/src/utils/nx.d.ts +3 -3
  432. package/src/utils/nx.js.map +1 -1
  433. package/src/utils/paths.js.map +1 -1
  434. package/src/utils/pkg-manager.d.ts +1 -1
  435. package/src/utils/pkg-manager.js.map +1 -1
  436. package/src/utils/pnpm-workspace.js.map +1 -1
  437. package/src/utils/project-package-json.js.map +1 -1
  438. package/src/utils/py.d.ts +2 -2
  439. package/src/utils/py.js.map +1 -1
  440. package/src/utils/rdb-constructs/rdb-constructs.d.ts +2 -2
  441. package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
  442. package/src/utils/shared-constructs-constants.js.map +1 -1
  443. package/src/utils/shared-constructs.d.ts +3 -3
  444. package/src/utils/shared-constructs.js.map +1 -1
  445. package/src/utils/shared-dynamodb-scripts.d.ts +1 -1
  446. package/src/utils/shared-dynamodb-scripts.js.map +1 -1
  447. package/src/utils/shared-infra-config.js.map +1 -1
  448. package/src/utils/shared-infra-scripts.d.ts +2 -2
  449. package/src/utils/shared-infra-scripts.js.map +1 -1
  450. package/src/utils/shared-rdb-scripts.d.ts +1 -1
  451. package/src/utils/shared-rdb-scripts.js.map +1 -1
  452. package/src/utils/shared-scripts.js.map +1 -1
  453. package/src/utils/shared-shadcn.d.ts +1 -1
  454. package/src/utils/shared-shadcn.js.map +1 -1
  455. package/src/utils/smithy.js.map +1 -1
  456. package/src/utils/test.js.map +1 -1
  457. package/src/utils/version-upgrade-migration/migration.js.map +1 -1
  458. package/src/utils/version-upgrade-migration/nx-package-updates.js.map +1 -1
  459. package/src/utils/version-upgrade-migration/owned-dependencies.d.ts +1 -1
  460. package/src/utils/version-upgrade-migration/owned-dependencies.js.map +1 -1
  461. package/src/utils/version-upgrade-migration/register.js.map +1 -1
  462. package/src/utils/version-upgrade-migration/sync-embedded-versions.d.ts +1 -1
  463. package/src/utils/version-upgrade-migration/sync-embedded-versions.js.map +1 -1
  464. package/src/utils/version-upgrade-migration/sync-metrics-version.js.map +1 -1
  465. package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
  466. package/src/utils/versions.d.ts +1 -1
  467. package/src/utils/versions.js.map +1 -1
  468. package/src/utils/website-constructs/website-constructs.d.ts +2 -2
  469. package/src/utils/website-constructs/website-constructs.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.57/0001-ts-agent-session-management-support/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 visitNotIgnoredFiles,\n} from '@nx/devkit';\nimport { TS_AGENT_GENERATOR_INFO } from '../../../ts/agent/generator';\nimport { AGENT_CONNECTION_PROJECT_DIR } from '../../../utils/agent-connection/agent-connection';\nimport {\n applyGritQL,\n captureGritQLVariable,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { isEsmWorkspace } from '../../../utils/module-format';\nimport { kebabCase } from '../../../utils/names';\nimport type { ComponentMetadata } from '../../../utils/nx';\nimport {\n getRelativePathToRootByDirectory,\n toProjectRelativePath,\n} from '../../../utils/paths';\n\n/**\n * Add session management support to ts#agent.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * your generators produce and report them via `nextSteps`, or consider a\n * hybrid migration, rather than clobbering the user's changes.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree` so the files your\n * migration wrote are formatted correctly.\n */\n\n// Reshapes an `agentRuntimes` rc.set entry from a bare ARN to `{ arn }`. Only\n// the 'agentcore' namespace — 'connection' (client-facing) stays a string,\n// since it shouldn't carry the session bucket name to the browser. No\n// `session` field added here; a fresh session.ts (created below) defaults to\n// in-memory. Idempotent: only matches the pre-migration shape.\nconst CDK_RC_SET_PATTERN = `\\`rc.set('agentcore', 'agentRuntimes', { ...rc.get('agentcore').agentRuntimes, $name: this.agentCoreRuntime.agentRuntimeArn });\\` => raw\\`rc.set('agentcore', 'agentRuntimes', {\n ...rc.get('agentcore').agentRuntimes,\n $name: {\n arn: this.agentCoreRuntime.agentRuntimeArn,\n },\n});\\``;\n\n// Terraform equivalent, anchored on the module's fixed name/shape so it\n// doesn't also match the 'connection' module's identical-looking `value` line.\nconst TF_VALUE_PATTERN = `language hcl\\n\\`module \"add_agent_runtime_to_runtime_config\" {\n source = \"../../../core/runtime-config/entry\"\n\n namespace = \"agentcore\"\n key = \"agentRuntimes\"\n value = { \"$name\" = module.agent_core_runtime.agent_core_runtime_arn }\n\n depends_on = [module.agent_core_runtime]\n}\\` => \\`module \"add_agent_runtime_to_runtime_config\" {\n source = \"../../../core/runtime-config/entry\"\n\n namespace = \"agentcore\"\n key = \"agentRuntimes\"\n value = { \"$name\" = { arn = module.agent_core_runtime.agent_core_runtime_arn } }\n\n depends_on = [module.agent_core_runtime]\n}\\``;\n\n// Shared `AgentCoreRuntimeConfig` interface, vended into\n// `packages/common/agent-connection/src/core/runtime-config.ts`.\nconst TS_RUNTIME_CONFIG_INTERFACE_PATTERN = `\\`export interface AgentCoreRuntimeConfig {\n agentRuntimes?: Record<string, string>;\n gateways?: Record<string, string>;\n}\\` => raw\\`export interface AgentRuntimeEntry {\n arn: string;\n /** Session storage details. Only set when the agent has S3 session storage configured. */\n session?: {\n /** Name of the S3 bucket storing session data. */\n bucketName: string;\n };\n}\n\nexport interface AgentCoreRuntimeConfig {\n agentRuntimes?: Record<string, AgentRuntimeEntry>;\n gateways?: Record<string, string>;\n}\\``;\n\n// `config.agentRuntimes?.['Name']` as read by generated TS a2a/mcp clients and\n// the agent-chat CLI. Idempotent via the `not contains ?.arn` guard.\nconst TS_CLIENT_ARN_PATTERNS = [\n '`config.agentRuntimes?.[$name]` => `config.agentRuntimes?.[$name]?.arn` where { $program <: not contains `config.agentRuntimes?.[$name]?.arn` }',\n '`config?.agentRuntimes?.[$name]` => `config?.agentRuntimes?.[$name]?.arn` where { $program <: not contains `config?.agentRuntimes?.[$name]?.arn` }',\n];\n\n// The agent-chat CLI's agentcore.ts calls `getAppConfig` directly rather than\n// the shared `AgentCoreRuntimeConfig` type, so its own inline cast needs the\n// same { arn } reshape TS_RUNTIME_CONFIG_INTERFACE_PATTERN gives the shared\n// interface.\nconst AGENTCORE_CHAT_SCRIPT_TYPE_PATTERN =\n '`{ agentRuntimes?: Record<string, string> }` => `{ agentRuntimes?: Record<string, { arn: string }> }`';\n\n// Python equivalent (Strands + LangChain client templates).\nconst PY_CLIENT_ARN_PATTERN =\n 'language python\\n`agent_runtime_arn = config.get(\"agentRuntimes\", {}).get($name)` => `agent_runtime = config.get(\"agentRuntimes\", {}).get($name)\\nagent_runtime_arn = agent_runtime.get(\"arn\") if agent_runtime else None`';\n\n// Removes the imperative logModelErrors(agent)/logToolErrors(agent) calls.\n// Required for AG-UI (its adapter clones the template agent per-thread, and\n// hooks added directly to the template don't carry over — the equivalent\n// behaviour is restored via the AGUI_INDEX_* plugins below). For HTTP/A2A\n// it's a style unification, since the imperative form already worked there.\nconst AGENT_TS_LOG_MODEL_CALL_PATTERN = '`logModelErrors(agent);` => .';\nconst AGENT_TS_LOG_TOOL_CALL_PATTERN = '`logToolErrors(agent);` => .';\n\n// HTTP/A2A agents build one Agent per session, so wiring `sessionManager`\n// directly into the constructor is safe. Generic over `$props` so this works\n// regardless of customised systemPrompt/tools, as long as it's an inline\n// object literal. Prepended (not appended) to sidestep a trailing-comma\n// double-comma when `$props` is captured as raw source text.\nconst AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN =\n '`new Agent({ $props })` => `new Agent({ sessionManager: await getSessionManager(), $props })` where { $props <: not contains `sessionManager` }';\n\n// Match-only gate for the rewrites above/below: only applies when the Agent\n// is an inline object literal, not e.g. a variable.\nconst AGENT_TS_CONSTRUCTOR_MATCH_PATTERN = '`new Agent({ $props })`';\n\n// Moves the model/tool error hooks to Agent constructor plugins, mirroring\n// the AG-UI rewrite for consistency (HTTP/A2A already worked with the\n// imperative form).\nconst AGENT_TS_PLUGINS_CONSTRUCTOR_PATTERN =\n '`new Agent({ $props })` => `new Agent({ plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()], $props })` where { $props <: not contains `plugins` }';\n\n// Captures the agent-connection package specifier so the new imports (and the\n// session.ts this migration creates) target the same module. Generic over\n// `$names` since a connection generator may have merged its own import here.\nconst AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN =\n \"`import { $names } from '$mod';` where { $names <: contains `logModelErrors`, $names <: contains `logToolErrors` }\";\n\n// Removes `logModelErrors`/`logToolErrors` from the import, preserving any\n// other merged specifiers (or the whole statement if none remain). Decomposed\n// via `import_clause(name=named_imports($imports))` since a naive\n// `$rest`-based rewrite silently fails once 2+ other specifiers are merged in.\nconst AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN =\n \"`import $clause from '$mod';` as $import where { $clause <: import_clause(name=named_imports($imports)), $imports <: contains `logModelErrors`, $imports <: contains `logToolErrors`, if ($imports <: [`logModelErrors`, `logToolErrors`]) { $import => . } else { $imports <: some import_specifier(name=or { `logModelErrors`, `logToolErrors` }) => . } }\";\n\n// Existing agents predate session.ts, so there's no prior storage to\n// preserve — default to in-memory.\nconst legacySessionManagerContent = (\n agentConnectionModule: string,\n localSessionsDir: string,\n): string => `import { SessionManager } from '@strands-agents/sdk';\nimport { InMemoryStorage, LocalFileStorage } from '@strands-agents/sdk/storage';\nimport { getCurrentSessionId } from '${agentConnectionModule}';\n\n/**\n * Returns a SessionManager for persisting conversation state across\n * invocations. Local development always uses local file storage for\n * convenience, regardless of the configured session option. Without a\n * configured session option, conversation state is kept in memory only and\n * does not survive process restarts.\n */\nexport const getSessionManager = async (): Promise<SessionManager> => {\n const sessionId = getCurrentSessionId();\n if (!sessionId) {\n throw new Error(\n 'No current session id — cannot resolve a SessionManager outside of a request scope.',\n );\n }\n if (process.env.LOCAL_DEV === 'true') {\n return new SessionManager({\n sessionId,\n storage: new LocalFileStorage('${localSessionsDir}'),\n });\n }\n return new SessionManager({ sessionId, storage: new InMemoryStorage() });\n};\n`;\n\n/** The Nx project owning `dirPath`, if any (the longest-matching project.root). */\nconst findOwningProject = (\n tree: Tree,\n dirPath: string,\n): ProjectConfiguration | undefined => {\n let best: ProjectConfiguration | undefined;\n for (const project of getProjects(tree).values()) {\n if (\n (dirPath === project.root || dirPath.startsWith(`${project.root}/`)) &&\n (!best || project.root.length > best.root.length)\n ) {\n best = project;\n }\n }\n return best;\n};\n\n/** This agent's own ComponentMetadata entry, as written by the ts#agent generator. */\nconst findAgentComponentMetadata = (\n project: ProjectConfiguration,\n dirRelativeToProjectRoot: string,\n): ComponentMetadata | undefined =>\n (project.metadata as { components?: ComponentMetadata[] })?.components?.find(\n (component) =>\n component.generator === TS_AGENT_GENERATOR_INFO.id &&\n component.path === dirRelativeToProjectRoot,\n );\n\n/** This agent's real kebab-case name, from ComponentMetadata's `rc` (class-name) field. */\nconst agentTmpNameFor = (\n project: ProjectConfiguration,\n dir: string,\n): string | undefined => {\n const dirRelativeToProjectRoot = toProjectRelativePath(project, dir);\n const rc = findAgentComponentMetadata(project, dirRelativeToProjectRoot)?.rc;\n return rc ? kebabCase(rc) : undefined;\n};\n\n/** This agent's protocol, from ComponentMetadata's `protocol` field. */\nconst agentProtocolFor = (\n project: ProjectConfiguration,\n dir: string,\n): string | undefined => {\n const dirRelativeToProjectRoot = toProjectRelativePath(project, dir);\n return findAgentComponentMetadata(project, dirRelativeToProjectRoot)\n ?.protocol;\n};\n\n/** The relative path from `projectRoot` up to this agent's workspace-root-level local session storage. */\nconst localSessionsDirFor = (\n projectRoot: string,\n agentTmpName: string,\n): string =>\n joinPathFragments(\n getRelativePathToRootByDirectory(projectRoot),\n `tmp/agents/strands/${agentTmpName}`,\n );\n\n// Wires ModelErrorLoggingPlugin/ToolErrorLoggingPlugin into the StrandsAgent\n// constructor, restoring the error-logging behaviour removed from agent.ts.\nconst AGUI_INDEX_IMPORT_PATTERN =\n \"`import { $names } from '$mod'` => `import { ModelErrorLoggingPlugin, ToolErrorLoggingPlugin, $names } from '$mod'` where { $names <: contains `runWithSessionId`, $names <: not contains `ModelErrorLoggingPlugin` }\";\n// Match-only form of the target shape, used to gate before touching the\n// sibling agent.ts, and before committing to the rewrite here.\nconst AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN =\n '`new StrandsAgent({ agent, name: $name, description: $desc })`';\nconst AGUI_INDEX_CONSTRUCTOR_PATTERN = `${AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN} => \\`new StrandsAgent({ agent, name: $name, description: $desc, plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()] })\\``;\n\nconst AGUI_INDEX_IMPORT_CAPTURE_PATTERN =\n \"`import { $names } from '$mod';` where { $names <: contains `runWithSessionId` }\";\n\n// AG-UI's StrandsAgent adapter needs a sessionManagerProvider (called once\n// per threadId), mirroring AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN.\nconst aguiIndexSessionManagerImportPattern = (esm: boolean) =>\n `\\`import { getAgent } from '$mod';\\` => raw\\`import { getAgent } from '$mod';\nimport { getSessionManager } from './session${esm ? '.js' : ''}';\\` where { $program <: not contains \\`getSessionManager\\` }`;\n// Anchored on the exact 4-property shape produced above, so this only fires\n// once plugins are wired in. Used both to gate and to rewrite.\nconst AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN =\n '`new StrandsAgent({ agent, name: $name, description: $desc, plugins: $plugins })`';\nconst AGUI_INDEX_SESSION_MANAGER_CONSTRUCTOR_PATTERN = `${AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN} => \\`new StrandsAgent({ agent, name: $name, description: $desc, plugins: $plugins, config: { sessionManagerProvider: getSessionManager } })\\``;\n\n// The plugin classes referenced above only exist once model-errors-strands.ts\n// / tool-errors-strands.ts are converted from their plain logXErrors function\n// form (see checkPluginClass/applyPluginClass below). Anchored on the\n// `agent.addHook(...)` call so this doesn't re-match its own output.\nconst MODEL_ERRORS_IMPORT_PATTERN =\n \"`import { AfterModelCallEvent, type LocalAgent } from '@strands-agents/sdk';` => `import { AfterModelCallEvent, type LocalAgent, type Plugin } from '@strands-agents/sdk';`\";\n// Match-only form of the target shape, checked before committing to either\n// this or the sibling tool-errors conversion — see checkPluginClass.\nconst MODEL_ERRORS_CLASS_MATCH_PATTERN =\n '`export const logModelErrors = (agent: LocalAgent): void => { agent.addHook(AfterModelCallEvent, $callback); };`';\nconst MODEL_ERRORS_CLASS_PATTERN = `${MODEL_ERRORS_CLASS_MATCH_PATTERN} => raw\\`export class ModelErrorLoggingPlugin implements Plugin {\\n readonly name = 'model-error-logging';\\n\\n initAgent(agent: LocalAgent): void {\\n agent.addHook(AfterModelCallEvent, $callback);\\n }\\n}\\``;\n\nconst TOOL_ERRORS_IMPORT_PATTERN =\n \"`import { AfterToolCallEvent, type LocalAgent, TextBlock } from '@strands-agents/sdk';` => `import { AfterToolCallEvent, type LocalAgent, type Plugin, TextBlock } from '@strands-agents/sdk';`\";\nconst TOOL_ERRORS_CLASS_MATCH_PATTERN =\n '`export const logToolErrors = (agent: LocalAgent): void => { agent.addHook(AfterToolCallEvent, $callback); };`';\nconst TOOL_ERRORS_CLASS_PATTERN = `${TOOL_ERRORS_CLASS_MATCH_PATTERN} => raw\\`export class ToolErrorLoggingPlugin implements Plugin {\\n readonly name = 'tool-error-logging';\\n\\n initAgent(agent: LocalAgent): void {\\n agent.addHook(AfterToolCallEvent, $callback);\\n }\\n}\\``;\n\ntype PluginClassStatus = 'ready' | 'done' | 'diverged';\n\n/**\n * Checks (without writing) whether `filePath` still needs converting from its\n * plain `logXErrors` function to `className`, and whether the conversion\n * pattern would actually apply. `'done'` covers both \"already converted\" and\n * \"file doesn't exist\" — either way there's nothing to do and nothing\n * blocking the sibling conversion.\n */\nasync function checkPluginClass(\n tree: Tree,\n filePath: string,\n className: string,\n classMatchPattern: string,\n): Promise<PluginClassStatus> {\n if (!tree.exists(filePath)) {\n return 'done';\n }\n if ((tree.read(filePath, 'utf-8') ?? '').includes(`class ${className}`)) {\n return 'done';\n }\n return (await matchGritQL(tree, filePath, classMatchPattern))\n ? 'ready'\n : 'diverged';\n}\n\n/** Applies the class + import rewrite for a file already confirmed `'ready'`. */\nasync function applyPluginClass(\n tree: Tree,\n filePath: string,\n importPattern: string,\n classPattern: string,\n): Promise<void> {\n // The class rewrite is applied first, and the import only added once it's\n // confirmed to have actually happened here — not because either could fail\n // at this point (checkPluginClass already confirmed the pattern matches),\n // but to keep this file's own edit order self-evidently safe to read.\n await applyGritQL(tree, filePath, classPattern);\n await applyGritQL(tree, filePath, importPattern);\n}\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n let anyChanges = false;\n\n // Both classes live in one shared agent-connection package, so their\n // readiness is resolved once up front rather than per agent.\n const modelErrorsPath = joinPathFragments(\n AGENT_CONNECTION_PROJECT_DIR,\n 'src',\n 'core',\n 'model-errors-strands.ts',\n );\n const toolErrorsPath = joinPathFragments(\n AGENT_CONNECTION_PROJECT_DIR,\n 'src',\n 'core',\n 'tool-errors-strands.ts',\n );\n // Checked together, before writing either: all-or-nothing, so a run either\n // converts both or leaves both untouched — never just one.\n const modelPluginStatus = await checkPluginClass(\n tree,\n modelErrorsPath,\n 'ModelErrorLoggingPlugin',\n MODEL_ERRORS_CLASS_MATCH_PATTERN,\n );\n const toolPluginStatus = await checkPluginClass(\n tree,\n toolErrorsPath,\n 'ToolErrorLoggingPlugin',\n TOOL_ERRORS_CLASS_MATCH_PATTERN,\n );\n const pluginsReady =\n modelPluginStatus !== 'diverged' && toolPluginStatus !== 'diverged';\n\n if (pluginsReady) {\n if (modelPluginStatus === 'ready') {\n await applyPluginClass(\n tree,\n modelErrorsPath,\n MODEL_ERRORS_IMPORT_PATTERN,\n MODEL_ERRORS_CLASS_PATTERN,\n );\n }\n if (toolPluginStatus === 'ready') {\n await applyPluginClass(\n tree,\n toolErrorsPath,\n TOOL_ERRORS_IMPORT_PATTERN,\n TOOL_ERRORS_CLASS_PATTERN,\n );\n }\n } else {\n if (modelPluginStatus === 'diverged') {\n nextSteps.push(\n `${modelErrorsPath}: diverged from the generated shape - left as-is. Manually convert it to a \\`ModelErrorLoggingPlugin\\` class implementing \\`Plugin\\` (see the ts#agent generator's template); agent.ts/index.ts files that reference it are left unmigrated until both this and ${toolErrorsPath} are converted.`,\n );\n }\n if (toolPluginStatus === 'diverged') {\n nextSteps.push(\n `${toolErrorsPath}: diverged from the generated shape - left as-is. Manually convert it to a \\`ToolErrorLoggingPlugin\\` class implementing \\`Plugin\\` (see the ts#agent generator's template); agent.ts/index.ts files that reference it are left unmigrated until both this and ${modelErrorsPath} are converted.`,\n );\n }\n }\n\n const filePaths: string[] = [];\n visitNotIgnoredFiles(tree, '', (filePath) => filePaths.push(filePath));\n\n for (const filePath of filePaths) {\n if (filePath === modelErrorsPath || filePath === toolErrorsPath) {\n continue;\n }\n if (filePath.endsWith('.d.ts')) {\n continue;\n }\n\n // session.ts already targets the new { arn, session } shape via\n // `config.agentRuntimes?.[$name]?.session?.bucketName` — the generic\n // reshape branch below would otherwise corrupt that into `?.arn?.session?.bucketName`.\n if (filePath.endsWith('/session.ts')) {\n continue;\n }\n\n if (filePath.endsWith('/agent.ts')) {\n const dir = filePath.split('/').slice(0, -1).join('/');\n const project = findOwningProject(tree, dir);\n\n // Without a registered project there's no ComponentMetadata, so this\n // agent's protocol/name/agent-connection module can't be resolved — and\n // a pre-migration AG-UI agent.ts is textually identical to an\n // HTTP/A2A one, so there's nothing left to safely guess from.\n if (!project) {\n if (\n await matchGritQL(tree, filePath, AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN)\n ) {\n nextSteps.push(\n `${filePath}: could not determine the project root — manually verify whether this is an AG-UI or HTTP/A2A agent and complete its session-manager/error-logging-plugin migration accordingly (see the ts#agent generator's template).`,\n );\n }\n continue;\n }\n\n const protocol = agentProtocolFor(project, dir);\n\n if (protocol === 'ag-ui') {\n const hasLogCalls =\n (await matchGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_MODEL_CALL_PATTERN,\n )) ||\n (await matchGritQL(tree, filePath, AGENT_TS_LOG_TOOL_CALL_PATTERN));\n if (!hasLogCalls) {\n continue;\n }\n\n // The sibling index.ts restores error-logging via StrandsAgent\n // plugins — removing the calls here without that succeeding would\n // drop error logging rather than move it.\n const indexPath = `${dir}/index.ts`;\n const indexReady =\n pluginsReady &&\n (await matchGritQL(\n tree,\n indexPath,\n AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN,\n ));\n\n if (!indexReady) {\n nextSteps.push(\n `${filePath}: left the logModelErrors/logToolErrors calls in place — ${indexPath} could not be automatically wired with the equivalent StrandsAgent plugins. Move error logging to plugins there manually (see the ts#agent generator's template), then remove these calls.`,\n );\n continue;\n }\n\n const rewroteImport = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN,\n );\n const rewroteModelCall = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_MODEL_CALL_PATTERN,\n );\n const rewroteToolCall = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_TOOL_CALL_PATTERN,\n );\n if (rewroteImport || rewroteModelCall || rewroteToolCall) {\n anyChanges = true;\n }\n continue;\n }\n\n if (!protocol) {\n if (\n await matchGritQL(tree, filePath, AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN)\n ) {\n nextSteps.push(\n `${filePath}: could not determine this agent's protocol from its ComponentMetadata — manually verify whether it's AG-UI or HTTP/A2A and wire sessionManager/the error-logging plugins in accordingly (see the ts#agent generator's template).`,\n );\n }\n continue;\n }\n\n // HTTP/A2A: wire sessionManager into the Agent constructor and create\n // the sibling session.ts if it doesn't exist yet.\n if (\n !(await matchGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN,\n ))\n ) {\n continue;\n }\n\n const sessionPath = `${dir}/session.ts`;\n\n // Checked before any writes: if the plugin classes aren't available, or\n // the Agent isn't an inline object literal, leave the file untouched\n // entirely rather than ending up half-migrated.\n if (!pluginsReady) {\n nextSteps.push(\n `${filePath}: left as-is — ModelErrorLoggingPlugin/ToolErrorLoggingPlugin are not available yet (see the model-errors-strands.ts/tool-errors-strands.ts next step above). Wire sessionManager and the plugins in manually once those classes exist.`,\n );\n continue;\n }\n if (\n !(await matchGritQL(tree, filePath, AGENT_TS_CONSTRUCTOR_MATCH_PATTERN))\n ) {\n nextSteps.push(\n `${filePath}: the Agent is not constructed with an inline object literal (\\`new Agent({ ... })\\`), so sessionManager and the error-logging plugins could not be wired in automatically. Manually add \\`sessionManager: await getSessionManager()\\` and \\`plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()]\\` to its constructor (see the ts#agent generator's template), creating ${sessionPath} first if it doesn't already exist.`,\n );\n continue;\n }\n\n if (!tree.exists(sessionPath)) {\n const mod = await captureGritQLVariable(\n tree,\n filePath,\n AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN,\n 'mod',\n );\n const agentName = agentTmpNameFor(project, dir);\n\n if (mod && agentName) {\n tree.write(\n sessionPath,\n legacySessionManagerContent(\n mod,\n localSessionsDirFor(project.root, agentName),\n ),\n );\n } else {\n nextSteps.push(\n `${filePath}: could not determine the agent-connection module or this agent's name from its ComponentMetadata — manually create a session.ts (see the ts#agent generator's template) and wire \\`sessionManager: await getSessionManager()\\` into the Agent constructor.`,\n );\n continue;\n }\n }\n\n // Merges the plugin imports into the existing logModelErrors/\n // logToolErrors import clause (rather than a redundant second import),\n // and adds getSessionManager as its own line. The old specifiers are\n // stripped separately below, after this rewrite anchors on them.\n const esm = isEsmWorkspace(tree);\n await applyGritQL(\n tree,\n filePath,\n `\\`import { $names } from '$mod';\\` => raw\\`import { ModelErrorLoggingPlugin, ToolErrorLoggingPlugin, $names } from '$mod';\nimport { getSessionManager } from './session${esm ? '.js' : ''}';\\` where { $names <: contains \\`logModelErrors\\`, $names <: contains \\`logToolErrors\\`, $program <: not contains \\`getSessionManager\\` }`,\n );\n\n // Only rewrite the constructor once the import is confirmed present.\n if (!(tree.read(filePath, 'utf-8') ?? '').includes('getSessionManager')) {\n nextSteps.push(\n `${filePath}: found ${sessionPath} but couldn't confirm the getSessionManager import — wire \\`sessionManager: await getSessionManager()\\` into the Agent constructor manually.`,\n );\n continue;\n }\n\n await applyGritQL(tree, filePath, AGENT_TS_LOG_MODEL_CALL_PATTERN);\n await applyGritQL(tree, filePath, AGENT_TS_LOG_TOOL_CALL_PATTERN);\n await applyGritQL(\n tree,\n filePath,\n AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN,\n );\n\n const rewrotePlugins = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_PLUGINS_CONSTRUCTOR_PATTERN,\n );\n const rewroteConstructor = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN,\n );\n if (rewrotePlugins || rewroteConstructor) {\n anyChanges = true;\n }\n continue;\n }\n\n if (\n filePath.endsWith('/index.ts') &&\n (tree.read(filePath, 'utf-8') ?? '').includes('@ag-ui/aws-strands')\n ) {\n const alreadyWired = (tree.read(filePath, 'utf-8') ?? '').includes(\n 'ModelErrorLoggingPlugin',\n );\n\n if (!alreadyWired) {\n // Import and constructor only apply cleanly together — adding the\n // import while the constructor can't be rewritten would leave an\n // unused import and no plugins wired in.\n const needsPluginWiring = await matchGritQL(\n tree,\n filePath,\n AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN,\n );\n if (!pluginsReady) {\n if (needsPluginWiring) {\n nextSteps.push(\n `${filePath}: left the StrandsAgent constructor as-is — ModelErrorLoggingPlugin/ToolErrorLoggingPlugin are not available yet (see the model-errors-strands.ts/tool-errors-strands.ts next step above). Wire them in manually once those classes exist.`,\n );\n }\n continue;\n }\n if (!needsPluginWiring) {\n nextSteps.push(\n `${filePath}: the StrandsAgent constructor has diverged from the generated shape - left as-is. Manually add \\`plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()]\\` to it (see the ts#agent generator's template).`,\n );\n continue;\n }\n\n const rewroteImport = await applyGritQL(\n tree,\n filePath,\n AGUI_INDEX_IMPORT_PATTERN,\n );\n const rewroteConstructor = await applyGritQL(\n tree,\n filePath,\n AGUI_INDEX_CONSTRUCTOR_PATTERN,\n );\n if (rewroteImport || rewroteConstructor) {\n anyChanges = true;\n }\n }\n\n // Create the sibling session.ts (once plugins are present) and wire in\n // sessionManagerProvider. Gated on the exact post-plugins shape, so a\n // customised constructor is left alone rather than creating an unused\n // session.ts.\n if (\n !(await matchGritQL(\n tree,\n filePath,\n AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN,\n ))\n ) {\n continue;\n }\n\n const dir = filePath.split('/').slice(0, -1).join('/');\n const sessionPath = `${dir}/session.ts`;\n\n if (!tree.exists(sessionPath)) {\n const project = findOwningProject(tree, dir);\n const mod = await captureGritQLVariable(\n tree,\n filePath,\n AGUI_INDEX_IMPORT_CAPTURE_PATTERN,\n 'mod',\n );\n const agentName = project && agentTmpNameFor(project, dir);\n\n if (project && mod && agentName) {\n tree.write(\n sessionPath,\n legacySessionManagerContent(\n mod,\n localSessionsDirFor(project.root, agentName),\n ),\n );\n } else {\n nextSteps.push(\n `${filePath}: could not determine the project root, agent-connection module, or this agent's name from its ComponentMetadata — manually create a session.ts (see the ts#agent generator's template) and wire \\`config: { sessionManagerProvider: getSessionManager }\\` into the StrandsAgent constructor.`,\n );\n continue;\n }\n }\n\n const esm = isEsmWorkspace(tree);\n await applyGritQL(\n tree,\n filePath,\n aguiIndexSessionManagerImportPattern(esm),\n );\n\n if (!(tree.read(filePath, 'utf-8') ?? '').includes('getSessionManager')) {\n nextSteps.push(\n `${filePath}: found ${sessionPath} but couldn't confirm the getSessionManager import — wire \\`config: { sessionManagerProvider: getSessionManager }\\` into the StrandsAgent constructor manually.`,\n );\n continue;\n }\n\n const rewroteSessionManagerConstructor = await applyGritQL(\n tree,\n filePath,\n AGUI_INDEX_SESSION_MANAGER_CONSTRUCTOR_PATTERN,\n );\n if (rewroteSessionManagerConstructor) {\n anyChanges = true;\n }\n continue;\n }\n\n if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {\n const contents = tree.read(filePath, 'utf-8') ?? '';\n if (!contents.includes('agentRuntimes')) {\n continue;\n }\n // Only the 'agentcore' namespace is reshaped — see CDK_RC_SET_PATTERN.\n const rewroteAgentcoreRcSet = await applyGritQL(\n tree,\n filePath,\n CDK_RC_SET_PATTERN,\n );\n const rewroteInterface = await applyGritQL(\n tree,\n filePath,\n TS_RUNTIME_CONFIG_INTERFACE_PATTERN,\n );\n let rewroteClientArn = false;\n for (const pattern of TS_CLIENT_ARN_PATTERNS) {\n rewroteClientArn = (await applyGritQL(tree, filePath, pattern))\n ? true\n : rewroteClientArn;\n }\n const rewroteChatScriptType = await applyGritQL(\n tree,\n filePath,\n AGENTCORE_CHAT_SCRIPT_TYPE_PATTERN,\n );\n\n if (\n rewroteAgentcoreRcSet ||\n rewroteInterface ||\n rewroteClientArn ||\n rewroteChatScriptType\n ) {\n anyChanges = true;\n }\n } else if (filePath.endsWith('.tf')) {\n const contents = tree.read(filePath, 'utf-8') ?? '';\n if (!contents.includes('\"agentRuntimes\"')) {\n continue;\n }\n const rewrote = await applyGritQL(tree, filePath, TF_VALUE_PATTERN);\n if (rewrote) {\n anyChanges = true;\n }\n } else if (filePath.endsWith('.py')) {\n const contents = tree.read(filePath, 'utf-8') ?? '';\n if (!contents.includes('agentRuntimes')) {\n continue;\n }\n const rewrote = await applyGritQL(tree, filePath, PY_CLIENT_ARN_PATTERN);\n if (rewrote) {\n anyChanges = true;\n }\n }\n }\n\n if (anyChanges) {\n nextSteps.push(\n 'If you have custom code reading the runtime config `agentcore.agentRuntimes` entries ' +\n 'as plain ARN strings (e.g. custom Lambda handlers or agent code), update it to read ' +\n 'the ARN from `.arn` on the new `{ arn }` shape.',\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","visitNotIgnoredFiles","TS_AGENT_GENERATOR_INFO","AGENT_CONNECTION_PROJECT_DIR","applyGritQL","captureGritQLVariable","matchGritQL","formatFilesInSubtree","isEsmWorkspace","kebabCase","getRelativePathToRootByDirectory","toProjectRelativePath","CDK_RC_SET_PATTERN","TF_VALUE_PATTERN","TS_RUNTIME_CONFIG_INTERFACE_PATTERN","TS_CLIENT_ARN_PATTERNS","AGENTCORE_CHAT_SCRIPT_TYPE_PATTERN","PY_CLIENT_ARN_PATTERN","AGENT_TS_LOG_MODEL_CALL_PATTERN","AGENT_TS_LOG_TOOL_CALL_PATTERN","AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN","AGENT_TS_CONSTRUCTOR_MATCH_PATTERN","AGENT_TS_PLUGINS_CONSTRUCTOR_PATTERN","AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN","AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN","legacySessionManagerContent","agentConnectionModule","localSessionsDir","findOwningProject","tree","dirPath","best","project","values","root","startsWith","length","findAgentComponentMetadata","dirRelativeToProjectRoot","metadata","components","find","component","generator","id","path","agentTmpNameFor","dir","rc","undefined","agentProtocolFor","protocol","localSessionsDirFor","projectRoot","agentTmpName","AGUI_INDEX_IMPORT_PATTERN","AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN","AGUI_INDEX_CONSTRUCTOR_PATTERN","AGUI_INDEX_IMPORT_CAPTURE_PATTERN","aguiIndexSessionManagerImportPattern","esm","AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN","AGUI_INDEX_SESSION_MANAGER_CONSTRUCTOR_PATTERN","MODEL_ERRORS_IMPORT_PATTERN","MODEL_ERRORS_CLASS_MATCH_PATTERN","MODEL_ERRORS_CLASS_PATTERN","TOOL_ERRORS_IMPORT_PATTERN","TOOL_ERRORS_CLASS_MATCH_PATTERN","TOOL_ERRORS_CLASS_PATTERN","checkPluginClass","filePath","className","classMatchPattern","exists","read","includes","applyPluginClass","importPattern","classPattern","migration","nextSteps","anyChanges","modelErrorsPath","toolErrorsPath","modelPluginStatus","toolPluginStatus","pluginsReady","push","filePaths","endsWith","split","slice","join","hasLogCalls","indexPath","indexReady","rewroteImport","rewroteModelCall","rewroteToolCall","sessionPath","mod","agentName","write","rewrotePlugins","rewroteConstructor","alreadyWired","needsPluginWiring","rewroteSessionManagerConstructor","contents","rewroteAgentcoreRcSet","rewroteInterface","rewroteClientArn","pattern","rewroteChatScriptType","rewrote"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.57/0001-ts-agent-session-management-support/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 visitNotIgnoredFiles,\n} from '@nx/devkit';\nimport { TS_AGENT_GENERATOR_INFO } from '../../../ts/agent/generator.js';\nimport { AGENT_CONNECTION_PROJECT_DIR } from '../../../utils/agent-connection/agent-connection.js';\nimport {\n applyGritQL,\n captureGritQLVariable,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { isEsmWorkspace } from '../../../utils/module-format.js';\nimport { kebabCase } from '../../../utils/names.js';\nimport type { ComponentMetadata } from '../../../utils/nx.js';\nimport {\n getRelativePathToRootByDirectory,\n toProjectRelativePath,\n} from '../../../utils/paths.js';\n\n/**\n * Add session management support to ts#agent.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the shape\n * your generators produce and report them via `nextSteps`, or consider a\n * hybrid migration, rather than clobbering the user's changes.\n * - Idempotent: re-running must be a no-op.\n * - Format what you write: finish with `formatFilesInSubtree` so the files your\n * migration wrote are formatted correctly.\n */\n\n// Reshapes an `agentRuntimes` rc.set entry from a bare ARN to `{ arn }`. Only\n// the 'agentcore' namespace — 'connection' (client-facing) stays a string,\n// since it shouldn't carry the session bucket name to the browser. No\n// `session` field added here; a fresh session.ts (created below) defaults to\n// in-memory. Idempotent: only matches the pre-migration shape.\nconst CDK_RC_SET_PATTERN = `\\`rc.set('agentcore', 'agentRuntimes', { ...rc.get('agentcore').agentRuntimes, $name: this.agentCoreRuntime.agentRuntimeArn });\\` => raw\\`rc.set('agentcore', 'agentRuntimes', {\n ...rc.get('agentcore').agentRuntimes,\n $name: {\n arn: this.agentCoreRuntime.agentRuntimeArn,\n },\n});\\``;\n\n// Terraform equivalent, anchored on the module's fixed name/shape so it\n// doesn't also match the 'connection' module's identical-looking `value` line.\nconst TF_VALUE_PATTERN = `language hcl\\n\\`module \"add_agent_runtime_to_runtime_config\" {\n source = \"../../../core/runtime-config/entry\"\n\n namespace = \"agentcore\"\n key = \"agentRuntimes\"\n value = { \"$name\" = module.agent_core_runtime.agent_core_runtime_arn }\n\n depends_on = [module.agent_core_runtime]\n}\\` => \\`module \"add_agent_runtime_to_runtime_config\" {\n source = \"../../../core/runtime-config/entry\"\n\n namespace = \"agentcore\"\n key = \"agentRuntimes\"\n value = { \"$name\" = { arn = module.agent_core_runtime.agent_core_runtime_arn } }\n\n depends_on = [module.agent_core_runtime]\n}\\``;\n\n// Shared `AgentCoreRuntimeConfig` interface, vended into\n// `packages/common/agent-connection/src/core/runtime-config.ts`.\nconst TS_RUNTIME_CONFIG_INTERFACE_PATTERN = `\\`export interface AgentCoreRuntimeConfig {\n agentRuntimes?: Record<string, string>;\n gateways?: Record<string, string>;\n}\\` => raw\\`export interface AgentRuntimeEntry {\n arn: string;\n /** Session storage details. Only set when the agent has S3 session storage configured. */\n session?: {\n /** Name of the S3 bucket storing session data. */\n bucketName: string;\n };\n}\n\nexport interface AgentCoreRuntimeConfig {\n agentRuntimes?: Record<string, AgentRuntimeEntry>;\n gateways?: Record<string, string>;\n}\\``;\n\n// `config.agentRuntimes?.['Name']` as read by generated TS a2a/mcp clients and\n// the agent-chat CLI. Idempotent via the `not contains ?.arn` guard.\nconst TS_CLIENT_ARN_PATTERNS = [\n '`config.agentRuntimes?.[$name]` => `config.agentRuntimes?.[$name]?.arn` where { $program <: not contains `config.agentRuntimes?.[$name]?.arn` }',\n '`config?.agentRuntimes?.[$name]` => `config?.agentRuntimes?.[$name]?.arn` where { $program <: not contains `config?.agentRuntimes?.[$name]?.arn` }',\n];\n\n// The agent-chat CLI's agentcore.ts calls `getAppConfig` directly rather than\n// the shared `AgentCoreRuntimeConfig` type, so its own inline cast needs the\n// same { arn } reshape TS_RUNTIME_CONFIG_INTERFACE_PATTERN gives the shared\n// interface.\nconst AGENTCORE_CHAT_SCRIPT_TYPE_PATTERN =\n '`{ agentRuntimes?: Record<string, string> }` => `{ agentRuntimes?: Record<string, { arn: string }> }`';\n\n// Python equivalent (Strands + LangChain client templates).\nconst PY_CLIENT_ARN_PATTERN =\n 'language python\\n`agent_runtime_arn = config.get(\"agentRuntimes\", {}).get($name)` => `agent_runtime = config.get(\"agentRuntimes\", {}).get($name)\\nagent_runtime_arn = agent_runtime.get(\"arn\") if agent_runtime else None`';\n\n// Removes the imperative logModelErrors(agent)/logToolErrors(agent) calls.\n// Required for AG-UI (its adapter clones the template agent per-thread, and\n// hooks added directly to the template don't carry over — the equivalent\n// behaviour is restored via the AGUI_INDEX_* plugins below). For HTTP/A2A\n// it's a style unification, since the imperative form already worked there.\nconst AGENT_TS_LOG_MODEL_CALL_PATTERN = '`logModelErrors(agent);` => .';\nconst AGENT_TS_LOG_TOOL_CALL_PATTERN = '`logToolErrors(agent);` => .';\n\n// HTTP/A2A agents build one Agent per session, so wiring `sessionManager`\n// directly into the constructor is safe. Generic over `$props` so this works\n// regardless of customised systemPrompt/tools, as long as it's an inline\n// object literal. Prepended (not appended) to sidestep a trailing-comma\n// double-comma when `$props` is captured as raw source text.\nconst AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN =\n '`new Agent({ $props })` => `new Agent({ sessionManager: await getSessionManager(), $props })` where { $props <: not contains `sessionManager` }';\n\n// Match-only gate for the rewrites above/below: only applies when the Agent\n// is an inline object literal, not e.g. a variable.\nconst AGENT_TS_CONSTRUCTOR_MATCH_PATTERN = '`new Agent({ $props })`';\n\n// Moves the model/tool error hooks to Agent constructor plugins, mirroring\n// the AG-UI rewrite for consistency (HTTP/A2A already worked with the\n// imperative form).\nconst AGENT_TS_PLUGINS_CONSTRUCTOR_PATTERN =\n '`new Agent({ $props })` => `new Agent({ plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()], $props })` where { $props <: not contains `plugins` }';\n\n// Captures the agent-connection package specifier so the new imports (and the\n// session.ts this migration creates) target the same module. Generic over\n// `$names` since a connection generator may have merged its own import here.\nconst AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN =\n \"`import { $names } from '$mod';` where { $names <: contains `logModelErrors`, $names <: contains `logToolErrors` }\";\n\n// Removes `logModelErrors`/`logToolErrors` from the import, preserving any\n// other merged specifiers (or the whole statement if none remain). Decomposed\n// via `import_clause(name=named_imports($imports))` since a naive\n// `$rest`-based rewrite silently fails once 2+ other specifiers are merged in.\nconst AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN =\n \"`import $clause from '$mod';` as $import where { $clause <: import_clause(name=named_imports($imports)), $imports <: contains `logModelErrors`, $imports <: contains `logToolErrors`, if ($imports <: [`logModelErrors`, `logToolErrors`]) { $import => . } else { $imports <: some import_specifier(name=or { `logModelErrors`, `logToolErrors` }) => . } }\";\n\n// Existing agents predate session.ts, so there's no prior storage to\n// preserve — default to in-memory.\nconst legacySessionManagerContent = (\n agentConnectionModule: string,\n localSessionsDir: string,\n): string => `import { SessionManager } from '@strands-agents/sdk';\nimport { InMemoryStorage, LocalFileStorage } from '@strands-agents/sdk/storage';\nimport { getCurrentSessionId } from '${agentConnectionModule}';\n\n/**\n * Returns a SessionManager for persisting conversation state across\n * invocations. Local development always uses local file storage for\n * convenience, regardless of the configured session option. Without a\n * configured session option, conversation state is kept in memory only and\n * does not survive process restarts.\n */\nexport const getSessionManager = async (): Promise<SessionManager> => {\n const sessionId = getCurrentSessionId();\n if (!sessionId) {\n throw new Error(\n 'No current session id — cannot resolve a SessionManager outside of a request scope.',\n );\n }\n if (process.env.LOCAL_DEV === 'true') {\n return new SessionManager({\n sessionId,\n storage: new LocalFileStorage('${localSessionsDir}'),\n });\n }\n return new SessionManager({ sessionId, storage: new InMemoryStorage() });\n};\n`;\n\n/** The Nx project owning `dirPath`, if any (the longest-matching project.root). */\nconst findOwningProject = (\n tree: Tree,\n dirPath: string,\n): ProjectConfiguration | undefined => {\n let best: ProjectConfiguration | undefined;\n for (const project of getProjects(tree).values()) {\n if (\n (dirPath === project.root || dirPath.startsWith(`${project.root}/`)) &&\n (!best || project.root.length > best.root.length)\n ) {\n best = project;\n }\n }\n return best;\n};\n\n/** This agent's own ComponentMetadata entry, as written by the ts#agent generator. */\nconst findAgentComponentMetadata = (\n project: ProjectConfiguration,\n dirRelativeToProjectRoot: string,\n): ComponentMetadata | undefined =>\n (project.metadata as { components?: ComponentMetadata[] })?.components?.find(\n (component) =>\n component.generator === TS_AGENT_GENERATOR_INFO.id &&\n component.path === dirRelativeToProjectRoot,\n );\n\n/** This agent's real kebab-case name, from ComponentMetadata's `rc` (class-name) field. */\nconst agentTmpNameFor = (\n project: ProjectConfiguration,\n dir: string,\n): string | undefined => {\n const dirRelativeToProjectRoot = toProjectRelativePath(project, dir);\n const rc = findAgentComponentMetadata(project, dirRelativeToProjectRoot)?.rc;\n return rc ? kebabCase(rc) : undefined;\n};\n\n/** This agent's protocol, from ComponentMetadata's `protocol` field. */\nconst agentProtocolFor = (\n project: ProjectConfiguration,\n dir: string,\n): string | undefined => {\n const dirRelativeToProjectRoot = toProjectRelativePath(project, dir);\n return findAgentComponentMetadata(project, dirRelativeToProjectRoot)\n ?.protocol;\n};\n\n/** The relative path from `projectRoot` up to this agent's workspace-root-level local session storage. */\nconst localSessionsDirFor = (\n projectRoot: string,\n agentTmpName: string,\n): string =>\n joinPathFragments(\n getRelativePathToRootByDirectory(projectRoot),\n `tmp/agents/strands/${agentTmpName}`,\n );\n\n// Wires ModelErrorLoggingPlugin/ToolErrorLoggingPlugin into the StrandsAgent\n// constructor, restoring the error-logging behaviour removed from agent.ts.\nconst AGUI_INDEX_IMPORT_PATTERN =\n \"`import { $names } from '$mod'` => `import { ModelErrorLoggingPlugin, ToolErrorLoggingPlugin, $names } from '$mod'` where { $names <: contains `runWithSessionId`, $names <: not contains `ModelErrorLoggingPlugin` }\";\n// Match-only form of the target shape, used to gate before touching the\n// sibling agent.ts, and before committing to the rewrite here.\nconst AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN =\n '`new StrandsAgent({ agent, name: $name, description: $desc })`';\nconst AGUI_INDEX_CONSTRUCTOR_PATTERN = `${AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN} => \\`new StrandsAgent({ agent, name: $name, description: $desc, plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()] })\\``;\n\nconst AGUI_INDEX_IMPORT_CAPTURE_PATTERN =\n \"`import { $names } from '$mod';` where { $names <: contains `runWithSessionId` }\";\n\n// AG-UI's StrandsAgent adapter needs a sessionManagerProvider (called once\n// per threadId), mirroring AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN.\nconst aguiIndexSessionManagerImportPattern = (esm: boolean) =>\n `\\`import { getAgent } from '$mod';\\` => raw\\`import { getAgent } from '$mod';\nimport { getSessionManager } from './session${esm ? '.js' : ''}';\\` where { $program <: not contains \\`getSessionManager\\` }`;\n// Anchored on the exact 4-property shape produced above, so this only fires\n// once plugins are wired in. Used both to gate and to rewrite.\nconst AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN =\n '`new StrandsAgent({ agent, name: $name, description: $desc, plugins: $plugins })`';\nconst AGUI_INDEX_SESSION_MANAGER_CONSTRUCTOR_PATTERN = `${AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN} => \\`new StrandsAgent({ agent, name: $name, description: $desc, plugins: $plugins, config: { sessionManagerProvider: getSessionManager } })\\``;\n\n// The plugin classes referenced above only exist once model-errors-strands.ts\n// / tool-errors-strands.ts are converted from their plain logXErrors function\n// form (see checkPluginClass/applyPluginClass below). Anchored on the\n// `agent.addHook(...)` call so this doesn't re-match its own output.\nconst MODEL_ERRORS_IMPORT_PATTERN =\n \"`import { AfterModelCallEvent, type LocalAgent } from '@strands-agents/sdk';` => `import { AfterModelCallEvent, type LocalAgent, type Plugin } from '@strands-agents/sdk';`\";\n// Match-only form of the target shape, checked before committing to either\n// this or the sibling tool-errors conversion — see checkPluginClass.\nconst MODEL_ERRORS_CLASS_MATCH_PATTERN =\n '`export const logModelErrors = (agent: LocalAgent): void => { agent.addHook(AfterModelCallEvent, $callback); };`';\nconst MODEL_ERRORS_CLASS_PATTERN = `${MODEL_ERRORS_CLASS_MATCH_PATTERN} => raw\\`export class ModelErrorLoggingPlugin implements Plugin {\\n readonly name = 'model-error-logging';\\n\\n initAgent(agent: LocalAgent): void {\\n agent.addHook(AfterModelCallEvent, $callback);\\n }\\n}\\``;\n\nconst TOOL_ERRORS_IMPORT_PATTERN =\n \"`import { AfterToolCallEvent, type LocalAgent, TextBlock } from '@strands-agents/sdk';` => `import { AfterToolCallEvent, type LocalAgent, type Plugin, TextBlock } from '@strands-agents/sdk';`\";\nconst TOOL_ERRORS_CLASS_MATCH_PATTERN =\n '`export const logToolErrors = (agent: LocalAgent): void => { agent.addHook(AfterToolCallEvent, $callback); };`';\nconst TOOL_ERRORS_CLASS_PATTERN = `${TOOL_ERRORS_CLASS_MATCH_PATTERN} => raw\\`export class ToolErrorLoggingPlugin implements Plugin {\\n readonly name = 'tool-error-logging';\\n\\n initAgent(agent: LocalAgent): void {\\n agent.addHook(AfterToolCallEvent, $callback);\\n }\\n}\\``;\n\ntype PluginClassStatus = 'ready' | 'done' | 'diverged';\n\n/**\n * Checks (without writing) whether `filePath` still needs converting from its\n * plain `logXErrors` function to `className`, and whether the conversion\n * pattern would actually apply. `'done'` covers both \"already converted\" and\n * \"file doesn't exist\" — either way there's nothing to do and nothing\n * blocking the sibling conversion.\n */\nasync function checkPluginClass(\n tree: Tree,\n filePath: string,\n className: string,\n classMatchPattern: string,\n): Promise<PluginClassStatus> {\n if (!tree.exists(filePath)) {\n return 'done';\n }\n if ((tree.read(filePath, 'utf-8') ?? '').includes(`class ${className}`)) {\n return 'done';\n }\n return (await matchGritQL(tree, filePath, classMatchPattern))\n ? 'ready'\n : 'diverged';\n}\n\n/** Applies the class + import rewrite for a file already confirmed `'ready'`. */\nasync function applyPluginClass(\n tree: Tree,\n filePath: string,\n importPattern: string,\n classPattern: string,\n): Promise<void> {\n // The class rewrite is applied first, and the import only added once it's\n // confirmed to have actually happened here — not because either could fail\n // at this point (checkPluginClass already confirmed the pattern matches),\n // but to keep this file's own edit order self-evidently safe to read.\n await applyGritQL(tree, filePath, classPattern);\n await applyGritQL(tree, filePath, importPattern);\n}\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n let anyChanges = false;\n\n // Both classes live in one shared agent-connection package, so their\n // readiness is resolved once up front rather than per agent.\n const modelErrorsPath = joinPathFragments(\n AGENT_CONNECTION_PROJECT_DIR,\n 'src',\n 'core',\n 'model-errors-strands.ts',\n );\n const toolErrorsPath = joinPathFragments(\n AGENT_CONNECTION_PROJECT_DIR,\n 'src',\n 'core',\n 'tool-errors-strands.ts',\n );\n // Checked together, before writing either: all-or-nothing, so a run either\n // converts both or leaves both untouched — never just one.\n const modelPluginStatus = await checkPluginClass(\n tree,\n modelErrorsPath,\n 'ModelErrorLoggingPlugin',\n MODEL_ERRORS_CLASS_MATCH_PATTERN,\n );\n const toolPluginStatus = await checkPluginClass(\n tree,\n toolErrorsPath,\n 'ToolErrorLoggingPlugin',\n TOOL_ERRORS_CLASS_MATCH_PATTERN,\n );\n const pluginsReady =\n modelPluginStatus !== 'diverged' && toolPluginStatus !== 'diverged';\n\n if (pluginsReady) {\n if (modelPluginStatus === 'ready') {\n await applyPluginClass(\n tree,\n modelErrorsPath,\n MODEL_ERRORS_IMPORT_PATTERN,\n MODEL_ERRORS_CLASS_PATTERN,\n );\n }\n if (toolPluginStatus === 'ready') {\n await applyPluginClass(\n tree,\n toolErrorsPath,\n TOOL_ERRORS_IMPORT_PATTERN,\n TOOL_ERRORS_CLASS_PATTERN,\n );\n }\n } else {\n if (modelPluginStatus === 'diverged') {\n nextSteps.push(\n `${modelErrorsPath}: diverged from the generated shape - left as-is. Manually convert it to a \\`ModelErrorLoggingPlugin\\` class implementing \\`Plugin\\` (see the ts#agent generator's template); agent.ts/index.ts files that reference it are left unmigrated until both this and ${toolErrorsPath} are converted.`,\n );\n }\n if (toolPluginStatus === 'diverged') {\n nextSteps.push(\n `${toolErrorsPath}: diverged from the generated shape - left as-is. Manually convert it to a \\`ToolErrorLoggingPlugin\\` class implementing \\`Plugin\\` (see the ts#agent generator's template); agent.ts/index.ts files that reference it are left unmigrated until both this and ${modelErrorsPath} are converted.`,\n );\n }\n }\n\n const filePaths: string[] = [];\n visitNotIgnoredFiles(tree, '', (filePath) => filePaths.push(filePath));\n\n for (const filePath of filePaths) {\n if (filePath === modelErrorsPath || filePath === toolErrorsPath) {\n continue;\n }\n if (filePath.endsWith('.d.ts')) {\n continue;\n }\n\n // session.ts already targets the new { arn, session } shape via\n // `config.agentRuntimes?.[$name]?.session?.bucketName` — the generic\n // reshape branch below would otherwise corrupt that into `?.arn?.session?.bucketName`.\n if (filePath.endsWith('/session.ts')) {\n continue;\n }\n\n if (filePath.endsWith('/agent.ts')) {\n const dir = filePath.split('/').slice(0, -1).join('/');\n const project = findOwningProject(tree, dir);\n\n // Without a registered project there's no ComponentMetadata, so this\n // agent's protocol/name/agent-connection module can't be resolved — and\n // a pre-migration AG-UI agent.ts is textually identical to an\n // HTTP/A2A one, so there's nothing left to safely guess from.\n if (!project) {\n if (\n await matchGritQL(tree, filePath, AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN)\n ) {\n nextSteps.push(\n `${filePath}: could not determine the project root — manually verify whether this is an AG-UI or HTTP/A2A agent and complete its session-manager/error-logging-plugin migration accordingly (see the ts#agent generator's template).`,\n );\n }\n continue;\n }\n\n const protocol = agentProtocolFor(project, dir);\n\n if (protocol === 'ag-ui') {\n const hasLogCalls =\n (await matchGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_MODEL_CALL_PATTERN,\n )) ||\n (await matchGritQL(tree, filePath, AGENT_TS_LOG_TOOL_CALL_PATTERN));\n if (!hasLogCalls) {\n continue;\n }\n\n // The sibling index.ts restores error-logging via StrandsAgent\n // plugins — removing the calls here without that succeeding would\n // drop error logging rather than move it.\n const indexPath = `${dir}/index.ts`;\n const indexReady =\n pluginsReady &&\n (await matchGritQL(\n tree,\n indexPath,\n AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN,\n ));\n\n if (!indexReady) {\n nextSteps.push(\n `${filePath}: left the logModelErrors/logToolErrors calls in place — ${indexPath} could not be automatically wired with the equivalent StrandsAgent plugins. Move error logging to plugins there manually (see the ts#agent generator's template), then remove these calls.`,\n );\n continue;\n }\n\n const rewroteImport = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN,\n );\n const rewroteModelCall = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_MODEL_CALL_PATTERN,\n );\n const rewroteToolCall = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_TOOL_CALL_PATTERN,\n );\n if (rewroteImport || rewroteModelCall || rewroteToolCall) {\n anyChanges = true;\n }\n continue;\n }\n\n if (!protocol) {\n if (\n await matchGritQL(tree, filePath, AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN)\n ) {\n nextSteps.push(\n `${filePath}: could not determine this agent's protocol from its ComponentMetadata — manually verify whether it's AG-UI or HTTP/A2A and wire sessionManager/the error-logging plugins in accordingly (see the ts#agent generator's template).`,\n );\n }\n continue;\n }\n\n // HTTP/A2A: wire sessionManager into the Agent constructor and create\n // the sibling session.ts if it doesn't exist yet.\n if (\n !(await matchGritQL(\n tree,\n filePath,\n AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN,\n ))\n ) {\n continue;\n }\n\n const sessionPath = `${dir}/session.ts`;\n\n // Checked before any writes: if the plugin classes aren't available, or\n // the Agent isn't an inline object literal, leave the file untouched\n // entirely rather than ending up half-migrated.\n if (!pluginsReady) {\n nextSteps.push(\n `${filePath}: left as-is — ModelErrorLoggingPlugin/ToolErrorLoggingPlugin are not available yet (see the model-errors-strands.ts/tool-errors-strands.ts next step above). Wire sessionManager and the plugins in manually once those classes exist.`,\n );\n continue;\n }\n if (\n !(await matchGritQL(tree, filePath, AGENT_TS_CONSTRUCTOR_MATCH_PATTERN))\n ) {\n nextSteps.push(\n `${filePath}: the Agent is not constructed with an inline object literal (\\`new Agent({ ... })\\`), so sessionManager and the error-logging plugins could not be wired in automatically. Manually add \\`sessionManager: await getSessionManager()\\` and \\`plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()]\\` to its constructor (see the ts#agent generator's template), creating ${sessionPath} first if it doesn't already exist.`,\n );\n continue;\n }\n\n if (!tree.exists(sessionPath)) {\n const mod = await captureGritQLVariable(\n tree,\n filePath,\n AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN,\n 'mod',\n );\n const agentName = agentTmpNameFor(project, dir);\n\n if (mod && agentName) {\n tree.write(\n sessionPath,\n legacySessionManagerContent(\n mod,\n localSessionsDirFor(project.root, agentName),\n ),\n );\n } else {\n nextSteps.push(\n `${filePath}: could not determine the agent-connection module or this agent's name from its ComponentMetadata — manually create a session.ts (see the ts#agent generator's template) and wire \\`sessionManager: await getSessionManager()\\` into the Agent constructor.`,\n );\n continue;\n }\n }\n\n // Merges the plugin imports into the existing logModelErrors/\n // logToolErrors import clause (rather than a redundant second import),\n // and adds getSessionManager as its own line. The old specifiers are\n // stripped separately below, after this rewrite anchors on them.\n const esm = isEsmWorkspace(tree);\n await applyGritQL(\n tree,\n filePath,\n `\\`import { $names } from '$mod';\\` => raw\\`import { ModelErrorLoggingPlugin, ToolErrorLoggingPlugin, $names } from '$mod';\nimport { getSessionManager } from './session${esm ? '.js' : ''}';\\` where { $names <: contains \\`logModelErrors\\`, $names <: contains \\`logToolErrors\\`, $program <: not contains \\`getSessionManager\\` }`,\n );\n\n // Only rewrite the constructor once the import is confirmed present.\n if (!(tree.read(filePath, 'utf-8') ?? '').includes('getSessionManager')) {\n nextSteps.push(\n `${filePath}: found ${sessionPath} but couldn't confirm the getSessionManager import — wire \\`sessionManager: await getSessionManager()\\` into the Agent constructor manually.`,\n );\n continue;\n }\n\n await applyGritQL(tree, filePath, AGENT_TS_LOG_MODEL_CALL_PATTERN);\n await applyGritQL(tree, filePath, AGENT_TS_LOG_TOOL_CALL_PATTERN);\n await applyGritQL(\n tree,\n filePath,\n AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN,\n );\n\n const rewrotePlugins = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_PLUGINS_CONSTRUCTOR_PATTERN,\n );\n const rewroteConstructor = await applyGritQL(\n tree,\n filePath,\n AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN,\n );\n if (rewrotePlugins || rewroteConstructor) {\n anyChanges = true;\n }\n continue;\n }\n\n if (\n filePath.endsWith('/index.ts') &&\n (tree.read(filePath, 'utf-8') ?? '').includes('@ag-ui/aws-strands')\n ) {\n const alreadyWired = (tree.read(filePath, 'utf-8') ?? '').includes(\n 'ModelErrorLoggingPlugin',\n );\n\n if (!alreadyWired) {\n // Import and constructor only apply cleanly together — adding the\n // import while the constructor can't be rewritten would leave an\n // unused import and no plugins wired in.\n const needsPluginWiring = await matchGritQL(\n tree,\n filePath,\n AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN,\n );\n if (!pluginsReady) {\n if (needsPluginWiring) {\n nextSteps.push(\n `${filePath}: left the StrandsAgent constructor as-is — ModelErrorLoggingPlugin/ToolErrorLoggingPlugin are not available yet (see the model-errors-strands.ts/tool-errors-strands.ts next step above). Wire them in manually once those classes exist.`,\n );\n }\n continue;\n }\n if (!needsPluginWiring) {\n nextSteps.push(\n `${filePath}: the StrandsAgent constructor has diverged from the generated shape - left as-is. Manually add \\`plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()]\\` to it (see the ts#agent generator's template).`,\n );\n continue;\n }\n\n const rewroteImport = await applyGritQL(\n tree,\n filePath,\n AGUI_INDEX_IMPORT_PATTERN,\n );\n const rewroteConstructor = await applyGritQL(\n tree,\n filePath,\n AGUI_INDEX_CONSTRUCTOR_PATTERN,\n );\n if (rewroteImport || rewroteConstructor) {\n anyChanges = true;\n }\n }\n\n // Create the sibling session.ts (once plugins are present) and wire in\n // sessionManagerProvider. Gated on the exact post-plugins shape, so a\n // customised constructor is left alone rather than creating an unused\n // session.ts.\n if (\n !(await matchGritQL(\n tree,\n filePath,\n AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN,\n ))\n ) {\n continue;\n }\n\n const dir = filePath.split('/').slice(0, -1).join('/');\n const sessionPath = `${dir}/session.ts`;\n\n if (!tree.exists(sessionPath)) {\n const project = findOwningProject(tree, dir);\n const mod = await captureGritQLVariable(\n tree,\n filePath,\n AGUI_INDEX_IMPORT_CAPTURE_PATTERN,\n 'mod',\n );\n const agentName = project && agentTmpNameFor(project, dir);\n\n if (project && mod && agentName) {\n tree.write(\n sessionPath,\n legacySessionManagerContent(\n mod,\n localSessionsDirFor(project.root, agentName),\n ),\n );\n } else {\n nextSteps.push(\n `${filePath}: could not determine the project root, agent-connection module, or this agent's name from its ComponentMetadata — manually create a session.ts (see the ts#agent generator's template) and wire \\`config: { sessionManagerProvider: getSessionManager }\\` into the StrandsAgent constructor.`,\n );\n continue;\n }\n }\n\n const esm = isEsmWorkspace(tree);\n await applyGritQL(\n tree,\n filePath,\n aguiIndexSessionManagerImportPattern(esm),\n );\n\n if (!(tree.read(filePath, 'utf-8') ?? '').includes('getSessionManager')) {\n nextSteps.push(\n `${filePath}: found ${sessionPath} but couldn't confirm the getSessionManager import — wire \\`config: { sessionManagerProvider: getSessionManager }\\` into the StrandsAgent constructor manually.`,\n );\n continue;\n }\n\n const rewroteSessionManagerConstructor = await applyGritQL(\n tree,\n filePath,\n AGUI_INDEX_SESSION_MANAGER_CONSTRUCTOR_PATTERN,\n );\n if (rewroteSessionManagerConstructor) {\n anyChanges = true;\n }\n continue;\n }\n\n if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {\n const contents = tree.read(filePath, 'utf-8') ?? '';\n if (!contents.includes('agentRuntimes')) {\n continue;\n }\n // Only the 'agentcore' namespace is reshaped — see CDK_RC_SET_PATTERN.\n const rewroteAgentcoreRcSet = await applyGritQL(\n tree,\n filePath,\n CDK_RC_SET_PATTERN,\n );\n const rewroteInterface = await applyGritQL(\n tree,\n filePath,\n TS_RUNTIME_CONFIG_INTERFACE_PATTERN,\n );\n let rewroteClientArn = false;\n for (const pattern of TS_CLIENT_ARN_PATTERNS) {\n rewroteClientArn = (await applyGritQL(tree, filePath, pattern))\n ? true\n : rewroteClientArn;\n }\n const rewroteChatScriptType = await applyGritQL(\n tree,\n filePath,\n AGENTCORE_CHAT_SCRIPT_TYPE_PATTERN,\n );\n\n if (\n rewroteAgentcoreRcSet ||\n rewroteInterface ||\n rewroteClientArn ||\n rewroteChatScriptType\n ) {\n anyChanges = true;\n }\n } else if (filePath.endsWith('.tf')) {\n const contents = tree.read(filePath, 'utf-8') ?? '';\n if (!contents.includes('\"agentRuntimes\"')) {\n continue;\n }\n const rewrote = await applyGritQL(tree, filePath, TF_VALUE_PATTERN);\n if (rewrote) {\n anyChanges = true;\n }\n } else if (filePath.endsWith('.py')) {\n const contents = tree.read(filePath, 'utf-8') ?? '';\n if (!contents.includes('agentRuntimes')) {\n continue;\n }\n const rewrote = await applyGritQL(tree, filePath, PY_CLIENT_ARN_PATTERN);\n if (rewrote) {\n anyChanges = true;\n }\n }\n }\n\n if (anyChanges) {\n nextSteps.push(\n 'If you have custom code reading the runtime config `agentcore.agentRuntimes` entries ' +\n 'as plain ARN strings (e.g. custom Lambda handlers or agent code), update it to read ' +\n 'the ARN from `.arn` on the new `{ arn }` shape.',\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","visitNotIgnoredFiles","TS_AGENT_GENERATOR_INFO","AGENT_CONNECTION_PROJECT_DIR","applyGritQL","captureGritQLVariable","matchGritQL","formatFilesInSubtree","isEsmWorkspace","kebabCase","getRelativePathToRootByDirectory","toProjectRelativePath","CDK_RC_SET_PATTERN","TF_VALUE_PATTERN","TS_RUNTIME_CONFIG_INTERFACE_PATTERN","TS_CLIENT_ARN_PATTERNS","AGENTCORE_CHAT_SCRIPT_TYPE_PATTERN","PY_CLIENT_ARN_PATTERN","AGENT_TS_LOG_MODEL_CALL_PATTERN","AGENT_TS_LOG_TOOL_CALL_PATTERN","AGENT_TS_SESSION_MANAGER_CONSTRUCTOR_PATTERN","AGENT_TS_CONSTRUCTOR_MATCH_PATTERN","AGENT_TS_PLUGINS_CONSTRUCTOR_PATTERN","AGENT_TS_LOG_IMPORT_CAPTURE_PATTERN","AGENT_TS_REMOVE_LOG_ERRORS_IMPORT_PATTERN","legacySessionManagerContent","agentConnectionModule","localSessionsDir","findOwningProject","tree","dirPath","best","project","values","root","startsWith","length","findAgentComponentMetadata","dirRelativeToProjectRoot","metadata","components","find","component","generator","id","path","agentTmpNameFor","dir","rc","undefined","agentProtocolFor","protocol","localSessionsDirFor","projectRoot","agentTmpName","AGUI_INDEX_IMPORT_PATTERN","AGUI_INDEX_CONSTRUCTOR_MATCH_PATTERN","AGUI_INDEX_CONSTRUCTOR_PATTERN","AGUI_INDEX_IMPORT_CAPTURE_PATTERN","aguiIndexSessionManagerImportPattern","esm","AGUI_INDEX_SESSION_MANAGER_MATCH_PATTERN","AGUI_INDEX_SESSION_MANAGER_CONSTRUCTOR_PATTERN","MODEL_ERRORS_IMPORT_PATTERN","MODEL_ERRORS_CLASS_MATCH_PATTERN","MODEL_ERRORS_CLASS_PATTERN","TOOL_ERRORS_IMPORT_PATTERN","TOOL_ERRORS_CLASS_MATCH_PATTERN","TOOL_ERRORS_CLASS_PATTERN","checkPluginClass","filePath","className","classMatchPattern","exists","read","includes","applyPluginClass","importPattern","classPattern","migration","nextSteps","anyChanges","modelErrorsPath","toolErrorsPath","modelPluginStatus","toolPluginStatus","pluginsReady","push","filePaths","endsWith","split","slice","join","hasLogCalls","indexPath","indexReady","rewroteImport","rewroteModelCall","rewroteToolCall","sessionPath","mod","agentName","write","rewrotePlugins","rewroteConstructor","alreadyWired","needsPluginWiring","rewroteSessionManagerConstructor","contents","rewroteAgentcoreRcSet","rewroteInterface","rewroteClientArn","pattern","rewroteChatScriptType","rewrote"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.58/0001-smithy-ssdk-bundle-pins/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 { SMITHY_PROJECT_GENERATOR_INFO } from '../../../smithy/project/generator';\nimport { applyGritQL } from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport { isVendedUpgrade } from '../../../utils/version-upgrade-migration/vended-upgrade';\n\n/**\n * Move a Smithy `build.Dockerfile` onto the SSDK bundle pins this release fixes.\n *\n * `rolldown-plugin-dts` named the bundled declaration after its content hash\n * before 0.20.0, so the generated handler's `./generated/ssdk/index.js` import\n * found no `index.d.ts` beside it and `compile` failed with TS7016. The two pins\n * move together: the plugin release that fixed the naming needs a rolldown past\n * the pin this shipped with.\n *\n * There is no Dockerfile grammar, so each pin is matched as an anchored rewrite\n * over the whole file with the version captured — `${...}` in these patterns is\n * GritQL metavariable syntax, not interpolation.\n */\n\n/** A pin in the file body, and the version this migration moves it to. */\ninterface Pin {\n /** The package as the install command names it. */\n readonly name: string;\n readonly target: string;\n}\n\n/**\n * Hardcoded rather than read from `TS_VERSIONS`: this runs once, for the release\n * that fixed the declaration naming, so it must keep applying that exact change\n * however far the vended versions move afterwards. A workspace on a later release\n * gets the newer pins from the version sync instead.\n */\nconst PINS: readonly Pin[] = [\n { name: 'rolldown', target: '1.2.0' },\n { name: 'rolldown-plugin-dts', target: '0.28.0' },\n { name: '@rollup/plugin-esm-shim', target: '0.1.8' },\n];\n\n/** A version ends at whitespace, a line break or the end of the command. */\nconst VERSION = String.raw`[^\\s\\\\]+`;\n\nconst escapeRegExp = (value: string): string =>\n value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * Rewrite every occurrence of one pin to its target version.\n *\n * The pin is matched by name, so a `rolldown-plugin-dts@x` in the same command as\n * `rolldown@y` keeps its own version — the `@` before the version terminates the\n * match, so the shorter name does not match the longer one.\n */\nconst rewritePin = ({ name, target }: Pin): string =>\n `r\"[\\\\s\\\\S]*${escapeRegExp(name)}@(${VERSION})[\\\\s\\\\S]*\"($version) where { $version => \\`${target}\\` }`;\n\n/** Whether the file pins this package behind the target version. */\nconst isBehindTarget = (contents: string, { name, target }: Pin): boolean => {\n const matches = contents.matchAll(\n new RegExp(`${escapeRegExp(name)}@(${VERSION})`, 'g'),\n );\n const declared = [...matches].flatMap((match) =>\n match[1] ? [match[1]] : [],\n );\n // A rewrite replaces every occurrence at once, so this has to hold for all of\n // them. Compared rather than tested for inequality, so a workspace a later\n // release has already moved past the target keeps its newer pin.\n return (\n declared.length > 0 &&\n declared.every((version) => isVendedUpgrade(target, version))\n );\n};\n\nconst divergedNextStep = (path: string): string =>\n `${path}: the Smithy build image's bundle pins have diverged from the generated shape - left untouched. Update \\`rolldown\\` to 1.2.0 and \\`rolldown-plugin-dts\\` to 0.28.0.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n // Only a Smithy service project bundles the SSDK; the shapes type builds the\n // model alone and pins none of this.\n const buildDockerfiles = [...getProjects(tree).values()]\n .filter((project) => {\n const metadata = project.metadata as\n | { generator?: string; smithyType?: string }\n | undefined;\n return (\n metadata?.generator === SMITHY_PROJECT_GENERATOR_INFO.id &&\n metadata.smithyType === 'service'\n );\n })\n .map((project) => joinPathFragments(project.root, 'build.Dockerfile'))\n .filter((filePath) => tree.exists(filePath));\n\n for (const path of buildDockerfiles) {\n const contents = tree.read(path, 'utf-8') ?? '';\n\n for (const pin of PINS) {\n if (!isBehindTarget(contents, pin)) {\n continue;\n }\n if (!(await applyGritQL(tree, path, rewritePin(pin)))) {\n nextSteps.push(divergedNextStep(path));\n break;\n }\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","SMITHY_PROJECT_GENERATOR_INFO","applyGritQL","formatFilesInSubtree","isVendedUpgrade","PINS","name","target","VERSION","String","raw","escapeRegExp","value","replace","rewritePin","isBehindTarget","contents","matches","matchAll","RegExp","declared","flatMap","match","length","every","version","divergedNextStep","path","migration","tree","nextSteps","buildDockerfiles","values","filter","project","metadata","generator","id","smithyType","map","root","filePath","exists","read","pin","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAGZ,aAAa;AACpB,SAASC,6BAA6B,QAAQ,uCAAoC;AAClF,SAASC,WAAW,QAAQ,wBAAqB;AACjD,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,eAAe,QAAQ,6DAA0D;AAuB1F;;;;;CAKC,GACD,MAAMC,OAAuB;IAC3B;QAAEC,MAAM;QAAYC,QAAQ;IAAQ;IACpC;QAAED,MAAM;QAAuBC,QAAQ;IAAS;IAChD;QAAED,MAAM;QAA2BC,QAAQ;IAAQ;CACpD;AAED,0EAA0E,GAC1E,MAAMC,UAAUC,OAAOC,GAAG,CAAC,QAAQ,CAAC;AAEpC,MAAMC,eAAe,CAACC,QACpBA,MAAMC,OAAO,CAAC,uBAAuB;AAEvC;;;;;;CAMC,GACD,MAAMC,aAAa,CAAC,EAAER,IAAI,EAAEC,MAAM,EAAO,GACvC,CAAC,WAAW,EAAEI,aAAaL,MAAM,EAAE,EAAEE,QAAQ,4CAA4C,EAAED,OAAO,IAAI,CAAC;AAEzG,kEAAkE,GAClE,MAAMQ,iBAAiB,CAACC,UAAkB,EAAEV,IAAI,EAAEC,MAAM,EAAO;IAC7D,MAAMU,UAAUD,SAASE,QAAQ,CAC/B,IAAIC,OAAO,GAAGR,aAAaL,MAAM,EAAE,EAAEE,QAAQ,CAAC,CAAC,EAAE;IAEnD,MAAMY,WAAW;WAAIH;KAAQ,CAACI,OAAO,CAAC,CAACC,QACrCA,KAAK,CAAC,EAAE,GAAG;YAACA,KAAK,CAAC,EAAE;SAAC,GAAG,EAAE;IAE5B,8EAA8E;IAC9E,2EAA2E;IAC3E,iEAAiE;IACjE,OACEF,SAASG,MAAM,GAAG,KAClBH,SAASI,KAAK,CAAC,CAACC,UAAYrB,gBAAgBG,QAAQkB;AAExD;AAEA,MAAMC,mBAAmB,CAACC,OACxB,GAAGA,KAAK,mKAAmK,CAAC;AAE9K,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,6EAA6E;IAC7E,qCAAqC;IACrC,MAAMC,mBAAmB;WAAIhC,YAAY8B,MAAMG,MAAM;KAAG,CACrDC,MAAM,CAAC,CAACC;QACP,MAAMC,WAAWD,QAAQC,QAAQ;QAGjC,OACEA,UAAUC,cAAcnC,8BAA8BoC,EAAE,IACxDF,SAASG,UAAU,KAAK;IAE5B,GACCC,GAAG,CAAC,CAACL,UAAYlC,kBAAkBkC,QAAQM,IAAI,EAAE,qBACjDP,MAAM,CAAC,CAACQ,WAAaZ,KAAKa,MAAM,CAACD;IAEpC,KAAK,MAAMd,QAAQI,iBAAkB;QACnC,MAAMf,WAAWa,KAAKc,IAAI,CAAChB,MAAM,YAAY;QAE7C,KAAK,MAAMiB,OAAOvC,KAAM;YACtB,IAAI,CAACU,eAAeC,UAAU4B,MAAM;gBAClC;YACF;YACA,IAAI,CAAE,MAAM1C,YAAY2B,MAAMF,MAAMb,WAAW8B,OAAQ;gBACrDd,UAAUe,IAAI,CAACnB,iBAAiBC;gBAChC;YACF;QACF;IACF;IAEA,MAAMxB,qBAAqB0B;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.58/0001-smithy-ssdk-bundle-pins/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 { SMITHY_PROJECT_GENERATOR_INFO } from '../../../smithy/project/generator.js';\nimport { applyGritQL } from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { isVendedUpgrade } from '../../../utils/version-upgrade-migration/vended-upgrade.js';\n\n/**\n * Move a Smithy `build.Dockerfile` onto the SSDK bundle pins this release fixes.\n *\n * `rolldown-plugin-dts` named the bundled declaration after its content hash\n * before 0.20.0, so the generated handler's `./generated/ssdk/index.js` import\n * found no `index.d.ts` beside it and `compile` failed with TS7016. The two pins\n * move together: the plugin release that fixed the naming needs a rolldown past\n * the pin this shipped with.\n *\n * There is no Dockerfile grammar, so each pin is matched as an anchored rewrite\n * over the whole file with the version captured — `${...}` in these patterns is\n * GritQL metavariable syntax, not interpolation.\n */\n\n/** A pin in the file body, and the version this migration moves it to. */\ninterface Pin {\n /** The package as the install command names it. */\n readonly name: string;\n readonly target: string;\n}\n\n/**\n * Hardcoded rather than read from `TS_VERSIONS`: this runs once, for the release\n * that fixed the declaration naming, so it must keep applying that exact change\n * however far the vended versions move afterwards. A workspace on a later release\n * gets the newer pins from the version sync instead.\n */\nconst PINS: readonly Pin[] = [\n { name: 'rolldown', target: '1.2.0' },\n { name: 'rolldown-plugin-dts', target: '0.28.0' },\n { name: '@rollup/plugin-esm-shim', target: '0.1.8' },\n];\n\n/** A version ends at whitespace, a line break or the end of the command. */\nconst VERSION = String.raw`[^\\s\\\\]+`;\n\nconst escapeRegExp = (value: string): string =>\n value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * Rewrite every occurrence of one pin to its target version.\n *\n * The pin is matched by name, so a `rolldown-plugin-dts@x` in the same command as\n * `rolldown@y` keeps its own version — the `@` before the version terminates the\n * match, so the shorter name does not match the longer one.\n */\nconst rewritePin = ({ name, target }: Pin): string =>\n `r\"[\\\\s\\\\S]*${escapeRegExp(name)}@(${VERSION})[\\\\s\\\\S]*\"($version) where { $version => \\`${target}\\` }`;\n\n/** Whether the file pins this package behind the target version. */\nconst isBehindTarget = (contents: string, { name, target }: Pin): boolean => {\n const matches = contents.matchAll(\n new RegExp(`${escapeRegExp(name)}@(${VERSION})`, 'g'),\n );\n const declared = [...matches].flatMap((match) =>\n match[1] ? [match[1]] : [],\n );\n // A rewrite replaces every occurrence at once, so this has to hold for all of\n // them. Compared rather than tested for inequality, so a workspace a later\n // release has already moved past the target keeps its newer pin.\n return (\n declared.length > 0 &&\n declared.every((version) => isVendedUpgrade(target, version))\n );\n};\n\nconst divergedNextStep = (path: string): string =>\n `${path}: the Smithy build image's bundle pins have diverged from the generated shape - left untouched. Update \\`rolldown\\` to 1.2.0 and \\`rolldown-plugin-dts\\` to 0.28.0.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n // Only a Smithy service project bundles the SSDK; the shapes type builds the\n // model alone and pins none of this.\n const buildDockerfiles = [...getProjects(tree).values()]\n .filter((project) => {\n const metadata = project.metadata as\n | { generator?: string; smithyType?: string }\n | undefined;\n return (\n metadata?.generator === SMITHY_PROJECT_GENERATOR_INFO.id &&\n metadata.smithyType === 'service'\n );\n })\n .map((project) => joinPathFragments(project.root, 'build.Dockerfile'))\n .filter((filePath) => tree.exists(filePath));\n\n for (const path of buildDockerfiles) {\n const contents = tree.read(path, 'utf-8') ?? '';\n\n for (const pin of PINS) {\n if (!isBehindTarget(contents, pin)) {\n continue;\n }\n if (!(await applyGritQL(tree, path, rewritePin(pin)))) {\n nextSteps.push(divergedNextStep(path));\n break;\n }\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","SMITHY_PROJECT_GENERATOR_INFO","applyGritQL","formatFilesInSubtree","isVendedUpgrade","PINS","name","target","VERSION","String","raw","escapeRegExp","value","replace","rewritePin","isBehindTarget","contents","matches","matchAll","RegExp","declared","flatMap","match","length","every","version","divergedNextStep","path","migration","tree","nextSteps","buildDockerfiles","values","filter","project","metadata","generator","id","smithyType","map","root","filePath","exists","read","pin","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAGZ,aAAa;AACpB,SAASC,6BAA6B,QAAQ,uCAAuC;AACrF,SAASC,WAAW,QAAQ,wBAAwB;AACpD,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SAASC,eAAe,QAAQ,6DAA6D;AAuB7F;;;;;CAKC,GACD,MAAMC,OAAuB;IAC3B;QAAEC,MAAM;QAAYC,QAAQ;IAAQ;IACpC;QAAED,MAAM;QAAuBC,QAAQ;IAAS;IAChD;QAAED,MAAM;QAA2BC,QAAQ;IAAQ;CACpD;AAED,0EAA0E,GAC1E,MAAMC,UAAUC,OAAOC,GAAG,CAAC,QAAQ,CAAC;AAEpC,MAAMC,eAAe,CAACC,QACpBA,MAAMC,OAAO,CAAC,uBAAuB;AAEvC;;;;;;CAMC,GACD,MAAMC,aAAa,CAAC,EAAER,IAAI,EAAEC,MAAM,EAAO,GACvC,CAAC,WAAW,EAAEI,aAAaL,MAAM,EAAE,EAAEE,QAAQ,4CAA4C,EAAED,OAAO,IAAI,CAAC;AAEzG,kEAAkE,GAClE,MAAMQ,iBAAiB,CAACC,UAAkB,EAAEV,IAAI,EAAEC,MAAM,EAAO;IAC7D,MAAMU,UAAUD,SAASE,QAAQ,CAC/B,IAAIC,OAAO,GAAGR,aAAaL,MAAM,EAAE,EAAEE,QAAQ,CAAC,CAAC,EAAE;IAEnD,MAAMY,WAAW;WAAIH;KAAQ,CAACI,OAAO,CAAC,CAACC,QACrCA,KAAK,CAAC,EAAE,GAAG;YAACA,KAAK,CAAC,EAAE;SAAC,GAAG,EAAE;IAE5B,8EAA8E;IAC9E,2EAA2E;IAC3E,iEAAiE;IACjE,OACEF,SAASG,MAAM,GAAG,KAClBH,SAASI,KAAK,CAAC,CAACC,UAAYrB,gBAAgBG,QAAQkB;AAExD;AAEA,MAAMC,mBAAmB,CAACC,OACxB,GAAGA,KAAK,mKAAmK,CAAC;AAE9K,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,6EAA6E;IAC7E,qCAAqC;IACrC,MAAMC,mBAAmB;WAAIhC,YAAY8B,MAAMG,MAAM;KAAG,CACrDC,MAAM,CAAC,CAACC;QACP,MAAMC,WAAWD,QAAQC,QAAQ;QAGjC,OACEA,UAAUC,cAAcnC,8BAA8BoC,EAAE,IACxDF,SAASG,UAAU,KAAK;IAE5B,GACCC,GAAG,CAAC,CAACL,UAAYlC,kBAAkBkC,QAAQM,IAAI,EAAE,qBACjDP,MAAM,CAAC,CAACQ,WAAaZ,KAAKa,MAAM,CAACD;IAEpC,KAAK,MAAMd,QAAQI,iBAAkB;QACnC,MAAMf,WAAWa,KAAKc,IAAI,CAAChB,MAAM,YAAY;QAE7C,KAAK,MAAMiB,OAAOvC,KAAM;YACtB,IAAI,CAACU,eAAeC,UAAU4B,MAAM;gBAClC;YACF;YACA,IAAI,CAAE,MAAM1C,YAAY2B,MAAMF,MAAMb,WAAW8B,OAAQ;gBACrDd,UAAUe,IAAI,CAACnB,iBAAiBC;gBAChC;YACF;QACF;IACF;IAEA,MAAMxB,qBAAqB0B;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.59/0001-gateway-agent-targets/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\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} from '../../../utils/shared-constructs-constants';\n\n/**\n * Bring existing workspaces up to the generators' current gateway-target\n * support, so agents can be attached to an http-protocol AgentCore Gateway:\n *\n * - The vended `AgentCoreGateway` core construct gains the `protocol` prop\n * (http gateways have no protocol type, which AgentCore Runtime targets\n * require) and the `addAgent` / `addAgentTarget` methods.\n * - Vended agent constructs gain the `agentName` member `addAgent` reads as\n * the default gateway target name.\n *\n * Both files are generated with `KeepExisting`, so without this an upgraded\n * workspace pairs new app-level constructs with stale core ones.\n */\n\nconst GATEWAY_CONSTRUCT_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/agentcore-gateway/agentcore-gateway.ts`;\n\nconst AGENTS_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/agents`;\n\nconst PROTOCOL_PROP = `/**\n * The gateway's protocol. An \\`mcp\\` gateway aggregates MCP server targets\n * into a single MCP endpoint. An \\`http\\` gateway has no protocol type and\n * proxies requests to AgentCore Runtime targets via path-based routing\n * (\\`/<targetName>/invocations\\`) — the target type AgentCore only allows on\n * gateways without a protocol type.\n *\n * @default 'mcp'\n */\n readonly protocol?: 'mcp' | 'http';`;\n\nconst PROTOCOL_CONSTRUCTOR_STATEMENTS = `this.protocol = props?.protocol ?? 'mcp';\n`;\n\nconst PROTOCOL_TYPE_REMOVAL = `\n if (this.protocol === 'http') {\n // AgentCore Runtime targets require a gateway without a protocol type,\n // which the Gateway L2 cannot express — it always renders MCP — so\n // remove the protocol from the underlying CloudFormation resource.\n const cfnGateway = this.gateway.node.defaultChild as agentcore.CfnGateway;\n cfnGateway.addPropertyDeletionOverride('ProtocolType');\n cfnGateway.addPropertyDeletionOverride('ProtocolConfiguration');\n }`;\n\nconst AGENT_TARGET_METHODS = `\n /**\n * Add an agent runtime construct as a target of this Gateway. Requires the\n * \\`http\\` protocol — the gateway proxies requests for the agent under\n * \\`<gatewayUrl>/<targetName>/invocations\\`, without protocol translation.\n *\n * The target name defaults to the agent construct's \\`agentName\\` (its\n * project's class name in kebab-case, e.g. \\`MyAgent\\` -> \\`my-agent\\`). It\n * forms the target's invocation path, so renaming it later is a breaking\n * change for consumers.\n */\n public addAgent(\n agent: Construct & {\n readonly agentCoreRuntime: agentcore.Runtime;\n readonly agentName: string;\n },\n props?: {\n gatewayTargetName?: string;\n },\n ): agentcore.CfnGatewayTarget {\n return this.addAgentTarget({\n gatewayTargetName: props?.gatewayTargetName ?? agent.agentName,\n agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn,\n });\n }\n\n /**\n * Register an agent runtime ARN as a Gateway target. Prefer\n * {@link addAgent} when the construct is in scope.\n */\n public addAgentTarget(props: {\n gatewayTargetName: string;\n agentRuntimeArn: string;\n }): agentcore.CfnGatewayTarget {\n if (this.protocol !== 'http') {\n throw new Error(\n \\`Agent runtime targets require an http-protocol gateway, but this gateway uses '\\${this.protocol}'.\\`,\n );\n }\n\n // The construct id is derived from the target name so the two change\n // together — target names are unique per gateway, and replacing a target\n // under an unchanged name fails with AlreadyExists.\n const target = new agentcore.CfnGatewayTarget(\n this,\n \\`Target-\\${props.gatewayTargetName}\\`,\n {\n gatewayIdentifier: this.gateway.gatewayId,\n name: props.gatewayTargetName,\n targetConfiguration: {\n http: {\n agentcoreRuntime: {\n arn: props.agentRuntimeArn,\n qualifier: 'DEFAULT',\n },\n },\n },\n // The bare gateway IAM role credential: runtime targets reject the\n // iamCredentialProvider detail MCP targets carry.\n credentialProviderConfigurations: [\n {\n credentialProviderType: 'GATEWAY_IAM_ROLE',\n },\n ],\n },\n );\n\n // Grant the gateway role invoke access to the target runtime before the\n // target is created — AgentCore validates access to the runtime during\n // target creation.\n const grant = this.gateway.role.addToPrincipalPolicy(\n new iam.PolicyStatement({\n actions: [\n 'bedrock-agentcore:InvokeAgentRuntime',\n 'bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream',\n // A2A targets additionally serve their agent card via the gateway.\n 'bedrock-agentcore:GetAgentCard',\n ],\n resources: [props.agentRuntimeArn, \\`\\${props.agentRuntimeArn}/*\\`],\n }),\n );\n if (grant.policyDependable) {\n target.node.addDependency(grant.policyDependable);\n }\n\n return target;\n }`;\n\n/**\n * Add the `protocol` prop, its constructor handling and the agent-target\n * methods to the vended `AgentCoreGateway` core construct.\n */\nconst migrateGatewayConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(GATEWAY_CONSTRUCT_FILE)) {\n // No vended gateway construct in this workspace - nothing to migrate.\n return;\n }\n\n if (\n (tree.read(GATEWAY_CONSTRUCT_FILE, 'utf-8') ?? '').includes(\n 'addAgentTarget',\n )\n ) {\n // Already migrated.\n return;\n }\n\n const divergedMessage = `${GATEWAY_CONSTRUCT_FILE}: the AgentCoreGateway construct has diverged from the generated shape - left untouched. Re-run the agentcore-gateway generator in a fresh workspace to see the current construct, which supports agent runtime targets via a 'protocol' prop and addAgent()/addAgentTarget() methods.`;\n\n // Anchored on the shapes every vended version of the construct carries: the\n // props interface, the class field the protocol field is inserted after,\n // and the Gateway creation in the constructor.\n const hasVendedShape =\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`export interface AgentCoreGatewayProps { $_ }`',\n )) &&\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`private readonly targetRuntimeArns: string[] = []`',\n )) &&\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n \"`this.gateway = new agentcore.Gateway(this, 'Gateway', $_)`\",\n ));\n\n if (!hasVendedShape) {\n nextSteps.push(divergedMessage);\n return;\n }\n\n // 1. The protocol prop on AgentCoreGatewayProps. The placeholder keeps the\n // prop's doc comment (with its backticks) out of the GritQL pattern.\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`export interface AgentCoreGatewayProps { $members }\\` where {\n $members <: not contains \\`protocol\\`\n} => \\`export interface AgentCoreGatewayProps { $members\n ${GRIT_INSERT_PLACEHOLDER}\n}\\``,\n PROTOCOL_PROP,\n );\n\n // 2. The protocol class field. Matched without the trailing semicolon —\n // GritQL parses the snippet standalone, where the semicolon is not part\n // of the field's AST node.\n await applyGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`private readonly targetRuntimeArns: string[] = []\\` as $field where {\n $program <: not contains \\`private readonly protocol\\`\n} => \\`$field;\n private readonly protocol: 'mcp' | 'http'\\``,\n );\n\n // 3. Assign the field and remove the protocol type for http gateways.\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`this.gateway = new agentcore.Gateway($args);\\` as $stmt where {\n $program <: not contains \\`this.protocol = props\\`\n} => \\`${GRIT_INSERT_PLACEHOLDER}\n $stmt\\``,\n PROTOCOL_CONSTRUCTOR_STATEMENTS,\n );\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`this.gateway = new agentcore.Gateway($args);\\` as $stmt where {\n $program <: not contains \\`addPropertyDeletionOverride\\`\n} => \\`$stmt\n${GRIT_INSERT_PLACEHOLDER}\\``,\n PROTOCOL_TYPE_REMOVAL,\n );\n\n // 4. The agent-target methods, inserted after addGatewayTarget (present in\n // every vended version that also has the readiness probe field).\n const addedMethods = await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`public addGatewayTarget($params): agentcore.CfnGatewayTarget { $body }\\` as $method where {\n $program <: not contains \\`addAgentTarget\\`\n} => \\`$method\n${GRIT_INSERT_PLACEHOLDER}\\``,\n AGENT_TARGET_METHODS,\n );\n\n if (!addedMethods) {\n nextSteps.push(divergedMessage);\n return;\n }\n};\n\n/**\n * Add the `agentName` member to each vended agent construct, which\n * `AgentCoreGateway.addAgent` reads as the default gateway target name.\n */\nconst migrateAgentConstructs = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(AGENTS_DIR)) {\n return;\n }\n for (const dir of tree.children(AGENTS_DIR)) {\n const constructFile = `${AGENTS_DIR}/${dir}/${dir}.ts`;\n if (!tree.exists(constructFile)) {\n continue;\n }\n if ((tree.read(constructFile, 'utf-8') ?? '').includes('agentName')) {\n // Already migrated (or user-added).\n continue;\n }\n const added = await insertViaGritQL(\n tree,\n constructFile,\n `\\`public readonly agentCoreRuntime: Runtime\\` as $field => \\`$field;\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n `/** Default Gateway target name for this agent. */\n public readonly agentName = '${dir}'`,\n );\n if (!added) {\n nextSteps.push(\n `${constructFile}: the agent construct has diverged from the generated shape - left untouched. To attach this agent to a gateway with addAgent(), add a \\`public readonly agentName = '${dir}';\\` member (or use addAgentTarget() with an explicit target name).`,\n );\n }\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateGatewayConstruct(tree, nextSteps);\n await migrateAgentConstructs(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","GATEWAY_CONSTRUCT_FILE","AGENTS_DIR","PROTOCOL_PROP","PROTOCOL_CONSTRUCTOR_STATEMENTS","PROTOCOL_TYPE_REMOVAL","AGENT_TARGET_METHODS","migrateGatewayConstruct","tree","nextSteps","exists","read","includes","divergedMessage","hasVendedShape","push","addedMethods","migrateAgentConstructs","dir","children","constructFile","added","migration"],"mappings":"AAAA;;;CAGC,GAED,SACEA,WAAW,EACXC,uBAAuB,EACvBC,eAAe,EACfC,WAAW,QACN,wBAAqB;AAC5B,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SACEC,YAAY,EACZC,qBAAqB,QAChB,gDAA6C;AAEpD;;;;;;;;;;;;CAYC,GAED,MAAMC,yBAAyB,GAAGF,aAAa,CAAC,EAAEC,sBAAsB,gDAAgD,CAAC;AAEzH,MAAME,aAAa,GAAGH,aAAa,CAAC,EAAEC,sBAAsB,eAAe,CAAC;AAE5E,MAAMG,gBAAgB,CAAC;;;;;;;;;qCASc,CAAC;AAEtC,MAAMC,kCAAkC,CAAC;AACzC,CAAC;AAED,MAAMC,wBAAwB,CAAC;;;;;;;;KAQ1B,CAAC;AAEN,MAAMC,uBAAuB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsF3B,CAAC;AAEJ;;;CAGC,GACD,MAAMC,0BAA0B,OAC9BC,MACAC;IAEA,IAAI,CAACD,KAAKE,MAAM,CAACT,yBAAyB;QACxC,sEAAsE;QACtE;IACF;IAEA,IACE,AAACO,CAAAA,KAAKG,IAAI,CAACV,wBAAwB,YAAY,EAAC,EAAGW,QAAQ,CACzD,mBAEF;QACA,oBAAoB;QACpB;IACF;IAEA,MAAMC,kBAAkB,GAAGZ,uBAAuB,sRAAsR,CAAC;IAEzU,4EAA4E;IAC5E,yEAAyE;IACzE,+CAA+C;IAC/C,MAAMa,iBACJ,AAAC,MAAMjB,YACLW,MACAP,wBACA,sDAED,MAAMJ,YACLW,MACAP,wBACA,0DAED,MAAMJ,YACLW,MACAP,wBACA;IAGJ,IAAI,CAACa,gBAAgB;QACnBL,UAAUM,IAAI,CAACF;QACf;IACF;IAEA,2EAA2E;IAC3E,wEAAwE;IACxE,MAAMjB,gBACJY,MACAP,wBACA,CAAC;;;EAGH,EAAEN,wBAAwB;GACzB,CAAC,EACAQ;IAGF,wEAAwE;IACxE,2EAA2E;IAC3E,8BAA8B;IAC9B,MAAMT,YACJc,MACAP,wBACA,CAAC;;;6CAGwC,CAAC;IAG5C,sEAAsE;IACtE,MAAML,gBACJY,MACAP,wBACA,CAAC;;OAEE,EAAEN,wBAAwB;WACtB,CAAC,EACRS;IAEF,MAAMR,gBACJY,MACAP,wBACA,CAAC;;;AAGL,EAAEN,wBAAwB,EAAE,CAAC,EACzBU;IAGF,2EAA2E;IAC3E,oEAAoE;IACpE,MAAMW,eAAe,MAAMpB,gBACzBY,MACAP,wBACA,CAAC;;;AAGL,EAAEN,wBAAwB,EAAE,CAAC,EACzBW;IAGF,IAAI,CAACU,cAAc;QACjBP,UAAUM,IAAI,CAACF;QACf;IACF;AACF;AAEA;;;CAGC,GACD,MAAMI,yBAAyB,OAC7BT,MACAC;IAEA,IAAI,CAACD,KAAKE,MAAM,CAACR,aAAa;QAC5B;IACF;IACA,KAAK,MAAMgB,OAAOV,KAAKW,QAAQ,CAACjB,YAAa;QAC3C,MAAMkB,gBAAgB,GAAGlB,WAAW,CAAC,EAAEgB,IAAI,CAAC,EAAEA,IAAI,GAAG,CAAC;QACtD,IAAI,CAACV,KAAKE,MAAM,CAACU,gBAAgB;YAC/B;QACF;QACA,IAAI,AAACZ,CAAAA,KAAKG,IAAI,CAACS,eAAe,YAAY,EAAC,EAAGR,QAAQ,CAAC,cAAc;YAEnE;QACF;QACA,MAAMS,QAAQ,MAAMzB,gBAClBY,MACAY,eACA,CAAC;EACL,EAAEzB,wBAAwB,EAAE,CAAC,EACzB,CAAC;+BACwB,EAAEuB,IAAI,CAAC,CAAC;QAEnC,IAAI,CAACG,OAAO;YACVZ,UAAUM,IAAI,CACZ,GAAGK,cAAc,sKAAsK,EAAEF,IAAI,mEAAmE,CAAC;QAErQ;IACF;AACF;AAEA,eAAe,eAAeI,UAC5Bd,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,MAAMF,wBAAwBC,MAAMC;IACpC,MAAMQ,uBAAuBT,MAAMC;IAEnC,MAAMX,qBAAqBU;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.59/0001-gateway-agent-targets/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\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} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Bring existing workspaces up to the generators' current gateway-target\n * support, so agents can be attached to an http-protocol AgentCore Gateway:\n *\n * - The vended `AgentCoreGateway` core construct gains the `protocol` prop\n * (http gateways have no protocol type, which AgentCore Runtime targets\n * require) and the `addAgent` / `addAgentTarget` methods.\n * - Vended agent constructs gain the `agentName` member `addAgent` reads as\n * the default gateway target name.\n *\n * Both files are generated with `KeepExisting`, so without this an upgraded\n * workspace pairs new app-level constructs with stale core ones.\n */\n\nconst GATEWAY_CONSTRUCT_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/agentcore-gateway/agentcore-gateway.ts`;\n\nconst AGENTS_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/agents`;\n\nconst PROTOCOL_PROP = `/**\n * The gateway's protocol. An \\`mcp\\` gateway aggregates MCP server targets\n * into a single MCP endpoint. An \\`http\\` gateway has no protocol type and\n * proxies requests to AgentCore Runtime targets via path-based routing\n * (\\`/<targetName>/invocations\\`) — the target type AgentCore only allows on\n * gateways without a protocol type.\n *\n * @default 'mcp'\n */\n readonly protocol?: 'mcp' | 'http';`;\n\nconst PROTOCOL_CONSTRUCTOR_STATEMENTS = `this.protocol = props?.protocol ?? 'mcp';\n`;\n\nconst PROTOCOL_TYPE_REMOVAL = `\n if (this.protocol === 'http') {\n // AgentCore Runtime targets require a gateway without a protocol type,\n // which the Gateway L2 cannot express — it always renders MCP — so\n // remove the protocol from the underlying CloudFormation resource.\n const cfnGateway = this.gateway.node.defaultChild as agentcore.CfnGateway;\n cfnGateway.addPropertyDeletionOverride('ProtocolType');\n cfnGateway.addPropertyDeletionOverride('ProtocolConfiguration');\n }`;\n\nconst AGENT_TARGET_METHODS = `\n /**\n * Add an agent runtime construct as a target of this Gateway. Requires the\n * \\`http\\` protocol — the gateway proxies requests for the agent under\n * \\`<gatewayUrl>/<targetName>/invocations\\`, without protocol translation.\n *\n * The target name defaults to the agent construct's \\`agentName\\` (its\n * project's class name in kebab-case, e.g. \\`MyAgent\\` -> \\`my-agent\\`). It\n * forms the target's invocation path, so renaming it later is a breaking\n * change for consumers.\n */\n public addAgent(\n agent: Construct & {\n readonly agentCoreRuntime: agentcore.Runtime;\n readonly agentName: string;\n },\n props?: {\n gatewayTargetName?: string;\n },\n ): agentcore.CfnGatewayTarget {\n return this.addAgentTarget({\n gatewayTargetName: props?.gatewayTargetName ?? agent.agentName,\n agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn,\n });\n }\n\n /**\n * Register an agent runtime ARN as a Gateway target. Prefer\n * {@link addAgent} when the construct is in scope.\n */\n public addAgentTarget(props: {\n gatewayTargetName: string;\n agentRuntimeArn: string;\n }): agentcore.CfnGatewayTarget {\n if (this.protocol !== 'http') {\n throw new Error(\n \\`Agent runtime targets require an http-protocol gateway, but this gateway uses '\\${this.protocol}'.\\`,\n );\n }\n\n // The construct id is derived from the target name so the two change\n // together — target names are unique per gateway, and replacing a target\n // under an unchanged name fails with AlreadyExists.\n const target = new agentcore.CfnGatewayTarget(\n this,\n \\`Target-\\${props.gatewayTargetName}\\`,\n {\n gatewayIdentifier: this.gateway.gatewayId,\n name: props.gatewayTargetName,\n targetConfiguration: {\n http: {\n agentcoreRuntime: {\n arn: props.agentRuntimeArn,\n qualifier: 'DEFAULT',\n },\n },\n },\n // The bare gateway IAM role credential: runtime targets reject the\n // iamCredentialProvider detail MCP targets carry.\n credentialProviderConfigurations: [\n {\n credentialProviderType: 'GATEWAY_IAM_ROLE',\n },\n ],\n },\n );\n\n // Grant the gateway role invoke access to the target runtime before the\n // target is created — AgentCore validates access to the runtime during\n // target creation.\n const grant = this.gateway.role.addToPrincipalPolicy(\n new iam.PolicyStatement({\n actions: [\n 'bedrock-agentcore:InvokeAgentRuntime',\n 'bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream',\n // A2A targets additionally serve their agent card via the gateway.\n 'bedrock-agentcore:GetAgentCard',\n ],\n resources: [props.agentRuntimeArn, \\`\\${props.agentRuntimeArn}/*\\`],\n }),\n );\n if (grant.policyDependable) {\n target.node.addDependency(grant.policyDependable);\n }\n\n return target;\n }`;\n\n/**\n * Add the `protocol` prop, its constructor handling and the agent-target\n * methods to the vended `AgentCoreGateway` core construct.\n */\nconst migrateGatewayConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(GATEWAY_CONSTRUCT_FILE)) {\n // No vended gateway construct in this workspace - nothing to migrate.\n return;\n }\n\n if (\n (tree.read(GATEWAY_CONSTRUCT_FILE, 'utf-8') ?? '').includes(\n 'addAgentTarget',\n )\n ) {\n // Already migrated.\n return;\n }\n\n const divergedMessage = `${GATEWAY_CONSTRUCT_FILE}: the AgentCoreGateway construct has diverged from the generated shape - left untouched. Re-run the agentcore-gateway generator in a fresh workspace to see the current construct, which supports agent runtime targets via a 'protocol' prop and addAgent()/addAgentTarget() methods.`;\n\n // Anchored on the shapes every vended version of the construct carries: the\n // props interface, the class field the protocol field is inserted after,\n // and the Gateway creation in the constructor.\n const hasVendedShape =\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`export interface AgentCoreGatewayProps { $_ }`',\n )) &&\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`private readonly targetRuntimeArns: string[] = []`',\n )) &&\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n \"`this.gateway = new agentcore.Gateway(this, 'Gateway', $_)`\",\n ));\n\n if (!hasVendedShape) {\n nextSteps.push(divergedMessage);\n return;\n }\n\n // 1. The protocol prop on AgentCoreGatewayProps. The placeholder keeps the\n // prop's doc comment (with its backticks) out of the GritQL pattern.\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`export interface AgentCoreGatewayProps { $members }\\` where {\n $members <: not contains \\`protocol\\`\n} => \\`export interface AgentCoreGatewayProps { $members\n ${GRIT_INSERT_PLACEHOLDER}\n}\\``,\n PROTOCOL_PROP,\n );\n\n // 2. The protocol class field. Matched without the trailing semicolon —\n // GritQL parses the snippet standalone, where the semicolon is not part\n // of the field's AST node.\n await applyGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`private readonly targetRuntimeArns: string[] = []\\` as $field where {\n $program <: not contains \\`private readonly protocol\\`\n} => \\`$field;\n private readonly protocol: 'mcp' | 'http'\\``,\n );\n\n // 3. Assign the field and remove the protocol type for http gateways.\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`this.gateway = new agentcore.Gateway($args);\\` as $stmt where {\n $program <: not contains \\`this.protocol = props\\`\n} => \\`${GRIT_INSERT_PLACEHOLDER}\n $stmt\\``,\n PROTOCOL_CONSTRUCTOR_STATEMENTS,\n );\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`this.gateway = new agentcore.Gateway($args);\\` as $stmt where {\n $program <: not contains \\`addPropertyDeletionOverride\\`\n} => \\`$stmt\n${GRIT_INSERT_PLACEHOLDER}\\``,\n PROTOCOL_TYPE_REMOVAL,\n );\n\n // 4. The agent-target methods, inserted after addGatewayTarget (present in\n // every vended version that also has the readiness probe field).\n const addedMethods = await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`public addGatewayTarget($params): agentcore.CfnGatewayTarget { $body }\\` as $method where {\n $program <: not contains \\`addAgentTarget\\`\n} => \\`$method\n${GRIT_INSERT_PLACEHOLDER}\\``,\n AGENT_TARGET_METHODS,\n );\n\n if (!addedMethods) {\n nextSteps.push(divergedMessage);\n return;\n }\n};\n\n/**\n * Add the `agentName` member to each vended agent construct, which\n * `AgentCoreGateway.addAgent` reads as the default gateway target name.\n */\nconst migrateAgentConstructs = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(AGENTS_DIR)) {\n return;\n }\n for (const dir of tree.children(AGENTS_DIR)) {\n const constructFile = `${AGENTS_DIR}/${dir}/${dir}.ts`;\n if (!tree.exists(constructFile)) {\n continue;\n }\n if ((tree.read(constructFile, 'utf-8') ?? '').includes('agentName')) {\n // Already migrated (or user-added).\n continue;\n }\n const added = await insertViaGritQL(\n tree,\n constructFile,\n `\\`public readonly agentCoreRuntime: Runtime\\` as $field => \\`$field;\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n `/** Default Gateway target name for this agent. */\n public readonly agentName = '${dir}'`,\n );\n if (!added) {\n nextSteps.push(\n `${constructFile}: the agent construct has diverged from the generated shape - left untouched. To attach this agent to a gateway with addAgent(), add a \\`public readonly agentName = '${dir}';\\` member (or use addAgentTarget() with an explicit target name).`,\n );\n }\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateGatewayConstruct(tree, nextSteps);\n await migrateAgentConstructs(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","GATEWAY_CONSTRUCT_FILE","AGENTS_DIR","PROTOCOL_PROP","PROTOCOL_CONSTRUCTOR_STATEMENTS","PROTOCOL_TYPE_REMOVAL","AGENT_TARGET_METHODS","migrateGatewayConstruct","tree","nextSteps","exists","read","includes","divergedMessage","hasVendedShape","push","addedMethods","migrateAgentConstructs","dir","children","constructFile","added","migration"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.60/0001-gateway-cognito-passthrough/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\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 gateway->agent\n * support for Cognito agents, which forward the caller's JWT to the runtime:\n *\n * - The vended `AgentCoreGateway` construct's `addAgent`/`addAgentTarget` pick\n * the outbound credential from the agent's `auth`: a `cognito` agent uses\n * `JWT_PASSTHROUGH` (the caller's token reaches the runtime), an `iam` agent\n * the gateway role (`GATEWAY_IAM_ROLE`, the previous behaviour).\n * - Vended agent constructs gain an `auth` member `addAgent` reads, and Cognito\n * agents allowlist the `Authorization` header (CDK + Terraform runtime) so the\n * runtime receives the forwarded token.\n *\n * These files are generated with `KeepExisting`, so without this an upgraded\n * workspace pairs new app-level constructs with stale core ones. Diverged files\n * are left untouched and reported via `nextSteps`.\n */\n\nconst GATEWAY_CONSTRUCT_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/agentcore-gateway/agentcore-gateway.ts`;\nconst AGENTS_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/agents`;\nconst TF_RUNTIME_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/agent-core/runtime.tf`;\n\n/**\n * Teach the vended `AgentCoreGateway` construct to pick the target credential\n * from the agent's `auth` (JWT passthrough for Cognito, gateway role for IAM).\n */\nconst migrateGatewayConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(GATEWAY_CONSTRUCT_FILE)) {\n return; // No vended gateway construct.\n }\n // Predates agent-target support (the gateway-agent-targets migration adds\n // addAgentTarget first) — match the method, not a bare identifier.\n if (\n !(await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`addAgentTarget(props: { $_ }): agentcore.CfnGatewayTarget { $_ }`',\n ))\n ) {\n return;\n }\n // Already migrated: the credentials member is on addAgentTarget's props.\n if (\n await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n \"`credentials?: 'gateway-iam' | 'jwt-passthrough'`\",\n )\n ) {\n return;\n }\n\n const divergedMessage = `In ${GATEWAY_CONSTRUCT_FILE}: have addAgent read the agent's \\`auth\\` and pass \\`credentials: 'jwt-passthrough'\\` to addAgentTarget, so the target's credentialProviderType becomes 'JWT_PASSTHROUGH' for Cognito agents.`;\n\n // GritQL patterns for each of the four edits. Verified against the tree\n // up-front so the transform is all-or-nothing: a construct missing any\n // anchor is left untouched with a single actionable next step, rather than\n // half-migrated.\n const authParamPattern = `\\`readonly agentName: string\\` as $sig where {\n $program <: not contains \\`readonly auth?\\`\n} => \\`$sig;\n readonly auth?: 'iam' | 'cognito'\\``;\n\n const callPattern = `\\`agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn\\` as $prop where {\n $program <: not contains \\`credentials:\\`\n} => \\`$prop,\n credentials: agent.auth === 'cognito' ? 'jwt-passthrough' : 'gateway-iam'\\``;\n\n // The addAgentTarget props type: matched on its `agentRuntimeArn: string`\n // member signature (without trailing semicolon), which the rewrite re-adds\n // followed by the credentials member. The `: string` type distinguishes it\n // from the `agentRuntimeArn:` value in the addAgent call.\n const paramPattern = `\\`agentRuntimeArn: string\\` as $sig where {\n $program <: not contains \\`credentials?\\`\n} => \\`$sig;\n credentials?: 'gateway-iam' | 'jwt-passthrough'\\``;\n\n // Scoped to the agent target's own CfnGatewayTarget (the one configured with\n // an agentcoreRuntime), so the MCP server target's GATEWAY_IAM_ROLE — a\n // sibling method with its own credential block — is left untouched.\n const credentialPattern = `\\`credentialProviderType: 'GATEWAY_IAM_ROLE'\\` as $cred where {\n $cred <: within \\`new agentcore.CfnGatewayTarget($_, $_, $config)\\`,\n $config <: contains \\`agentcoreRuntime\\`\n} => \\`credentialProviderType:\n props.credentials === 'jwt-passthrough'\n ? 'JWT_PASSTHROUGH'\n : 'GATEWAY_IAM_ROLE'\\``;\n\n // Verify every anchor matches before mutating anything (matchGritQL is\n // read-only), so a diverged construct is never left partially migrated.\n for (const pattern of [\n authParamPattern,\n callPattern,\n paramPattern,\n credentialPattern,\n ]) {\n if (!(await matchGritQL(tree, GATEWAY_CONSTRUCT_FILE, pattern))) {\n nextSteps.push(divergedMessage);\n return;\n }\n }\n\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, authParamPattern);\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, callPattern);\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, paramPattern);\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, credentialPattern);\n};\n\n/**\n * Add the `auth` member to each vended agent construct, and for Cognito agents\n * allowlist the Authorization header so the runtime receives the forwarded JWT.\n */\nconst migrateAgentConstructs = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(AGENTS_DIR)) {\n return;\n }\n for (const dir of tree.children(AGENTS_DIR)) {\n const constructFile = `${AGENTS_DIR}/${dir}/${dir}.ts`;\n if (!tree.exists(constructFile)) {\n continue;\n }\n // Only agents (which carry a gateway target name), not MCP servers.\n if (\n !(await matchGritQL(\n tree,\n constructFile,\n '`public readonly agentName = $_`',\n ))\n ) {\n continue;\n }\n if (await matchGritQL(tree, constructFile, '`public readonly auth = $_`')) {\n continue; // Already migrated (or user-added).\n }\n\n // Cognito agents configure the runtime's inbound authorizer with a Cognito\n // JWT — match that authorizerConfiguration property specifically.\n const isCognito = await matchGritQL(\n tree,\n constructFile,\n '`authorizerConfiguration: RuntimeAuthorizerConfiguration.usingCognito($_)`',\n );\n const authValue = isCognito ? 'cognito' : 'iam';\n\n // The `auth` member, after the agentName member. Matched without the\n // trailing semicolon — GritQL parses the field's initializer as its AST\n // node, so the semicolon is appended by the rewrite.\n const authPattern = `\\`public readonly agentName = $name\\` as $field => \\`$field;\n /** Inbound auth — a fronting Gateway uses this to pick its outbound credential. */\n public readonly auth = '${authValue}'\\``;\n\n // Cognito agents allowlist the Authorization header so the runtime (and a\n // fronting gateway, via passthrough) receives the caller's token.\n const headerNeeded =\n isCognito &&\n !(await matchGritQL(\n tree,\n constructFile,\n '`requestHeaderConfiguration: $_`',\n ));\n const headerPattern = `\\`authorizerConfiguration: RuntimeAuthorizerConfiguration.usingCognito($args)\\` as $authz where {\n $program <: not contains \\`requestHeaderConfiguration\\`\n} => \\`$authz,\n ${GRIT_INSERT_PLACEHOLDER}\\``;\n const headerText = `// Receive the caller's Authorization header (validated by the authorizer).\n requestHeaderConfiguration: {\n allowlistedHeaders: ['Authorization'],\n }`;\n\n // Verify every anchor up-front so the construct is never half-migrated:\n // if any edit can't be applied, leave the file untouched with one\n // actionable next step.\n const authOk = await matchGritQL(tree, constructFile, authPattern);\n const headerOk =\n !headerNeeded || (await matchGritQL(tree, constructFile, headerPattern));\n if (!authOk || !headerOk) {\n const actions = [\n `add a \\`public readonly auth = '${authValue}';\\` member`,\n ];\n if (headerNeeded) {\n actions.push(\n `add \\`requestHeaderConfiguration: { allowlistedHeaders: ['Authorization'] }\\` to its Runtime so a gateway can pass the caller's JWT through`,\n );\n }\n nextSteps.push(`In ${constructFile}: ${actions.join('; and ')}.`);\n continue;\n }\n\n await applyGritQL(tree, constructFile, authPattern);\n if (headerNeeded) {\n await insertViaGritQL(tree, constructFile, headerPattern, headerText);\n }\n }\n};\n\n/**\n * Add the `request_header_configuration` block to the vended Terraform runtime\n * module so a JWT-authorized runtime receives the forwarded Authorization\n * header (the analogue of the CDK requestHeaderConfiguration).\n */\nconst migrateTerraformRuntime = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(TF_RUNTIME_FILE)) {\n return;\n }\n if (\n await matchGritQL(\n tree,\n TF_RUNTIME_FILE,\n 'language hcl\\n`dynamic \"request_header_configuration\" { $_ }`',\n )\n ) {\n return; // Already migrated.\n }\n\n const tfActionMessage = `In ${TF_RUNTIME_FILE}: add a \\`request_header_configuration { request_header_allowlist = [\"Authorization\"] }\\` block (guarded by the JWT authorizer) to the aws_bedrockagentcore_agent_runtime resource so a gateway can pass the caller's JWT through.`;\n\n const hasAuthorizerBlock = await matchGritQL(\n tree,\n TF_RUNTIME_FILE,\n 'language hcl\\n`dynamic \"authorizer_configuration\" { $_ }`',\n );\n if (!hasAuthorizerBlock) {\n nextSteps.push(tfActionMessage);\n return;\n }\n\n const added = await insertViaGritQL(\n tree,\n TF_RUNTIME_FILE,\n `language hcl\n\\`dynamic \"authorizer_configuration\" { $body }\\` as $block where {\n $block <: within \\`resource \"aws_bedrockagentcore_agent_runtime\" $_ { $_ }\\`\n} => \\`$block\n\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n `# Receive the caller's Authorization header (validated by the JWT authorizer).\n dynamic \"request_header_configuration\" {\n for_each = var.authorizer_configuration != null && try(var.authorizer_configuration.custom_jwt_authorizer, null) != null ? [1] : []\n content {\n request_header_allowlist = [\"Authorization\"]\n }\n }`,\n );\n if (!added) {\n nextSteps.push(tfActionMessage);\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateGatewayConstruct(tree, nextSteps);\n await migrateAgentConstructs(tree, nextSteps);\n await migrateTerraformRuntime(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","GATEWAY_CONSTRUCT_FILE","AGENTS_DIR","TF_RUNTIME_FILE","migrateGatewayConstruct","tree","nextSteps","exists","divergedMessage","authParamPattern","callPattern","paramPattern","credentialPattern","pattern","push","migrateAgentConstructs","dir","children","constructFile","isCognito","authValue","authPattern","headerNeeded","headerPattern","headerText","authOk","headerOk","actions","join","migrateTerraformRuntime","tfActionMessage","hasAuthorizerBlock","added","migration"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.60/0001-gateway-cognito-passthrough/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\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 gateway->agent\n * support for Cognito agents, which forward the caller's JWT to the runtime:\n *\n * - The vended `AgentCoreGateway` construct's `addAgent`/`addAgentTarget` pick\n * the outbound credential from the agent's `auth`: a `cognito` agent uses\n * `JWT_PASSTHROUGH` (the caller's token reaches the runtime), an `iam` agent\n * the gateway role (`GATEWAY_IAM_ROLE`, the previous behaviour).\n * - Vended agent constructs gain an `auth` member `addAgent` reads, and Cognito\n * agents allowlist the `Authorization` header (CDK + Terraform runtime) so the\n * runtime receives the forwarded token.\n *\n * These files are generated with `KeepExisting`, so without this an upgraded\n * workspace pairs new app-level constructs with stale core ones. Diverged files\n * are left untouched and reported via `nextSteps`.\n */\n\nconst GATEWAY_CONSTRUCT_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/agentcore-gateway/agentcore-gateway.ts`;\nconst AGENTS_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/agents`;\nconst TF_RUNTIME_FILE = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/core/agent-core/runtime.tf`;\n\n/**\n * Teach the vended `AgentCoreGateway` construct to pick the target credential\n * from the agent's `auth` (JWT passthrough for Cognito, gateway role for IAM).\n */\nconst migrateGatewayConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(GATEWAY_CONSTRUCT_FILE)) {\n return; // No vended gateway construct.\n }\n // Predates agent-target support (the gateway-agent-targets migration adds\n // addAgentTarget first) — match the method, not a bare identifier.\n if (\n !(await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`addAgentTarget(props: { $_ }): agentcore.CfnGatewayTarget { $_ }`',\n ))\n ) {\n return;\n }\n // Already migrated: the credentials member is on addAgentTarget's props.\n if (\n await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n \"`credentials?: 'gateway-iam' | 'jwt-passthrough'`\",\n )\n ) {\n return;\n }\n\n const divergedMessage = `In ${GATEWAY_CONSTRUCT_FILE}: have addAgent read the agent's \\`auth\\` and pass \\`credentials: 'jwt-passthrough'\\` to addAgentTarget, so the target's credentialProviderType becomes 'JWT_PASSTHROUGH' for Cognito agents.`;\n\n // GritQL patterns for each of the four edits. Verified against the tree\n // up-front so the transform is all-or-nothing: a construct missing any\n // anchor is left untouched with a single actionable next step, rather than\n // half-migrated.\n const authParamPattern = `\\`readonly agentName: string\\` as $sig where {\n $program <: not contains \\`readonly auth?\\`\n} => \\`$sig;\n readonly auth?: 'iam' | 'cognito'\\``;\n\n const callPattern = `\\`agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn\\` as $prop where {\n $program <: not contains \\`credentials:\\`\n} => \\`$prop,\n credentials: agent.auth === 'cognito' ? 'jwt-passthrough' : 'gateway-iam'\\``;\n\n // The addAgentTarget props type: matched on its `agentRuntimeArn: string`\n // member signature (without trailing semicolon), which the rewrite re-adds\n // followed by the credentials member. The `: string` type distinguishes it\n // from the `agentRuntimeArn:` value in the addAgent call.\n const paramPattern = `\\`agentRuntimeArn: string\\` as $sig where {\n $program <: not contains \\`credentials?\\`\n} => \\`$sig;\n credentials?: 'gateway-iam' | 'jwt-passthrough'\\``;\n\n // Scoped to the agent target's own CfnGatewayTarget (the one configured with\n // an agentcoreRuntime), so the MCP server target's GATEWAY_IAM_ROLE — a\n // sibling method with its own credential block — is left untouched.\n const credentialPattern = `\\`credentialProviderType: 'GATEWAY_IAM_ROLE'\\` as $cred where {\n $cred <: within \\`new agentcore.CfnGatewayTarget($_, $_, $config)\\`,\n $config <: contains \\`agentcoreRuntime\\`\n} => \\`credentialProviderType:\n props.credentials === 'jwt-passthrough'\n ? 'JWT_PASSTHROUGH'\n : 'GATEWAY_IAM_ROLE'\\``;\n\n // Verify every anchor matches before mutating anything (matchGritQL is\n // read-only), so a diverged construct is never left partially migrated.\n for (const pattern of [\n authParamPattern,\n callPattern,\n paramPattern,\n credentialPattern,\n ]) {\n if (!(await matchGritQL(tree, GATEWAY_CONSTRUCT_FILE, pattern))) {\n nextSteps.push(divergedMessage);\n return;\n }\n }\n\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, authParamPattern);\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, callPattern);\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, paramPattern);\n await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, credentialPattern);\n};\n\n/**\n * Add the `auth` member to each vended agent construct, and for Cognito agents\n * allowlist the Authorization header so the runtime receives the forwarded JWT.\n */\nconst migrateAgentConstructs = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(AGENTS_DIR)) {\n return;\n }\n for (const dir of tree.children(AGENTS_DIR)) {\n const constructFile = `${AGENTS_DIR}/${dir}/${dir}.ts`;\n if (!tree.exists(constructFile)) {\n continue;\n }\n // Only agents (which carry a gateway target name), not MCP servers.\n if (\n !(await matchGritQL(\n tree,\n constructFile,\n '`public readonly agentName = $_`',\n ))\n ) {\n continue;\n }\n if (await matchGritQL(tree, constructFile, '`public readonly auth = $_`')) {\n continue; // Already migrated (or user-added).\n }\n\n // Cognito agents configure the runtime's inbound authorizer with a Cognito\n // JWT — match that authorizerConfiguration property specifically.\n const isCognito = await matchGritQL(\n tree,\n constructFile,\n '`authorizerConfiguration: RuntimeAuthorizerConfiguration.usingCognito($_)`',\n );\n const authValue = isCognito ? 'cognito' : 'iam';\n\n // The `auth` member, after the agentName member. Matched without the\n // trailing semicolon — GritQL parses the field's initializer as its AST\n // node, so the semicolon is appended by the rewrite.\n const authPattern = `\\`public readonly agentName = $name\\` as $field => \\`$field;\n /** Inbound auth — a fronting Gateway uses this to pick its outbound credential. */\n public readonly auth = '${authValue}'\\``;\n\n // Cognito agents allowlist the Authorization header so the runtime (and a\n // fronting gateway, via passthrough) receives the caller's token.\n const headerNeeded =\n isCognito &&\n !(await matchGritQL(\n tree,\n constructFile,\n '`requestHeaderConfiguration: $_`',\n ));\n const headerPattern = `\\`authorizerConfiguration: RuntimeAuthorizerConfiguration.usingCognito($args)\\` as $authz where {\n $program <: not contains \\`requestHeaderConfiguration\\`\n} => \\`$authz,\n ${GRIT_INSERT_PLACEHOLDER}\\``;\n const headerText = `// Receive the caller's Authorization header (validated by the authorizer).\n requestHeaderConfiguration: {\n allowlistedHeaders: ['Authorization'],\n }`;\n\n // Verify every anchor up-front so the construct is never half-migrated:\n // if any edit can't be applied, leave the file untouched with one\n // actionable next step.\n const authOk = await matchGritQL(tree, constructFile, authPattern);\n const headerOk =\n !headerNeeded || (await matchGritQL(tree, constructFile, headerPattern));\n if (!authOk || !headerOk) {\n const actions = [\n `add a \\`public readonly auth = '${authValue}';\\` member`,\n ];\n if (headerNeeded) {\n actions.push(\n `add \\`requestHeaderConfiguration: { allowlistedHeaders: ['Authorization'] }\\` to its Runtime so a gateway can pass the caller's JWT through`,\n );\n }\n nextSteps.push(`In ${constructFile}: ${actions.join('; and ')}.`);\n continue;\n }\n\n await applyGritQL(tree, constructFile, authPattern);\n if (headerNeeded) {\n await insertViaGritQL(tree, constructFile, headerPattern, headerText);\n }\n }\n};\n\n/**\n * Add the `request_header_configuration` block to the vended Terraform runtime\n * module so a JWT-authorized runtime receives the forwarded Authorization\n * header (the analogue of the CDK requestHeaderConfiguration).\n */\nconst migrateTerraformRuntime = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(TF_RUNTIME_FILE)) {\n return;\n }\n if (\n await matchGritQL(\n tree,\n TF_RUNTIME_FILE,\n 'language hcl\\n`dynamic \"request_header_configuration\" { $_ }`',\n )\n ) {\n return; // Already migrated.\n }\n\n const tfActionMessage = `In ${TF_RUNTIME_FILE}: add a \\`request_header_configuration { request_header_allowlist = [\"Authorization\"] }\\` block (guarded by the JWT authorizer) to the aws_bedrockagentcore_agent_runtime resource so a gateway can pass the caller's JWT through.`;\n\n const hasAuthorizerBlock = await matchGritQL(\n tree,\n TF_RUNTIME_FILE,\n 'language hcl\\n`dynamic \"authorizer_configuration\" { $_ }`',\n );\n if (!hasAuthorizerBlock) {\n nextSteps.push(tfActionMessage);\n return;\n }\n\n const added = await insertViaGritQL(\n tree,\n TF_RUNTIME_FILE,\n `language hcl\n\\`dynamic \"authorizer_configuration\" { $body }\\` as $block where {\n $block <: within \\`resource \"aws_bedrockagentcore_agent_runtime\" $_ { $_ }\\`\n} => \\`$block\n\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n `# Receive the caller's Authorization header (validated by the JWT authorizer).\n dynamic \"request_header_configuration\" {\n for_each = var.authorizer_configuration != null && try(var.authorizer_configuration.custom_jwt_authorizer, null) != null ? [1] : []\n content {\n request_header_allowlist = [\"Authorization\"]\n }\n }`,\n );\n if (!added) {\n nextSteps.push(tfActionMessage);\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateGatewayConstruct(tree, nextSteps);\n await migrateAgentConstructs(tree, nextSteps);\n await migrateTerraformRuntime(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","GATEWAY_CONSTRUCT_FILE","AGENTS_DIR","TF_RUNTIME_FILE","migrateGatewayConstruct","tree","nextSteps","exists","divergedMessage","authParamPattern","callPattern","paramPattern","credentialPattern","pattern","push","migrateAgentConstructs","dir","children","constructFile","isCognito","authValue","authPattern","headerNeeded","headerPattern","headerText","authOk","headerOk","actions","join","migrateTerraformRuntime","tfActionMessage","hasAuthorizerBlock","added","migration"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.60/0002-waf-log-group-removal/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\n addDestructuredImport,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Vended WAF log groups have a deterministic name (WAFv2 requires the\n * `aws-waf-logs-` prefix, so the name can't be CloudFormation-generated) and,\n * without an explicit removal policy, inherit CloudFormation's default RETAIN\n * for log groups. A rolled-back or replaced deploy then orphans the log group,\n * so the next deploy fails to create one of the same name. Set\n * `RemovalPolicy.DESTROY` so it is torn down with the stack, matching the\n * vended user-identity (Cognito) construct.\n */\n\nconst CONSTRUCTS_SRC = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src`;\n\n/**\n * A vended construct carrying a WAF log group. They differ in how the log\n * group is constructed and how `cdk` is imported: the gateway namespaces both\n * (`logs.LogGroup`, `cdk.RemovalPolicy`), the rest api destructures both\n * (`LogGroup`, `RemovalPolicy` — the latter added by this migration when\n * absent).\n */\ninterface WafConstruct {\n file: string;\n /** How `LogGroup` is referenced in this file (`LogGroup` or `logs.LogGroup`). */\n logGroupExpr: string;\n /** The removal policy expression, matching the file's import style. */\n removalPolicyExpr: string;\n /** When set, ensure this destructured import from `aws-cdk-lib`. */\n destructuredImport?: string;\n}\n\nconst WAF_CONSTRUCTS: WafConstruct[] = [\n {\n file: `${CONSTRUCTS_SRC}/core/agentcore-gateway/agentcore-gateway.ts`,\n logGroupExpr: 'logs.LogGroup',\n removalPolicyExpr: 'cdk.RemovalPolicy.DESTROY',\n },\n {\n file: `${CONSTRUCTS_SRC}/core/api/rest-api.ts`,\n logGroupExpr: 'LogGroup',\n removalPolicyExpr: 'RemovalPolicy.DESTROY',\n destructuredImport: 'RemovalPolicy',\n },\n];\n\nconst migrateConstruct = async (\n tree: Tree,\n construct: WafConstruct,\n nextSteps: string[],\n): Promise<void> => {\n const { file, logGroupExpr } = construct;\n if (!tree.exists(file)) {\n // Construct not vended in this workspace - nothing to migrate.\n return;\n }\n\n const contents = tree.read(file, 'utf-8') ?? '';\n\n // The WAF web ACL (and its log group) is optional in some constructs, so it\n // may be absent. Nothing to do if it is.\n if (!contents.includes(`new ${logGroupExpr}(this, 'WebAclLogs'`)) {\n return;\n }\n\n // Already migrated (or user-added a removal policy).\n if (\n await matchGritQL(\n tree,\n file,\n `\\`new ${logGroupExpr}(this, 'WebAclLogs', { $props })\\` where { $props <: contains \\`removalPolicy\\` }`,\n )\n ) {\n return;\n }\n\n // Append the removal policy after the WAF log group's `encryptionKey`\n // property. The rewrite is scoped to the `WebAclLogs` LogGroup because a\n // construct can have other log groups sharing the `encryptionKey: logsKey`\n // shape (e.g. the rest api's access logs).\n const added = await insertViaGritQL(\n tree,\n file,\n `\\`new ${logGroupExpr}(this, 'WebAclLogs', { $props })\\` where {\n $props <: contains \\`encryptionKey: logsKey\\` as $enc,\n $enc => \\`encryptionKey: logsKey,\n __GRIT_INSERT_PLACEHOLDER__\\`\n}`,\n `// The log group name is deterministic, so retaining it on delete would\n // orphan it and block re-creation (e.g. after a rolled-back deploy).\n removalPolicy: ${construct.removalPolicyExpr}`,\n );\n\n if (!added) {\n nextSteps.push(\n `${file}: could not add a removal policy to the WAF log group automatically - it may have diverged from the generated shape. Add \\`removalPolicy: ${construct.removalPolicyExpr}\\` to the \\`new ${logGroupExpr}(this, 'WebAclLogs', ...)\\` call so a rolled-back deploy does not orphan the log group.`,\n );\n return;\n }\n\n if (construct.destructuredImport) {\n await addDestructuredImport(\n tree,\n file,\n [construct.destructuredImport],\n 'aws-cdk-lib',\n );\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const construct of WAF_CONSTRUCTS) {\n await migrateConstruct(tree, construct, nextSteps);\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["addDestructuredImport","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","CONSTRUCTS_SRC","WAF_CONSTRUCTS","file","logGroupExpr","removalPolicyExpr","destructuredImport","migrateConstruct","tree","construct","nextSteps","exists","contents","read","includes","added","push","migration"],"mappings":"AAAA;;;CAGC,GAED,SACEA,qBAAqB,EACrBC,eAAe,EACfC,WAAW,QACN,wBAAqB;AAC5B,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SACEC,YAAY,EACZC,qBAAqB,QAChB,gDAA6C;AAEpD;;;;;;;;CAQC,GAED,MAAMC,iBAAiB,GAAGF,aAAa,CAAC,EAAEC,sBAAsB,IAAI,CAAC;AAmBrE,MAAME,iBAAiC;IACrC;QACEC,MAAM,GAAGF,eAAe,4CAA4C,CAAC;QACrEG,cAAc;QACdC,mBAAmB;IACrB;IACA;QACEF,MAAM,GAAGF,eAAe,qBAAqB,CAAC;QAC9CG,cAAc;QACdC,mBAAmB;QACnBC,oBAAoB;IACtB;CACD;AAED,MAAMC,mBAAmB,OACvBC,MACAC,WACAC;IAEA,MAAM,EAAEP,IAAI,EAAEC,YAAY,EAAE,GAAGK;IAC/B,IAAI,CAACD,KAAKG,MAAM,CAACR,OAAO;QACtB,+DAA+D;QAC/D;IACF;IAEA,MAAMS,WAAWJ,KAAKK,IAAI,CAACV,MAAM,YAAY;IAE7C,4EAA4E;IAC5E,yCAAyC;IACzC,IAAI,CAACS,SAASE,QAAQ,CAAC,CAAC,IAAI,EAAEV,aAAa,mBAAmB,CAAC,GAAG;QAChE;IACF;IAEA,qDAAqD;IACrD,IACE,MAAMP,YACJW,MACAL,MACA,CAAC,MAAM,EAAEC,aAAa,iFAAiF,CAAC,GAE1G;QACA;IACF;IAEA,sEAAsE;IACtE,yEAAyE;IACzE,2EAA2E;IAC3E,2CAA2C;IAC3C,MAAMW,QAAQ,MAAMnB,gBAClBY,MACAL,MACA,CAAC,MAAM,EAAEC,aAAa;;;;CAIzB,CAAC,EACE,CAAC;;qBAEgB,EAAEK,UAAUJ,iBAAiB,EAAE;IAGlD,IAAI,CAACU,OAAO;QACVL,UAAUM,IAAI,CACZ,GAAGb,KAAK,0IAA0I,EAAEM,UAAUJ,iBAAiB,CAAC,gBAAgB,EAAED,aAAa,uFAAuF,CAAC;QAEzS;IACF;IAEA,IAAIK,UAAUH,kBAAkB,EAAE;QAChC,MAAMX,sBACJa,MACAL,MACA;YAACM,UAAUH,kBAAkB;SAAC,EAC9B;IAEJ;AACF;AAEA,eAAe,eAAeW,UAC5BT,IAAU;IAEV,MAAME,YAAsB,EAAE;IAE9B,KAAK,MAAMD,aAAaP,eAAgB;QACtC,MAAMK,iBAAiBC,MAAMC,WAAWC;IAC1C;IAEA,MAAMZ,qBAAqBU;IAE3B,OAAO;QAAEE;IAAU;AACrB"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.60/0002-waf-log-group-removal/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\n addDestructuredImport,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Vended WAF log groups have a deterministic name (WAFv2 requires the\n * `aws-waf-logs-` prefix, so the name can't be CloudFormation-generated) and,\n * without an explicit removal policy, inherit CloudFormation's default RETAIN\n * for log groups. A rolled-back or replaced deploy then orphans the log group,\n * so the next deploy fails to create one of the same name. Set\n * `RemovalPolicy.DESTROY` so it is torn down with the stack, matching the\n * vended user-identity (Cognito) construct.\n */\n\nconst CONSTRUCTS_SRC = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src`;\n\n/**\n * A vended construct carrying a WAF log group. They differ in how the log\n * group is constructed and how `cdk` is imported: the gateway namespaces both\n * (`logs.LogGroup`, `cdk.RemovalPolicy`), the rest api destructures both\n * (`LogGroup`, `RemovalPolicy` — the latter added by this migration when\n * absent).\n */\ninterface WafConstruct {\n file: string;\n /** How `LogGroup` is referenced in this file (`LogGroup` or `logs.LogGroup`). */\n logGroupExpr: string;\n /** The removal policy expression, matching the file's import style. */\n removalPolicyExpr: string;\n /** When set, ensure this destructured import from `aws-cdk-lib`. */\n destructuredImport?: string;\n}\n\nconst WAF_CONSTRUCTS: WafConstruct[] = [\n {\n file: `${CONSTRUCTS_SRC}/core/agentcore-gateway/agentcore-gateway.ts`,\n logGroupExpr: 'logs.LogGroup',\n removalPolicyExpr: 'cdk.RemovalPolicy.DESTROY',\n },\n {\n file: `${CONSTRUCTS_SRC}/core/api/rest-api.ts`,\n logGroupExpr: 'LogGroup',\n removalPolicyExpr: 'RemovalPolicy.DESTROY',\n destructuredImport: 'RemovalPolicy',\n },\n];\n\nconst migrateConstruct = async (\n tree: Tree,\n construct: WafConstruct,\n nextSteps: string[],\n): Promise<void> => {\n const { file, logGroupExpr } = construct;\n if (!tree.exists(file)) {\n // Construct not vended in this workspace - nothing to migrate.\n return;\n }\n\n const contents = tree.read(file, 'utf-8') ?? '';\n\n // The WAF web ACL (and its log group) is optional in some constructs, so it\n // may be absent. Nothing to do if it is.\n if (!contents.includes(`new ${logGroupExpr}(this, 'WebAclLogs'`)) {\n return;\n }\n\n // Already migrated (or user-added a removal policy).\n if (\n await matchGritQL(\n tree,\n file,\n `\\`new ${logGroupExpr}(this, 'WebAclLogs', { $props })\\` where { $props <: contains \\`removalPolicy\\` }`,\n )\n ) {\n return;\n }\n\n // Append the removal policy after the WAF log group's `encryptionKey`\n // property. The rewrite is scoped to the `WebAclLogs` LogGroup because a\n // construct can have other log groups sharing the `encryptionKey: logsKey`\n // shape (e.g. the rest api's access logs).\n const added = await insertViaGritQL(\n tree,\n file,\n `\\`new ${logGroupExpr}(this, 'WebAclLogs', { $props })\\` where {\n $props <: contains \\`encryptionKey: logsKey\\` as $enc,\n $enc => \\`encryptionKey: logsKey,\n __GRIT_INSERT_PLACEHOLDER__\\`\n}`,\n `// The log group name is deterministic, so retaining it on delete would\n // orphan it and block re-creation (e.g. after a rolled-back deploy).\n removalPolicy: ${construct.removalPolicyExpr}`,\n );\n\n if (!added) {\n nextSteps.push(\n `${file}: could not add a removal policy to the WAF log group automatically - it may have diverged from the generated shape. Add \\`removalPolicy: ${construct.removalPolicyExpr}\\` to the \\`new ${logGroupExpr}(this, 'WebAclLogs', ...)\\` call so a rolled-back deploy does not orphan the log group.`,\n );\n return;\n }\n\n if (construct.destructuredImport) {\n await addDestructuredImport(\n tree,\n file,\n [construct.destructuredImport],\n 'aws-cdk-lib',\n );\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const construct of WAF_CONSTRUCTS) {\n await migrateConstruct(tree, construct, nextSteps);\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["addDestructuredImport","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","CONSTRUCTS_SRC","WAF_CONSTRUCTS","file","logGroupExpr","removalPolicyExpr","destructuredImport","migrateConstruct","tree","construct","nextSteps","exists","contents","read","includes","added","push","migration"],"mappings":"AAAA;;;CAGC,GAED,SACEA,qBAAqB,EACrBC,eAAe,EACfC,WAAW,QACN,wBAAwB;AAC/B,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,qBAAqB,QAChB,gDAAgD;AAEvD;;;;;;;;CAQC,GAED,MAAMC,iBAAiB,GAAGF,aAAa,CAAC,EAAEC,sBAAsB,IAAI,CAAC;AAmBrE,MAAME,iBAAiC;IACrC;QACEC,MAAM,GAAGF,eAAe,4CAA4C,CAAC;QACrEG,cAAc;QACdC,mBAAmB;IACrB;IACA;QACEF,MAAM,GAAGF,eAAe,qBAAqB,CAAC;QAC9CG,cAAc;QACdC,mBAAmB;QACnBC,oBAAoB;IACtB;CACD;AAED,MAAMC,mBAAmB,OACvBC,MACAC,WACAC;IAEA,MAAM,EAAEP,IAAI,EAAEC,YAAY,EAAE,GAAGK;IAC/B,IAAI,CAACD,KAAKG,MAAM,CAACR,OAAO;QACtB,+DAA+D;QAC/D;IACF;IAEA,MAAMS,WAAWJ,KAAKK,IAAI,CAACV,MAAM,YAAY;IAE7C,4EAA4E;IAC5E,yCAAyC;IACzC,IAAI,CAACS,SAASE,QAAQ,CAAC,CAAC,IAAI,EAAEV,aAAa,mBAAmB,CAAC,GAAG;QAChE;IACF;IAEA,qDAAqD;IACrD,IACE,MAAMP,YACJW,MACAL,MACA,CAAC,MAAM,EAAEC,aAAa,iFAAiF,CAAC,GAE1G;QACA;IACF;IAEA,sEAAsE;IACtE,yEAAyE;IACzE,2EAA2E;IAC3E,2CAA2C;IAC3C,MAAMW,QAAQ,MAAMnB,gBAClBY,MACAL,MACA,CAAC,MAAM,EAAEC,aAAa;;;;CAIzB,CAAC,EACE,CAAC;;qBAEgB,EAAEK,UAAUJ,iBAAiB,EAAE;IAGlD,IAAI,CAACU,OAAO;QACVL,UAAUM,IAAI,CACZ,GAAGb,KAAK,0IAA0I,EAAEM,UAAUJ,iBAAiB,CAAC,gBAAgB,EAAED,aAAa,uFAAuF,CAAC;QAEzS;IACF;IAEA,IAAIK,UAAUH,kBAAkB,EAAE;QAChC,MAAMX,sBACJa,MACAL,MACA;YAACM,UAAUH,kBAAkB;SAAC,EAC9B;IAEJ;AACF;AAEA,eAAe,eAAeW,UAC5BT,IAAU;IAEV,MAAME,YAAsB,EAAE;IAE9B,KAAK,MAAMD,aAAaP,eAAgB;QACtC,MAAMK,iBAAiBC,MAAMC,WAAWC;IAC1C;IAEA,MAAMZ,qBAAqBU;IAE3B,OAAO;QAAEE;IAAU;AACrB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.60/0003-strip-pip-from-python-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 * Remove pip from the vended Python agent / MCP server images.\n *\n * The runtime runs entirely from the bundled `/app` environment and never needs\n * pip, whose vendored packages (setuptools, msgpack) in the base image carry\n * known HIGH/CRITICAL vulnerabilities the image scan flags. New workspaces get\n * this from the generator templates; this brings existing ones up to date.\n *\n * Only the Dockerfiles of `py#agent` / `py#mcp-server` components are touched,\n * located from their project metadata. The Dockerfile is generated\n * `KeepExisting`, so it is edited in place: the pip removal is inserted right\n * after the `FROM` line. A Dockerfile whose pip usage has been customised (an\n * added `pip install`, or any pip command other than this removal) is left\n * untouched and reported via `nextSteps`, since stripping pip could break it.\n */\n\n/**\n * The generators whose runtime images vend pip and should have it stripped.\n * Hardcoded rather than imported from the generators: a migration matches the\n * ids workspaces recorded at generation time, which must stay fixed even if the\n * generators' current ids change later.\n */\nconst RUNTIME_IMAGE_GENERATOR_IDS = ['py#agent', 'py#mcp-server'];\n\nconst PIP_REMOVAL = `# Remove the base image's pip: the runtime runs from the bundled environment and\n# never needs it, and pip's vendored packages carry known HIGH/CRITICAL\n# vulnerabilities flagged by the image scan.\nRUN python -m pip uninstall -y pip && \\\\\n rm -rf /usr/local/lib/python*/site-packages/pip \\\\\n /usr/local/lib/python*/site-packages/pip-*.dist-info`;\n\n/** The exact pip command this migration adds; used to detect an applied fix. */\nconst PIP_UNINSTALL = 'pip uninstall -y pip';\n\n/** Matches any `pip` invocation in a RUN instruction (python -m pip … or pip …). */\nconst PIP_COMMAND = /\\b(?:python\\s+-m\\s+)?pip\\s+\\S+/g;\n\n/**\n * The Dockerfiles of every `py#agent` / `py#mcp-server` component, located from\n * each project's recorded component metadata (`path` is the component directory\n * relative to 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 const nextSteps: string[] = [];\n\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(PIP_UNINSTALL)) {\n continue; // Already stripped (migrated or user-added).\n }\n\n // Leave a customised Dockerfile alone: any pip usage other than this\n // migration's removal (e.g. an added `pip install`) means stripping pip\n // could break the image, so flag it for the user instead of editing.\n const pipUsages = content.match(PIP_COMMAND) ?? [];\n if (pipUsages.length > 0) {\n nextSteps.push(\n `In ${filePath}: this image uses pip (${pipUsages.join(', ')}), so it was left unchanged. pip's vendored packages carry known vulnerabilities flagged by the image scan — remove pip once it is no longer needed, e.g. \\`RUN python -m pip uninstall -y pip && rm -rf /usr/local/lib/python*/site-packages/pip /usr/local/lib/python*/site-packages/pip-*.dist-info\\`.`,\n );\n continue;\n }\n\n // Insert the pip removal after the FROM line and its trailing blank line,\n // matching the spacing a freshly generated Dockerfile has.\n const updated = content.replace(\n /^(FROM\\s+\\S*python:.*\\n)\\n/m,\n `$1\\n${PIP_REMOVAL}\\n\\n`,\n );\n if (updated === content) {\n nextSteps.push(\n `In ${filePath}: remove pip from the image so its vulnerable vendored packages are not scanned — add \\`RUN python -m pip uninstall -y pip && rm -rf /usr/local/lib/python*/site-packages/pip /usr/local/lib/python*/site-packages/pip-*.dist-info\\` after the FROM line (the runtime does not need pip).`,\n );\n continue;\n }\n tree.write(filePath, updated);\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","formatFilesInSubtree","RUNTIME_IMAGE_GENERATOR_IDS","PIP_REMOVAL","PIP_UNINSTALL","PIP_COMMAND","runtimeImageDockerfiles","tree","paths","project","values","components","metadata","component","includes","generator","path","dockerfile","projectRoot","exists","push","root","sourceRoot","migration","nextSteps","filePath","content","read","pipUsages","match","length","join","updated","replace","write"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAIZ,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAAwB;AAG7D;;;;;;;;;;;;;;CAcC,GAED;;;;;CAKC,GACD,MAAMC,8BAA8B;IAAC;IAAY;CAAgB;AAEjE,MAAMC,cAAc,CAAC;;;;;+DAK0C,CAAC;AAEhE,8EAA8E,GAC9E,MAAMC,gBAAgB;AAEtB,kFAAkF,GAClF,MAAMC,cAAc;AAEpB;;;;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,MAAMiB,YAAsB,EAAE;IAE9B,KAAK,MAAMC,YAAYnB,wBAAwBC,MAAO;QACpD,MAAMmB,UAAUnB,KAAKoB,IAAI,CAACF,UAAU;QACpC,IAAI,CAACC,SAAS;YACZ;QACF;QACA,IAAIA,QAAQZ,QAAQ,CAACV,gBAAgB;YACnC,UAAU,6CAA6C;QACzD;QAEA,qEAAqE;QACrE,wEAAwE;QACxE,qEAAqE;QACrE,MAAMwB,YAAYF,QAAQG,KAAK,CAACxB,gBAAgB,EAAE;QAClD,IAAIuB,UAAUE,MAAM,GAAG,GAAG;YACxBN,UAAUJ,IAAI,CACZ,CAAC,GAAG,EAAEK,SAAS,uBAAuB,EAAEG,UAAUG,IAAI,CAAC,MAAM,ySAAyS,CAAC;YAEzW;QACF;QAEA,0EAA0E;QAC1E,2DAA2D;QAC3D,MAAMC,UAAUN,QAAQO,OAAO,CAC7B,+BACA,CAAC,IAAI,EAAE9B,YAAY,IAAI,CAAC;QAE1B,IAAI6B,YAAYN,SAAS;YACvBF,UAAUJ,IAAI,CACZ,CAAC,GAAG,EAAEK,SAAS,yRAAyR,CAAC;YAE3S;QACF;QACAlB,KAAK2B,KAAK,CAACT,UAAUO;IACvB;IAEA,MAAM/B,qBAAqBM;IAE3B,OAAO;QAAEiB;IAAU;AACrB"}
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.60/0003-strip-pip-from-python-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 * Remove pip from the vended Python agent / MCP server images.\n *\n * The runtime runs entirely from the bundled `/app` environment and never needs\n * pip, whose vendored packages (setuptools, msgpack) in the base image carry\n * known HIGH/CRITICAL vulnerabilities the image scan flags. New workspaces get\n * this from the generator templates; this brings existing ones up to date.\n *\n * Only the Dockerfiles of `py#agent` / `py#mcp-server` components are touched,\n * located from their project metadata. The Dockerfile is generated\n * `KeepExisting`, so it is edited in place: the pip removal is inserted right\n * after the `FROM` line. A Dockerfile whose pip usage has been customised (an\n * added `pip install`, or any pip command other than this removal) is left\n * untouched and reported via `nextSteps`, since stripping pip could break it.\n */\n\n/**\n * The generators whose runtime images vend pip and should have it stripped.\n * Hardcoded rather than imported from the generators: a migration matches the\n * ids workspaces recorded at generation time, which must stay fixed even if the\n * generators' current ids change later.\n */\nconst RUNTIME_IMAGE_GENERATOR_IDS = ['py#agent', 'py#mcp-server'];\n\nconst PIP_REMOVAL = `# Remove the base image's pip: the runtime runs from the bundled environment and\n# never needs it, and pip's vendored packages carry known HIGH/CRITICAL\n# vulnerabilities flagged by the image scan.\nRUN python -m pip uninstall -y pip && \\\\\n rm -rf /usr/local/lib/python*/site-packages/pip \\\\\n /usr/local/lib/python*/site-packages/pip-*.dist-info`;\n\n/** The exact pip command this migration adds; used to detect an applied fix. */\nconst PIP_UNINSTALL = 'pip uninstall -y pip';\n\n/** Matches any `pip` invocation in a RUN instruction (python -m pip … or pip …). */\nconst PIP_COMMAND = /\\b(?:python\\s+-m\\s+)?pip\\s+\\S+/g;\n\n/**\n * The Dockerfiles of every `py#agent` / `py#mcp-server` component, located from\n * each project's recorded component metadata (`path` is the component directory\n * relative to 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 const nextSteps: string[] = [];\n\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(PIP_UNINSTALL)) {\n continue; // Already stripped (migrated or user-added).\n }\n\n // Leave a customised Dockerfile alone: any pip usage other than this\n // migration's removal (e.g. an added `pip install`) means stripping pip\n // could break the image, so flag it for the user instead of editing.\n const pipUsages = content.match(PIP_COMMAND) ?? [];\n if (pipUsages.length > 0) {\n nextSteps.push(\n `In ${filePath}: this image uses pip (${pipUsages.join(', ')}), so it was left unchanged. pip's vendored packages carry known vulnerabilities flagged by the image scan — remove pip once it is no longer needed, e.g. \\`RUN python -m pip uninstall -y pip && rm -rf /usr/local/lib/python*/site-packages/pip /usr/local/lib/python*/site-packages/pip-*.dist-info\\`.`,\n );\n continue;\n }\n\n // Insert the pip removal after the FROM line and its trailing blank line,\n // matching the spacing a freshly generated Dockerfile has.\n const updated = content.replace(\n /^(FROM\\s+\\S*python:.*\\n)\\n/m,\n `$1\\n${PIP_REMOVAL}\\n\\n`,\n );\n if (updated === content) {\n nextSteps.push(\n `In ${filePath}: remove pip from the image so its vulnerable vendored packages are not scanned — add \\`RUN python -m pip uninstall -y pip && rm -rf /usr/local/lib/python*/site-packages/pip /usr/local/lib/python*/site-packages/pip-*.dist-info\\` after the FROM line (the runtime does not need pip).`,\n );\n continue;\n }\n tree.write(filePath, updated);\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","joinPathFragments","formatFilesInSubtree","RUNTIME_IMAGE_GENERATOR_IDS","PIP_REMOVAL","PIP_UNINSTALL","PIP_COMMAND","runtimeImageDockerfiles","tree","paths","project","values","components","metadata","component","includes","generator","path","dockerfile","projectRoot","exists","push","root","sourceRoot","migration","nextSteps","filePath","content","read","pipUsages","match","length","join","updated","replace","write"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EACXC,iBAAiB,QAIZ,aAAa;AACpB,SAASC,oBAAoB,QAAQ,2BAA2B;AAGhE;;;;;;;;;;;;;;CAcC,GAED;;;;;CAKC,GACD,MAAMC,8BAA8B;IAAC;IAAY;CAAgB;AAEjE,MAAMC,cAAc,CAAC;;;;;+DAK0C,CAAC;AAEhE,8EAA8E,GAC9E,MAAMC,gBAAgB;AAEtB,kFAAkF,GAClF,MAAMC,cAAc;AAEpB;;;;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,MAAMiB,YAAsB,EAAE;IAE9B,KAAK,MAAMC,YAAYnB,wBAAwBC,MAAO;QACpD,MAAMmB,UAAUnB,KAAKoB,IAAI,CAACF,UAAU;QACpC,IAAI,CAACC,SAAS;YACZ;QACF;QACA,IAAIA,QAAQZ,QAAQ,CAACV,gBAAgB;YACnC,UAAU,6CAA6C;QACzD;QAEA,qEAAqE;QACrE,wEAAwE;QACxE,qEAAqE;QACrE,MAAMwB,YAAYF,QAAQG,KAAK,CAACxB,gBAAgB,EAAE;QAClD,IAAIuB,UAAUE,MAAM,GAAG,GAAG;YACxBN,UAAUJ,IAAI,CACZ,CAAC,GAAG,EAAEK,SAAS,uBAAuB,EAAEG,UAAUG,IAAI,CAAC,MAAM,ySAAyS,CAAC;YAEzW;QACF;QAEA,0EAA0E;QAC1E,2DAA2D;QAC3D,MAAMC,UAAUN,QAAQO,OAAO,CAC7B,+BACA,CAAC,IAAI,EAAE9B,YAAY,IAAI,CAAC;QAE1B,IAAI6B,YAAYN,SAAS;YACvBF,UAAUJ,IAAI,CACZ,CAAC,GAAG,EAAEK,SAAS,yRAAyR,CAAC;YAE3S;QACF;QACAlB,KAAK2B,KAAK,CAACT,UAAUO;IACvB;IAEA,MAAM/B,qBAAqBM;IAE3B,OAAO;QAAEiB;IAAU;AACrB"}