primitive-admin 1.1.0-alpha.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (591) hide show
  1. package/README.md +523 -109
  2. package/assets/skill/skills/primitive-platform/SKILL.md +289 -0
  3. package/dist/bin/primitive.d.ts +2 -0
  4. package/dist/bin/primitive.js +372 -21
  5. package/dist/bin/primitive.js.map +1 -1
  6. package/dist/src/commands/admins.d.ts +2 -0
  7. package/dist/src/commands/admins.js +136 -30
  8. package/dist/src/commands/admins.js.map +1 -1
  9. package/dist/src/commands/analytics.d.ts +2 -0
  10. package/dist/src/commands/analytics.js +713 -55
  11. package/dist/src/commands/analytics.js.map +1 -1
  12. package/dist/src/commands/apps.d.ts +2 -0
  13. package/dist/src/commands/apps.js +65 -100
  14. package/dist/src/commands/apps.js.map +1 -1
  15. package/dist/src/commands/auth-sessions.d.ts +7 -0
  16. package/dist/src/commands/auth-sessions.js +144 -0
  17. package/dist/src/commands/auth-sessions.js.map +1 -0
  18. package/dist/src/commands/auth.d.ts +2 -0
  19. package/dist/src/commands/auth.js +238 -108
  20. package/dist/src/commands/auth.js.map +1 -1
  21. package/dist/src/commands/blob-buckets.d.ts +2 -0
  22. package/dist/src/commands/blob-buckets.js +331 -0
  23. package/dist/src/commands/blob-buckets.js.map +1 -0
  24. package/dist/src/commands/catalog.d.ts +2 -0
  25. package/dist/src/commands/catalog.js +63 -48
  26. package/dist/src/commands/catalog.js.map +1 -1
  27. package/dist/src/commands/collection-type-configs.d.ts +2 -0
  28. package/dist/src/commands/collection-type-configs.js +85 -0
  29. package/dist/src/commands/collection-type-configs.js.map +1 -0
  30. package/dist/src/commands/collections.d.ts +2 -0
  31. package/dist/src/commands/collections.js +1282 -0
  32. package/dist/src/commands/collections.js.map +1 -0
  33. package/dist/src/commands/comparisons.d.ts +2 -0
  34. package/dist/src/commands/comparisons.js +6 -6
  35. package/dist/src/commands/comparisons.js.map +1 -1
  36. package/dist/src/commands/config.d.ts +46 -0
  37. package/dist/src/commands/config.js +465 -0
  38. package/dist/src/commands/config.js.map +1 -0
  39. package/dist/src/commands/connections.d.ts +2 -0
  40. package/dist/src/commands/connections.js +99 -0
  41. package/dist/src/commands/connections.js.map +1 -0
  42. package/dist/src/commands/cron-triggers.d.ts +2 -0
  43. package/dist/src/commands/cron-triggers.js +266 -0
  44. package/dist/src/commands/cron-triggers.js.map +1 -0
  45. package/dist/src/commands/database-type-configs.d.ts +2 -0
  46. package/dist/src/commands/database-type-configs.js +164 -0
  47. package/dist/src/commands/database-type-configs.js.map +1 -0
  48. package/dist/src/commands/database-types.d.ts +2 -0
  49. package/dist/src/commands/database-types.js +471 -0
  50. package/dist/src/commands/database-types.js.map +1 -0
  51. package/dist/src/commands/databases.d.ts +65 -0
  52. package/dist/src/commands/databases.js +1887 -243
  53. package/dist/src/commands/databases.js.map +1 -1
  54. package/dist/src/commands/documents.d.ts +60 -0
  55. package/dist/src/commands/documents.js +2888 -22
  56. package/dist/src/commands/documents.js.map +1 -1
  57. package/dist/src/commands/email-templates.d.ts +2 -0
  58. package/dist/src/commands/email-templates.js +175 -0
  59. package/dist/src/commands/email-templates.js.map +1 -0
  60. package/dist/src/commands/env.d.ts +23 -0
  61. package/dist/src/commands/env.js +395 -0
  62. package/dist/src/commands/env.js.map +1 -0
  63. package/dist/src/commands/feature-flags.d.ts +14 -0
  64. package/dist/src/commands/feature-flags.js +117 -0
  65. package/dist/src/commands/feature-flags.js.map +1 -0
  66. package/dist/src/commands/functions.d.ts +20 -0
  67. package/dist/src/commands/functions.js +1630 -0
  68. package/dist/src/commands/functions.js.map +1 -0
  69. package/dist/src/commands/group-type-configs.d.ts +2 -0
  70. package/dist/src/commands/group-type-configs.js +87 -0
  71. package/dist/src/commands/group-type-configs.js.map +1 -0
  72. package/dist/src/commands/groups.d.ts +2 -0
  73. package/dist/src/commands/groups.js +65 -113
  74. package/dist/src/commands/groups.js.map +1 -1
  75. package/dist/src/commands/guides.d.ts +223 -0
  76. package/dist/src/commands/guides.js +627 -69
  77. package/dist/src/commands/guides.js.map +1 -1
  78. package/dist/src/commands/init.d.ts +37 -0
  79. package/dist/src/commands/init.js +1693 -208
  80. package/dist/src/commands/init.js.map +1 -1
  81. package/dist/src/commands/integrations.d.ts +2 -0
  82. package/dist/src/commands/integrations.js +428 -187
  83. package/dist/src/commands/integrations.js.map +1 -1
  84. package/dist/src/commands/llm.d.ts +2 -0
  85. package/dist/src/commands/llm.js +4 -2
  86. package/dist/src/commands/llm.js.map +1 -1
  87. package/dist/src/commands/locks.d.ts +8 -0
  88. package/dist/src/commands/locks.js +175 -0
  89. package/dist/src/commands/locks.js.map +1 -0
  90. package/dist/src/commands/metadata-category-configs.d.ts +12 -0
  91. package/dist/src/commands/metadata-category-configs.js +113 -0
  92. package/dist/src/commands/metadata-category-configs.js.map +1 -0
  93. package/dist/src/commands/metadata.d.ts +2 -0
  94. package/dist/src/commands/metadata.js +288 -0
  95. package/dist/src/commands/metadata.js.map +1 -0
  96. package/dist/src/commands/prompts.d.ts +2 -0
  97. package/dist/src/commands/prompts.js +322 -634
  98. package/dist/src/commands/prompts.js.map +1 -1
  99. package/dist/src/commands/rule-sets.d.ts +3 -0
  100. package/dist/src/commands/rule-sets.js +139 -148
  101. package/dist/src/commands/rule-sets.js.map +1 -1
  102. package/dist/src/commands/scripts.d.ts +30 -0
  103. package/dist/src/commands/scripts.js +688 -0
  104. package/dist/src/commands/scripts.js.map +1 -0
  105. package/dist/src/commands/secrets.d.ts +2 -0
  106. package/dist/src/commands/secrets.js +109 -0
  107. package/dist/src/commands/secrets.js.map +1 -0
  108. package/dist/src/commands/sessions.d.ts +2 -0
  109. package/dist/src/commands/sessions.js +76 -0
  110. package/dist/src/commands/sessions.js.map +1 -0
  111. package/dist/src/commands/skill.d.ts +2 -0
  112. package/dist/src/commands/skill.js +29 -0
  113. package/dist/src/commands/skill.js.map +1 -0
  114. package/dist/src/commands/sync-app-settings.d.ts +158 -0
  115. package/dist/src/commands/sync-app-settings.js +328 -0
  116. package/dist/src/commands/sync-app-settings.js.map +1 -0
  117. package/dist/src/commands/sync.d.ts +2670 -0
  118. package/dist/src/commands/sync.js +17144 -834
  119. package/dist/src/commands/sync.js.map +1 -1
  120. package/dist/src/commands/tokens.d.ts +2 -0
  121. package/dist/src/commands/tokens.js +132 -22
  122. package/dist/src/commands/tokens.js.map +1 -1
  123. package/dist/src/commands/users.d.ts +2 -0
  124. package/dist/src/commands/users.js +542 -24
  125. package/dist/src/commands/users.js.map +1 -1
  126. package/dist/src/commands/vars.d.ts +8 -0
  127. package/dist/src/commands/vars.js +97 -0
  128. package/dist/src/commands/vars.js.map +1 -0
  129. package/dist/src/commands/waitlist.d.ts +2 -0
  130. package/dist/src/commands/waitlist.js +12 -11
  131. package/dist/src/commands/waitlist.js.map +1 -1
  132. package/dist/src/commands/webhooks.d.ts +31 -0
  133. package/dist/src/commands/webhooks.js +633 -0
  134. package/dist/src/commands/webhooks.js.map +1 -0
  135. package/dist/src/commands/workflows.d.ts +88 -0
  136. package/dist/src/commands/workflows.js +1568 -742
  137. package/dist/src/commands/workflows.js.map +1 -1
  138. package/dist/src/lib/access-rule-display.d.ts +21 -0
  139. package/dist/src/lib/access-rule-display.js +34 -0
  140. package/dist/src/lib/access-rule-display.js.map +1 -0
  141. package/dist/src/lib/api-client.d.ts +2550 -0
  142. package/dist/src/lib/api-client.js +2503 -160
  143. package/dist/src/lib/api-client.js.map +1 -1
  144. package/dist/src/lib/app-settings-descriptor.d.ts +263 -0
  145. package/dist/src/lib/app-settings-descriptor.js +583 -0
  146. package/dist/src/lib/app-settings-descriptor.js.map +1 -0
  147. package/dist/src/lib/auth-flow.d.ts +8 -0
  148. package/dist/src/lib/batch.d.ts +26 -0
  149. package/dist/src/lib/batch.js +32 -0
  150. package/dist/src/lib/batch.js.map +1 -0
  151. package/dist/src/lib/block-layout.d.ts +160 -0
  152. package/dist/src/lib/block-layout.js +451 -0
  153. package/dist/src/lib/block-layout.js.map +1 -0
  154. package/dist/src/lib/block-selector.d.ts +58 -0
  155. package/dist/src/lib/block-selector.js +92 -0
  156. package/dist/src/lib/block-selector.js.map +1 -0
  157. package/dist/src/lib/canonical-json.d.ts +12 -0
  158. package/dist/src/lib/canonical-json.js +35 -0
  159. package/dist/src/lib/canonical-json.js.map +1 -0
  160. package/dist/src/lib/channel.d.ts +30 -0
  161. package/dist/src/lib/channel.js +68 -0
  162. package/dist/src/lib/channel.js.map +1 -0
  163. package/dist/src/lib/cli-manifest.d.ts +68 -0
  164. package/dist/src/lib/cli-manifest.js +71 -0
  165. package/dist/src/lib/cli-manifest.js.map +1 -0
  166. package/dist/src/lib/codegen-shared/generatedFiles.d.ts +101 -0
  167. package/dist/src/lib/codegen-shared/generatedFiles.js +191 -0
  168. package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -0
  169. package/dist/src/lib/codegen-shared/prettierStable.d.ts +262 -0
  170. package/dist/src/lib/codegen-shared/prettierStable.js +610 -0
  171. package/dist/src/lib/codegen-shared/prettierStable.js.map +1 -0
  172. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +38 -0
  173. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +46 -0
  174. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -0
  175. package/dist/src/lib/collection-export.d.ts +184 -0
  176. package/dist/src/lib/collection-export.js +252 -0
  177. package/dist/src/lib/collection-export.js.map +1 -0
  178. package/dist/src/lib/config-json-field.d.ts +28 -0
  179. package/dist/src/lib/config-json-field.js +56 -0
  180. package/dist/src/lib/config-json-field.js.map +1 -0
  181. package/dist/src/lib/config-object-descriptor.d.ts +127 -0
  182. package/dist/src/lib/config-object-descriptor.js +740 -0
  183. package/dist/src/lib/config-object-descriptor.js.map +1 -0
  184. package/dist/src/lib/config-payload.d.ts +92 -0
  185. package/dist/src/lib/config-payload.js +161 -0
  186. package/dist/src/lib/config-payload.js.map +1 -0
  187. package/dist/src/lib/config-surface.d.ts +141 -0
  188. package/dist/src/lib/config-surface.js +368 -0
  189. package/dist/src/lib/config-surface.js.map +1 -0
  190. package/dist/src/lib/config-toml.d.ts +10 -0
  191. package/dist/src/lib/config-toml.js +42 -0
  192. package/dist/src/lib/config-toml.js.map +1 -0
  193. package/dist/src/lib/config.d.ts +71 -0
  194. package/dist/src/lib/config.js +71 -68
  195. package/dist/src/lib/config.js.map +1 -1
  196. package/dist/src/lib/confirm-prompt.d.ts +83 -0
  197. package/dist/src/lib/confirm-prompt.js +110 -0
  198. package/dist/src/lib/confirm-prompt.js.map +1 -0
  199. package/dist/src/lib/constants.d.ts +11 -0
  200. package/dist/src/lib/constants.js +12 -0
  201. package/dist/src/lib/constants.js.map +1 -0
  202. package/dist/src/lib/crash-handlers.d.ts +20 -0
  203. package/dist/src/lib/crash-handlers.js +49 -0
  204. package/dist/src/lib/crash-handlers.js.map +1 -0
  205. package/dist/src/lib/credentials-store.d.ts +104 -0
  206. package/dist/src/lib/credentials-store.js +336 -0
  207. package/dist/src/lib/credentials-store.js.map +1 -0
  208. package/dist/src/lib/csv.d.ts +47 -0
  209. package/dist/src/lib/csv.js +172 -0
  210. package/dist/src/lib/csv.js.map +1 -0
  211. package/dist/src/lib/data-input.d.ts +23 -0
  212. package/dist/src/lib/data-input.js +50 -0
  213. package/dist/src/lib/data-input.js.map +1 -0
  214. package/dist/src/lib/db-codegen/dbFingerprint.d.ts +10 -0
  215. package/dist/src/lib/db-codegen/dbFingerprint.js +17 -0
  216. package/dist/src/lib/db-codegen/dbFingerprint.js.map +1 -0
  217. package/dist/src/lib/db-codegen/dbGenerator.d.ts +67 -0
  218. package/dist/src/lib/db-codegen/dbGenerator.js +170 -0
  219. package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -0
  220. package/dist/src/lib/db-codegen/dbNaming.d.ts +87 -0
  221. package/dist/src/lib/db-codegen/dbNaming.js +180 -0
  222. package/dist/src/lib/db-codegen/dbNaming.js.map +1 -0
  223. package/dist/src/lib/db-codegen/dbTemplates.d.ts +272 -0
  224. package/dist/src/lib/db-codegen/dbTemplates.js +480 -0
  225. package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -0
  226. package/dist/src/lib/db-codegen/dbTsTypes.d.ts +73 -0
  227. package/dist/src/lib/db-codegen/dbTsTypes.js +139 -0
  228. package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -0
  229. package/dist/src/lib/db-codegen/dbTypeIR.d.ts +146 -0
  230. package/dist/src/lib/db-codegen/dbTypeIR.js +525 -0
  231. package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -0
  232. package/dist/src/lib/db-codegen/generated-operation-def-descriptor.d.ts +112 -0
  233. package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js +211 -0
  234. package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js.map +1 -0
  235. package/dist/src/lib/deprecation.d.ts +22 -0
  236. package/dist/src/lib/deprecation.js +43 -0
  237. package/dist/src/lib/deprecation.js.map +1 -0
  238. package/dist/src/lib/document-export-permissions.d.ts +30 -0
  239. package/dist/src/lib/document-export-permissions.js +54 -0
  240. package/dist/src/lib/document-export-permissions.js.map +1 -0
  241. package/dist/src/lib/document-ingest-artifact.d.ts +120 -0
  242. package/dist/src/lib/document-ingest-artifact.js +505 -0
  243. package/dist/src/lib/document-ingest-artifact.js.map +1 -0
  244. package/dist/src/lib/document-ingest-input.d.ts +51 -0
  245. package/dist/src/lib/document-ingest-input.js +132 -0
  246. package/dist/src/lib/document-ingest-input.js.map +1 -0
  247. package/dist/src/lib/document-ingest-rows.d.ts +137 -0
  248. package/dist/src/lib/document-ingest-rows.js +181 -0
  249. package/dist/src/lib/document-ingest-rows.js.map +1 -0
  250. package/dist/src/lib/document-ingest.d.ts +101 -0
  251. package/dist/src/lib/document-ingest.js +384 -0
  252. package/dist/src/lib/document-ingest.js.map +1 -0
  253. package/dist/src/lib/env-resolver-core.d.ts +258 -0
  254. package/dist/src/lib/env-resolver-core.js +447 -0
  255. package/dist/src/lib/env-resolver-core.js.map +1 -0
  256. package/dist/src/lib/env-resolver.d.ts +99 -0
  257. package/dist/src/lib/env-resolver.js +153 -0
  258. package/dist/src/lib/env-resolver.js.map +1 -0
  259. package/dist/src/lib/fetch.d.ts +5 -0
  260. package/dist/src/lib/function-bundle.d.ts +147 -0
  261. package/dist/src/lib/function-bundle.js +341 -0
  262. package/dist/src/lib/function-bundle.js.map +1 -0
  263. package/dist/src/lib/function-collect.d.ts +123 -0
  264. package/dist/src/lib/function-collect.js +610 -0
  265. package/dist/src/lib/function-collect.js.map +1 -0
  266. package/dist/src/lib/function-db-types.d.ts +202 -0
  267. package/dist/src/lib/function-db-types.js +870 -0
  268. package/dist/src/lib/function-db-types.js.map +1 -0
  269. package/dist/src/lib/function-document-types.d.ts +144 -0
  270. package/dist/src/lib/function-document-types.js +370 -0
  271. package/dist/src/lib/function-document-types.js.map +1 -0
  272. package/dist/src/lib/function-grants-preflight.d.ts +64 -0
  273. package/dist/src/lib/function-grants-preflight.js +105 -0
  274. package/dist/src/lib/function-grants-preflight.js.map +1 -0
  275. package/dist/src/lib/function-log-lines.d.ts +76 -0
  276. package/dist/src/lib/function-log-lines.js +160 -0
  277. package/dist/src/lib/function-log-lines.js.map +1 -0
  278. package/dist/src/lib/function-log-row.d.ts +29 -0
  279. package/dist/src/lib/function-log-row.js +73 -0
  280. package/dist/src/lib/function-log-row.js.map +1 -0
  281. package/dist/src/lib/function-log-tail.d.ts +132 -0
  282. package/dist/src/lib/function-log-tail.js +262 -0
  283. package/dist/src/lib/function-log-tail.js.map +1 -0
  284. package/dist/src/lib/function-run.d.ts +289 -0
  285. package/dist/src/lib/function-run.js +389 -0
  286. package/dist/src/lib/function-run.js.map +1 -0
  287. package/dist/src/lib/function-schema-codegen.d.ts +143 -0
  288. package/dist/src/lib/function-schema-codegen.js +420 -0
  289. package/dist/src/lib/function-schema-codegen.js.map +1 -0
  290. package/dist/src/lib/function-sync.d.ts +459 -0
  291. package/dist/src/lib/function-sync.js +1258 -0
  292. package/dist/src/lib/function-sync.js.map +1 -0
  293. package/dist/src/lib/function-trigger-listing.d.ts +27 -0
  294. package/dist/src/lib/function-trigger-listing.js +70 -0
  295. package/dist/src/lib/function-trigger-listing.js.map +1 -0
  296. package/dist/src/lib/function-typecheck.d.ts +86 -0
  297. package/dist/src/lib/function-typecheck.js +370 -0
  298. package/dist/src/lib/function-typecheck.js.map +1 -0
  299. package/dist/src/lib/function-versions.d.ts +122 -0
  300. package/dist/src/lib/function-versions.js +182 -0
  301. package/dist/src/lib/function-versions.js.map +1 -0
  302. package/dist/src/lib/generated-allowlist.d.ts +28 -0
  303. package/dist/src/lib/generated-allowlist.js +281 -0
  304. package/dist/src/lib/generated-allowlist.js.map +1 -0
  305. package/dist/src/lib/generated-config-surfaces.d.ts +2936 -0
  306. package/dist/src/lib/generated-config-surfaces.js +10569 -0
  307. package/dist/src/lib/generated-config-surfaces.js.map +1 -0
  308. package/dist/src/lib/generated-sdk-types.d.ts +12 -0
  309. package/dist/src/lib/generated-sdk-types.js +13 -0
  310. package/dist/src/lib/generated-sdk-types.js.map +1 -0
  311. package/dist/src/lib/generated-template-lint.d.ts +212 -0
  312. package/dist/src/lib/generated-template-lint.js +624 -0
  313. package/dist/src/lib/generated-template-lint.js.map +1 -0
  314. package/dist/src/lib/init-adopt.d.ts +16 -0
  315. package/dist/src/lib/init-adopt.js +34 -0
  316. package/dist/src/lib/init-adopt.js.map +1 -0
  317. package/dist/src/lib/init-assets.d.ts +39 -0
  318. package/dist/src/lib/init-assets.js +97 -0
  319. package/dist/src/lib/init-assets.js.map +1 -0
  320. package/dist/src/lib/init-client-platforms.d.ts +14 -0
  321. package/dist/src/lib/init-client-platforms.js +71 -0
  322. package/dist/src/lib/init-client-platforms.js.map +1 -0
  323. package/dist/src/lib/init-config.d.ts +98 -0
  324. package/dist/src/lib/init-config.js +186 -0
  325. package/dist/src/lib/init-config.js.map +1 -0
  326. package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
  327. package/dist/src/lib/init-email-redirect-uris.js +46 -0
  328. package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
  329. package/dist/src/lib/init-ios-links.d.ts +91 -0
  330. package/dist/src/lib/init-ios-links.js +219 -0
  331. package/dist/src/lib/init-ios-links.js.map +1 -0
  332. package/dist/src/lib/init-plan.d.ts +80 -0
  333. package/dist/src/lib/init-plan.js +95 -0
  334. package/dist/src/lib/init-plan.js.map +1 -0
  335. package/dist/src/lib/init-production-env.d.ts +48 -0
  336. package/dist/src/lib/init-production-env.js +59 -0
  337. package/dist/src/lib/init-production-env.js.map +1 -0
  338. package/dist/src/lib/init-schema.d.ts +74 -0
  339. package/dist/src/lib/init-schema.js +358 -0
  340. package/dist/src/lib/init-schema.js.map +1 -0
  341. package/dist/src/lib/init-xcode.d.ts +34 -0
  342. package/dist/src/lib/init-xcode.js +138 -0
  343. package/dist/src/lib/init-xcode.js.map +1 -0
  344. package/dist/src/lib/integration-request-config.d.ts +30 -0
  345. package/dist/src/lib/integration-request-config.js +145 -0
  346. package/dist/src/lib/integration-request-config.js.map +1 -0
  347. package/dist/src/lib/integration-selector.d.ts +42 -0
  348. package/dist/src/lib/integration-selector.js +46 -0
  349. package/dist/src/lib/integration-selector.js.map +1 -0
  350. package/dist/src/lib/ios-app-id.d.ts +34 -0
  351. package/dist/src/lib/ios-app-id.js +69 -0
  352. package/dist/src/lib/ios-app-id.js.map +1 -0
  353. package/dist/src/lib/list-options.d.ts +68 -0
  354. package/dist/src/lib/list-options.js +89 -0
  355. package/dist/src/lib/list-options.js.map +1 -0
  356. package/dist/src/lib/local-state.d.ts +55 -0
  357. package/dist/src/lib/local-state.js +167 -0
  358. package/dist/src/lib/local-state.js.map +1 -0
  359. package/dist/src/lib/local-test-cases.d.ts +63 -0
  360. package/dist/src/lib/local-test-cases.js +136 -0
  361. package/dist/src/lib/local-test-cases.js.map +1 -0
  362. package/dist/src/lib/log-inspection.d.ts +715 -0
  363. package/dist/src/lib/log-inspection.js +816 -0
  364. package/dist/src/lib/log-inspection.js.map +1 -0
  365. package/dist/src/lib/logout-admin-session.d.ts +33 -0
  366. package/dist/src/lib/logout-admin-session.js +70 -0
  367. package/dist/src/lib/logout-admin-session.js.map +1 -0
  368. package/dist/src/lib/migration-nag.d.ts +49 -0
  369. package/dist/src/lib/migration-nag.js +163 -0
  370. package/dist/src/lib/migration-nag.js.map +1 -0
  371. package/dist/src/lib/object-status-filter.d.ts +22 -0
  372. package/dist/src/lib/object-status-filter.js +45 -0
  373. package/dist/src/lib/object-status-filter.js.map +1 -0
  374. package/dist/src/lib/output.d.ts +124 -0
  375. package/dist/src/lib/output.js +219 -8
  376. package/dist/src/lib/output.js.map +1 -1
  377. package/dist/src/lib/package-manager.d.ts +140 -0
  378. package/dist/src/lib/package-manager.js +305 -0
  379. package/dist/src/lib/package-manager.js.map +1 -0
  380. package/dist/src/lib/paginate.d.ts +98 -0
  381. package/dist/src/lib/paginate.js +112 -0
  382. package/dist/src/lib/paginate.js.map +1 -0
  383. package/dist/src/lib/platform-owned.d.ts +63 -0
  384. package/dist/src/lib/platform-owned.js +85 -0
  385. package/dist/src/lib/platform-owned.js.map +1 -0
  386. package/dist/src/lib/project-config.d.ts +122 -0
  387. package/dist/src/lib/project-config.js +244 -0
  388. package/dist/src/lib/project-config.js.map +1 -0
  389. package/dist/src/lib/prompt-cost-format.d.ts +11 -0
  390. package/dist/src/lib/prompt-cost-format.js +41 -0
  391. package/dist/src/lib/prompt-cost-format.js.map +1 -0
  392. package/dist/src/lib/prompt-schema-codegen.d.ts +147 -0
  393. package/dist/src/lib/prompt-schema-codegen.js +462 -0
  394. package/dist/src/lib/prompt-schema-codegen.js.map +1 -0
  395. package/dist/src/lib/query-operators.d.ts +43 -0
  396. package/dist/src/lib/query-operators.js +80 -0
  397. package/dist/src/lib/query-operators.js.map +1 -0
  398. package/dist/src/lib/record-filter.d.ts +18 -0
  399. package/dist/src/lib/record-filter.js +55 -0
  400. package/dist/src/lib/record-filter.js.map +1 -0
  401. package/dist/src/lib/refresh-admin-credentials.d.ts +73 -0
  402. package/dist/src/lib/refresh-admin-credentials.js +123 -0
  403. package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
  404. package/dist/src/lib/resolve-init-dev-port.d.ts +56 -0
  405. package/dist/src/lib/resolve-init-dev-port.js +55 -0
  406. package/dist/src/lib/resolve-init-dev-port.js.map +1 -0
  407. package/dist/src/lib/resolve-init-server.d.ts +64 -0
  408. package/dist/src/lib/resolve-init-server.js +77 -0
  409. package/dist/src/lib/resolve-init-server.js.map +1 -0
  410. package/dist/src/lib/resolve-owner.d.ts +19 -0
  411. package/dist/src/lib/resolve-owner.js +20 -0
  412. package/dist/src/lib/resolve-owner.js.map +1 -0
  413. package/dist/src/lib/resolve-platform.d.ts +74 -0
  414. package/dist/src/lib/resolve-platform.js +105 -0
  415. package/dist/src/lib/resolve-platform.js.map +1 -0
  416. package/dist/src/lib/run-status.d.ts +19 -0
  417. package/dist/src/lib/run-status.generated.d.ts +39 -0
  418. package/dist/src/lib/run-status.generated.js +66 -0
  419. package/dist/src/lib/run-status.generated.js.map +1 -0
  420. package/dist/src/lib/run-status.js +19 -0
  421. package/dist/src/lib/run-status.js.map +1 -0
  422. package/dist/src/lib/server-text-normalization.d.ts +51 -0
  423. package/dist/src/lib/server-text-normalization.js +90 -0
  424. package/dist/src/lib/server-text-normalization.js.map +1 -0
  425. package/dist/src/lib/server-url.d.ts +22 -0
  426. package/dist/src/lib/server-url.js +33 -0
  427. package/dist/src/lib/server-url.js.map +1 -0
  428. package/dist/src/lib/signing-secret-status.d.ts +81 -0
  429. package/dist/src/lib/signing-secret-status.js +116 -0
  430. package/dist/src/lib/signing-secret-status.js.map +1 -0
  431. package/dist/src/lib/skill-installer.d.ts +71 -0
  432. package/dist/src/lib/skill-installer.js +441 -0
  433. package/dist/src/lib/skill-installer.js.map +1 -0
  434. package/dist/src/lib/snapshot-audit-source.d.ts +45 -0
  435. package/dist/src/lib/snapshot-audit-source.js +58 -0
  436. package/dist/src/lib/snapshot-audit-source.js.map +1 -0
  437. package/dist/src/lib/snapshot-audit-store.d.ts +52 -0
  438. package/dist/src/lib/snapshot-audit-store.js +196 -0
  439. package/dist/src/lib/snapshot-audit-store.js.map +1 -0
  440. package/dist/src/lib/snapshot-audit.d.ts +207 -0
  441. package/dist/src/lib/snapshot-audit.js +431 -0
  442. package/dist/src/lib/snapshot-audit.js.map +1 -0
  443. package/dist/src/lib/snapshot-build-rows.d.ts +60 -0
  444. package/dist/src/lib/snapshot-build-rows.js +87 -0
  445. package/dist/src/lib/snapshot-build-rows.js.map +1 -0
  446. package/dist/src/lib/snapshot-build.d.ts +50 -0
  447. package/dist/src/lib/snapshot-build.js +111 -0
  448. package/dist/src/lib/snapshot-build.js.map +1 -0
  449. package/dist/src/lib/snapshot-manifest-layout.d.ts +61 -0
  450. package/dist/src/lib/snapshot-manifest-layout.js +70 -0
  451. package/dist/src/lib/snapshot-manifest-layout.js.map +1 -0
  452. package/dist/src/lib/snapshots.d.ts +98 -0
  453. package/dist/src/lib/snapshots.js +294 -0
  454. package/dist/src/lib/snapshots.js.map +1 -0
  455. package/dist/src/lib/step-run-table.d.ts +43 -0
  456. package/dist/src/lib/step-run-table.js +129 -0
  457. package/dist/src/lib/step-run-table.js.map +1 -0
  458. package/dist/src/lib/storage-pending-retry.d.ts +26 -0
  459. package/dist/src/lib/storage-pending-retry.js +42 -0
  460. package/dist/src/lib/storage-pending-retry.js.map +1 -0
  461. package/dist/src/lib/swift-codegen/agentGenerator.d.ts +42 -0
  462. package/dist/src/lib/swift-codegen/agentGenerator.js +118 -0
  463. package/dist/src/lib/swift-codegen/agentGenerator.js.map +1 -0
  464. package/dist/src/lib/swift-codegen/banners.d.ts +24 -0
  465. package/dist/src/lib/swift-codegen/banners.js +25 -0
  466. package/dist/src/lib/swift-codegen/banners.js.map +1 -0
  467. package/dist/src/lib/swift-codegen/dbGenerator.d.ts +113 -0
  468. package/dist/src/lib/swift-codegen/dbGenerator.js +926 -0
  469. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -0
  470. package/dist/src/lib/swift-codegen/dbSwiftTypes.d.ts +42 -0
  471. package/dist/src/lib/swift-codegen/dbSwiftTypes.js +100 -0
  472. package/dist/src/lib/swift-codegen/dbSwiftTypes.js.map +1 -0
  473. package/dist/src/lib/swift-codegen/functionGenerator.d.ts +139 -0
  474. package/dist/src/lib/swift-codegen/functionGenerator.js +462 -0
  475. package/dist/src/lib/swift-codegen/functionGenerator.js.map +1 -0
  476. package/dist/src/lib/swift-codegen/generator.d.ts +100 -0
  477. package/dist/src/lib/swift-codegen/generator.js +457 -0
  478. package/dist/src/lib/swift-codegen/generator.js.map +1 -0
  479. package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +87 -0
  480. package/dist/src/lib/swift-codegen/schemaToSwift.js +661 -0
  481. package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -0
  482. package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +94 -0
  483. package/dist/src/lib/swift-codegen/siblingSymbols.js +155 -0
  484. package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -0
  485. package/dist/src/lib/swift-codegen/swiftNaming.d.ts +85 -0
  486. package/dist/src/lib/swift-codegen/swiftNaming.js +198 -0
  487. package/dist/src/lib/swift-codegen/swiftNaming.js.map +1 -0
  488. package/dist/src/lib/sync-dir-selector.d.ts +21 -0
  489. package/dist/src/lib/sync-dir-selector.js +30 -0
  490. package/dist/src/lib/sync-dir-selector.js.map +1 -0
  491. package/dist/src/lib/sync-paths.d.ts +128 -0
  492. package/dist/src/lib/sync-paths.js +195 -0
  493. package/dist/src/lib/sync-paths.js.map +1 -0
  494. package/dist/src/lib/sync-resource-types.d.ts +563 -0
  495. package/dist/src/lib/sync-resource-types.js +1073 -0
  496. package/dist/src/lib/sync-resource-types.js.map +1 -0
  497. package/dist/src/lib/sync-selectors.d.ts +138 -0
  498. package/dist/src/lib/sync-selectors.js +289 -0
  499. package/dist/src/lib/sync-selectors.js.map +1 -0
  500. package/dist/src/lib/template.d.ts +170 -0
  501. package/dist/src/lib/template.js +484 -68
  502. package/dist/src/lib/template.js.map +1 -1
  503. package/dist/src/lib/test-case-file-names.d.ts +40 -0
  504. package/dist/src/lib/test-case-file-names.js +91 -0
  505. package/dist/src/lib/test-case-file-names.js.map +1 -0
  506. package/dist/src/lib/test-case-keys.d.ts +29 -0
  507. package/dist/src/lib/test-case-keys.js +55 -0
  508. package/dist/src/lib/test-case-keys.js.map +1 -0
  509. package/dist/src/lib/test-case-variables.d.ts +29 -0
  510. package/dist/src/lib/test-case-variables.js +71 -0
  511. package/dist/src/lib/test-case-variables.js.map +1 -0
  512. package/dist/src/lib/token-inject.d.ts +56 -0
  513. package/dist/src/lib/token-inject.js +204 -0
  514. package/dist/src/lib/token-inject.js.map +1 -0
  515. package/dist/src/lib/toml-database-config.d.ts +123 -0
  516. package/dist/src/lib/toml-database-config.js +544 -0
  517. package/dist/src/lib/toml-database-config.js.map +1 -0
  518. package/dist/src/lib/toml-metadata-config.d.ts +151 -0
  519. package/dist/src/lib/toml-metadata-config.js +476 -0
  520. package/dist/src/lib/toml-metadata-config.js.map +1 -0
  521. package/dist/src/lib/toml-native-form.d.ts +46 -0
  522. package/dist/src/lib/toml-native-form.js +78 -0
  523. package/dist/src/lib/toml-native-form.js.map +1 -0
  524. package/dist/src/lib/toml-params-validator.d.ts +129 -0
  525. package/dist/src/lib/toml-params-validator.js +298 -0
  526. package/dist/src/lib/toml-params-validator.js.map +1 -0
  527. package/dist/src/lib/toml-scalar-edit.d.ts +43 -0
  528. package/dist/src/lib/toml-scalar-edit.js +283 -0
  529. package/dist/src/lib/toml-scalar-edit.js.map +1 -0
  530. package/dist/src/lib/user-selector.d.ts +24 -0
  531. package/dist/src/lib/user-selector.js +33 -0
  532. package/dist/src/lib/user-selector.js.map +1 -0
  533. package/dist/src/lib/version-check.d.ts +35 -0
  534. package/dist/src/lib/version-check.js +241 -0
  535. package/dist/src/lib/version-check.js.map +1 -0
  536. package/dist/src/lib/watch.d.ts +121 -0
  537. package/dist/src/lib/watch.js +169 -0
  538. package/dist/src/lib/watch.js.map +1 -0
  539. package/dist/src/lib/web-url.d.ts +40 -0
  540. package/dist/src/lib/web-url.js +76 -0
  541. package/dist/src/lib/web-url.js.map +1 -0
  542. package/dist/src/lib/webhook-deliver.d.ts +209 -0
  543. package/dist/src/lib/webhook-deliver.js +519 -0
  544. package/dist/src/lib/webhook-deliver.js.map +1 -0
  545. package/dist/src/lib/workflow-apply.d.ts +110 -0
  546. package/dist/src/lib/workflow-apply.js +164 -0
  547. package/dist/src/lib/workflow-apply.js.map +1 -0
  548. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.d.ts +129 -0
  549. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js +269 -0
  550. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js.map +1 -0
  551. package/dist/src/lib/workflow-codegen/generator.d.ts +96 -0
  552. package/dist/src/lib/workflow-codegen/generator.js +361 -0
  553. package/dist/src/lib/workflow-codegen/generator.js.map +1 -0
  554. package/dist/src/lib/workflow-codegen/invokerIR.d.ts +94 -0
  555. package/dist/src/lib/workflow-codegen/invokerIR.js +76 -0
  556. package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -0
  557. package/dist/src/lib/workflow-codegen/naming.d.ts +33 -0
  558. package/dist/src/lib/workflow-codegen/naming.js +81 -0
  559. package/dist/src/lib/workflow-codegen/naming.js.map +1 -0
  560. package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +80 -0
  561. package/dist/src/lib/workflow-codegen/schemaToTs.js +303 -0
  562. package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -0
  563. package/dist/src/lib/workflow-config-apply.d.ts +70 -0
  564. package/dist/src/lib/workflow-config-apply.js +137 -0
  565. package/dist/src/lib/workflow-config-apply.js.map +1 -0
  566. package/dist/src/lib/workflow-config-sidecar.d.ts +63 -0
  567. package/dist/src/lib/workflow-config-sidecar.js +96 -0
  568. package/dist/src/lib/workflow-config-sidecar.js.map +1 -0
  569. package/dist/src/lib/workflow-defaults.d.ts +29 -0
  570. package/dist/src/lib/workflow-defaults.js +41 -0
  571. package/dist/src/lib/workflow-defaults.js.map +1 -0
  572. package/dist/src/lib/workflow-fragments.d.ts +64 -0
  573. package/dist/src/lib/workflow-fragments.js +342 -0
  574. package/dist/src/lib/workflow-fragments.js.map +1 -0
  575. package/dist/src/lib/workflow-include-preserve.d.ts +76 -0
  576. package/dist/src/lib/workflow-include-preserve.js +286 -0
  577. package/dist/src/lib/workflow-include-preserve.js.map +1 -0
  578. package/dist/src/lib/workflow-payload.d.ts +98 -0
  579. package/dist/src/lib/workflow-payload.js +178 -0
  580. package/dist/src/lib/workflow-payload.js.map +1 -0
  581. package/dist/src/lib/workflow-toml-validator.d.ts +211 -0
  582. package/dist/src/lib/workflow-toml-validator.js +770 -0
  583. package/dist/src/lib/workflow-toml-validator.js.map +1 -0
  584. package/dist/src/lib/workflow-usage.d.ts +196 -0
  585. package/dist/src/lib/workflow-usage.js +310 -0
  586. package/dist/src/lib/workflow-usage.js.map +1 -0
  587. package/dist/src/types/index.d.ts +591 -0
  588. package/dist/src/validators.d.ts +65 -0
  589. package/dist/src/validators.js +64 -0
  590. package/dist/src/validators.js.map +1 -0
  591. package/package.json +34 -9
