alchemy 2.0.0-beta.37 → 2.0.0-beta.39

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 (640) hide show
  1. package/bin/exec.js +488 -69
  2. package/bin/exec.js.map +1 -1
  3. package/lib/AWS/AutoScaling/LaunchTemplate.d.ts +1 -1
  4. package/lib/AWS/CloudWatch/common.d.ts +1 -1
  5. package/lib/AWS/Credentials.d.ts.map +1 -1
  6. package/lib/AWS/Credentials.js +1 -2
  7. package/lib/AWS/Credentials.js.map +1 -1
  8. package/lib/AWS/DynamoDB/Stream.d.ts.map +1 -1
  9. package/lib/AWS/DynamoDB/Stream.js +1 -1
  10. package/lib/AWS/DynamoDB/Stream.js.map +1 -1
  11. package/lib/AWS/EC2/Instance.d.ts +1 -1
  12. package/lib/AWS/EC2/hosted.d.ts +1 -1
  13. package/lib/AWS/EC2/hosted.d.ts.map +1 -1
  14. package/lib/AWS/EC2/hosted.js +3 -5
  15. package/lib/AWS/EC2/hosted.js.map +1 -1
  16. package/lib/AWS/ECS/Task.d.ts +1 -1
  17. package/lib/AWS/ECS/Task.d.ts.map +1 -1
  18. package/lib/AWS/ECS/Task.js +3 -5
  19. package/lib/AWS/ECS/Task.js.map +1 -1
  20. package/lib/AWS/Endpoint.d.ts.map +1 -1
  21. package/lib/AWS/Endpoint.js +1 -2
  22. package/lib/AWS/Endpoint.js.map +1 -1
  23. package/lib/AWS/Environment.d.ts +2 -2
  24. package/lib/AWS/EventBridge/EventSource.d.ts.map +1 -1
  25. package/lib/AWS/EventBridge/EventSource.js +1 -1
  26. package/lib/AWS/EventBridge/EventSource.js.map +1 -1
  27. package/lib/AWS/Kinesis/StreamEventSource.d.ts.map +1 -1
  28. package/lib/AWS/Kinesis/StreamEventSource.js +1 -1
  29. package/lib/AWS/Kinesis/StreamEventSource.js.map +1 -1
  30. package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
  31. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
  32. package/lib/AWS/Lambda/Function.d.ts +1 -1
  33. package/lib/AWS/Lambda/Function.d.ts.map +1 -1
  34. package/lib/AWS/Lambda/Function.js +7 -11
  35. package/lib/AWS/Lambda/Function.js.map +1 -1
  36. package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
  37. package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
  38. package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
  39. package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
  40. package/lib/AWS/Organizations/common.d.ts +1 -1
  41. package/lib/AWS/Providers.d.ts.map +1 -1
  42. package/lib/AWS/Providers.js +21 -3
  43. package/lib/AWS/Providers.js.map +1 -1
  44. package/lib/AWS/Region.d.ts +1 -1
  45. package/lib/AWS/Region.d.ts.map +1 -1
  46. package/lib/AWS/Region.js +2 -3
  47. package/lib/AWS/Region.js.map +1 -1
  48. package/lib/AWS/S3/Bucket.d.ts.map +1 -1
  49. package/lib/AWS/S3/Bucket.js +5 -2
  50. package/lib/AWS/S3/Bucket.js.map +1 -1
  51. package/lib/AWS/S3/BucketNotifications.d.ts.map +1 -1
  52. package/lib/AWS/S3/BucketNotifications.js +1 -1
  53. package/lib/AWS/S3/BucketNotifications.js.map +1 -1
  54. package/lib/AWS/SNS/TopicEventSource.d.ts.map +1 -1
  55. package/lib/AWS/SNS/TopicEventSource.js +1 -1
  56. package/lib/AWS/SNS/TopicEventSource.js.map +1 -1
  57. package/lib/AWS/SQS/Queue.d.ts.map +1 -1
  58. package/lib/AWS/SQS/Queue.js +23 -5
  59. package/lib/AWS/SQS/Queue.js.map +1 -1
  60. package/lib/Action.d.ts +77 -0
  61. package/lib/Action.d.ts.map +1 -0
  62. package/lib/Action.js +89 -0
  63. package/lib/Action.js.map +1 -0
  64. package/lib/AlchemyContext.d.ts +1 -1
  65. package/lib/Apply.d.ts.map +1 -1
  66. package/lib/Apply.js +222 -3
  67. package/lib/Apply.js.map +1 -1
  68. package/lib/Artifacts.d.ts +1 -1
  69. package/lib/Artifacts.d.ts.map +1 -1
  70. package/lib/Artifacts.js +1 -1
  71. package/lib/Artifacts.js.map +1 -1
  72. package/lib/Auth/AuthProvider.js +1 -1
  73. package/lib/Auth/AuthProvider.js.map +1 -1
  74. package/lib/Auth/Env.d.ts.map +1 -1
  75. package/lib/Auth/Env.js +4 -12
  76. package/lib/Auth/Env.js.map +1 -1
  77. package/lib/Binding.d.ts.map +1 -1
  78. package/lib/Binding.js +5 -5
  79. package/lib/Binding.js.map +1 -1
  80. package/lib/Build/Command.d.ts +1 -1
  81. package/lib/Build/Memo.d.ts +1 -1
  82. package/lib/Bundle/Docker.d.ts +3 -3
  83. package/lib/Bundle/Docker.js +1 -1
  84. package/lib/Bundle/Docker.js.map +1 -1
  85. package/lib/Bundle/TempRoot.d.ts +3 -3
  86. package/lib/Cli/Event.d.ts +1 -1
  87. package/lib/Cli/Event.d.ts.map +1 -1
  88. package/lib/Cli/NamespaceTree.d.ts +11 -5
  89. package/lib/Cli/NamespaceTree.d.ts.map +1 -1
  90. package/lib/Cli/NamespaceTree.js +28 -1
  91. package/lib/Cli/NamespaceTree.js.map +1 -1
  92. package/lib/Cli/commands/_shared.d.ts +1 -1
  93. package/lib/Cli/commands/_shared.js +2 -2
  94. package/lib/Cli/commands/_shared.js.map +1 -1
  95. package/lib/Cli/commands/aws.d.ts +1 -1
  96. package/lib/Cli/commands/cloudflare.d.ts +2 -2
  97. package/lib/Cli/commands/cloudflare.d.ts.map +1 -1
  98. package/lib/Cli/commands/deploy.d.ts +9 -9
  99. package/lib/Cli/commands/deploy.js +1 -1
  100. package/lib/Cli/commands/deploy.js.map +1 -1
  101. package/lib/Cli/commands/login.d.ts +1 -1
  102. package/lib/Cli/commands/logs.d.ts +1 -1
  103. package/lib/Cli/commands/logs.js.map +1 -1
  104. package/lib/Cli/commands/profile.d.ts +1 -3
  105. package/lib/Cli/commands/profile.d.ts.map +1 -1
  106. package/lib/Cli/commands/state.d.ts +1 -1
  107. package/lib/Cli/commands/state.d.ts.map +1 -1
  108. package/lib/Cli/commands/tail.d.ts +1 -1
  109. package/lib/Cli/commands/tail.js.map +1 -1
  110. package/lib/Cli/tui/components/Plan.d.ts.map +1 -1
  111. package/lib/Cli/tui/components/Plan.js +27 -13
  112. package/lib/Cli/tui/components/Plan.js.map +1 -1
  113. package/lib/Cli/tui/components/PlanProgress.d.ts +8 -1
  114. package/lib/Cli/tui/components/PlanProgress.d.ts.map +1 -1
  115. package/lib/Cli/tui/components/PlanProgress.js +95 -16
  116. package/lib/Cli/tui/components/PlanProgress.js.map +1 -1
  117. package/lib/Cloudflare/Access.js +0 -1
  118. package/lib/Cloudflare/Access.js.map +1 -1
  119. package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js +1 -1
  120. package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js.map +1 -1
  121. package/lib/Cloudflare/Artifacts/ArtifactsBinding.js +1 -1
  122. package/lib/Cloudflare/Artifacts/ArtifactsBinding.js.map +1 -1
  123. package/lib/Cloudflare/CloudflareEnvironment.d.ts +1 -1
  124. package/lib/Cloudflare/Container/Container.js +0 -1
  125. package/lib/Cloudflare/Container/Container.js.map +1 -1
  126. package/lib/Cloudflare/Container/ContainerApplication.d.ts +1 -1
  127. package/lib/Cloudflare/Container/ContainerApplication.d.ts.map +1 -1
  128. package/lib/Cloudflare/Container/ContainerApplication.js +4 -6
  129. package/lib/Cloudflare/Container/ContainerApplication.js.map +1 -1
  130. package/lib/Cloudflare/Container/ContainerBinding.js +2 -2
  131. package/lib/Cloudflare/Container/ContainerBinding.js.map +1 -1
  132. package/lib/Cloudflare/D1/D1Database.d.ts +1 -1
  133. package/lib/Cloudflare/D1/D1SqlFile.d.ts +2 -2
  134. package/lib/Cloudflare/Email/EmailAddress.d.ts +45 -0
  135. package/lib/Cloudflare/Email/EmailAddress.d.ts.map +1 -0
  136. package/lib/Cloudflare/Email/EmailAddress.js +99 -0
  137. package/lib/Cloudflare/Email/EmailAddress.js.map +1 -0
  138. package/lib/Cloudflare/Email/EmailRouting.d.ts +42 -0
  139. package/lib/Cloudflare/Email/EmailRouting.d.ts.map +1 -0
  140. package/lib/Cloudflare/Email/EmailRouting.js +89 -0
  141. package/lib/Cloudflare/Email/EmailRouting.js.map +1 -0
  142. package/lib/Cloudflare/Email/EmailRule.d.ts +80 -0
  143. package/lib/Cloudflare/Email/EmailRule.d.ts.map +1 -0
  144. package/lib/Cloudflare/Email/EmailRule.js +110 -0
  145. package/lib/Cloudflare/Email/EmailRule.js.map +1 -0
  146. package/lib/Cloudflare/Email/SendEmail.d.ts +74 -0
  147. package/lib/Cloudflare/Email/SendEmail.d.ts.map +1 -0
  148. package/lib/Cloudflare/Email/SendEmail.js +19 -0
  149. package/lib/Cloudflare/Email/SendEmail.js.map +1 -0
  150. package/lib/Cloudflare/Email/SendEmailBinding.d.ts +64 -0
  151. package/lib/Cloudflare/Email/SendEmailBinding.d.ts.map +1 -0
  152. package/lib/Cloudflare/Email/SendEmailBinding.js +54 -0
  153. package/lib/Cloudflare/Email/SendEmailBinding.js.map +1 -0
  154. package/lib/Cloudflare/Email/index.d.ts +6 -0
  155. package/lib/Cloudflare/Email/index.d.ts.map +1 -0
  156. package/lib/Cloudflare/Email/index.js +6 -0
  157. package/lib/Cloudflare/Email/index.js.map +1 -0
  158. package/lib/Cloudflare/Hyperdrive/Hyperdrive.d.ts +1 -1
  159. package/lib/Cloudflare/Images/ImagesBinding.js +1 -1
  160. package/lib/Cloudflare/Images/ImagesBinding.js.map +1 -1
  161. package/lib/Cloudflare/KV/KVNamespaceBinding.js +1 -1
  162. package/lib/Cloudflare/KV/KVNamespaceBinding.js.map +1 -1
  163. package/lib/Cloudflare/Local/Sidecar.d.ts +1 -1
  164. package/lib/Cloudflare/Local/SidecarHandlers.d.ts +1 -1
  165. package/lib/Cloudflare/Local/SidecarServer.js +1 -1
  166. package/lib/Cloudflare/Local/SidecarServer.js.map +1 -1
  167. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  168. package/lib/Cloudflare/Providers.js +6 -1
  169. package/lib/Cloudflare/Providers.js.map +1 -1
  170. package/lib/Cloudflare/Queue/QueueBinding.js +1 -1
  171. package/lib/Cloudflare/Queue/QueueBinding.js.map +1 -1
  172. package/lib/Cloudflare/R2/R2BucketBinding.js +1 -1
  173. package/lib/Cloudflare/R2/R2BucketBinding.js.map +1 -1
  174. package/lib/Cloudflare/SecretsStore/SecretBinding.js +1 -1
  175. package/lib/Cloudflare/SecretsStore/SecretBinding.js.map +1 -1
  176. package/lib/Cloudflare/StateStore/Api.d.ts +1 -1
  177. package/lib/Cloudflare/StateStore/State.d.ts +2 -2
  178. package/lib/Cloudflare/Workers/Assets.d.ts +2 -2
  179. package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
  180. package/lib/Cloudflare/Workers/Assets.js +5 -4
  181. package/lib/Cloudflare/Workers/Assets.js.map +1 -1
  182. package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
  183. package/lib/Cloudflare/Workers/HttpServer.js +25 -3
  184. package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
  185. package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
  186. package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
  187. package/lib/Cloudflare/Workers/Worker.d.ts +4 -3
  188. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  189. package/lib/Cloudflare/Workers/Worker.js +67 -32
  190. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  191. package/lib/Cloudflare/Workers/WorkerBundle.d.ts +1 -1
  192. package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
  193. package/lib/Cloudflare/Workers/WorkerBundle.js +4 -6
  194. package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
  195. package/lib/Cloudflare/Workers/WorkerName.d.ts +1 -1
  196. package/lib/Cloudflare/Workers/Workflow.js +2 -2
  197. package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
  198. package/lib/Cloudflare/index.d.ts +1 -0
  199. package/lib/Cloudflare/index.d.ts.map +1 -1
  200. package/lib/Cloudflare/index.js +1 -0
  201. package/lib/Cloudflare/index.js.map +1 -1
  202. package/lib/Construct.d.ts +3 -3
  203. package/lib/Construct.d.ts.map +1 -1
  204. package/lib/Construct.js.map +1 -1
  205. package/lib/Deploy.d.ts +1 -1
  206. package/lib/Destroy.d.ts +1 -1
  207. package/lib/Destroy.d.ts.map +1 -1
  208. package/lib/Destroy.js +1 -0
  209. package/lib/Destroy.js.map +1 -1
  210. package/lib/Drizzle/Providers.d.ts +1 -1
  211. package/lib/Drizzle/Schema.d.ts +1 -1
  212. package/lib/GitHub/Providers.d.ts +1 -1
  213. package/lib/Http.d.ts +1 -1
  214. package/lib/Http.d.ts.map +1 -1
  215. package/lib/Http.js +1 -1
  216. package/lib/Http.js.map +1 -1
  217. package/lib/Namespace.d.ts.map +1 -1
  218. package/lib/Namespace.js +3 -4
  219. package/lib/Namespace.js.map +1 -1
  220. package/lib/Neon/Branch.d.ts +2 -2
  221. package/lib/Neon/Branch.d.ts.map +1 -1
  222. package/lib/Neon/Branch.js +59 -27
  223. package/lib/Neon/Branch.js.map +1 -1
  224. package/lib/Neon/Credentials.d.ts +2 -2
  225. package/lib/Neon/Credentials.d.ts.map +1 -1
  226. package/lib/Neon/Credentials.js +2 -2
  227. package/lib/Neon/Credentials.js.map +1 -1
  228. package/lib/Neon/NeonEnvironment.d.ts +1 -1
  229. package/lib/Neon/Project.d.ts +25 -1
  230. package/lib/Neon/Project.d.ts.map +1 -1
  231. package/lib/Neon/Project.js +121 -42
  232. package/lib/Neon/Project.js.map +1 -1
  233. package/lib/Neon/Providers.d.ts +1 -1
  234. package/lib/Neon/SqlFile.d.ts +2 -2
  235. package/lib/Output.d.ts +3 -4
  236. package/lib/Output.d.ts.map +1 -1
  237. package/lib/Output.js +7 -4
  238. package/lib/Output.js.map +1 -1
  239. package/lib/PhysicalName.d.ts +1 -1
  240. package/lib/Plan.d.ts +36 -1
  241. package/lib/Plan.d.ts.map +1 -1
  242. package/lib/Plan.js +197 -31
  243. package/lib/Plan.js.map +1 -1
  244. package/lib/Platform.js +6 -6
  245. package/lib/Platform.js.map +1 -1
  246. package/lib/Provider.d.ts +1 -1
  247. package/lib/Provider.d.ts.map +1 -1
  248. package/lib/Provider.js +1 -1
  249. package/lib/Provider.js.map +1 -1
  250. package/lib/Random.d.ts +1 -1
  251. package/lib/Random.d.ts.map +1 -1
  252. package/lib/Random.js +1 -1
  253. package/lib/Random.js.map +1 -1
  254. package/lib/Resource.d.ts.map +1 -1
  255. package/lib/Resource.js +2 -25
  256. package/lib/Resource.js.map +1 -1
  257. package/lib/Runtime.d.ts +24 -0
  258. package/lib/Runtime.d.ts.map +1 -0
  259. package/lib/Runtime.js +31 -0
  260. package/lib/Runtime.js.map +1 -0
  261. package/lib/Secret.js +1 -1
  262. package/lib/Secret.js.map +1 -1
  263. package/lib/Sidecar/RpcClient.d.ts +1 -1
  264. package/lib/Sidecar/RpcPaths.d.ts +1 -1
  265. package/lib/Sidecar/RpcServer.d.ts +1 -1
  266. package/lib/Sidecar/RpcServices.d.ts +1 -1
  267. package/lib/Stack.d.ts +7 -2
  268. package/lib/Stack.d.ts.map +1 -1
  269. package/lib/Stack.js +4 -4
  270. package/lib/Stack.js.map +1 -1
  271. package/lib/State/ActionState.d.ts +48 -0
  272. package/lib/State/ActionState.d.ts.map +1 -0
  273. package/lib/State/ActionState.js +1 -0
  274. package/lib/State/ActionState.js.map +1 -0
  275. package/lib/State/HttpStateStore.d.ts.map +1 -1
  276. package/lib/State/HttpStateStore.js +1 -1
  277. package/lib/State/HttpStateStore.js.map +1 -1
  278. package/lib/State/InMemoryState.d.ts.map +1 -1
  279. package/lib/State/InMemoryState.js.map +1 -1
  280. package/lib/State/LocalState.d.ts +2 -2
  281. package/lib/State/ResourceState.d.ts +5 -0
  282. package/lib/State/ResourceState.d.ts.map +1 -1
  283. package/lib/State/State.d.ts +10 -2
  284. package/lib/State/State.d.ts.map +1 -1
  285. package/lib/State/State.js +2 -0
  286. package/lib/State/State.js.map +1 -1
  287. package/lib/State/index.d.ts +1 -0
  288. package/lib/State/index.d.ts.map +1 -1
  289. package/lib/State/index.js +1 -0
  290. package/lib/State/index.js.map +1 -1
  291. package/lib/Test/Core.d.ts +2 -2
  292. package/lib/Test/Core.d.ts.map +1 -1
  293. package/lib/Test/Core.js +4 -1
  294. package/lib/Test/Core.js.map +1 -1
  295. package/lib/Util/FileLogger.d.ts +1 -1
  296. package/lib/Util/effect.js +4 -4
  297. package/lib/Util/effect.js.map +1 -1
  298. package/lib/Util/exec.d.ts.map +1 -0
  299. package/lib/Util/exec.js.map +1 -0
  300. package/lib/Util/hash.d.ts +8 -0
  301. package/lib/Util/hash.d.ts.map +1 -0
  302. package/lib/Util/hash.js +11 -0
  303. package/lib/Util/hash.js.map +1 -0
  304. package/lib/Util/ignore.d.ts +40 -0
  305. package/lib/Util/ignore.d.ts.map +1 -0
  306. package/lib/Util/ignore.js +591 -0
  307. package/lib/Util/ignore.js.map +1 -0
  308. package/lib/index.d.ts +1 -0
  309. package/lib/index.d.ts.map +1 -1
  310. package/lib/index.js +1 -0
  311. package/lib/index.js.map +1 -1
  312. package/lib/tsconfig.test.tsbuildinfo +1 -1
  313. package/package.json +22 -28
  314. package/src/AWS/Credentials.ts +1 -2
  315. package/src/AWS/DynamoDB/Stream.ts +1 -4
  316. package/src/AWS/EC2/hosted.ts +14 -16
  317. package/src/AWS/ECS/Task.ts +14 -16
  318. package/src/AWS/Endpoint.ts +2 -5
  319. package/src/AWS/EventBridge/EventSource.ts +1 -4
  320. package/src/AWS/Kinesis/StreamEventSource.ts +1 -4
  321. package/src/AWS/Lambda/Function.ts +31 -35
  322. package/src/AWS/Providers.ts +22 -3
  323. package/src/AWS/Region.ts +2 -3
  324. package/src/AWS/S3/Bucket.ts +7 -2
  325. package/src/AWS/S3/BucketNotifications.ts +1 -4
  326. package/src/AWS/SNS/TopicEventSource.ts +1 -4
  327. package/src/AWS/SQS/Queue.ts +40 -6
  328. package/src/Action.ts +280 -0
  329. package/src/Apply.ts +351 -23
  330. package/src/Artifacts.ts +2 -4
  331. package/src/Auth/AuthProvider.ts +1 -1
  332. package/src/Auth/Env.ts +12 -20
  333. package/src/Binding.ts +5 -9
  334. package/src/Bundle/Docker.ts +1 -1
  335. package/src/Cli/Event.ts +4 -0
  336. package/src/Cli/NamespaceTree.ts +52 -5
  337. package/src/Cli/commands/_shared.ts +2 -2
  338. package/src/Cli/commands/deploy.ts +1 -1
  339. package/src/Cli/commands/logs.ts +4 -4
  340. package/src/Cli/commands/tail.ts +4 -4
  341. package/src/Cli/tui/components/Plan.tsx +65 -17
  342. package/src/Cli/tui/components/PlanProgress.tsx +142 -32
  343. package/src/Cloudflare/Access.ts +1 -1
  344. package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.ts +1 -1
  345. package/src/Cloudflare/Artifacts/ArtifactsBinding.ts +1 -1
  346. package/src/Cloudflare/Container/Container.ts +1 -1
  347. package/src/Cloudflare/Container/ContainerApplication.ts +4 -6
  348. package/src/Cloudflare/Container/ContainerBinding.ts +2 -2
  349. package/src/Cloudflare/Email/EmailAddress.ts +155 -0
  350. package/src/Cloudflare/Email/EmailRouting.ts +138 -0
  351. package/src/Cloudflare/Email/EmailRule.ts +210 -0
  352. package/src/Cloudflare/Email/SendEmail.ts +95 -0
  353. package/src/Cloudflare/Email/SendEmailBinding.ts +124 -0
  354. package/src/Cloudflare/Email/index.ts +5 -0
  355. package/src/Cloudflare/Images/ImagesBinding.ts +1 -1
  356. package/src/Cloudflare/KV/KVNamespaceBinding.ts +1 -1
  357. package/src/Cloudflare/Local/SidecarServer.ts +1 -1
  358. package/src/Cloudflare/Providers.ts +9 -0
  359. package/src/Cloudflare/Queue/QueueBinding.ts +1 -1
  360. package/src/Cloudflare/R2/R2BucketBinding.ts +1 -1
  361. package/src/Cloudflare/SecretsStore/SecretBinding.ts +1 -1
  362. package/src/Cloudflare/Workers/Assets.ts +5 -6
  363. package/src/Cloudflare/Workers/HttpServer.ts +37 -5
  364. package/src/Cloudflare/Workers/InferEnv.ts +15 -11
  365. package/src/Cloudflare/Workers/Worker.ts +78 -36
  366. package/src/Cloudflare/Workers/WorkerBundle.ts +4 -6
  367. package/src/Cloudflare/Workers/Workflow.ts +2 -2
  368. package/src/Cloudflare/index.ts +1 -0
  369. package/src/Construct.ts +3 -7
  370. package/src/Destroy.ts +1 -0
  371. package/src/Http.ts +1 -1
  372. package/src/Namespace.ts +4 -4
  373. package/src/Neon/Branch.ts +93 -59
  374. package/src/Neon/Credentials.ts +2 -2
  375. package/src/Neon/Project.ts +193 -64
  376. package/src/Output.ts +9 -7
  377. package/src/Plan.ts +303 -53
  378. package/src/Platform.ts +7 -7
  379. package/src/Provider.ts +8 -3
  380. package/src/Random.ts +1 -1
  381. package/src/Resource.ts +2 -25
  382. package/src/Runtime.ts +38 -0
  383. package/src/Secret.ts +1 -1
  384. package/src/Stack.ts +10 -6
  385. package/src/State/ActionState.ts +51 -0
  386. package/src/State/HttpStateStore.ts +6 -2
  387. package/src/State/InMemoryState.ts +3 -3
  388. package/src/State/ResourceState.ts +5 -0
  389. package/src/State/State.ts +17 -2
  390. package/src/State/index.ts +1 -0
  391. package/src/Test/Core.ts +4 -3
  392. package/src/Util/effect.ts +4 -4
  393. package/src/Util/hash.ts +14 -0
  394. package/src/Util/ignore.ts +815 -0
  395. package/src/index.ts +6 -0
  396. package/lib/Agent/Agent.d.ts +0 -9
  397. package/lib/Agent/Agent.d.ts.map +0 -1
  398. package/lib/Agent/Agent.js +0 -10
  399. package/lib/Agent/Agent.js.map +0 -1
  400. package/lib/Agent/Aspect.d.ts +0 -51
  401. package/lib/Agent/Aspect.d.ts.map +0 -1
  402. package/lib/Agent/Aspect.js +0 -45
  403. package/lib/Agent/Aspect.js.map +0 -1
  404. package/lib/Agent/AspectGraph.d.ts +0 -45
  405. package/lib/Agent/AspectGraph.d.ts.map +0 -1
  406. package/lib/Agent/AspectGraph.js +0 -39
  407. package/lib/Agent/AspectGraph.js.map +0 -1
  408. package/lib/Agent/ContextPlugin.d.ts +0 -8
  409. package/lib/Agent/ContextPlugin.d.ts.map +0 -1
  410. package/lib/Agent/ContextPlugin.js +0 -3
  411. package/lib/Agent/ContextPlugin.js.map +0 -1
  412. package/lib/Agent/Plugin.d.ts +0 -18
  413. package/lib/Agent/Plugin.d.ts.map +0 -1
  414. package/lib/Agent/Plugin.js +0 -8
  415. package/lib/Agent/Plugin.js.map +0 -1
  416. package/lib/Agent/chat/channel.d.ts +0 -9
  417. package/lib/Agent/chat/channel.d.ts.map +0 -1
  418. package/lib/Agent/chat/channel.js +0 -10
  419. package/lib/Agent/chat/channel.js.map +0 -1
  420. package/lib/Agent/chat/event.d.ts +0 -32
  421. package/lib/Agent/chat/event.d.ts.map +0 -1
  422. package/lib/Agent/chat/event.js +0 -32
  423. package/lib/Agent/chat/event.js.map +0 -1
  424. package/lib/Agent/chat/message.d.ts +0 -22
  425. package/lib/Agent/chat/message.d.ts.map +0 -1
  426. package/lib/Agent/chat/message.js +0 -31
  427. package/lib/Agent/chat/message.js.map +0 -1
  428. package/lib/Agent/chat/service.d.ts +0 -102
  429. package/lib/Agent/chat/service.d.ts.map +0 -1
  430. package/lib/Agent/chat/service.js +0 -79
  431. package/lib/Agent/chat/service.js.map +0 -1
  432. package/lib/Agent/chat/thread.d.ts +0 -13
  433. package/lib/Agent/chat/thread.d.ts.map +0 -1
  434. package/lib/Agent/chat/thread.js +0 -16
  435. package/lib/Agent/chat/thread.js.map +0 -1
  436. package/lib/Agent/coding/bash.d.ts +0 -36
  437. package/lib/Agent/coding/bash.d.ts.map +0 -1
  438. package/lib/Agent/coding/bash.js +0 -170
  439. package/lib/Agent/coding/bash.js.map +0 -1
  440. package/lib/Agent/coding/edit.d.ts +0 -31
  441. package/lib/Agent/coding/edit.d.ts.map +0 -1
  442. package/lib/Agent/coding/edit.js +0 -90
  443. package/lib/Agent/coding/edit.js.map +0 -1
  444. package/lib/Agent/coding/glob.d.ts +0 -23
  445. package/lib/Agent/coding/glob.d.ts.map +0 -1
  446. package/lib/Agent/coding/glob.js +0 -78
  447. package/lib/Agent/coding/glob.js.map +0 -1
  448. package/lib/Agent/coding/grep.d.ts +0 -26
  449. package/lib/Agent/coding/grep.d.ts.map +0 -1
  450. package/lib/Agent/coding/grep.js +0 -105
  451. package/lib/Agent/coding/grep.js.map +0 -1
  452. package/lib/Agent/coding/index.d.ts +0 -8
  453. package/lib/Agent/coding/index.d.ts.map +0 -1
  454. package/lib/Agent/coding/index.js +0 -8
  455. package/lib/Agent/coding/index.js.map +0 -1
  456. package/lib/Agent/coding/read.d.ts +0 -27
  457. package/lib/Agent/coding/read.d.ts.map +0 -1
  458. package/lib/Agent/coding/read.js +0 -89
  459. package/lib/Agent/coding/read.js.map +0 -1
  460. package/lib/Agent/coding/readlints.d.ts +0 -19
  461. package/lib/Agent/coding/readlints.d.ts.map +0 -1
  462. package/lib/Agent/coding/readlints.js +0 -53
  463. package/lib/Agent/coding/readlints.js.map +0 -1
  464. package/lib/Agent/coding/write.d.ts +0 -22
  465. package/lib/Agent/coding/write.d.ts.map +0 -1
  466. package/lib/Agent/coding/write.js +0 -53
  467. package/lib/Agent/coding/write.js.map +0 -1
  468. package/lib/Agent/fs/file.d.ts +0 -12
  469. package/lib/Agent/fs/file.d.ts.map +0 -1
  470. package/lib/Agent/fs/file.js +0 -8
  471. package/lib/Agent/fs/file.js.map +0 -1
  472. package/lib/Agent/fs/folder.d.ts +0 -5
  473. package/lib/Agent/fs/folder.d.ts.map +0 -1
  474. package/lib/Agent/fs/folder.js +0 -3
  475. package/lib/Agent/fs/folder.js.map +0 -1
  476. package/lib/Agent/index.d.ts +0 -9
  477. package/lib/Agent/index.d.ts.map +0 -1
  478. package/lib/Agent/index.js +0 -9
  479. package/lib/Agent/index.js.map +0 -1
  480. package/lib/Agent/llm/error.d.ts +0 -208
  481. package/lib/Agent/llm/error.d.ts.map +0 -1
  482. package/lib/Agent/llm/error.js +0 -209
  483. package/lib/Agent/llm/error.js.map +0 -1
  484. package/lib/Agent/llm/index.d.ts +0 -5
  485. package/lib/Agent/llm/index.d.ts.map +0 -1
  486. package/lib/Agent/llm/index.js +0 -5
  487. package/lib/Agent/llm/index.js.map +0 -1
  488. package/lib/Agent/llm/llm.d.ts +0 -32
  489. package/lib/Agent/llm/llm.d.ts.map +0 -1
  490. package/lib/Agent/llm/llm.js +0 -74
  491. package/lib/Agent/llm/llm.js.map +0 -1
  492. package/lib/Agent/llm/stream-collectors.d.ts +0 -46
  493. package/lib/Agent/llm/stream-collectors.d.ts.map +0 -1
  494. package/lib/Agent/llm/stream-collectors.js +0 -33
  495. package/lib/Agent/llm/stream-collectors.js.map +0 -1
  496. package/lib/Agent/llm/stream-text-part.d.ts +0 -5
  497. package/lib/Agent/llm/stream-text-part.d.ts.map +0 -1
  498. package/lib/Agent/llm/stream-text-part.js +0 -4
  499. package/lib/Agent/llm/stream-text-part.js.map +0 -1
  500. package/lib/Agent/lsp/client.d.ts +0 -122
  501. package/lib/Agent/lsp/client.d.ts.map +0 -1
  502. package/lib/Agent/lsp/client.js +0 -180
  503. package/lib/Agent/lsp/client.js.map +0 -1
  504. package/lib/Agent/lsp/diagnostics.d.ts +0 -16
  505. package/lib/Agent/lsp/diagnostics.d.ts.map +0 -1
  506. package/lib/Agent/lsp/diagnostics.js +0 -48
  507. package/lib/Agent/lsp/diagnostics.js.map +0 -1
  508. package/lib/Agent/lsp/jsonrpc.d.ts +0 -90
  509. package/lib/Agent/lsp/jsonrpc.d.ts.map +0 -1
  510. package/lib/Agent/lsp/jsonrpc.js +0 -178
  511. package/lib/Agent/lsp/jsonrpc.js.map +0 -1
  512. package/lib/Agent/lsp/manager.d.ts +0 -38
  513. package/lib/Agent/lsp/manager.d.ts.map +0 -1
  514. package/lib/Agent/lsp/manager.js +0 -98
  515. package/lib/Agent/lsp/manager.js.map +0 -1
  516. package/lib/Agent/lsp/servers.d.ts +0 -28
  517. package/lib/Agent/lsp/servers.d.ts.map +0 -1
  518. package/lib/Agent/lsp/servers.js +0 -21
  519. package/lib/Agent/lsp/servers.js.map +0 -1
  520. package/lib/Agent/process/driver.d.ts +0 -10
  521. package/lib/Agent/process/driver.d.ts.map +0 -1
  522. package/lib/Agent/process/driver.js +0 -153
  523. package/lib/Agent/process/driver.js.map +0 -1
  524. package/lib/Agent/process/issue-service.d.ts +0 -44
  525. package/lib/Agent/process/issue-service.d.ts.map +0 -1
  526. package/lib/Agent/process/issue-service.js +0 -28
  527. package/lib/Agent/process/issue-service.js.map +0 -1
  528. package/lib/Agent/process/issue-tools.d.ts +0 -28
  529. package/lib/Agent/process/issue-tools.d.ts.map +0 -1
  530. package/lib/Agent/process/issue-tools.js +0 -28
  531. package/lib/Agent/process/issue-tools.js.map +0 -1
  532. package/lib/Agent/process/issue.d.ts +0 -16
  533. package/lib/Agent/process/issue.d.ts.map +0 -1
  534. package/lib/Agent/process/issue.js +0 -17
  535. package/lib/Agent/process/issue.js.map +0 -1
  536. package/lib/Agent/process/organization.d.ts +0 -4
  537. package/lib/Agent/process/organization.d.ts.map +0 -1
  538. package/lib/Agent/process/organization.js +0 -3
  539. package/lib/Agent/process/organization.js.map +0 -1
  540. package/lib/Agent/process/process.d.ts +0 -5
  541. package/lib/Agent/process/process.d.ts.map +0 -1
  542. package/lib/Agent/process/process.js +0 -3
  543. package/lib/Agent/process/process.js.map +0 -1
  544. package/lib/Agent/process/reply.d.ts +0 -16
  545. package/lib/Agent/process/reply.d.ts.map +0 -1
  546. package/lib/Agent/process/reply.js +0 -18
  547. package/lib/Agent/process/reply.js.map +0 -1
  548. package/lib/Agent/process/task.d.ts +0 -25
  549. package/lib/Agent/process/task.d.ts.map +0 -1
  550. package/lib/Agent/process/task.js +0 -26
  551. package/lib/Agent/process/task.js.map +0 -1
  552. package/lib/Agent/tool/index.d.ts +0 -4
  553. package/lib/Agent/tool/index.d.ts.map +0 -1
  554. package/lib/Agent/tool/index.js +0 -4
  555. package/lib/Agent/tool/index.js.map +0 -1
  556. package/lib/Agent/tool/parameter.d.ts +0 -12
  557. package/lib/Agent/tool/parameter.d.ts.map +0 -1
  558. package/lib/Agent/tool/parameter.js +0 -6
  559. package/lib/Agent/tool/parameter.js.map +0 -1
  560. package/lib/Agent/tool/result.d.ts +0 -17
  561. package/lib/Agent/tool/result.d.ts.map +0 -1
  562. package/lib/Agent/tool/result.js +0 -6
  563. package/lib/Agent/tool/result.js.map +0 -1
  564. package/lib/Agent/tool/tool.d.ts +0 -32
  565. package/lib/Agent/tool/tool.d.ts.map +0 -1
  566. package/lib/Agent/tool/tool.js +0 -16
  567. package/lib/Agent/tool/tool.js.map +0 -1
  568. package/lib/Agent/util/command-validator.d.ts +0 -12
  569. package/lib/Agent/util/command-validator.d.ts.map +0 -1
  570. package/lib/Agent/util/command-validator.js +0 -74
  571. package/lib/Agent/util/command-validator.js.map +0 -1
  572. package/lib/Agent/util/exec.d.ts.map +0 -1
  573. package/lib/Agent/util/exec.js.map +0 -1
  574. package/lib/Agent/util/parser.d.ts +0 -5
  575. package/lib/Agent/util/parser.d.ts.map +0 -1
  576. package/lib/Agent/util/parser.js +0 -41
  577. package/lib/Agent/util/parser.js.map +0 -1
  578. package/lib/Agent/util/replace.d.ts +0 -38
  579. package/lib/Agent/util/replace.d.ts.map +0 -1
  580. package/lib/Agent/util/replace.js +0 -458
  581. package/lib/Agent/util/replace.js.map +0 -1
  582. package/lib/Agent/util/ripgrep.d.ts +0 -109
  583. package/lib/Agent/util/ripgrep.d.ts.map +0 -1
  584. package/lib/Agent/util/ripgrep.js +0 -221
  585. package/lib/Agent/util/ripgrep.js.map +0 -1
  586. package/lib/Neon/api.d.ts +0 -258
  587. package/lib/Neon/api.d.ts.map +0 -1
  588. package/lib/Neon/api.js +0 -215
  589. package/lib/Neon/api.js.map +0 -1
  590. package/src/Agent/Agent.ts +0 -26
  591. package/src/Agent/Aspect.ts +0 -173
  592. package/src/Agent/AspectGraph.ts +0 -98
  593. package/src/Agent/ContextPlugin.ts +0 -18
  594. package/src/Agent/Plugin.ts +0 -29
  595. package/src/Agent/chat/channel.ts +0 -26
  596. package/src/Agent/chat/event.ts +0 -43
  597. package/src/Agent/chat/message.ts +0 -35
  598. package/src/Agent/chat/service.ts +0 -133
  599. package/src/Agent/chat/thread.ts +0 -17
  600. package/src/Agent/coding/bash.ts +0 -197
  601. package/src/Agent/coding/edit.ts +0 -152
  602. package/src/Agent/coding/glob.ts +0 -96
  603. package/src/Agent/coding/grep.ts +0 -143
  604. package/src/Agent/coding/index.ts +0 -7
  605. package/src/Agent/coding/read.ts +0 -119
  606. package/src/Agent/coding/readlints.ts +0 -78
  607. package/src/Agent/coding/write.ts +0 -79
  608. package/src/Agent/fs/file.ts +0 -22
  609. package/src/Agent/fs/folder.ts +0 -16
  610. package/src/Agent/index.ts +0 -9
  611. package/src/Agent/llm/error.ts +0 -330
  612. package/src/Agent/llm/index.ts +0 -4
  613. package/src/Agent/llm/llm.ts +0 -131
  614. package/src/Agent/llm/stream-collectors.ts +0 -58
  615. package/src/Agent/llm/stream-text-part.ts +0 -7
  616. package/src/Agent/lsp/client.ts +0 -293
  617. package/src/Agent/lsp/diagnostics.ts +0 -64
  618. package/src/Agent/lsp/jsonrpc.ts +0 -317
  619. package/src/Agent/lsp/manager.ts +0 -213
  620. package/src/Agent/lsp/servers.ts +0 -37
  621. package/src/Agent/process/driver.ts +0 -168
  622. package/src/Agent/process/issue-service.ts +0 -48
  623. package/src/Agent/process/issue-tools.ts +0 -33
  624. package/src/Agent/process/issue.ts +0 -22
  625. package/src/Agent/process/organization.ts +0 -16
  626. package/src/Agent/process/process.ts +0 -16
  627. package/src/Agent/process/reply.ts +0 -21
  628. package/src/Agent/process/task.ts +0 -34
  629. package/src/Agent/tool/index.ts +0 -3
  630. package/src/Agent/tool/parameter.ts +0 -35
  631. package/src/Agent/tool/result.ts +0 -51
  632. package/src/Agent/tool/tool.ts +0 -74
  633. package/src/Agent/util/command-validator.ts +0 -98
  634. package/src/Agent/util/parser.ts +0 -39
  635. package/src/Agent/util/replace.ts +0 -559
  636. package/src/Agent/util/ripgrep.ts +0 -256
  637. package/src/Neon/api.ts +0 -579
  638. /package/lib/{Agent/util → Util}/exec.d.ts +0 -0
  639. /package/lib/{Agent/util → Util}/exec.js +0 -0
  640. /package/src/{Agent/util → Util}/exec.ts +0 -0