@@ -0,0 +1,770 @@
1
+ /**
2
+ * Push-time validator for workflow TOML files (issue #685, #998).
3
+ *
4
+ * Detects the common footgun where a user writes `[steps.<id>.<field>]` under
5
+ * an open `[[steps]]` array. TOML parses that as a sub-table on the
6
+ * most-recent step keyed by the step's id (e.g. `steps[0]["refresh-each"]`),
7
+ * not as the intended `steps[0].request`. The result is a step with an
8
+ * unrecognized top-level field — the runtime silently ignores it, and the
9
+ * step then runs with an empty `request` block.
10
+ *
11
+ * The validator walks every step in `tomlData.steps[]`. For a step whose
12
+ * `kind` the CLI KNOWS about, it reports any top-level field not in the
13
+ * generated allowlist. For an UNKNOWN kind (an old CLI run against a newer
14
+ * server that registered a step kind the CLI doesn't have), it SKIPS the
15
+ * per-field allowlist check — but still runs the kind-agnostic
16
+ * misnested-header footgun detector. This is the #998 fix: the recurring
17
+ * "newer server kind → false-reject of valid fields" failure (#685/#802/#971
18
+ * were all false rejections) becomes "unvalidated, not rejected."
19
+ *
20
+ * ── Source of truth (#998) ───────────────────────────────────────────────
21
+ * The allowlist field union and the known-kind set are GENERATED from the
22
+ * server step runners (`src/workflows/steps/*.ts`) and the universal
23
+ * `BaseStepDefinition` shape into the committed
24
+ * `cli/src/lib/generated-allowlist.ts` artifact (the CLI does NOT import
25
+ * server `src/` at runtime — only the build-time generator does). The union is
26
+ * derived from what each runner READS, not what the `*StepDefinition` TYPE
27
+ * declares — types over-declare and would weaken the footgun detector. A CI
28
+ * freshness guard (`gen-allowlist.mjs --check`, also asserted by the #985
29
+ * drift-guard test) keeps the committed artifact in sync with the runners, so
30
+ * the hand-edit drift class (#685/#802/#971) cannot recur for the same-version
31
+ * case. Regenerate with `node cli/scripts/gen-allowlist.mjs`.
32
+ */
33
+ import { GENERATED_ALLOWLISTED_FIELDS, GENERATED_KNOWN_KINDS, } from "./generated-allowlist.js";
34
+ // #2689 — the static `{{ }}` template lint, generated verbatim from the server
35
+ // module `src/workflows/runner/template-static-lint.ts` (see
36
+ // `cli/scripts/gen-template-lint.mjs`) so push-time and save-time verdicts are
37
+ // produced by the same code rather than a hand mirror.
38
+ import { lintWorkflowStepTemplates } from "./generated-template-lint.js";
39
+ // #3374 — the `runAs = "system"` + `accessRule` predicate is the server's own,
40
+ // vendored from `src/config-surface/workflow-rules.ts`; this module renders
41
+ // the CLI's hint from its answer rather than restating the conjunction.
42
+ import { checkWorkflowSystemAccessRule } from "./generated-config-surfaces.js";
43
+ /**
44
+ * Universal-and-consumed allowlist of top-level fields permitted on a step
45
+ * (known kinds). Generated from the runners; see header.
46
+ */
47
+ const ALLOWLISTED_FIELDS = new Set(GENERATED_ALLOWLISTED_FIELDS);
48
+ /**
49
+ * The set of step kinds the CLI knows about (the server's registered kinds at
50
+ * generation time). A step whose `kind` is NOT in this set has its per-field
51
+ * allowlist check skipped — the kind-agnostic footgun detector still runs.
52
+ */
53
+ const KNOWN_KINDS = new Set(GENERATED_KNOWN_KINDS);
54
+ /**
55
+ * Read-only view of `ALLOWLISTED_FIELDS` for the drift-guard test (#985).
56
+ *
57
+ * Exported so `cli/tests/unit/workflow-toml-validator-drift-guard.test.ts` can
58
+ * assert this set stays a superset of every top-level field the step runners
59
+ * in `src/workflows/steps/*.ts` actually read — checking the *live* set the
60
+ * validator enforces rather than a copy that could itself drift. Not part of
61
+ * the public validator API; consumed only by the guard.
62
+ */
63
+ export const ALLOWLISTED_FIELDS_FOR_DRIFT_GUARD = ALLOWLISTED_FIELDS;
64
+ /**
65
+ * Read-only view of `KNOWN_KINDS` for the drift-guard test (#998). Lets the
66
+ * guard assert the generated known-kind set matches a fresh scan.
67
+ */
68
+ export const KNOWN_KINDS_FOR_DRIFT_GUARD = KNOWN_KINDS;
69
+ /**
70
+ * #1447 workflow-identity predicate, extracted (codex review, 2026-07-15) so
71
+ * command sites that apply command-line metadata overrides can re-run it
72
+ * against the merged/effective workflow rather than only the parsed file.
73
+ *
74
+ * `runAs = "system"` + a non-empty `accessRule` is dead config: a system run
75
+ * can only be started by the system and never evaluates its accessRule, so any
76
+ * non-empty rule is inert. The server rejects this at save time (#1258,
77
+ * `src/workflows/config/workflow-save-rules.ts`); catching it locally puts the
78
+ * refusal in the PREFLIGHT, which aborts before the first mutating call, rather
79
+ * than mid-apply after earlier entities have been written (#1418 drift).
80
+ *
81
+ * "All-or-nothing", which this comment used to claim, was never what push
82
+ * offers and is corrected here (#3320): the preflight is all-or-nothing, and
83
+ * the apply stage that follows it is incremental and convergent with no
84
+ * rollback. See `config push --help`.
85
+ *
86
+ * Delegates the decision to the server's own predicate,
87
+ * `checkWorkflowSystemAccessRule` (#3374, vendored from
88
+ * `src/config-surface/workflow-rules.ts`): the sentinel is returned exactly
89
+ * when it reports a violation — `runAs === "system"` with a non-empty string
90
+ * `accessRule`. Default/unset/empty/whitespace-only runAs or accessRule (and a
91
+ * bare non-string boolean accessRule) return `null`. Only the HINT is this
92
+ * module's: it names the preflight remedy, where the server's sentence names
93
+ * the save-time one.
94
+ *
95
+ * @param workflow The workflow-metadata object — the `[workflow]` table, or
96
+ * for commands that accept unwrapped root-level metadata, the root TOML
97
+ * object (`tomlData.workflow || tomlData`). Non-object inputs return `null`.
98
+ */
99
+ export function validateWorkflowIdentity(workflow) {
100
+ if (workflow === null ||
101
+ typeof workflow !== "object" ||
102
+ Array.isArray(workflow)) {
103
+ return null;
104
+ }
105
+ const violation = checkWorkflowSystemAccessRule({
106
+ runAs: workflow.runAs,
107
+ accessRule: workflow.accessRule,
108
+ });
109
+ if (violation) {
110
+ return {
111
+ stepIndex: -1,
112
+ stepId: null,
113
+ field: "__workflow_system_access_rule__",
114
+ hint: 'accessRule has no effect when runAs = "system" (system runs skip ' +
115
+ "accessRule; gate callers with syncCallable + caller-mode, or see #1433)",
116
+ };
117
+ }
118
+ return null;
119
+ }
120
+ /**
121
+ * #2643 — `templateMissingMarker` was removed from the platform. A workflow
122
+ * TOML that still sets it is rejected here, before the push, with the same
123
+ * sentence the server returns, rather than being silently dropped.
124
+ */
125
+ export const REMOVED_TEMPLATE_MISSING_MARKER_MESSAGE = "templateMissingMarker is no longer supported. An unresolved template " +
126
+ "reference now fails the step on every workflow; mark individual " +
127
+ "expressions optional with `{{ x | default: '' }}` instead.";
128
+ /**
129
+ * #2645 — named workflow configs moved to sidecar files
130
+ * (`workflows/<key>.configs/<name>.toml`), so an inline `[[configs]]` list is
131
+ * no longer read by anything.
132
+ *
133
+ * It fails the push rather than being ignored. A pull taken before this change
134
+ * wrote those blocks, and push now applies only the sidecars: tolerating the
135
+ * list would leave the file describing configurations the server does not have
136
+ * — silently, since the content hash deliberately excludes the legacy list, so
137
+ * the object would not even report as Modified. The whole point of authoring
138
+ * configuration in TOML is that the committed file describes the server.
139
+ */
140
+ const RETIRED_INLINE_CONFIGS_MESSAGE = "`[[configs]]` is no longer read from a workflow file (#2645). Named " +
141
+ "configurations are authored one per file at " +
142
+ "`workflows/<key>.configs/<name>.toml`, and `[workflow].activeConfigName` " +
143
+ "selects the live one. Move each entry's body to its own sidecar file and " +
144
+ "delete the `[[configs]]` blocks.";
145
+ function validateRetiredInlineConfigs(tomlData) {
146
+ const configs = tomlData?.configs;
147
+ if (!Array.isArray(configs) || configs.length === 0)
148
+ return null;
149
+ return {
150
+ stepIndex: -1,
151
+ stepId: null,
152
+ field: "__workflow_inline_configs__",
153
+ hint: RETIRED_INLINE_CONFIGS_MESSAGE,
154
+ };
155
+ }
156
+ function validateRemovedWorkflowFields(workflow) {
157
+ if (!workflow || typeof workflow !== "object")
158
+ return null;
159
+ if (!Object.prototype.hasOwnProperty.call(workflow, "templateMissingMarker")) {
160
+ return null;
161
+ }
162
+ return {
163
+ stepIndex: -1,
164
+ stepId: null,
165
+ field: "__workflow_removed_field__",
166
+ hint: REMOVED_TEMPLATE_MISSING_MARKER_MESSAGE,
167
+ };
168
+ }
169
+ /**
170
+ * Non-blocking notes for a workflow TOML — things worth saying on a push that
171
+ * are not errors.
172
+ *
173
+ * #2643: `strict` / `strictParams` are accepted and ignored, because the
174
+ * failure they used to opt into now applies to every workflow. A definition
175
+ * that sets them keeps working unchanged, so this is a note, not an error.
176
+ */
177
+ export function collectWorkflowTomlNotes(tomlData) {
178
+ const notes = [];
179
+ const steps = tomlData?.steps;
180
+ if (!Array.isArray(steps))
181
+ return notes;
182
+ const usesStrict = steps.some((step) => step &&
183
+ typeof step === "object" &&
184
+ (Object.prototype.hasOwnProperty.call(step, "strict") ||
185
+ Object.prototype.hasOwnProperty.call(step, "strictParams")));
186
+ if (usesStrict) {
187
+ notes.push("Note: `strict` / `strictParams` no longer do anything — an unresolved " +
188
+ "template reference fails the step on every workflow (#2643). The keys " +
189
+ "are still accepted, so you can remove them at your convenience.");
190
+ }
191
+ return notes;
192
+ }
193
+ /**
194
+ * #1447 (maintainer decision, 2026-07-21): compute the EFFECTIVE workflow
195
+ * identity that an `update --from-file` push will leave on the server — the
196
+ * merge of the persisted record with the incoming file/flags.
197
+ *
198
+ * The merge exists for a caller whose push OMITS one side of the
199
+ * runAs/accessRule pair and lets the server retain it. Linting the incoming
200
+ * payload alone misses the case where the OTHER side is already `system` / a
201
+ * stored rule: an existing `runAs="system"` workflow plus a file adding only an
202
+ * `accessRule`, or a file flipping a workflow with a stored rule to
203
+ * `runAs="system"`. Both pass a payload-only lint and are then rejected by the
204
+ * server's PATCH. Merging the two before `validateWorkflowIdentity` catches
205
+ * them locally at zero extra cost — the persisted record is already fetched at
206
+ * the call site.
207
+ *
208
+ * NOT `config push`, since #2743: its update is always-send, so the file alone IS
209
+ * the effective config (an omitted `accessRule` clears the stored rule rather
210
+ * than inheriting it) and its push-time lint of the file is exact. The merge
211
+ * semantics below are unchanged for any caller that does omit fields: a field
212
+ * PRESENT in `incoming` (including an empty-string clear) overrides the stored
213
+ * value; an ABSENT field (undefined) falls back to what the server keeps.
214
+ */
215
+ export function effectiveWorkflowIdentity(existing, incoming) {
216
+ const ex = existing ?? {};
217
+ const inc = incoming ?? {};
218
+ return {
219
+ runAs: inc.runAs !== undefined ? inc.runAs : ex.runAs,
220
+ accessRule: inc.accessRule !== undefined ? inc.accessRule : ex.accessRule,
221
+ };
222
+ }
223
+ /**
224
+ * Walk a parsed workflow TOML document and return all unknown-field errors.
225
+ *
226
+ * @param tomlData The output of `parseConfigToml()` for a workflow TOML file.
227
+ * @param opts.skipWorkflowIdentity When true, suppress the #1447 workflow
228
+ * identity check (`runAs="system"` + non-empty `accessRule`). Callers that
229
+ * merge command-line overrides after parsing re-run `validateWorkflowIdentity`
230
+ * against the effective metadata themselves.
231
+ * @returns An array of error objects, one per offending field. Empty if no
232
+ * errors were found.
233
+ */
234
+ export function validateWorkflowToml(tomlData, opts) {
235
+ const errors = [];
236
+ if (tomlData === null || tomlData === undefined) {
237
+ return errors;
238
+ }
239
+ // #1447 — workflow-level identity lint: `runAs = "system"` + a non-empty
240
+ // `accessRule` is dead config. See `validateWorkflowIdentity` for the
241
+ // predicate. This runs BEFORE the `steps` early-returns below so a file
242
+ // carrying the bad combo but with missing/malformed `[[steps]]` is still
243
+ // flagged.
244
+ //
245
+ // Metadata shape (codex review, 2026-07-15): read the workflow table with
246
+ // the same `tomlData.workflow || tomlData` fallback the consuming commands
247
+ // use (`workflows create/update --from-file`), so an UNWRAPPED root-level
248
+ // TOML carrying `runAs`/`accessRule` is checked too — not only the wrapped
249
+ // `[workflow]` form.
250
+ //
251
+ // `skipWorkflowIdentity` (codex review, 2026-07-15): callers that apply
252
+ // command-line metadata overrides AFTER parsing (e.g. `workflows update
253
+ // --from-file` with `--access-rule`) pass this to suppress the identity
254
+ // check on the raw file, then re-run `validateWorkflowIdentity` against the
255
+ // merged/effective metadata themselves. Otherwise `--access-rule ""` could
256
+ // not repair an offending file, and an override-introduced accessRule would
257
+ // escape the lint. Structural checks (#685 misnest, etc.) still run.
258
+ if (!opts?.skipWorkflowIdentity) {
259
+ const identityError = validateWorkflowIdentity(tomlData.workflow || tomlData);
260
+ if (identityError)
261
+ errors.push(identityError);
262
+ }
263
+ // #2643 — a `[workflow]` key the platform has removed. Checked with the same
264
+ // `tomlData.workflow || tomlData` fallback as the identity lint so the
265
+ // unwrapped root-level form is caught too, and BEFORE the `steps`
266
+ // early-returns so a metadata-only file is still flagged.
267
+ const removedFieldError = validateRemovedWorkflowFields(tomlData.workflow || tomlData);
268
+ if (removedFieldError)
269
+ errors.push(removedFieldError);
270
+ // #2645 — an inline `[[configs]]` list, which named configs left behind when
271
+ // they moved to sidecar files. Read from the document root (not the
272
+ // `[workflow]` table) and before the `steps` early-returns, so a
273
+ // configs-only file is flagged too.
274
+ const inlineConfigsError = validateRetiredInlineConfigs(tomlData);
275
+ if (inlineConfigsError)
276
+ errors.push(inlineConfigsError);
277
+ const steps = tomlData.steps;
278
+ // No steps section at all → nothing to validate. This is fine for
279
+ // partial TOML files (some commands accept a metadata-only file).
280
+ if (steps === undefined || steps === null) {
281
+ return errors;
282
+ }
283
+ // `steps` is a table instead of an array. This typically means the user
284
+ // wrote `[steps.foo]` with no preceding `[[steps]]` array marker, so
285
+ // TOML resolved `steps` to a table. The runtime expects an array — flag
286
+ // it with a clear shape diagnostic.
287
+ if (!Array.isArray(steps)) {
288
+ if (typeof steps === "object") {
289
+ errors.push({
290
+ stepIndex: -1,
291
+ stepId: null,
292
+ field: "__steps_shape__",
293
+ hint: 'The `steps` section is a table, not an array. Workflow TOML expects `[[steps]]` array markers — add `[[steps]]` before any `[steps.<field>]` blocks.',
294
+ });
295
+ }
296
+ else {
297
+ errors.push({
298
+ stepIndex: -1,
299
+ stepId: null,
300
+ field: "__steps_shape__",
301
+ hint: `The \`steps\` section must be an array of step tables (received: ${typeof steps}).`,
302
+ });
303
+ }
304
+ return errors;
305
+ }
306
+ for (let i = 0; i < steps.length; i++) {
307
+ const step = steps[i];
308
+ // Defensive: array entry isn't an object. Should be near-impossible with
309
+ // valid `[[steps]]` syntax, but possible if the user writes `steps =
310
+ // ["a", "b"]`. Surface it so the user gets a diagnostic instead of a
311
+ // silent skip.
312
+ if (step === null || typeof step !== "object" || Array.isArray(step)) {
313
+ errors.push({
314
+ stepIndex: i,
315
+ stepId: null,
316
+ field: "__step_shape__",
317
+ hint: `Each entry in \`steps[]\` must be a table. Got: ${step === null ? "null" : Array.isArray(step) ? "array" : typeof step}.`,
318
+ });
319
+ continue;
320
+ }
321
+ validateStepObject(step, i, /* parentStepId */ null, errors);
322
+ // Codex finding 2 (PR #762, 2026-05-15): a `collect` step's nested
323
+ // `step` field is itself a step definition that the collect runner
324
+ // executes. The outer-step allowlist accepts `step` as a top-level
325
+ // field, but that's a structural pass-through — we need to recurse
326
+ // into the inner step's keys to catch the same misnested-header
327
+ // footgun (e.g. `[steps.step.call.request]` parses as `step.step =
328
+ // { call: { request: {...} } }`, with `call` as an unknown inner
329
+ // field; without the recursion this slips through). We only recurse
330
+ // for `kind === "collect"` — other kinds with a `step`-named field
331
+ // (none today) would need their own audit.
332
+ if (step.kind === "collect" &&
333
+ step.step !== null &&
334
+ typeof step.step === "object" &&
335
+ !Array.isArray(step.step)) {
336
+ const outerStepId = typeof step.id === "string" ? step.id : null;
337
+ validateStepObject(step.step, i, outerStepId, errors);
338
+ }
339
+ }
340
+ // #2689 — statically-dead `{{ }}` expressions (unknown root, undeclared
341
+ // `steps.<id>` / `outputs.<name>`) are guaranteed run-time failures since
342
+ // #2643. Reject them here so `config push` reports them before anything is
343
+ // pushed, instead of after a deploy-and-run cycle.
344
+ //
345
+ // `knownKinds` carries the #998 skew posture into the lint: an old CLI must
346
+ // not judge a NEWER server's step kind, whose runner may bind template roots
347
+ // this copy of the lint has never heard of. The server-side check in
348
+ // `validateWorkflowSteps` scans every step and stays authoritative.
349
+ for (const finding of lintWorkflowStepTemplates(steps, {
350
+ knownKinds: KNOWN_KINDS,
351
+ })) {
352
+ errors.push({
353
+ stepIndex: finding.stepIndex,
354
+ stepId: finding.stepId,
355
+ field: "__template_expression__",
356
+ hint: `${finding.location}: ${finding.message}`,
357
+ });
358
+ }
359
+ return errors;
360
+ }
361
+ /**
362
+ * Validate a single step object's top-level keys against the allowlist and
363
+ * push any errors found onto `errors`. Used for both the top-level
364
+ * `steps[]` walk and the recursive `collect.step` walk.
365
+ *
366
+ * When `parentStepId` is set, the step being validated is the inner step
367
+ * of a `collect`. Errors carry the outer-step context so the rendered
368
+ * diagnostic can point operators at the right slot in the TOML.
369
+ */
370
+ function validateStepObject(step, stepIndex, parentStepId, errors) {
371
+ const stepId = typeof step.id === "string" ? step.id : null;
372
+ // #998: kind-membership branch. The CLI ships independently and may run
373
+ // against a NEWER server that registered a step kind the CLI's generated
374
+ // known-kind set doesn't have. For such an UNKNOWN kind we skip the
375
+ // per-field allowlist check (so a valid new-kind field is never falsely
376
+ // rejected — the recurring #685/#802/#971 failure) while STILL running the
377
+ // kind-agnostic misnested-header footgun detector below. For a KNOWN kind
378
+ // the full allowlist check applies as before. A missing/non-string `kind`
379
+ // is treated as known so the legacy strict check still catches obviously
380
+ // malformed steps (the runtime would reject a kindless step anyway).
381
+ const kind = typeof step.kind === "string" ? step.kind : null;
382
+ const isKnownKind = kind === null || KNOWN_KINDS.has(kind);
383
+ for (const key of Object.keys(step)) {
384
+ const value = step[key];
385
+ // Codex finding 1 (PR #762, 2026-05-15): self-id misnesting must be
386
+ // checked BEFORE the allowlist skip. When the step's `id` happens to
387
+ // match an allowlisted field name (e.g. `id = "query"`,
388
+ // `id = "request"`, `id = "input"`, `id = "output"`), TOML's
389
+ // `[steps.<id>.<sub-field>]` misnest produces a sub-table on the step
390
+ // keyed by the id — the same shape the validator was meant to catch.
391
+ // The allowlist would otherwise skip it as "expected per-kind field".
392
+ // Heuristic: when `step[step.id]` is a non-array table, this is
393
+ // (effectively always) the misnest pattern. Scalars are fine (the
394
+ // user really did mean to set the scalar field).
395
+ //
396
+ // Codex finding (PR #819, 2026-05-21): the heuristic over-fires for the
397
+ // `switch` step kind. A switch legitimately named `id = "default"` has a
398
+ // real `[steps.default]` fallback that parses as a non-array table at
399
+ // `step.default` — structurally identical to the misnest shape, but it's
400
+ // the field's *valid* form. (Likewise `id = "cases"`.) For these ids the
401
+ // footgun and the legitimate declaration are indistinguishable, so the
402
+ // heuristic must defer to the allowlist. Carve-out scope is narrow on
403
+ // purpose: only `kind === "switch"` with key `cases`/`default`. Every
404
+ // other (kind, id) collision — e.g. `id = "query"` on a database step —
405
+ // is still treated as the footgun, preserving finding 1's safety net.
406
+ const isSwitchFallbackField = step.kind === "switch" && (key === "cases" || key === "default");
407
+ const isSelfIdMisnest = stepId !== null &&
408
+ key === stepId &&
409
+ value !== null &&
410
+ typeof value === "object" &&
411
+ !Array.isArray(value) &&
412
+ !isSwitchFallbackField;
413
+ // Known kind → full allowlist check (an allowlisted field passes).
414
+ // Unknown kind → skip the per-field allowlist check entirely: only the
415
+ // structural footgun (self-id misnest) below can flag a field. The
416
+ // footgun check is kind-agnostic, so it fires on every step regardless.
417
+ if (!isSelfIdMisnest && (!isKnownKind || ALLOWLISTED_FIELDS.has(key)))
418
+ continue;
419
+ // Two failure modes are common enough to call out specifically in
420
+ // the hint:
421
+ //
422
+ // 1) `[steps.<id>.<field>]` under `[[steps]]` — TOML places the
423
+ // sub-table under `steps[N][<id>]`. We detect this when the
424
+ // unknown field name equals the step's own id (including the
425
+ // self-id-allowlist-collision case above). We use the first
426
+ // sub-key of the offending value (e.g. `request`) to build a
427
+ // concrete corrected-form example so the user sees exactly what
428
+ // to rewrite, not just an abstract `<field>`.
429
+ //
430
+ // 2) Any other unknown top-level field — covered by the generic hint.
431
+ let hint;
432
+ if (stepId !== null && key === stepId) {
433
+ const subKey = value && typeof value === "object" && !Array.isArray(value)
434
+ ? Object.keys(value)[0]
435
+ : null;
436
+ const exampleSub = subKey ?? "request";
437
+ hint =
438
+ `This is usually caused by writing [steps.${stepId}.${exampleSub}] instead of [steps.${exampleSub}]. ` +
439
+ `TOML can't address an array element by id — use [steps.${exampleSub}] (refers to the most recent step).`;
440
+ }
441
+ else {
442
+ hint =
443
+ `\`${key}\` is not a recognized step field. ` +
444
+ `If you meant to write a nested config block on this step, use [steps.${key}] (which refers to the most recent step) instead of [steps.<id>.${key}].`;
445
+ }
446
+ errors.push({
447
+ stepIndex,
448
+ stepId,
449
+ field: key,
450
+ hint,
451
+ parentStepId,
452
+ });
453
+ }
454
+ // #1252 — form-urlencoded body conflict. `[steps.request.form]` encodes an
455
+ // `application/x-www-form-urlencoded` body; it cannot coexist with a
456
+ // `request.body` or a raw/multipart `bodyMode`. The runtime rejects the same
457
+ // combination, but catching it at push time gives a clearer, earlier
458
+ // diagnostic. (`request.form` itself needs no allowlist entry — the validator
459
+ // only checks top-level step fields, and `request` is already allowlisted.)
460
+ if (step.kind === "integration.call" &&
461
+ step.request !== null &&
462
+ typeof step.request === "object" &&
463
+ !Array.isArray(step.request)) {
464
+ const req = step.request;
465
+ const hasForm = req.form !== undefined && req.form !== null;
466
+ if (hasForm) {
467
+ if (req.body !== undefined && req.body !== null) {
468
+ errors.push({
469
+ stepIndex,
470
+ stepId,
471
+ field: "request.form",
472
+ hint: "`request.form` (application/x-www-form-urlencoded) cannot be combined with `request.body`. " +
473
+ "Use one request body — either the JSON `body` or the `form` table.",
474
+ parentStepId,
475
+ });
476
+ }
477
+ const mode = step.bodyMode;
478
+ if (mode === "raw" || mode === "multipart") {
479
+ errors.push({
480
+ stepIndex,
481
+ stepId,
482
+ field: "request.form",
483
+ hint: `\`request.form\` (application/x-www-form-urlencoded) cannot be combined with bodyMode "${mode}". ` +
484
+ "Remove `form` or the `bodyMode`.",
485
+ parentStepId,
486
+ });
487
+ }
488
+ }
489
+ }
490
+ }
491
+ /**
492
+ * Render a multi-line diagnostic for a list of errors. Designed for the
493
+ * shape called out in the issue:
494
+ *
495
+ * Error in workflows/refresh.toml:
496
+ * steps[0] (id="refresh-each") has unknown field "refresh-each".
497
+ * This is usually caused by writing [steps.refresh-each.request] instead of [steps.request].
498
+ * TOML can't address an array element by id — use [steps.request] (refers to the most recent step).
499
+ *
500
+ * @param filePath The TOML file path (or display name) to include in the
501
+ * header.
502
+ * @param errors The error list from `validateWorkflowToml`.
503
+ * @returns A multi-line string ready to print to stderr.
504
+ */
505
+ export function formatWorkflowTomlErrors(filePath, errors) {
506
+ if (errors.length === 0)
507
+ return "";
508
+ const lines = [`Error in ${filePath}:`];
509
+ for (const err of errors) {
510
+ if (err.field === "__steps_shape__") {
511
+ lines.push(` ${err.hint}`);
512
+ continue;
513
+ }
514
+ if (err.field === "__step_shape__") {
515
+ lines.push(` steps[${err.stepIndex}] is malformed: ${err.hint}`);
516
+ continue;
517
+ }
518
+ // #2689 — a statically-dead `{{ }}` expression. The offending FIELD is
519
+ // fine; its contents are not, so the "unknown field" wording would be
520
+ // actively misleading. Render the step slot plus the lint's message, which
521
+ // already names the expression, the problem and the fix.
522
+ if (err.field === "__template_expression__") {
523
+ const idPart = err.stepId ? ` (id="${err.stepId}")` : "";
524
+ lines.push(` steps[${err.stepIndex}]${idPart}:`);
525
+ lines.push(` ${err.hint}`);
526
+ continue;
527
+ }
528
+ // #1447 — workflow-level error, not tied to a step. Render the bare hint
529
+ // (no `steps[N]` prefix) under the file header.
530
+ if (err.field === "__workflow_system_access_rule__" ||
531
+ err.field === "__workflow_removed_field__") {
532
+ lines.push(` ${err.hint}`);
533
+ continue;
534
+ }
535
+ // For errors inside a `collect` step's nested inner step (codex review,
536
+ // 2026-05-15), use a `steps[N].step` slot prefix so operators see that
537
+ // the offending field is on the inner step, not the outer collect.
538
+ // The outer step's id (if any) is also included in the prefix so the
539
+ // diagnostic can be cross-referenced against the parent's TOML header.
540
+ //
541
+ // #971: top-level errors carry `parentStepId: null` (set explicitly at the
542
+ // top-level `validateStepObject` call); only genuine collect-inner errors
543
+ // carry a real id (or `undefined` if a future caller omits it). Use a
544
+ // non-null check so BOTH `null` and `undefined` top-level errors render as
545
+ // a bare `steps[N]` without the `(inside collect step)` suffix. The prior
546
+ // `!== undefined` check treated `null` as inner (`null !== undefined` is
547
+ // `true`), mislabeling every top-level error as inside a collect step (a
548
+ // regression from PR #762).
549
+ const isInnerStep = err.parentStepId != null;
550
+ const slot = isInnerStep
551
+ ? `steps[${err.stepIndex}].step`
552
+ : `steps[${err.stepIndex}]`;
553
+ const idPart = err.stepId ? ` (id="${err.stepId}")` : "";
554
+ const parentPart = isInnerStep && err.parentStepId
555
+ ? ` (inside collect step id="${err.parentStepId}")`
556
+ : isInnerStep
557
+ ? ` (inside collect step)`
558
+ : "";
559
+ lines.push(` ${slot}${idPart}${parentPart} has unknown field "${err.field}".`);
560
+ lines.push(` ${err.hint}`);
561
+ }
562
+ return lines.join("\n");
563
+ }
564
+ /**
565
+ * #1614 — client-side mirror of the server's `validateWorkflowExpressions`
566
+ * (`src/workflows/definition-store.ts`) for named `expr.*` CEL guards. Returns
567
+ * structural errors so `config push` fails fast with the same class of diagnostic
568
+ * the server would 400 on:
569
+ * 1. every `expr.<name>` reference — in a definition body OR a step guard
570
+ * (`runIf` / `successWhen` / switch `when`) — names a DECLARED definition;
571
+ * 2. the definition reference graph is a DAG (no cycles);
572
+ * 3. each definition body is a non-empty string.
573
+ *
574
+ * The CLI has no CEL parser, so full CEL parse validation stays server-side
575
+ * (the authoritative check) — this mirror catches the common undeclared-name
576
+ * and cycle mistakes before a network round-trip, matching how the CLI does
577
+ * structural checks and the server does authoritative validation elsewhere.
578
+ */
579
+ /**
580
+ * #1614 — validate the RAW `[expr.cel]` table shape BEFORE
581
+ * `parseWorkflowExpressionsToml` filters it. That parser drops any entry whose
582
+ * body is not a string, so a mistyped `ready = true` would vanish and, with no
583
+ * references left to fail on, `config push` would succeed while omitting the whole
584
+ * expression table. Surface non-string / empty / wrong-typed bodies (and a
585
+ * non-table `cel`) as a hard CLI validation error instead. Mirrors the server's
586
+ * `validateRawExpressionsShape` (`src/workflows/definition-store.ts`).
587
+ *
588
+ * `tomlData.expr.cel` is the parsed `[expr.cel]` table.
589
+ */
590
+ export function validateWorkflowExpressionsRawToml(tomlData) {
591
+ const errors = [];
592
+ const cel = tomlData?.expr?.cel;
593
+ if (cel === undefined || cel === null)
594
+ return errors;
595
+ if (typeof cel !== "object" || Array.isArray(cel)) {
596
+ errors.push("[expr.cel] must be a table mapping each name to a CEL string");
597
+ return errors;
598
+ }
599
+ for (const [name, body] of Object.entries(cel)) {
600
+ if (typeof body !== "string" || !body.trim()) {
601
+ errors.push(`expr.cel.${name}: definition body must be a non-empty CEL string`);
602
+ }
603
+ }
604
+ return errors;
605
+ }
606
+ export function validateWorkflowExpressionsToml(steps, expressions) {
607
+ const errors = [];
608
+ const cel = expressions?.cel;
609
+ const declared = new Set(cel ? Object.keys(cel) : []);
610
+ const refsFromDef = new Map();
611
+ if (cel) {
612
+ for (const [name, body] of Object.entries(cel)) {
613
+ if (typeof body !== "string" || !body.trim()) {
614
+ errors.push(`expr.cel.${name}: definition body must be a non-empty CEL string`);
615
+ refsFromDef.set(name, new Set());
616
+ continue;
617
+ }
618
+ const refs = extractExprRefs(body);
619
+ refsFromDef.set(name, refs);
620
+ for (const ref of refs) {
621
+ if (!declared.has(ref)) {
622
+ errors.push(`expr.cel.${name} references undeclared expr.${ref}`);
623
+ }
624
+ }
625
+ }
626
+ }
627
+ if (Array.isArray(steps)) {
628
+ steps.forEach((step, index) => {
629
+ for (const guard of collectGuardExpressions(step)) {
630
+ for (const ref of extractExprRefs(guard.expr)) {
631
+ if (!declared.has(ref)) {
632
+ errors.push(`steps[${index}].${guard.field} references undeclared expr.${ref}`);
633
+ }
634
+ }
635
+ }
636
+ });
637
+ }
638
+ const cycle = findExprCycle(declared, refsFromDef);
639
+ if (cycle) {
640
+ errors.push(`expr.cel definitions form a cycle: ${cycle.join(" -> ")}`);
641
+ }
642
+ return errors;
643
+ }
644
+ function collectGuardExpressions(step) {
645
+ const out = [];
646
+ if (!step || typeof step !== "object")
647
+ return out;
648
+ if (typeof step.runIf === "string" && step.runIf.trim()) {
649
+ out.push({ field: "runIf", expr: step.runIf });
650
+ }
651
+ if (typeof step.successWhen === "string" && step.successWhen.trim()) {
652
+ out.push({ field: "successWhen", expr: step.successWhen });
653
+ }
654
+ if (Array.isArray(step.cases)) {
655
+ step.cases.forEach((c, ci) => {
656
+ if (c && typeof c.when === "string" && c.when.trim()) {
657
+ out.push({ field: `cases[${ci}].when`, expr: c.when });
658
+ }
659
+ });
660
+ }
661
+ return out;
662
+ }
663
+ /**
664
+ * Scan a CEL string for `expr.<name>` / `expr['name']` / `expr["name"]`
665
+ * references, skipping quoted string literals. Mirrors the server's
666
+ * `extractExprRefs`.
667
+ */
668
+ function extractExprRefs(expression) {
669
+ const refs = new Set();
670
+ if (!expression)
671
+ return refs;
672
+ const len = expression.length;
673
+ let i = 0;
674
+ // #1614 — match the server's `isIdentChar` exactly (includes `$`) so a
675
+ // `$`-containing expr name (`expr.a$b`) is not falsely flagged as an
676
+ // undeclared reference by the CLI mirror when the server would accept it.
677
+ const isIdent = (ch) => !!ch && /[A-Za-z0-9_$]/.test(ch);
678
+ const skipStr = (start) => {
679
+ const quote = expression[start];
680
+ let k = start + 1;
681
+ while (k < len) {
682
+ if (expression[k] === "\\") {
683
+ k += 2;
684
+ continue;
685
+ }
686
+ if (expression[k] === quote)
687
+ return k + 1;
688
+ k++;
689
+ }
690
+ return len;
691
+ };
692
+ while (i < len) {
693
+ const ch = expression[i];
694
+ if (ch === "'" || ch === '"') {
695
+ i = skipStr(i);
696
+ continue;
697
+ }
698
+ if (ch === "e" &&
699
+ expression.slice(i, i + 4) === "expr" &&
700
+ (i === 0 || !isIdent(expression[i - 1]))) {
701
+ let j = i + 4;
702
+ if (expression[j] === ".") {
703
+ j++;
704
+ const start = j;
705
+ while (j < len && isIdent(expression[j]))
706
+ j++;
707
+ if (j > start)
708
+ refs.add(expression.slice(start, j));
709
+ i = j;
710
+ continue;
711
+ }
712
+ if (expression[j] === "[") {
713
+ let k = j + 1;
714
+ while (k < len && expression[k] === " ")
715
+ k++;
716
+ const q = expression[k];
717
+ if (q === "'" || q === '"') {
718
+ const s = k + 1;
719
+ let e = s;
720
+ while (e < len && expression[e] !== q)
721
+ e++;
722
+ if (e < len) {
723
+ refs.add(expression.slice(s, e));
724
+ i = e + 1;
725
+ continue;
726
+ }
727
+ }
728
+ }
729
+ i = j;
730
+ continue;
731
+ }
732
+ i++;
733
+ }
734
+ return refs;
735
+ }
736
+ /** DFS cycle detection over the declared `expr.*` reference graph. */
737
+ function findExprCycle(declared, refs) {
738
+ const WHITE = 0;
739
+ const GRAY = 1;
740
+ const BLACK = 2;
741
+ const color = new Map();
742
+ for (const n of declared)
743
+ color.set(n, WHITE);
744
+ const stack = [];
745
+ let found = null;
746
+ const dfs = (n) => {
747
+ color.set(n, GRAY);
748
+ stack.push(n);
749
+ for (const m of refs.get(n) ?? []) {
750
+ if (!declared.has(m))
751
+ continue;
752
+ if (color.get(m) === GRAY) {
753
+ const idx = stack.indexOf(m);
754
+ found = stack.slice(idx).concat(m);
755
+ return true;
756
+ }
757
+ if (color.get(m) === WHITE && dfs(m))
758
+ return true;
759
+ }
760
+ stack.pop();
761
+ color.set(n, BLACK);
762
+ return false;
763
+ };
764
+ for (const n of declared) {
765
+ if (color.get(n) === WHITE && dfs(n))
766
+ break;
767
+ }
768
+ return found;
769
+ }
770
+ //# sourceMappingURL=workflow-toml-validator.js.map