package/bin/exec.js CHANGED
@@ -28,6 +28,7 @@ import "effect/Scope";
28
28
  import * as Duration from "effect/Duration";
29
29
  import * as Exit from "effect/Exit";
30
30
  import * as Metric from "effect/Metric";
31
+ import { createHash } from "node:crypto";
31
32
  import * as Argument from "effect/unstable/cli/Argument";
32
33
  import * as CliError from "effect/unstable/cli/CliError";
33
34
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -469,17 +470,17 @@ const effectClass = ((impl) => impl === void 0 ? (innerImpl) => effectClass(inne
469
470
  return impl;
470
471
  }
471
472
  static [Symbol.iterator]() {
472
- return new SingleShotGen(this);
473
+ return new SingleShotGen(this.asEffect());
473
474
  }
474
475
  static pipe(...fns) {
475
- return pipeArguments(this.asEffect(), fns);
476
+ return pipeArguments(this, fns);
476
477
  }
477
478
  }, impl));
478
479
  const taggedFunction = (tag$1, fn) => {
479
480
  const overrides = {
480
- asEffect: () => tag$1.asEffect(),
481
+ asEffect: () => tag$1,
481
482
  [Symbol.iterator]: () => tag$1[Symbol.iterator](),
482
- pipe: (...fns) => pipeArguments(tag$1.asEffect(), fns),
483
+ pipe: (...fns) => pipeArguments(tag$1, fns),
483
484
  toString: () => `${tag$1.toString()}.${fn.name}`
484
485
  };
485
486
  return new Proxy(fn, {
@@ -516,22 +517,23 @@ const StackName = Stack.use((stack) => Effect.succeed(stack.name));
516
517
  const make$1 = (options) => (effect) => Effect.scope.pipe(Effect.flatMap((scope) => {
517
518
  if (options.state == null) return Effect.die(/* @__PURE__ */ new Error(`Stack "${options.name}" is missing a state store. Add a \`state\` layer to the stack options, e.g.:\n Alchemy.Stack("${options.name}", {\n providers: Cloudflare.providers(),\n state: Cloudflare.state(), // <-- required\n }, ...)\nSee https://v2.alchemy.run/concepts/state-store for available state stores.`));
518
519
  if (options.providers == null) return Effect.die(/* @__PURE__ */ new Error(`Stack "${options.name}" is missing a providers layer. Add a \`providers\` layer to the stack options, e.g.:\n Alchemy.Stack("${options.name}", {\n providers: Cloudflare.providers(), // <-- required\n state: Cloudflare.state(),\n }, ...)`));
519
- return options.providers.pipe(Layer.provideMerge(options.state), Layer.provideMerge(Layer.effect(Stack, Stage.asEffect().pipe(Effect.map((stage$1) => options.stack ?? {
520
+ return options.providers.pipe(Layer.provideMerge(options.state), Layer.provideMerge(Layer.effect(Stack, Stage.pipe(Effect.map((stage$1) => options.stack ?? {
520
521
  name: options.name,
521
522
  stage: stage$1,
522
523
  resources: {},
523
- bindings: {}
524
+ bindings: {},
525
+ actions: {}
524
526
  })))), Layer.buildWithScope(scope));
525
527
  }), Effect.flatMap((context) => Effect.all([
526
528
  effect,
527
- Stack.asEffect(),
529
+ Stack,
528
530
  Effect.context()
529
531
  ]).pipe(Effect.map(([output, stack, services$1]) => ({
530
532
  ...stack,
531
533
  output,
532
534
  services: EffectContext.merge(services$1, context)
533
535
  })), Effect.provideContext(context))));
534
- const CurrentStack = Effect.serviceOption(Stack).asEffect().pipe(Effect.map(Option.getOrUndefined));
536
+ const CurrentStack = Effect.serviceOption(Stack).pipe(Effect.map(Option.getOrUndefined));
535
537
  const platform = Layer.mergeAll(PlatformServices, FetchHttpClient.layer, Logger.layer([fileLogger("out")], { mergeWithExisting: true }), Layer.provide(ProfileLive, PlatformServices), Layer.provide(CredentialsStoreLive, PlatformServices));
536
538
 
537
539
  //#endregion
@@ -552,6 +554,7 @@ const CurrentRuntimeContext = Effect.serviceOption(RuntimeContext).pipe(Effect.m
552
554
 
553
555
  //#endregion
554
556
  //#region lib/State/State.js
557
+ const isActionState = (s) => !!s && s.kind === "action";
555
558
  var State = class extends EffectContext.Service()("alchemy/State") {};
556
559
 
557
560
  //#endregion
@@ -577,13 +580,13 @@ var BaseExpr = class {
577
580
  return this;
578
581
  }
579
582
  [Symbol.iterator]() {
580
- return new SingleShotGen(this);
583
+ return new SingleShotGen(this.asEffect());
581
584
  }
582
585
  asEffect() {
583
586
  return this.bind(this.toString());
584
587
  }
585
588
  bind(id) {
586
- return RuntimeContext.asEffect().pipe(Effect.flatMap((ctx) => Effect.map(ctx.set(id, this), (key) => ctx.get(key))));
589
+ return RuntimeContext.pipe(Effect.flatMap((ctx) => Effect.map(ctx.set(id, this), (key) => ctx.get(key))));
587
590
  }
588
591
  pipe(...fns) {
589
592
  return pipe(this, ...fns);
@@ -670,7 +673,7 @@ const isNamedExpr = (node) => node?.kind === "NamedExpr";
670
673
  /**
671
674
  * Wraps another `Expr` and overrides its `toString()` / inspect output.
672
675
  *
673
- * `BaseExpr.asEffect()` derives the binding id from `this.toString()`, so
676
+ * `BaseExpr` derives the binding id from `this.toString()`, so
674
677
  * wrapping an expression in `NamedExpr` makes that derived id stable and
675
678
  * caller-controlled (e.g. an env var name like `"API_KEY"`).
676
679
  */
@@ -812,7 +815,7 @@ const evaluate = (expr, upstream$1) => Effect.gen(function* () {
812
815
  stage: stage$1,
813
816
  resourceId: expr.resourceId
814
817
  }));
815
- return resource.attr;
818
+ return resource.attr ?? resource.output;
816
819
  } else if (isStackRefExpr(expr)) {
817
820
  const state = yield* State;
818
821
  const stack = expr.stack;
@@ -994,6 +997,19 @@ const recordOutcome = (baseAttrs, status, duration) => {
994
997
  return Effect.all([Metric.update(Metric.withAttributes(resourceCounter, attrs), 1), Metric.update(Metric.withAttributes(resourceDuration, attrs), duration)], { discard: true });
995
998
  };
996
999
 
1000
+ //#endregion
1001
+ //#region lib/Action.js
1002
+ const isAction = (value) => typeof value === "object" && value !== null && value?.Kind === "action";
1003
+
1004
+ //#endregion
1005
+ //#region lib/Util/hash.js
1006
+ /**
1007
+ * Stable hash of a resolved Task input. Wrapped in `Effect.sync` so the
1008
+ * call participates in the Effect runtime (tracing/interruption) per the
1009
+ * Effect-platform conventions.
1010
+ */
1011
+ const hashInput = (input) => Effect.sync(() => createHash("sha256").update(JSON.stringify(input ?? null)).digest("hex"));
1012
+
997
1013
  //#endregion
998
1014
  //#region lib/Util/scc.js
999
1015
  /**
@@ -1072,6 +1088,7 @@ const findCycleMembers = (edges) => {
1072
1088
  const make = (stack, options = {}) => Effect.gen(function* () {
1073
1089
  const state = yield* State;
1074
1090
  const resources = Object.values(stack.resources);
1091
+ const actions = Object.values(stack.actions ?? {});
1075
1092
  const stackName = stack.name;
1076
1093
  const stage$1 = stack.stage;
1077
1094
  const shouldAdopt = Effect.gen(function* () {
@@ -1094,15 +1111,17 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1094
1111
  })), { concurrency: "unbounded" });
1095
1112
  const resolvedResources = {};
1096
1113
  const resolveResource = (resourceExpr) => Effect.gen(function* () {
1114
+ if (isAction(resourceExpr.src)) return resourceExpr;
1097
1115
  return yield* resolvedResources[resourceExpr.src.FQN] ??= yield* Effect.cached(Effect.gen(function* () {
1098
1116
  const resource = resourceExpr.src;
1099
1117
  const provider = yield* findProviderByType(resource.Type);
1100
1118
  const props = yield* resolveInput(resource.Props);
1101
- const oldState = yield* state.get({
1119
+ const persisted = yield* state.get({
1102
1120
  stack: stackName,
1103
1121
  stage: stage$1,
1104
1122
  fqn: resource.FQN
1105
1123
  });
1124
+ const oldState = isActionState(persisted) ? void 0 : persisted;
1106
1125
  if (!oldState || oldState.status === "creating") return resourceExpr;
1107
1126
  const oldProps = oldState.status === "updating" ? oldState.old.props : oldState.props;
1108
1127
  const oldBindings = oldState.bindings ?? [];
@@ -1160,7 +1179,7 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1160
1179
  stage: refStage,
1161
1180
  resourceId: expr.resourceId
1162
1181
  }));
1163
- return refState.attr;
1182
+ return refState.attr ?? refState.output;
1164
1183
  } else if (isStackRefExpr(expr)) {
1165
1184
  const refStack = expr.stack;
1166
1185
  const refStage = expr.stage ?? stage$1;
@@ -1180,21 +1199,28 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1180
1199
  });
1181
1200
  const oldDownstreamDependencies = Object.fromEntries(oldResources.filter((resource) => !!resource).map((resource) => [resource.fqn, resource.downstream]));
1182
1201
  const newResourceFqns = new Set(resources.map((r) => r.FQN));
1183
- const newUpstreamDependencies = Object.fromEntries(resources.map((resource) => [resource.FQN, Object.values(upstreamAny(resource.Props)).map((r) => r.FQN)]));
1202
+ const newActionFqns = new Set(actions.map((t) => t.FQN));
1203
+ const newNodeFqns = new Set([...newResourceFqns, ...newActionFqns]);
1204
+ const newUpstreamDependencies = Object.fromEntries([...resources.map((resource) => [resource.FQN, Object.values(upstreamAny(resource.Props)).map((r) => r.FQN)]), ...actions.map((action) => [action.FQN, Object.values(upstreamAny(action.Input)).map((r) => r.FQN)])]);
1184
1205
  const bindingUpstreamDependencies = Object.fromEntries(resources.map((resource) => [resource.FQN, Object.values(upstreamAny(stack.bindings[resource.FQN] ?? [])).map((r) => r.FQN)]));
1185
- const rawUpstreamDependencies = Object.fromEntries(resources.map((resource) => {
1206
+ const rawUpstreamDependencies = Object.fromEntries([...resources.map((resource) => {
1186
1207
  const fqn = resource.FQN;
1187
1208
  const propDeps = newUpstreamDependencies[fqn] ?? [];
1188
1209
  const bindDeps = bindingUpstreamDependencies[fqn] ?? [];
1189
1210
  return [fqn, [...new Set([...propDeps, ...bindDeps])]];
1190
- }));
1191
- const allUpstreamDependencies = Object.fromEntries(resources.map((resource) => {
1211
+ }), ...actions.map((action) => {
1212
+ const fqn = action.FQN;
1213
+ return [fqn, newUpstreamDependencies[fqn] ?? []];
1214
+ })]);
1215
+ const allUpstreamDependencies = Object.fromEntries([...resources.map((resource) => {
1192
1216
  const fqn = resource.FQN;
1193
- return [fqn, (rawUpstreamDependencies[fqn] ?? []).filter((dep) => newResourceFqns.has(dep))];
1194
- }));
1217
+ return [fqn, (rawUpstreamDependencies[fqn] ?? []).filter((dep) => newNodeFqns.has(dep))];
1218
+ }), ...actions.map((action) => {
1219
+ const fqn = action.FQN;
1220
+ return [fqn, (newUpstreamDependencies[fqn] ?? []).filter((dep) => newNodeFqns.has(dep))];
1221
+ })]);
1195
1222
  const combinedCycleMembers = findCycleMembers(allUpstreamDependencies);
1196
- const newDownstreamDependencies = Object.fromEntries(resources.map((resource) => {
1197
- const upFqn = resource.FQN;
1223
+ const computeDownstream = (upFqn) => {
1198
1224
  const downstream = [];
1199
1225
  for (const [downFqn, upstreams] of Object.entries(rawUpstreamDependencies)) {
1200
1226
  if (downFqn === upFqn) continue;
@@ -1206,8 +1232,9 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1206
1232
  if (combinedCycleMembers.has(upFqn) && combinedCycleMembers.has(downFqn)) continue;
1207
1233
  downstream.push(downFqn);
1208
1234
  }
1209
- return [upFqn, downstream];
1210
- }));
1235
+ return downstream;
1236
+ };
1237
+ const newDownstreamDependencies = Object.fromEntries([...resources.map((resource) => [resource.FQN, computeDownstream(resource.FQN)]), ...actions.map((action) => [action.FQN, computeDownstream(action.FQN)])]);
1211
1238
  const resourceGraph = Object.fromEntries((yield* Effect.all(resources.map(Effect.fn("plan.diff.resource")(function* (resource) {
1212
1239
  const provider = yield* findProviderByType(resource.Type);
1213
1240
  const id = resource.LogicalId;
@@ -1215,11 +1242,12 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1215
1242
  const news = yield* resolveInput(resource.Props);
1216
1243
  const downstream = newDownstreamDependencies[fqn] ?? [];
1217
1244
  const newBindings = yield* resolveInput(stack.bindings[fqn] ?? []);
1218
- let oldState = yield* state.get({
1245
+ const persisted = yield* state.get({
1219
1246
  stack: stackName,
1220
1247
  stage: stage$1,
1221
1248
  fqn
1222
1249
  });
1250
+ let oldState = isActionState(persisted) ? void 0 : persisted;
1223
1251
  let forceUpdateAfterAdoption = false;
1224
1252
  if (oldState === void 0 && provider.read && isResolved(news)) {
1225
1253
  const adoptInstanceId = yield* generateInstanceId();
@@ -1390,6 +1418,42 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1390
1418
  state: oldState
1391
1419
  });
1392
1420
  })), { concurrency: "unbounded" })).map((update) => [update.resource.FQN, update]));
1421
+ const actionGraph = Object.fromEntries(yield* Effect.all(actions.map(Effect.fn("plan.diff.action")(function* (action) {
1422
+ const fqn = action.FQN;
1423
+ const downstream = newDownstreamDependencies[fqn] ?? [];
1424
+ const inputHash = yield* hashInput(yield* resolveInput(action.Input));
1425
+ const oldState = yield* state.get({
1426
+ stack: stackName,
1427
+ stage: stage$1,
1428
+ fqn
1429
+ });
1430
+ if (oldState && !isActionState(oldState)) return [fqn, {
1431
+ kind: "action",
1432
+ action: "run",
1433
+ def: action,
1434
+ input: action.Input,
1435
+ state: void 0,
1436
+ downstream,
1437
+ forced: false
1438
+ }];
1439
+ const prior = oldState;
1440
+ if (prior?.status === "ran" && prior.inputHash === inputHash && !options.force) return [fqn, {
1441
+ kind: "action",
1442
+ action: "noop",
1443
+ def: action,
1444
+ state: prior,
1445
+ downstream
1446
+ }];
1447
+ return [fqn, {
1448
+ kind: "action",
1449
+ action: "run",
1450
+ def: action,
1451
+ input: action.Input,
1452
+ state: prior,
1453
+ downstream,
1454
+ forced: !!options.force
1455
+ }];
1456
+ })), { concurrency: "unbounded" }));
1393
1457
  const cycleMembers = combinedCycleMembers;
1394
1458
  {
1395
1459
  const createReplaceNodes = new Set(Object.entries(resourceGraph).filter(([_, node]) => node.action === "create" || node.action === "replace").map(([fqn]) => fqn));
@@ -1418,16 +1482,47 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1418
1482
  }
1419
1483
  }
1420
1484
  }
1485
+ const actionDeletions = Object.fromEntries((yield* Effect.all((yield* state.list({
1486
+ stack: stackName,
1487
+ stage: stage$1
1488
+ })).map(Effect.fn("plan.diff.actionDeletion")(function* (fqn) {
1489
+ if (newActionFqns.has(fqn) || newResourceFqns.has(fqn)) return;
1490
+ const persisted = yield* state.get({
1491
+ stack: stackName,
1492
+ stage: stage$1,
1493
+ fqn
1494
+ });
1495
+ if (!isActionState(persisted)) return;
1496
+ const { logicalId } = parseFqn(fqn);
1497
+ return [fqn, {
1498
+ kind: "action",
1499
+ action: "delete",
1500
+ state: persisted,
1501
+ downstream: persisted.downstream ?? [],
1502
+ def: {
1503
+ Kind: "action",
1504
+ Namespace: persisted.namespace,
1505
+ FQN: fqn,
1506
+ LogicalId: logicalId,
1507
+ Type: persisted.actionType,
1508
+ Input: persisted.input,
1509
+ Run: () => void 0,
1510
+ Output: void 0
1511
+ }
1512
+ }];
1513
+ })), { concurrency: "unbounded" })).filter((v) => !!v));
1421
1514
  const deletions = Object.fromEntries((yield* Effect.all((yield* state.list({
1422
1515
  stack: stackName,
1423
1516
  stage: stage$1
1424
1517
  })).map(Effect.fn("plan.diff.deletion")(function* (fqn) {
1425
- if (newResourceFqns.has(fqn)) return;
1426
- const oldState = yield* state.get({
1518
+ if (newResourceFqns.has(fqn) || newActionFqns.has(fqn)) return;
1519
+ const persisted = yield* state.get({
1427
1520
  stack: stackName,
1428
1521
  stage: stage$1,
1429
1522
  fqn
1430
1523
  });
1524
+ if (isActionState(persisted)) return;
1525
+ const oldState = persisted;
1431
1526
  let attr = oldState?.attr;
1432
1527
  if (oldState) {
1433
1528
  const { logicalId } = parseFqn(fqn);
@@ -1480,7 +1575,9 @@ const make = (stack, options = {}) => Effect.gen(function* () {
1480
1575
  }
1481
1576
  return {
1482
1577
  resources: resourceGraph,
1578
+ actions: actionGraph,
1483
1579
  deletions,
1580
+ actionDeletions,
1484
1581
  output: stack.output,
1485
1582
  cycleMembers
1486
1583
  };
@@ -1546,14 +1643,20 @@ const apply = (plan) => Effect.gen(function* () {
1546
1643
  "alchemy.deletions.count": Object.keys(plan.deletions).length
1547
1644
  } }));
1548
1645
  const executePlan = Effect.fnUntraced(function* (plan, tracker, terminalStatuses, session, state, stackName, stage$1) {
1549
- const ready = Object.fromEntries(yield* Effect.all(Object.keys(plan.resources).map((fqn) => Effect.map(Deferred.make(), (d) => [fqn, d]))));
1646
+ const allNodes = {
1647
+ ...plan.resources,
1648
+ ...plan.actions
1649
+ };
1650
+ const ready = Object.fromEntries(yield* Effect.all(Object.keys(allNodes).map((fqn) => Effect.map(Deferred.make(), (d) => [fqn, d]))));
1651
+ const readyStable = Object.fromEntries(yield* Effect.all(Object.keys(allNodes).map((fqn) => Effect.map(Deferred.make(), (d) => [fqn, d]))));
1550
1652
  const getOutputs = () => Object.fromEntries(Object.entries(tracker).map(([fqn, t]) => [fqn, t.output]));
1551
1653
  const waitForDeps = (fqns) => Effect.all(fqns.filter((fqn) => fqn in ready).map((fqn) => Deferred.await(ready[fqn])), { concurrency: "unbounded" });
1654
+ const waitForStableDeps = (fqns) => Effect.all(fqns.filter((fqn) => fqn in readyStable).map((fqn) => Deferred.await(readyStable[fqn])), { concurrency: "unbounded" });
1552
1655
  const failures = [];
1553
- yield* Effect.all(Object.entries(plan.resources).map(([fqn, node]) => executeNode(fqn, node, tracker, ready, terminalStatuses, session, state, stackName, stage$1, getOutputs, waitForDeps, failures, plan.cycleMembers.has(fqn))), { concurrency: "unbounded" });
1656
+ yield* Effect.all(Object.entries(allNodes).map(([fqn, node]) => node.kind === "action" ? executeActionNode(fqn, node, tracker, ready, readyStable, terminalStatuses, session, state, stackName, stage$1, getOutputs, waitForStableDeps, failures) : executeNode(fqn, node, tracker, ready, readyStable, terminalStatuses, session, state, stackName, stage$1, getOutputs, waitForDeps, failures, plan.cycleMembers.has(fqn))), { concurrency: "unbounded" });
1554
1657
  if (failures.length > 0) yield* Effect.failCause(failures.map((f) => f.cause).reduce(Cause.combine));
1555
1658
  });
1556
- const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state, stackName, stage$1, getOutputs, waitForDeps, failures, inCycle) => Effect.gen(function* () {
1659
+ const executeNode = (fqn, node, tracker, ready, readyStable, terminalStatuses, session, state, stackName, stage$1, getOutputs, waitForDeps, failures, inCycle) => Effect.gen(function* () {
1557
1660
  const logicalId = node.resource.LogicalId;
1558
1661
  const namespace = node.resource.Namespace;
1559
1662
  const commit = (value) => state.set({
@@ -1587,11 +1690,13 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1587
1690
  });
1588
1691
  });
1589
1692
  const signalReady = Deferred.succeed(ready[fqn], void 0);
1693
+ const signalReadyStable = Deferred.succeed(readyStable[fqn], void 0);
1590
1694
  const storeAndSignal = (t) => Effect.gen(function* () {
1591
1695
  tracker[fqn] = t;
1592
1696
  yield* signalReady;
1593
1697
  });
1594
1698
  if (node.action === "noop") {
1699
+ yield* signalReadyStable;
1595
1700
  yield* storeAndSignal({
1596
1701
  output: node.state.attr,
1597
1702
  props: node.state.props,
@@ -1727,6 +1832,7 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1727
1832
  instanceId
1728
1833
  };
1729
1834
  yield* signalReady;
1835
+ yield* signalReadyStable;
1730
1836
  yield* markTerminal("created");
1731
1837
  return;
1732
1838
  }
@@ -1795,6 +1901,7 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1795
1901
  instanceId
1796
1902
  };
1797
1903
  yield* signalReady;
1904
+ yield* signalReadyStable;
1798
1905
  yield* markTerminal("updated");
1799
1906
  return;
1800
1907
  }
@@ -1807,6 +1914,7 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1807
1914
  instanceId
1808
1915
  };
1809
1916
  yield* signalReady;
1917
+ yield* signalReadyStable;
1810
1918
  yield* markTerminal("created");
1811
1919
  return;
1812
1920
  }
@@ -1901,6 +2009,7 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1901
2009
  instanceId
1902
2010
  };
1903
2011
  yield* signalReady;
2012
+ yield* signalReadyStable;
1904
2013
  yield* markTerminal("created");
1905
2014
  return;
1906
2015
  }
@@ -1914,6 +2023,7 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1914
2023
  cause
1915
2024
  });
1916
2025
  yield* Deferred.failCause(ready[fqn], cause);
2026
+ yield* Deferred.failCause(readyStable[fqn], cause);
1917
2027
  yield* session.emit({
1918
2028
  kind: "status-change",
1919
2029
  id: node.resource.LogicalId,
@@ -1926,6 +2036,104 @@ const executeNode = (fqn, node, tracker, ready, terminalStatuses, session, state
1926
2036
  "alchemy.resource.logical_id": node.resource.LogicalId,
1927
2037
  "alchemy.resource.action": node.action
1928
2038
  } }));
2039
+ const executeActionNode = (fqn, node, tracker, ready, readyStable, terminalStatuses, session, state, stackName, stage$1, getOutputs, waitForDeps, failures) => Effect.gen(function* () {
2040
+ const task = node.def;
2041
+ const logicalId = task.LogicalId;
2042
+ const namespace = task.Namespace;
2043
+ const commit = (value) => state.set({
2044
+ stack: stackName,
2045
+ stage: stage$1,
2046
+ fqn,
2047
+ value: {
2048
+ ...value,
2049
+ namespace
2050
+ }
2051
+ });
2052
+ const report = (status) => session.emit({
2053
+ kind: "status-change",
2054
+ id: logicalId,
2055
+ type: task.Type,
2056
+ status
2057
+ });
2058
+ const signalReady = Deferred.succeed(ready[fqn], void 0);
2059
+ const signalReadyStable = Deferred.succeed(readyStable[fqn], void 0);
2060
+ if (node.action === "noop") {
2061
+ tracker[fqn] = {
2062
+ output: node.state.output,
2063
+ props: { __input: node.state.input },
2064
+ bindings: [],
2065
+ instanceId: fqn
2066
+ };
2067
+ yield* signalReady;
2068
+ yield* signalReadyStable;
2069
+ terminalStatuses.set(fqn, {
2070
+ id: logicalId,
2071
+ type: task.Type,
2072
+ status: "skipped"
2073
+ });
2074
+ return;
2075
+ }
2076
+ yield* waitForDeps(Object.keys(resolveUpstream(node.input)).filter((f) => f in readyStable));
2077
+ const outputs = getOutputs();
2078
+ const resolvedInput = yield* evaluate(node.input, outputs);
2079
+ const inputHashValue = yield* hashInput(resolvedInput);
2080
+ yield* commit({
2081
+ kind: "action",
2082
+ status: "running",
2083
+ fqn,
2084
+ logicalId,
2085
+ actionType: task.Type,
2086
+ inputHash: inputHashValue,
2087
+ input: resolvedInput,
2088
+ downstream: node.downstream
2089
+ });
2090
+ yield* report("running");
2091
+ const result = yield* task.Run(resolvedInput);
2092
+ yield* commit({
2093
+ kind: "action",
2094
+ status: "ran",
2095
+ fqn,
2096
+ logicalId,
2097
+ actionType: task.Type,
2098
+ inputHash: inputHashValue,
2099
+ input: resolvedInput,
2100
+ output: result,
2101
+ downstream: node.downstream
2102
+ });
2103
+ tracker[fqn] = {
2104
+ output: result,
2105
+ props: { __input: resolvedInput },
2106
+ bindings: [],
2107
+ instanceId: fqn
2108
+ };
2109
+ yield* signalReady;
2110
+ yield* signalReadyStable;
2111
+ terminalStatuses.set(fqn, {
2112
+ id: logicalId,
2113
+ type: task.Type,
2114
+ status: "ran"
2115
+ });
2116
+ }).pipe(Effect.catchCause((cause) => Effect.gen(function* () {
2117
+ failures.push({
2118
+ fqn,
2119
+ logicalId: node.def.LogicalId,
2120
+ type: node.def.Type,
2121
+ cause
2122
+ });
2123
+ yield* Deferred.failCause(ready[fqn], cause);
2124
+ yield* Deferred.failCause(readyStable[fqn], cause);
2125
+ yield* session.emit({
2126
+ kind: "status-change",
2127
+ id: node.def.LogicalId,
2128
+ type: node.def.Type,
2129
+ status: "fail"
2130
+ });
2131
+ })), Effect.withSpan("apply.action", { attributes: {
2132
+ "alchemy.action.fqn": fqn,
2133
+ "alchemy.action.type": node.def.Type,
2134
+ "alchemy.action.logical_id": node.def.LogicalId,
2135
+ "alchemy.action.verb": node.action
2136
+ } }));
1929
2137
  const converge = Effect.fnUntraced(function* (plan, tracker, terminalStatuses, session, state, stackName, stage$1) {
1930
2138
  for (;;) {
1931
2139
  let anyUpdated = false;
@@ -1992,6 +2200,61 @@ const converge = Effect.fnUntraced(function* (plan, tracker, terminalStatuses, s
1992
2200
  status: "updated"
1993
2201
  });
1994
2202
  }
2203
+ for (const [fqn, node] of Object.entries(plan.actions)) {
2204
+ if (node.action !== "run") continue;
2205
+ if (!tracker[fqn]) continue;
2206
+ const outputs = Object.fromEntries(Object.entries(tracker).map(([k, t]) => [k, t.output]));
2207
+ const newInput = yield* evaluate(node.input, outputs);
2208
+ const newHash = yield* hashInput(newInput);
2209
+ const oldInput = tracker[fqn].props?.__input;
2210
+ if (newHash === (yield* hashInput(oldInput))) continue;
2211
+ anyUpdated = true;
2212
+ yield* state.set({
2213
+ stack: stackName,
2214
+ stage: stage$1,
2215
+ fqn,
2216
+ value: {
2217
+ kind: "action",
2218
+ status: "running",
2219
+ fqn,
2220
+ logicalId: node.def.LogicalId,
2221
+ namespace: node.def.Namespace,
2222
+ actionType: node.def.Type,
2223
+ inputHash: newHash,
2224
+ input: newInput,
2225
+ downstream: node.downstream
2226
+ }
2227
+ });
2228
+ const result = yield* node.def.Run(newInput);
2229
+ yield* state.set({
2230
+ stack: stackName,
2231
+ stage: stage$1,
2232
+ fqn,
2233
+ value: {
2234
+ kind: "action",
2235
+ status: "ran",
2236
+ fqn,
2237
+ logicalId: node.def.LogicalId,
2238
+ namespace: node.def.Namespace,
2239
+ actionType: node.def.Type,
2240
+ inputHash: newHash,
2241
+ input: newInput,
2242
+ output: result,
2243
+ downstream: node.downstream
2244
+ }
2245
+ });
2246
+ tracker[fqn] = {
2247
+ output: result,
2248
+ props: { __input: newInput },
2249
+ bindings: [],
2250
+ instanceId: fqn
2251
+ };
2252
+ terminalStatuses.set(fqn, {
2253
+ id: node.def.LogicalId,
2254
+ type: node.def.Type,
2255
+ status: "ran"
2256
+ });
2257
+ }
1995
2258
  if (!anyUpdated) break;
1996
2259
  }
1997
2260
  });
@@ -1999,6 +2262,25 @@ const collectGarbage = Effect.fnUntraced(function* (plan, session) {
1999
2262
  const state = yield* State;
2000
2263
  const stackName = (yield* Stack).name;
2001
2264
  const stage$1 = yield* Stage;
2265
+ yield* Effect.all(Object.entries(plan.actionDeletions ?? {}).map(([fqn, node]) => node === void 0 ? Effect.void : Effect.gen(function* () {
2266
+ yield* session.emit({
2267
+ kind: "status-change",
2268
+ id: node.def.LogicalId,
2269
+ type: node.def.Type,
2270
+ status: "deleting"
2271
+ });
2272
+ yield* state.delete({
2273
+ stack: stackName,
2274
+ stage: stage$1,
2275
+ fqn
2276
+ });
2277
+ yield* session.emit({
2278
+ kind: "status-change",
2279
+ id: node.def.LogicalId,
2280
+ type: node.def.Type,
2281
+ status: "deleted"
2282
+ });
2283
+ })), { concurrency: "unbounded" });
2002
2284
  const deleteGraph = Effect.fnUntraced(function* (deletionGraph) {
2003
2285
  const deletions = {};
2004
2286
  const deleteResource = (node, ancestors = /* @__PURE__ */ new Set()) => Effect.gen(function* () {
@@ -2153,10 +2435,10 @@ var __rewriteRelativeImportExtension = void 0 && (void 0).__rewriteRelativeImpor
2153
2435
  return path$1;
2154
2436
  };
2155
2437
  const USER = Config.string("USER").pipe(Config.orElse(() => Config.string("USERNAME")), Config.withDefault("unknown"));
2156
- const STAGE = Config.string("stage").pipe(Config.option, (a) => a.asEffect(), Effect.map(Option.getOrUndefined));
2438
+ const STAGE = Config.string("stage").pipe(Config.option, (a) => a, Effect.map(Option.getOrUndefined));
2157
2439
  const stage = Flag.string("stage").pipe(Flag.withSchema(S.String.check(S.isPattern(/^[a-z0-9]+([-_a-z0-9]+)*$/gi))), Flag.withDescription("Stage to deploy to, defaults to dev_${USER}"), Flag.optional, Flag.map(Option.getOrUndefined), Flag.mapEffect(Effect.fn(function* (stage$1) {
2158
2440
  if (stage$1) return stage$1;
2159
- return yield* STAGE.pipe(Effect.catch(() => Effect.fail(new CliError.MissingOption({ option: "stage" }))), Effect.flatMap((s) => s === void 0 ? USER.asEffect().pipe(Effect.map((user) => `dev_${user}`), Effect.catch(() => Effect.succeed("unknown"))) : Effect.succeed(s)));
2441
+ return yield* STAGE.pipe(Effect.catch(() => Effect.fail(new CliError.MissingOption({ option: "stage" }))), Effect.flatMap((s) => s === void 0 ? USER.pipe(Effect.map((user) => `dev_${user}`), Effect.catch(() => Effect.succeed("unknown"))) : Effect.succeed(s)));
2160
2442
  })));
2161
2443
  const envFile = Flag.file("env-file").pipe(Flag.optional, Flag.withDescription("File to load environment variables from, defaults to .env"));
2162
2444
  const dryRun = Flag.boolean("dry-run").pipe(Flag.withDescription("Dry run the deployment, do not actually deploy"), Flag.withDefault(false));
@@ -2219,7 +2501,7 @@ const stackSpanAttrs = (args) => ({
2219
2501
  const adopt = Flag.boolean("adopt").pipe(Flag.withDescription("Adopt pre-existing cloud resources that conflict with this stack instead of failing. Useful for re-importing infrastructure into a fresh state store."), Flag.withDefault(false));
2220
2502
  const execStack = Effect.fn(function* ({ main, stage: stage$1, envFile: envFile$1, profile: profile$1, dryRun: dryRun$1 = false, force: force$1 = false, yes: yes$1 = false, destroy = false, dev = false, adopt: adopt$1 = false }) {
2221
2503
  const stackEffect = yield* importStack(main);
2222
- const services$1 = Layer.mergeAll(Layer.effect(AlchemyContext, AlchemyContext.asEffect().pipe(Effect.map((ctx) => ({
2504
+ const services$1 = Layer.mergeAll(Layer.effect(AlchemyContext, AlchemyContext.pipe(Effect.map((ctx) => ({
2223
2505
  ...ctx,
2224
2506
  dev,
2225
2507
  adopt: adopt$1
@@ -2373,12 +2655,13 @@ const LoggingCli = Layer.succeed(Cli, Cli.of({
2373
2655
 
2374
2656
  //#endregion
2375
2657
  //#region lib/Cli/NamespaceTree.js
2376
- function buildNamespaceTree(items) {
2658
+ function buildNamespaceTree(items, actions = []) {
2377
2659
  const root = {
2378
2660
  id: "",
2379
2661
  path: [],
2380
2662
  children: /* @__PURE__ */ new Map(),
2381
- resources: []
2663
+ resources: [],
2664
+ actions: []
2382
2665
  };
2383
2666
  const getNode = (path$1) => {
2384
2667
  let current = root;
@@ -2390,7 +2673,8 @@ function buildNamespaceTree(items) {
2390
2673
  id: segment,
2391
2674
  path: path$1.slice(0, i + 1),
2392
2675
  children: /* @__PURE__ */ new Map(),
2393
- resources: []
2676
+ resources: [],
2677
+ actions: []
2394
2678
  };
2395
2679
  current.children.set(segment, child);
2396
2680
  }
@@ -2399,11 +2683,13 @@ function buildNamespaceTree(items) {
2399
2683
  return current;
2400
2684
  };
2401
2685
  for (const item of items) getNode(toPath(item.resource.Namespace)).resources.push(item);
2686
+ for (const action of actions) getNode(toPath(action.def.Namespace)).actions.push(action);
2402
2687
  return root;
2403
2688
  }
2404
2689
  function deriveNamespaceAction(node) {
2405
2690
  const actions = /* @__PURE__ */ new Set();
2406
2691
  for (const resource of node.resources) actions.add(deriveResourceChildrenAction(resource, node));
2692
+ for (const action of node.actions) actions.add(action.action === "run" ? "create" : action.action === "delete" ? "delete" : "noop");
2407
2693
  for (const child of node.children.values()) {
2408
2694
  const childAction = deriveNamespaceAction(child);
2409
2695
  if (childAction === "mixed") return "mixed";
@@ -2456,8 +2742,17 @@ const flattenNamespace = (node, depth, result) => {
2456
2742
  });
2457
2743
  if (childNamespace) flattenNamespace(childNamespace, depth + 1, result);
2458
2744
  }
2745
+ const sortedActions = [...node.actions].sort((a, b) => a.def.LogicalId.localeCompare(b.def.LogicalId));
2746
+ for (const action of sortedActions) result.push({
2747
+ type: "action",
2748
+ depth,
2749
+ id: action.def.LogicalId,
2750
+ path: [...node.path, action.def.LogicalId],
2751
+ action: action.action,
2752
+ actionType: action.def.Type
2753
+ });
2459
2754
  };
2460
- const isEmpty = (node) => node.resources.length === 0 && Array.from(node.children.values()).every(isEmpty);
2755
+ const isEmpty = (node) => node.resources.length === 0 && node.actions.length === 0 && Array.from(node.children.values()).every(isEmpty);
2461
2756
  const deriveResourceChildrenAction = (resource, node) => {
2462
2757
  const actions = new Set([resource.action]);
2463
2758
  for (const binding of resource.bindings) actions.add(binding.action);
@@ -2478,10 +2773,11 @@ const deriveAction = (actions) => {
2478
2773
  //#region lib/Cli/tui/components/Plan.js
2479
2774
  function Plan({ plan }) {
2480
2775
  const items = useMemo(() => [...Object.values(plan.resources), ...Object.values(plan.deletions)], [plan]);
2776
+ const taskItems = useMemo(() => [...Object.values(plan.actions ?? {}), ...Object.values(plan.actionDeletions ?? {})].filter((t) => t !== void 0), [plan]);
2481
2777
  const flatItems = useMemo(() => {
2482
- return flattenTree(buildNamespaceTree(items));
2483
- }, [items]);
2484
- if (items.length === 0) return jsx(Text, {
2778
+ return flattenTree(buildNamespaceTree(items, taskItems));
2779
+ }, [items, taskItems]);
2780
+ if (items.length === 0 && taskItems.length === 0) return jsx(Text, {
2485
2781
  color: "gray",
2486
2782
  children: "No changes planned"
2487
2783
  });
@@ -2492,12 +2788,18 @@ function Plan({ plan }) {
2492
2788
  noop: 0,
2493
2789
  replace: 0
2494
2790
  });
2791
+ const taskCounts = taskItems.reduce((acc, item) => (acc[item.action]++, acc), {
2792
+ run: 0,
2793
+ noop: 0,
2794
+ delete: 0
2795
+ });
2495
2796
  const actions = [
2496
2797
  "create",
2497
2798
  "update",
2498
2799
  "delete",
2499
2800
  "replace"
2500
2801
  ].filter((action) => counts[action] > 0);
2802
+ const taskHeaderEntries = [taskCounts.run > 0 ? `${taskCounts.run} to run` : void 0, taskCounts.delete > 0 ? `${taskCounts.delete} to drop` : void 0].filter((s) => !!s);
2501
2803
  return jsxs(Box, {
2502
2804
  flexDirection: "column",
2503
2805
  children: [jsxs(Box, {
@@ -2508,20 +2810,20 @@ function Plan({ plan }) {
2508
2810
  children: "Plan"
2509
2811
  }),
2510
2812
  jsx(Text, { children: ": " }),
2511
- actions.flatMap((action, i) => {
2813
+ [...actions.map((action) => {
2512
2814
  const count = counts[action];
2513
- const color = actionColor(action);
2514
- if (count === 0) return [];
2515
- const box = jsx(Box, { children: jsxs(Text, {
2516
- color,
2815
+ return jsx(Box, { children: jsxs(Text, {
2816
+ color: actionColor(action),
2517
2817
  children: [
2518
2818
  count,
2519
2819
  " to ",
2520
2820
  action
2521
2821
  ]
2522
2822
  }) }, action);
2523
- return i === actions.length - 1 ? [box] : [box, jsx(Text, { children: " | " }, `${action}-separator`)];
2524
- })
2823
+ }), ...taskHeaderEntries.map((label, i) => jsx(Box, { children: jsx(Text, {
2824
+ color: "cyan",
2825
+ children: label
2826
+ }) }, `task-${i}`))].flatMap((box, i, arr) => i === arr.length - 1 ? [box] : [box, jsx(Text, { children: " | " }, `sep-${i}`)])
2525
2827
  ]
2526
2828
  }), jsx(Box, {
2527
2829
  flexDirection: "column",
@@ -2565,6 +2867,41 @@ function Plan({ plan }) {
2565
2867
  })
2566
2868
  ]
2567
2869
  }, key);
2870
+ if (item.type === "action") return jsxs(Box, {
2871
+ flexDirection: "row",
2872
+ children: [
2873
+ jsx(Text, { children: indent }),
2874
+ jsx(Box, {
2875
+ width: 2,
2876
+ children: jsxs(Text, {
2877
+ color,
2878
+ children: [icon, " "]
2879
+ })
2880
+ }),
2881
+ jsx(Box, { children: jsx(Text, {
2882
+ bold: true,
2883
+ children: item.id
2884
+ }) }),
2885
+ jsx(Box, {
2886
+ marginLeft: 1,
2887
+ children: jsxs(Text, {
2888
+ color: "blackBright",
2889
+ children: [
2890
+ "(",
2891
+ item.actionType,
2892
+ ")"
2893
+ ]
2894
+ })
2895
+ }),
2896
+ jsx(Box, {
2897
+ marginLeft: 1,
2898
+ children: jsx(Text, {
2899
+ color: "cyan",
2900
+ children: "[action]"
2901
+ })
2902
+ })
2903
+ ]
2904
+ }, key);
2568
2905
  return jsxs(Box, {
2569
2906
  flexDirection: "row",
2570
2907
  children: [
@@ -2614,7 +2951,8 @@ const getActionColor = (action) => ({
2614
2951
  update: "yellow",
2615
2952
  delete: "red",
2616
2953
  replace: "magenta",
2617
- mixed: "cyan"
2954
+ mixed: "cyan",
2955
+ run: "cyan"
2618
2956
  })[action] ?? "gray";
2619
2957
  const getActionIcon = (action) => ({
2620
2958
  create: "+",
@@ -2622,7 +2960,8 @@ const getActionIcon = (action) => ({
2622
2960
  delete: "-",
2623
2961
  noop: "•",
2624
2962
  replace: "!",
2625
- mixed: "*"
2963
+ mixed: "*",
2964
+ run: "λ"
2626
2965
  })[action] ?? "?";
2627
2966
  const actionColor = (action) => getActionColor(action);
2628
2967
 
@@ -2665,29 +3004,40 @@ function ApprovePlan(props) {
2665
3004
  //#region lib/Cli/tui/components/PlanProgress.js
2666
3005
  const getTaskKey = (item) => item.path.join("/");
2667
3006
  const buildProgressRows = (plan) => {
2668
- return flattenTree(buildNamespaceTree([...Object.values(plan.resources), ...Object.values(plan.deletions).filter((item) => item !== void 0)])).filter((item) => item.type !== "binding").map((item) => item.type === "namespace" ? {
2669
- key: getTaskKey(item),
2670
- type: "namespace",
2671
- id: item.id,
2672
- depth: item.depth,
2673
- action: item.action
2674
- } : {
2675
- key: getTaskKey(item),
2676
- type: "resource",
2677
- id: item.id,
2678
- depth: item.depth,
2679
- resourceType: item.resourceType ?? "unknown",
2680
- action: item.action,
2681
- persistedApplyStatus: item.action === "noop" ? (() => {
2682
- const crud = findCrudByLogicalId(plan, item.id);
2683
- return crud?.action === "noop" ? crud.state.status : void 0;
2684
- })() : void 0
3007
+ return flattenTree(buildNamespaceTree([...Object.values(plan.resources), ...Object.values(plan.deletions).filter((item) => item !== void 0)], [...Object.values(plan.actions ?? {}), ...Object.values(plan.actionDeletions ?? {})].filter((t) => t !== void 0))).filter((item) => item.type !== "binding").map((item) => {
3008
+ if (item.type === "namespace") return {
3009
+ key: getTaskKey(item),
3010
+ type: "namespace",
3011
+ id: item.id,
3012
+ depth: item.depth,
3013
+ action: item.action
3014
+ };
3015
+ if (item.type === "action") return {
3016
+ key: getTaskKey(item),
3017
+ type: "task",
3018
+ id: item.id,
3019
+ depth: item.depth,
3020
+ actionType: item.actionType ?? "unknown",
3021
+ action: item.action
3022
+ };
3023
+ return {
3024
+ key: getTaskKey(item),
3025
+ type: "resource",
3026
+ id: item.id,
3027
+ depth: item.depth,
3028
+ resourceType: item.resourceType ?? "unknown",
3029
+ action: item.action,
3030
+ persistedApplyStatus: item.action === "noop" ? (() => {
3031
+ const crud = findCrudByLogicalId(plan, item.id);
3032
+ return crud?.action === "noop" ? crud.state.status : void 0;
3033
+ })() : void 0
3034
+ };
2685
3035
  });
2686
3036
  };
2687
3037
  const buildLogicalIdIndex = (rows) => {
2688
3038
  const index = /* @__PURE__ */ new Map();
2689
3039
  for (const row of rows) {
2690
- if (row.type !== "resource") continue;
3040
+ if (row.type !== "resource" && row.type !== "task") continue;
2691
3041
  const keys = index.get(row.id);
2692
3042
  if (keys) keys.push(row.key);
2693
3043
  else index.set(row.id, [row.key]);
@@ -2710,7 +3060,13 @@ function toPlanTask(rowOrId, planItem) {
2710
3060
  updatedAt: Date.now()
2711
3061
  };
2712
3062
  }
2713
- const buildInitialTasks = (rows) => new Map(rows.flatMap((row) => row.type === "resource" ? [[row.key, toPlanTask(row)]] : []));
3063
+ const buildInitialTasks = (rows) => new Map(rows.flatMap((row) => row.type === "resource" ? [[row.key, toPlanTask(row)]] : row.type === "task" ? [[row.key, {
3064
+ key: row.key,
3065
+ id: row.id,
3066
+ type: row.actionType,
3067
+ status: row.action === "noop" ? "skipped" : "pending",
3068
+ updatedAt: Date.now()
3069
+ }]] : []));
2714
3070
  function PlanProgress(props) {
2715
3071
  const { source, plan } = props;
2716
3072
  const spinner = useGlobalSpinner();
@@ -2777,6 +3133,56 @@ function PlanProgress(props) {
2777
3133
  })
2778
3134
  ]
2779
3135
  }, row.key);
3136
+ if (row.type === "task") {
3137
+ const t = tasks.get(row.key);
3138
+ const status = t?.status ?? (row.action === "noop" ? "ran" : "pending");
3139
+ const color$1 = statusColor(status);
3140
+ const icon$1 = taskIcon(row.action, status, spinner);
3141
+ const label = row.action === "delete" ? status === "deleted" ? "deleted" : "drop" : status === "ran" ? row.action === "noop" ? "skip" : "ran" : status === "running" ? "running" : status === "fail" ? "fail" : row.action === "noop" ? "skip" : "run";
3142
+ return jsxs(Box, {
3143
+ flexDirection: "column",
3144
+ children: [jsxs(Box, {
3145
+ flexDirection: "row",
3146
+ children: [
3147
+ jsx(Text, { children: indent }),
3148
+ jsx(Box, {
3149
+ width: 2,
3150
+ children: jsxs(Text, {
3151
+ color: color$1,
3152
+ children: [icon$1, " "]
3153
+ })
3154
+ }),
3155
+ jsx(Text, {
3156
+ bold: true,
3157
+ children: row.id
3158
+ }),
3159
+ jsxs(Text, {
3160
+ dimColor: true,
3161
+ children: [
3162
+ " (",
3163
+ row.actionType,
3164
+ ")"
3165
+ ]
3166
+ }),
3167
+ jsxs(Text, {
3168
+ color: color$1,
3169
+ children: [" ", label]
3170
+ }),
3171
+ jsxs(Text, {
3172
+ color: "cyan",
3173
+ dimColor: true,
3174
+ children: [" ", "[action]"]
3175
+ })
3176
+ ]
3177
+ }), t?.message ? jsx(Box, {
3178
+ paddingLeft: row.depth * 2 + 2,
3179
+ children: jsxs(Text, {
3180
+ dimColor: true,
3181
+ children: ["• ", t.message]
3182
+ })
3183
+ }) : null]
3184
+ }, row.key);
3185
+ }
2780
3186
  const task = tasks.get(row.key) ?? toPlanTask(row);
2781
3187
  const displayStatus = getDisplayStatus(row, task.status);
2782
3188
  const color = statusColor(displayStatus);
@@ -2836,17 +3242,30 @@ function statusColor(status) {
2836
3242
  case "updated": return "yellow";
2837
3243
  case "deleting":
2838
3244
  case "deleted": return "red";
3245
+ case "running":
3246
+ case "ran": return "cyan";
3247
+ case "skipped": return "gray";
2839
3248
  case "fail": return "redBright";
2840
3249
  default: return;
2841
3250
  }
2842
3251
  }
3252
+ function taskIcon(action, status, spinnerChar) {
3253
+ if (status === "running") return spinnerChar;
3254
+ if (status === "fail") return "✗";
3255
+ if (status === "skipped") return "•";
3256
+ if (status === "ran") return action === "noop" ? "•" : "✓";
3257
+ if (status === "deleted") return "✓";
3258
+ if (action === "delete") return "-";
3259
+ if (action === "noop") return "•";
3260
+ return "λ";
3261
+ }
2843
3262
  function statusIcon(status, spinnerChar) {
2844
3263
  if (isInProgress(status)) return spinnerChar;
2845
3264
  if (status === "fail") return "✗";
2846
3265
  return "✓";
2847
3266
  }
2848
3267
  function isInProgress(status) {
2849
- return status === "pending" || status === "creating" || status === "updating" || status === "deleting";
3268
+ return status === "pending" || status === "creating" || status === "updating" || status === "deleting" || status === "running";
2850
3269
  }
2851
3270
  const spinnerFrames = [
2852
3271
  "⠋",