primitive-admin 1.1.0-alpha.8 → 1.1.0-alpha.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (522) hide show
  1. package/README.md +444 -106
  2. package/assets/skill/skills/primitive-platform/SKILL.md +811 -0
  3. package/dist/bin/primitive.d.ts +2 -0
  4. package/dist/bin/primitive.js +373 -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 +128 -19
  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 +700 -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 +54 -96
  14. package/dist/src/commands/apps.js.map +1 -1
  15. package/dist/src/commands/auth.d.ts +2 -0
  16. package/dist/src/commands/auth.js +196 -105
  17. package/dist/src/commands/auth.js.map +1 -1
  18. package/dist/src/commands/blob-buckets.d.ts +2 -0
  19. package/dist/src/commands/blob-buckets.js +330 -0
  20. package/dist/src/commands/blob-buckets.js.map +1 -0
  21. package/dist/src/commands/catalog.d.ts +2 -0
  22. package/dist/src/commands/catalog.js +37 -38
  23. package/dist/src/commands/catalog.js.map +1 -1
  24. package/dist/src/commands/collection-type-configs.d.ts +2 -0
  25. package/dist/src/commands/collection-type-configs.js +84 -0
  26. package/dist/src/commands/collection-type-configs.js.map +1 -0
  27. package/dist/src/commands/collections.d.ts +2 -0
  28. package/dist/src/commands/collections.js +565 -0
  29. package/dist/src/commands/collections.js.map +1 -0
  30. package/dist/src/commands/comparisons.d.ts +2 -0
  31. package/dist/src/commands/comparisons.js +6 -6
  32. package/dist/src/commands/comparisons.js.map +1 -1
  33. package/dist/src/commands/config.d.ts +46 -0
  34. package/dist/src/commands/config.js +465 -0
  35. package/dist/src/commands/config.js.map +1 -0
  36. package/dist/src/commands/connections.d.ts +2 -0
  37. package/dist/src/commands/connections.js +100 -0
  38. package/dist/src/commands/connections.js.map +1 -0
  39. package/dist/src/commands/cron-triggers.d.ts +2 -0
  40. package/dist/src/commands/cron-triggers.js +265 -0
  41. package/dist/src/commands/cron-triggers.js.map +1 -0
  42. package/dist/src/commands/database-type-configs.d.ts +2 -0
  43. package/dist/src/commands/database-type-configs.js +163 -0
  44. package/dist/src/commands/database-type-configs.js.map +1 -0
  45. package/dist/src/commands/database-types.d.ts +2 -0
  46. package/dist/src/commands/database-types.js +171 -0
  47. package/dist/src/commands/database-types.js.map +1 -0
  48. package/dist/src/commands/databases.d.ts +65 -0
  49. package/dist/src/commands/databases.js +1859 -238
  50. package/dist/src/commands/databases.js.map +1 -1
  51. package/dist/src/commands/documents.d.ts +2 -0
  52. package/dist/src/commands/documents.js +2062 -19
  53. package/dist/src/commands/documents.js.map +1 -1
  54. package/dist/src/commands/email-templates.d.ts +2 -0
  55. package/dist/src/commands/email-templates.js +174 -0
  56. package/dist/src/commands/email-templates.js.map +1 -0
  57. package/dist/src/commands/env.d.ts +23 -0
  58. package/dist/src/commands/env.js +385 -0
  59. package/dist/src/commands/env.js.map +1 -0
  60. package/dist/src/commands/feature-flags.d.ts +14 -0
  61. package/dist/src/commands/feature-flags.js +116 -0
  62. package/dist/src/commands/feature-flags.js.map +1 -0
  63. package/dist/src/commands/functions.d.ts +20 -0
  64. package/dist/src/commands/functions.js +672 -0
  65. package/dist/src/commands/functions.js.map +1 -0
  66. package/dist/src/commands/group-type-configs.d.ts +2 -0
  67. package/dist/src/commands/group-type-configs.js +86 -0
  68. package/dist/src/commands/group-type-configs.js.map +1 -0
  69. package/dist/src/commands/groups.d.ts +2 -0
  70. package/dist/src/commands/groups.js +39 -108
  71. package/dist/src/commands/groups.js.map +1 -1
  72. package/dist/src/commands/guides.d.ts +223 -0
  73. package/dist/src/commands/guides.js +617 -65
  74. package/dist/src/commands/guides.js.map +1 -1
  75. package/dist/src/commands/init.d.ts +37 -0
  76. package/dist/src/commands/init.js +1693 -208
  77. package/dist/src/commands/init.js.map +1 -1
  78. package/dist/src/commands/integrations.d.ts +2 -0
  79. package/dist/src/commands/integrations.js +402 -182
  80. package/dist/src/commands/integrations.js.map +1 -1
  81. package/dist/src/commands/llm.d.ts +2 -0
  82. package/dist/src/commands/llm.js +13 -8
  83. package/dist/src/commands/llm.js.map +1 -1
  84. package/dist/src/commands/locks.d.ts +8 -0
  85. package/dist/src/commands/locks.js +160 -0
  86. package/dist/src/commands/locks.js.map +1 -0
  87. package/dist/src/commands/metadata-category-configs.d.ts +12 -0
  88. package/dist/src/commands/metadata-category-configs.js +112 -0
  89. package/dist/src/commands/metadata-category-configs.js.map +1 -0
  90. package/dist/src/commands/metadata.d.ts +2 -0
  91. package/dist/src/commands/metadata.js +281 -0
  92. package/dist/src/commands/metadata.js.map +1 -0
  93. package/dist/src/commands/prompts.d.ts +2 -0
  94. package/dist/src/commands/prompts.js +275 -621
  95. package/dist/src/commands/prompts.js.map +1 -1
  96. package/dist/src/commands/rule-sets.d.ts +3 -0
  97. package/dist/src/commands/rule-sets.js +137 -147
  98. package/dist/src/commands/rule-sets.js.map +1 -1
  99. package/dist/src/commands/scripts.d.ts +30 -0
  100. package/dist/src/commands/scripts.js +679 -0
  101. package/dist/src/commands/scripts.js.map +1 -0
  102. package/dist/src/commands/secrets.d.ts +2 -0
  103. package/dist/src/commands/secrets.js +108 -0
  104. package/dist/src/commands/secrets.js.map +1 -0
  105. package/dist/src/commands/sessions.d.ts +2 -0
  106. package/dist/src/commands/sessions.js +75 -0
  107. package/dist/src/commands/sessions.js.map +1 -0
  108. package/dist/src/commands/settings.d.ts +18 -0
  109. package/dist/src/commands/settings.js +54 -0
  110. package/dist/src/commands/settings.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 +2514 -0
  118. package/dist/src/commands/sync.js +16106 -848
  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 +130 -21
  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 +532 -23
  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 +96 -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 +10 -10
  131. package/dist/src/commands/waitlist.js.map +1 -1
  132. package/dist/src/commands/webhooks.d.ts +2 -0
  133. package/dist/src/commands/webhooks.js +562 -0
  134. package/dist/src/commands/webhooks.js.map +1 -0
  135. package/dist/src/commands/workflows.d.ts +116 -0
  136. package/dist/src/commands/workflows.js +1638 -729
  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 +2147 -0
  142. package/dist/src/lib/api-client.js +2042 -160
  143. package/dist/src/lib/api-client.js.map +1 -1
  144. package/dist/src/lib/app-match-guard.d.ts +44 -0
  145. package/dist/src/lib/app-match-guard.js +72 -0
  146. package/dist/src/lib/app-match-guard.js.map +1 -0
  147. package/dist/src/lib/app-settings-descriptor.d.ts +263 -0
  148. package/dist/src/lib/app-settings-descriptor.js +584 -0
  149. package/dist/src/lib/app-settings-descriptor.js.map +1 -0
  150. package/dist/src/lib/auth-flow.d.ts +8 -0
  151. package/dist/src/lib/batch.d.ts +26 -0
  152. package/dist/src/lib/batch.js +32 -0
  153. package/dist/src/lib/batch.js.map +1 -0
  154. package/dist/src/lib/block-layout.d.ts +160 -0
  155. package/dist/src/lib/block-layout.js +451 -0
  156. package/dist/src/lib/block-layout.js.map +1 -0
  157. package/dist/src/lib/block-selector.d.ts +58 -0
  158. package/dist/src/lib/block-selector.js +92 -0
  159. package/dist/src/lib/block-selector.js.map +1 -0
  160. package/dist/src/lib/canonical-json.d.ts +12 -0
  161. package/dist/src/lib/canonical-json.js +35 -0
  162. package/dist/src/lib/canonical-json.js.map +1 -0
  163. package/dist/src/lib/channel.d.ts +30 -0
  164. package/dist/src/lib/channel.js +68 -0
  165. package/dist/src/lib/channel.js.map +1 -0
  166. package/dist/src/lib/cli-manifest.d.ts +68 -0
  167. package/dist/src/lib/cli-manifest.js +71 -0
  168. package/dist/src/lib/cli-manifest.js.map +1 -0
  169. package/dist/src/lib/codegen-shared/generatedFiles.d.ts +101 -0
  170. package/dist/src/lib/codegen-shared/generatedFiles.js +191 -0
  171. package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -0
  172. package/dist/src/lib/codegen-shared/prettierStable.d.ts +262 -0
  173. package/dist/src/lib/codegen-shared/prettierStable.js +610 -0
  174. package/dist/src/lib/codegen-shared/prettierStable.js.map +1 -0
  175. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +38 -0
  176. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +46 -0
  177. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.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 +696 -0
  183. package/dist/src/lib/config-object-descriptor.js.map +1 -0
  184. package/dist/src/lib/config-payload.d.ts +85 -0
  185. package/dist/src/lib/config-payload.js +116 -0
  186. package/dist/src/lib/config-payload.js.map +1 -0
  187. package/dist/src/lib/config-surface.d.ts +140 -0
  188. package/dist/src/lib/config-surface.js +317 -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 +517 -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/document-export-permissions.d.ts +30 -0
  236. package/dist/src/lib/document-export-permissions.js +54 -0
  237. package/dist/src/lib/document-export-permissions.js.map +1 -0
  238. package/dist/src/lib/env-resolver-core.d.ts +253 -0
  239. package/dist/src/lib/env-resolver-core.js +459 -0
  240. package/dist/src/lib/env-resolver-core.js.map +1 -0
  241. package/dist/src/lib/env-resolver.d.ts +99 -0
  242. package/dist/src/lib/env-resolver.js +153 -0
  243. package/dist/src/lib/env-resolver.js.map +1 -0
  244. package/dist/src/lib/fetch.d.ts +5 -0
  245. package/dist/src/lib/function-bundle.d.ts +141 -0
  246. package/dist/src/lib/function-bundle.js +333 -0
  247. package/dist/src/lib/function-bundle.js.map +1 -0
  248. package/dist/src/lib/function-collect.d.ts +123 -0
  249. package/dist/src/lib/function-collect.js +594 -0
  250. package/dist/src/lib/function-collect.js.map +1 -0
  251. package/dist/src/lib/function-db-types.d.ts +187 -0
  252. package/dist/src/lib/function-db-types.js +782 -0
  253. package/dist/src/lib/function-db-types.js.map +1 -0
  254. package/dist/src/lib/function-document-types.d.ts +50 -0
  255. package/dist/src/lib/function-document-types.js +163 -0
  256. package/dist/src/lib/function-document-types.js.map +1 -0
  257. package/dist/src/lib/function-grants-preflight.d.ts +64 -0
  258. package/dist/src/lib/function-grants-preflight.js +100 -0
  259. package/dist/src/lib/function-grants-preflight.js.map +1 -0
  260. package/dist/src/lib/function-log-tail.d.ts +83 -0
  261. package/dist/src/lib/function-log-tail.js +115 -0
  262. package/dist/src/lib/function-log-tail.js.map +1 -0
  263. package/dist/src/lib/function-schema-codegen.d.ts +118 -0
  264. package/dist/src/lib/function-schema-codegen.js +402 -0
  265. package/dist/src/lib/function-schema-codegen.js.map +1 -0
  266. package/dist/src/lib/function-sync.d.ts +263 -0
  267. package/dist/src/lib/function-sync.js +604 -0
  268. package/dist/src/lib/function-sync.js.map +1 -0
  269. package/dist/src/lib/function-triggers.d.ts +66 -0
  270. package/dist/src/lib/function-triggers.js +285 -0
  271. package/dist/src/lib/function-triggers.js.map +1 -0
  272. package/dist/src/lib/function-typecheck.d.ts +86 -0
  273. package/dist/src/lib/function-typecheck.js +370 -0
  274. package/dist/src/lib/function-typecheck.js.map +1 -0
  275. package/dist/src/lib/generated-allowlist.d.ts +28 -0
  276. package/dist/src/lib/generated-allowlist.js +281 -0
  277. package/dist/src/lib/generated-allowlist.js.map +1 -0
  278. package/dist/src/lib/generated-config-surfaces.d.ts +1445 -0
  279. package/dist/src/lib/generated-config-surfaces.js +5836 -0
  280. package/dist/src/lib/generated-config-surfaces.js.map +1 -0
  281. package/dist/src/lib/generated-sdk-types.d.ts +12 -0
  282. package/dist/src/lib/generated-sdk-types.js +13 -0
  283. package/dist/src/lib/generated-sdk-types.js.map +1 -0
  284. package/dist/src/lib/generated-template-lint.d.ts +212 -0
  285. package/dist/src/lib/generated-template-lint.js +624 -0
  286. package/dist/src/lib/generated-template-lint.js.map +1 -0
  287. package/dist/src/lib/generated-workflow-model-fields.d.ts +20 -0
  288. package/dist/src/lib/generated-workflow-model-fields.js +53 -0
  289. package/dist/src/lib/generated-workflow-model-fields.js.map +1 -0
  290. package/dist/src/lib/google-client-secret-status.d.ts +35 -0
  291. package/dist/src/lib/google-client-secret-status.js +56 -0
  292. package/dist/src/lib/google-client-secret-status.js.map +1 -0
  293. package/dist/src/lib/init-adopt.d.ts +16 -0
  294. package/dist/src/lib/init-adopt.js +34 -0
  295. package/dist/src/lib/init-adopt.js.map +1 -0
  296. package/dist/src/lib/init-assets.d.ts +39 -0
  297. package/dist/src/lib/init-assets.js +97 -0
  298. package/dist/src/lib/init-assets.js.map +1 -0
  299. package/dist/src/lib/init-client-platforms.d.ts +14 -0
  300. package/dist/src/lib/init-client-platforms.js +71 -0
  301. package/dist/src/lib/init-client-platforms.js.map +1 -0
  302. package/dist/src/lib/init-config.d.ts +98 -0
  303. package/dist/src/lib/init-config.js +186 -0
  304. package/dist/src/lib/init-config.js.map +1 -0
  305. package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
  306. package/dist/src/lib/init-email-redirect-uris.js +46 -0
  307. package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
  308. package/dist/src/lib/init-ios-links.d.ts +91 -0
  309. package/dist/src/lib/init-ios-links.js +219 -0
  310. package/dist/src/lib/init-ios-links.js.map +1 -0
  311. package/dist/src/lib/init-plan.d.ts +80 -0
  312. package/dist/src/lib/init-plan.js +95 -0
  313. package/dist/src/lib/init-plan.js.map +1 -0
  314. package/dist/src/lib/init-production-env.d.ts +48 -0
  315. package/dist/src/lib/init-production-env.js +59 -0
  316. package/dist/src/lib/init-production-env.js.map +1 -0
  317. package/dist/src/lib/init-schema.d.ts +74 -0
  318. package/dist/src/lib/init-schema.js +358 -0
  319. package/dist/src/lib/init-schema.js.map +1 -0
  320. package/dist/src/lib/init-xcode.d.ts +34 -0
  321. package/dist/src/lib/init-xcode.js +138 -0
  322. package/dist/src/lib/init-xcode.js.map +1 -0
  323. package/dist/src/lib/integration-request-config.d.ts +30 -0
  324. package/dist/src/lib/integration-request-config.js +145 -0
  325. package/dist/src/lib/integration-request-config.js.map +1 -0
  326. package/dist/src/lib/integration-selector.d.ts +42 -0
  327. package/dist/src/lib/integration-selector.js +46 -0
  328. package/dist/src/lib/integration-selector.js.map +1 -0
  329. package/dist/src/lib/ios-app-id.d.ts +34 -0
  330. package/dist/src/lib/ios-app-id.js +69 -0
  331. package/dist/src/lib/ios-app-id.js.map +1 -0
  332. package/dist/src/lib/local-state.d.ts +55 -0
  333. package/dist/src/lib/local-state.js +167 -0
  334. package/dist/src/lib/local-state.js.map +1 -0
  335. package/dist/src/lib/local-test-cases.d.ts +63 -0
  336. package/dist/src/lib/local-test-cases.js +136 -0
  337. package/dist/src/lib/local-test-cases.js.map +1 -0
  338. package/dist/src/lib/log-inspection.d.ts +680 -0
  339. package/dist/src/lib/log-inspection.js +784 -0
  340. package/dist/src/lib/log-inspection.js.map +1 -0
  341. package/dist/src/lib/migration-nag.d.ts +49 -0
  342. package/dist/src/lib/migration-nag.js +164 -0
  343. package/dist/src/lib/migration-nag.js.map +1 -0
  344. package/dist/src/lib/object-status-filter.d.ts +22 -0
  345. package/dist/src/lib/object-status-filter.js +45 -0
  346. package/dist/src/lib/object-status-filter.js.map +1 -0
  347. package/dist/src/lib/output.d.ts +109 -0
  348. package/dist/src/lib/output.js +191 -8
  349. package/dist/src/lib/output.js.map +1 -1
  350. package/dist/src/lib/package-manager.d.ts +140 -0
  351. package/dist/src/lib/package-manager.js +305 -0
  352. package/dist/src/lib/package-manager.js.map +1 -0
  353. package/dist/src/lib/paginate.d.ts +83 -0
  354. package/dist/src/lib/paginate.js +95 -0
  355. package/dist/src/lib/paginate.js.map +1 -0
  356. package/dist/src/lib/platform-owned.d.ts +63 -0
  357. package/dist/src/lib/platform-owned.js +85 -0
  358. package/dist/src/lib/platform-owned.js.map +1 -0
  359. package/dist/src/lib/project-config.d.ts +122 -0
  360. package/dist/src/lib/project-config.js +244 -0
  361. package/dist/src/lib/project-config.js.map +1 -0
  362. package/dist/src/lib/query-operators.d.ts +43 -0
  363. package/dist/src/lib/query-operators.js +80 -0
  364. package/dist/src/lib/query-operators.js.map +1 -0
  365. package/dist/src/lib/record-filter.d.ts +18 -0
  366. package/dist/src/lib/record-filter.js +55 -0
  367. package/dist/src/lib/record-filter.js.map +1 -0
  368. package/dist/src/lib/refresh-admin-credentials.d.ts +65 -0
  369. package/dist/src/lib/refresh-admin-credentials.js +103 -0
  370. package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
  371. package/dist/src/lib/resolve-init-dev-port.d.ts +56 -0
  372. package/dist/src/lib/resolve-init-dev-port.js +55 -0
  373. package/dist/src/lib/resolve-init-dev-port.js.map +1 -0
  374. package/dist/src/lib/resolve-init-server.d.ts +64 -0
  375. package/dist/src/lib/resolve-init-server.js +77 -0
  376. package/dist/src/lib/resolve-init-server.js.map +1 -0
  377. package/dist/src/lib/resolve-platform.d.ts +74 -0
  378. package/dist/src/lib/resolve-platform.js +105 -0
  379. package/dist/src/lib/resolve-platform.js.map +1 -0
  380. package/dist/src/lib/run-status.d.ts +19 -0
  381. package/dist/src/lib/run-status.generated.d.ts +39 -0
  382. package/dist/src/lib/run-status.generated.js +66 -0
  383. package/dist/src/lib/run-status.generated.js.map +1 -0
  384. package/dist/src/lib/run-status.js +19 -0
  385. package/dist/src/lib/run-status.js.map +1 -0
  386. package/dist/src/lib/server-text-normalization.d.ts +51 -0
  387. package/dist/src/lib/server-text-normalization.js +90 -0
  388. package/dist/src/lib/server-text-normalization.js.map +1 -0
  389. package/dist/src/lib/server-url.d.ts +22 -0
  390. package/dist/src/lib/server-url.js +33 -0
  391. package/dist/src/lib/server-url.js.map +1 -0
  392. package/dist/src/lib/signing-secret-status.d.ts +81 -0
  393. package/dist/src/lib/signing-secret-status.js +116 -0
  394. package/dist/src/lib/signing-secret-status.js.map +1 -0
  395. package/dist/src/lib/skill-installer.d.ts +25 -0
  396. package/dist/src/lib/skill-installer.js +266 -0
  397. package/dist/src/lib/skill-installer.js.map +1 -0
  398. package/dist/src/lib/snapshots.d.ts +98 -0
  399. package/dist/src/lib/snapshots.js +294 -0
  400. package/dist/src/lib/snapshots.js.map +1 -0
  401. package/dist/src/lib/swift-codegen/dbGenerator.d.ts +113 -0
  402. package/dist/src/lib/swift-codegen/dbGenerator.js +914 -0
  403. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -0
  404. package/dist/src/lib/swift-codegen/dbSwiftTypes.d.ts +42 -0
  405. package/dist/src/lib/swift-codegen/dbSwiftTypes.js +100 -0
  406. package/dist/src/lib/swift-codegen/dbSwiftTypes.js.map +1 -0
  407. package/dist/src/lib/swift-codegen/generator.d.ts +94 -0
  408. package/dist/src/lib/swift-codegen/generator.js +440 -0
  409. package/dist/src/lib/swift-codegen/generator.js.map +1 -0
  410. package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +72 -0
  411. package/dist/src/lib/swift-codegen/schemaToSwift.js +644 -0
  412. package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -0
  413. package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +94 -0
  414. package/dist/src/lib/swift-codegen/siblingSymbols.js +155 -0
  415. package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -0
  416. package/dist/src/lib/swift-codegen/swiftNaming.d.ts +85 -0
  417. package/dist/src/lib/swift-codegen/swiftNaming.js +198 -0
  418. package/dist/src/lib/swift-codegen/swiftNaming.js.map +1 -0
  419. package/dist/src/lib/sync-dir-selector.d.ts +21 -0
  420. package/dist/src/lib/sync-dir-selector.js +30 -0
  421. package/dist/src/lib/sync-dir-selector.js.map +1 -0
  422. package/dist/src/lib/sync-paths.d.ts +123 -0
  423. package/dist/src/lib/sync-paths.js +193 -0
  424. package/dist/src/lib/sync-paths.js.map +1 -0
  425. package/dist/src/lib/sync-resource-types.d.ts +563 -0
  426. package/dist/src/lib/sync-resource-types.js +1073 -0
  427. package/dist/src/lib/sync-resource-types.js.map +1 -0
  428. package/dist/src/lib/sync-selectors.d.ts +95 -0
  429. package/dist/src/lib/sync-selectors.js +228 -0
  430. package/dist/src/lib/sync-selectors.js.map +1 -0
  431. package/dist/src/lib/template.d.ts +170 -0
  432. package/dist/src/lib/template.js +484 -68
  433. package/dist/src/lib/template.js.map +1 -1
  434. package/dist/src/lib/test-case-file-names.d.ts +40 -0
  435. package/dist/src/lib/test-case-file-names.js +91 -0
  436. package/dist/src/lib/test-case-file-names.js.map +1 -0
  437. package/dist/src/lib/test-case-keys.d.ts +29 -0
  438. package/dist/src/lib/test-case-keys.js +55 -0
  439. package/dist/src/lib/test-case-keys.js.map +1 -0
  440. package/dist/src/lib/test-case-variables.d.ts +29 -0
  441. package/dist/src/lib/test-case-variables.js +71 -0
  442. package/dist/src/lib/test-case-variables.js.map +1 -0
  443. package/dist/src/lib/token-inject.d.ts +56 -0
  444. package/dist/src/lib/token-inject.js +204 -0
  445. package/dist/src/lib/token-inject.js.map +1 -0
  446. package/dist/src/lib/toml-database-config.d.ts +123 -0
  447. package/dist/src/lib/toml-database-config.js +544 -0
  448. package/dist/src/lib/toml-database-config.js.map +1 -0
  449. package/dist/src/lib/toml-metadata-config.d.ts +151 -0
  450. package/dist/src/lib/toml-metadata-config.js +476 -0
  451. package/dist/src/lib/toml-metadata-config.js.map +1 -0
  452. package/dist/src/lib/toml-native-form.d.ts +46 -0
  453. package/dist/src/lib/toml-native-form.js +78 -0
  454. package/dist/src/lib/toml-native-form.js.map +1 -0
  455. package/dist/src/lib/toml-params-validator.d.ts +129 -0
  456. package/dist/src/lib/toml-params-validator.js +298 -0
  457. package/dist/src/lib/toml-params-validator.js.map +1 -0
  458. package/dist/src/lib/toml-scalar-edit.d.ts +43 -0
  459. package/dist/src/lib/toml-scalar-edit.js +283 -0
  460. package/dist/src/lib/toml-scalar-edit.js.map +1 -0
  461. package/dist/src/lib/user-selector.d.ts +24 -0
  462. package/dist/src/lib/user-selector.js +33 -0
  463. package/dist/src/lib/user-selector.js.map +1 -0
  464. package/dist/src/lib/version-check.d.ts +35 -0
  465. package/dist/src/lib/version-check.js +241 -0
  466. package/dist/src/lib/version-check.js.map +1 -0
  467. package/dist/src/lib/watch.d.ts +121 -0
  468. package/dist/src/lib/watch.js +169 -0
  469. package/dist/src/lib/watch.js.map +1 -0
  470. package/dist/src/lib/web-url.d.ts +40 -0
  471. package/dist/src/lib/web-url.js +76 -0
  472. package/dist/src/lib/web-url.js.map +1 -0
  473. package/dist/src/lib/workflow-apply.d.ts +110 -0
  474. package/dist/src/lib/workflow-apply.js +164 -0
  475. package/dist/src/lib/workflow-apply.js.map +1 -0
  476. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.d.ts +129 -0
  477. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js +269 -0
  478. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js.map +1 -0
  479. package/dist/src/lib/workflow-codegen/generator.d.ts +96 -0
  480. package/dist/src/lib/workflow-codegen/generator.js +361 -0
  481. package/dist/src/lib/workflow-codegen/generator.js.map +1 -0
  482. package/dist/src/lib/workflow-codegen/invokerIR.d.ts +94 -0
  483. package/dist/src/lib/workflow-codegen/invokerIR.js +76 -0
  484. package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -0
  485. package/dist/src/lib/workflow-codegen/naming.d.ts +33 -0
  486. package/dist/src/lib/workflow-codegen/naming.js +81 -0
  487. package/dist/src/lib/workflow-codegen/naming.js.map +1 -0
  488. package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +80 -0
  489. package/dist/src/lib/workflow-codegen/schemaToTs.js +303 -0
  490. package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -0
  491. package/dist/src/lib/workflow-config-apply.d.ts +70 -0
  492. package/dist/src/lib/workflow-config-apply.js +137 -0
  493. package/dist/src/lib/workflow-config-apply.js.map +1 -0
  494. package/dist/src/lib/workflow-config-sidecar.d.ts +63 -0
  495. package/dist/src/lib/workflow-config-sidecar.js +96 -0
  496. package/dist/src/lib/workflow-config-sidecar.js.map +1 -0
  497. package/dist/src/lib/workflow-defaults.d.ts +29 -0
  498. package/dist/src/lib/workflow-defaults.js +41 -0
  499. package/dist/src/lib/workflow-defaults.js.map +1 -0
  500. package/dist/src/lib/workflow-field-descriptor.d.ts +91 -0
  501. package/dist/src/lib/workflow-field-descriptor.js +153 -0
  502. package/dist/src/lib/workflow-field-descriptor.js.map +1 -0
  503. package/dist/src/lib/workflow-fragments.d.ts +64 -0
  504. package/dist/src/lib/workflow-fragments.js +342 -0
  505. package/dist/src/lib/workflow-fragments.js.map +1 -0
  506. package/dist/src/lib/workflow-include-preserve.d.ts +76 -0
  507. package/dist/src/lib/workflow-include-preserve.js +286 -0
  508. package/dist/src/lib/workflow-include-preserve.js.map +1 -0
  509. package/dist/src/lib/workflow-payload.d.ts +98 -0
  510. package/dist/src/lib/workflow-payload.js +178 -0
  511. package/dist/src/lib/workflow-payload.js.map +1 -0
  512. package/dist/src/lib/workflow-toml-validator.d.ts +207 -0
  513. package/dist/src/lib/workflow-toml-validator.js +762 -0
  514. package/dist/src/lib/workflow-toml-validator.js.map +1 -0
  515. package/dist/src/lib/workflow-usage.d.ts +198 -0
  516. package/dist/src/lib/workflow-usage.js +312 -0
  517. package/dist/src/lib/workflow-usage.js.map +1 -0
  518. package/dist/src/types/index.d.ts +591 -0
  519. package/dist/src/validators.d.ts +65 -0
  520. package/dist/src/validators.js +64 -0
  521. package/dist/src/validators.js.map +1 -0
  522. package/package.json +34 -9
@@ -1,18 +1,36 @@
1
- import { readFileSync } from "fs";
2
- import * as TOML from "@iarna/toml";
1
+ import chalk from "chalk";
3
2
  import { ApiClient } from "../lib/api-client.js";
4
3
  import { resolveAppId } from "../lib/config.js";
5
- import { success, error, info, keyValue, formatTable, formatId, formatDate, formatStatus, formatDuration, json, divider, } from "../lib/output.js";
4
+ import { success, error, info, keyValue, result as printResult, formatTable, formatId, formatDate, formatStatus, formatDuration, json, divider, } from "../lib/output.js";
5
+ import { buildIntegrationEnvelope } from "../lib/log-inspection.js";
6
+ import { confirmPrompt } from "../lib/confirm-prompt.js";
7
+ import { parseStatusFilter } from "../lib/object-status-filter.js";
8
+ import { requireTestCaseInputVariables, testCaseInputVariables, } from "../lib/test-case-variables.js";
9
+ import { resolveIntegrationSelector } from "../lib/integration-selector.js";
6
10
  export function registerIntegrationsCommands(program) {
7
11
  const integrations = program
8
12
  .command("integrations")
9
- .description("Configure external HTTP API connections and manage secrets")
13
+ .description("Configure external HTTP API connections")
10
14
  .addHelpText("after", `
11
15
  Examples:
12
16
  $ primitive integrations list
13
- $ primitive integrations create --from-file weather-api.toml
17
+ $ primitive config create integration weather-api # scaffold integrations/weather-api.toml
18
+ $ primitive config push --only integration/weather-api # apply it
14
19
  $ primitive integrations test 01HXY...
15
- $ primitive integrations secrets add 01HXY... --data '{"apiKey":"..."}'
20
+ $ primitive integrations archive 01HXY... # retire it (soft delete)
21
+
22
+ Storing credentials for an integration:
23
+ $ primitive secrets set MY_API_KEY --value <value>
24
+ # then reference it in integration config via {{secrets.MY_API_KEY}}
25
+ `);
26
+ // Server-side configuration is authored in TOML and applied with `config push`
27
+ // (issue #2645) — this group no longer carries config-setting flags.
28
+ integrations.addHelpText("after", `
29
+ Configuration lives in integrations/<key>.toml:
30
+ $ primitive config fields integration # the file's keys, types and defaults
31
+ $ primitive config create integration <key> # scaffold one locally
32
+ $ primitive config set integration/<key> <path>=<value>
33
+ $ primitive config push --only integration/<key>
16
34
  `);
17
35
  // List integrations
18
36
  integrations
@@ -20,14 +38,20 @@ Examples:
20
38
  .description("List integrations")
21
39
  .argument("[app-id]", "App ID (uses current app if not specified)")
22
40
  .option("--app <app-id>", "App ID")
23
- .option("--status <status>", "Filter by status: draft, active, archived")
41
+ .option("--status <status>", "Filter by status: active, inactive, archived")
24
42
  .option("--json", "Output as JSON")
25
43
  .action(async (appId, options) => {
26
44
  const resolvedAppId = resolveAppId(appId, options);
27
45
  const client = new ApiClient();
28
46
  try {
47
+ // #2803 — `draft` is gone; refuse it by name rather than returning the
48
+ // empty list a canonical filter would produce.
29
49
  const { items } = await client.listIntegrations(resolvedAppId, {
30
- status: options.status,
50
+ status: parseStatusFilter("integrations", options.status, [
51
+ "active",
52
+ "inactive",
53
+ "archived",
54
+ ]),
31
55
  });
32
56
  if (options.json) {
33
57
  json(items);
@@ -50,195 +74,161 @@ Examples:
50
74
  process.exit(1);
51
75
  }
52
76
  });
53
- // Create integration
77
+ // #2645 criterion 9 / #2803 — the operational verbs. They are the only
78
+ // writers of `status`, which is server-owned and no longer a TOML key.
54
79
  integrations
55
- .command("create")
56
- .description("Create a new integration")
57
- .argument("[app-id]", "App ID (uses current app if not specified)")
58
- .option("--app <app-id>", "App ID")
59
- .option("--key <key>", "Integration key (unique identifier)")
60
- .option("--name <name>", "Display name")
61
- .option("--description <desc>", "Description")
62
- .option("--base-url <url>", "Base URL for API requests")
63
- .option("--allowed-methods <methods>", "Comma-separated list of allowed HTTP methods")
64
- .option("--allowed-paths <paths>", "Comma-separated list of allowed paths")
65
- .option("--timeout-ms <ms>", "Request timeout in milliseconds")
66
- .option("--from-file <path>", "Load integration from TOML file")
80
+ .command("disable")
81
+ .description("Take integration out of service now. Operational, not configuration: `status` is server-owned and 'config push' can neither set nor clear it.")
82
+ .argument("<integration-id>", "Integration ID")
83
+ .option("--app <app-id>", "App ID (uses current app if not specified)")
67
84
  .option("--json", "Output as JSON")
68
- .action(async (appId, options) => {
69
- const resolvedAppId = resolveAppId(appId, options);
85
+ .action(async (id, options) => {
86
+ const resolvedAppId = resolveAppId(undefined, options);
70
87
  const client = new ApiClient();
71
- let payload;
72
- if (options.fromFile) {
73
- try {
74
- const content = readFileSync(options.fromFile, "utf-8");
75
- const tomlData = TOML.parse(content);
76
- payload = {
77
- integrationKey: tomlData.integration?.key || tomlData.key,
78
- displayName: tomlData.integration?.displayName || tomlData.displayName,
79
- description: tomlData.integration?.description || tomlData.description,
80
- requestConfig: tomlData.requestConfig || {},
81
- timeoutMs: tomlData.integration?.timeoutMs || tomlData.timeoutMs,
82
- };
83
- }
84
- catch (err) {
85
- error(`Failed to read TOML file: ${err.message}`);
86
- process.exit(1);
87
- }
88
- }
89
- else {
90
- if (!options.key || !options.name || !options.baseUrl) {
91
- error("Required: --key, --name, --base-url (or use --from-file)");
92
- process.exit(1);
93
- }
94
- payload = {
95
- integrationKey: options.key,
96
- displayName: options.name,
97
- description: options.description,
98
- requestConfig: {
99
- baseUrl: options.baseUrl,
100
- allowedMethods: options.allowedMethods?.split(",").map((s) => s.trim()),
101
- allowedPaths: options.allowedPaths?.split(",").map((s) => s.trim()),
102
- },
103
- timeoutMs: options.timeoutMs ? parseInt(options.timeoutMs) : undefined,
104
- };
105
- }
106
88
  try {
107
- const result = await client.createIntegration(resolvedAppId, payload);
89
+ const result = await client.setIntegrationAvailability(resolvedAppId, id, "disable");
108
90
  if (options.json) {
109
91
  json(result);
110
92
  return;
111
93
  }
112
- success(`Integration created: ${result.displayName}`);
113
- keyValue("Integration ID", result.integrationId);
114
- keyValue("Key", result.integrationKey);
94
+ success(`Integration disabled: ${result.integrationKey || id}`);
115
95
  }
116
96
  catch (err) {
117
97
  error(err.message);
118
98
  process.exit(1);
119
99
  }
120
100
  });
121
- // Get integration
122
101
  integrations
123
- .command("get")
124
- .description("Get integration details")
102
+ .command("enable")
103
+ .description("Put integration back in service.")
125
104
  .argument("<integration-id>", "Integration ID")
126
105
  .option("--app <app-id>", "App ID (uses current app if not specified)")
127
106
  .option("--json", "Output as JSON")
128
- .action(async (integrationId, options) => {
107
+ .action(async (id, options) => {
129
108
  const resolvedAppId = resolveAppId(undefined, options);
130
109
  const client = new ApiClient();
131
110
  try {
132
- const result = await client.getIntegration(resolvedAppId, integrationId);
111
+ const result = await client.setIntegrationAvailability(resolvedAppId, id, "enable");
133
112
  if (options.json) {
134
113
  json(result);
135
114
  return;
136
115
  }
137
- keyValue("Integration ID", result.integrationId);
138
- keyValue("Key", result.integrationKey);
139
- keyValue("Name", result.displayName);
140
- keyValue("Description", result.description);
141
- keyValue("Status", formatStatus(result.status));
142
- keyValue("Timeout", result.timeoutMs ? `${result.timeoutMs}ms` : "-");
143
- if (result.requestConfig) {
144
- divider();
145
- info("Request Config:");
146
- keyValue(" Base URL", result.requestConfig.baseUrl);
147
- keyValue(" Allowed Methods", result.requestConfig.allowedMethods?.join(", ") || "all");
148
- keyValue(" Allowed Paths", result.requestConfig.allowedPaths?.join(", ") || "all");
149
- keyValue(" Response Passthrough", result.requestConfig.responsePassthrough);
150
- if (result.requestConfig.bodyMode) {
151
- keyValue(" Body Mode", result.requestConfig.bodyMode);
152
- }
153
- if (result.requestConfig.multipartFieldMapping?.length) {
154
- keyValue(" Multipart Fields", result.requestConfig.multipartFieldMapping
155
- .map((f) => `${f.fieldName} (${f.type}${f.attachmentIndex != null ? `, attachment[${f.attachmentIndex}]` : ""})`)
156
- .join(", "));
157
- }
158
- }
116
+ success(`Integration enabled: ${result.integrationKey || id}`);
159
117
  }
160
118
  catch (err) {
161
119
  error(err.message);
162
120
  process.exit(1);
163
121
  }
164
122
  });
165
- // Update integration
123
+ // #2907 — the delete flow's CLI spelling. Not a second writer of `status`:
124
+ // this is the plain `DELETE` the server has always answered by writing the
125
+ // tombstone, which until now only the admin API and the console could reach.
126
+ // Named `archive`, not `delete`, because a configuration noun gets no
127
+ // `delete` verb (docs/cli-design.md) and prune-by-push stays the only CLI
128
+ // hard-delete path.
166
129
  integrations
167
- .command("update")
168
- .description("Update an integration")
130
+ .command("archive")
131
+ .description("Retire an integration (soft delete). Delete-lifecycle, not `disable`: the row is kept, goes on holding its key, and there is no un-archive.")
169
132
  .argument("<integration-id>", "Integration ID")
170
133
  .option("--app <app-id>", "App ID (uses current app if not specified)")
171
- .option("--name <name>", "Display name")
172
- .option("--description <desc>", "Description")
173
- .option("--status <status>", "Status: draft, active, archived")
174
- .option("--timeout-ms <ms>", "Request timeout in milliseconds")
134
+ .option("-y, --yes", "Skip confirmation prompt")
175
135
  .option("--json", "Output as JSON")
176
- .action(async (integrationId, options) => {
136
+ .addHelpText("after", `
137
+ What archiving an integration costs:
138
+ The proxy refuses it, and so does every workflow step that calls it.
139
+ The archived row still holds its integrationKey, so a push cannot re-create
140
+ one under the same key.
141
+ \`primitive integrations enable\` refuses an archived integration; there is no
142
+ un-archive.
143
+
144
+ Reclaiming the key means hard-deleting the row:
145
+ $ rm integrations/<key>.toml
146
+ $ primitive config push --prune # confirmed; hard-deletes the row
147
+ # or hard-delete it in the console, then re-add the file and push.
148
+ `)
149
+ .action(async (id, options) => {
177
150
  const resolvedAppId = resolveAppId(undefined, options);
178
- const payload = {};
179
- if (options.name)
180
- payload.displayName = options.name;
181
- if (options.description)
182
- payload.description = options.description;
183
- if (options.status)
184
- payload.status = options.status;
185
- if (options.timeoutMs)
186
- payload.timeoutMs = parseInt(options.timeoutMs);
187
- if (Object.keys(payload).length === 0) {
188
- error("No update options specified.");
189
- process.exit(1);
151
+ if (!options.yes) {
152
+ let confirmed;
153
+ try {
154
+ confirmed = await confirmPrompt(`Archive integration ${id}? It is retired, goes on holding its key, ` +
155
+ `and there is no un-archive.`);
156
+ }
157
+ catch (err) {
158
+ error(err.message);
159
+ process.exit(1);
160
+ }
161
+ if (!confirmed) {
162
+ info("Cancelled.");
163
+ return;
164
+ }
190
165
  }
191
166
  const client = new ApiClient();
192
167
  try {
193
- const result = await client.updateIntegration(resolvedAppId, integrationId, payload);
168
+ // The soft delete: no `hard`, so the server writes the tombstone and
169
+ // keeps the row (and its canonical block mirror) in step.
170
+ const result = await client.deleteIntegration(resolvedAppId, id);
194
171
  if (options.json) {
195
172
  json(result);
196
173
  return;
197
174
  }
198
- success("Integration updated.");
175
+ success(`Integration archived: ${id}`);
176
+ info("It is retired and still holds its key — reclaim the key by removing its file and running a confirmed `primitive config push --prune`.");
199
177
  }
200
178
  catch (err) {
201
179
  error(err.message);
202
180
  process.exit(1);
203
181
  }
204
182
  });
205
- // Delete integration
206
183
  integrations
207
- .command("delete")
208
- .description("Delete or archive an integration")
184
+ .command("get")
185
+ .description("Get integration details")
209
186
  .argument("<integration-id>", "Integration ID")
210
187
  .option("--app <app-id>", "App ID (uses current app if not specified)")
211
- .option("--hard", "Permanently delete instead of archive")
212
- .option("-y, --yes", "Skip confirmation prompt")
188
+ .option("--json", "Output as JSON")
213
189
  .action(async (integrationId, options) => {
214
190
  const resolvedAppId = resolveAppId(undefined, options);
215
- if (!options.yes) {
216
- const action = options.hard ? "permanently delete" : "archive";
217
- const inquirer = await import("inquirer");
218
- const { confirm } = await inquirer.default.prompt([
219
- {
220
- type: "confirm",
221
- name: "confirm",
222
- message: `Are you sure you want to ${action} integration ${integrationId}?`,
223
- default: false,
224
- },
225
- ]);
226
- if (!confirm) {
227
- info("Cancelled.");
228
- return;
229
- }
230
- }
231
191
  const client = new ApiClient();
232
192
  try {
233
- await client.deleteIntegration(resolvedAppId, integrationId, options.hard);
234
- success(`Integration ${options.hard ? "deleted" : "archived"}.`);
193
+ const result = await client.getIntegration(resolvedAppId, integrationId);
194
+ if (options.json) {
195
+ json(result);
196
+ return;
197
+ }
198
+ printResult("Integration ID", result.integrationId);
199
+ printResult("Key", result.integrationKey);
200
+ printResult("Name", result.displayName);
201
+ printResult("Description", result.description);
202
+ printResult("Status", formatStatus(result.status));
203
+ printResult("Timeout", result.timeoutMs ? `${result.timeoutMs}ms` : "-");
204
+ // #2631: no rule means every non-admin call is denied. Print that in
205
+ // words — a blank or "-" would read as "unrestricted" and hide an
206
+ // integration that was never given a rule.
207
+ printResult("Access Rule", typeof result.accessRule === "string" && result.accessRule !== ""
208
+ ? result.accessRule
209
+ : "(none — all non-admin calls are denied; set one to allow callers)");
210
+ if (result.requestConfig) {
211
+ divider();
212
+ info("Request Config:");
213
+ printResult(" Base URL", result.requestConfig.baseUrl);
214
+ printResult(" Allowed Methods", result.requestConfig.allowedMethods?.join(", ") || "all");
215
+ printResult(" Allowed Paths", result.requestConfig.allowedPaths?.join(", ") || "all");
216
+ printResult(" Response Passthrough", result.requestConfig.responsePassthrough);
217
+ if (result.requestConfig.bodyMode) {
218
+ printResult(" Body Mode", result.requestConfig.bodyMode);
219
+ }
220
+ if (result.requestConfig.multipartFieldMapping?.length) {
221
+ printResult(" Multipart Fields", result.requestConfig.multipartFieldMapping
222
+ .map((f) => `${f.fieldName} (${f.type}${f.attachmentIndex != null ? `, attachment[${f.attachmentIndex}]` : ""})`)
223
+ .join(", "));
224
+ }
225
+ }
235
226
  }
236
227
  catch (err) {
237
228
  error(err.message);
238
229
  process.exit(1);
239
230
  }
240
231
  });
241
- // Test integration
242
232
  integrations
243
233
  .command("test")
244
234
  .description("Test an integration by making a request")
@@ -304,20 +294,33 @@ Examples:
304
294
  // List integration logs
305
295
  integrations
306
296
  .command("logs")
307
- .description("View integration request logs")
297
+ .description("View integration request logs (includes workflow-initiated calls; filter with --source workflow|user|admin|test)")
308
298
  .argument("<integration-id>", "Integration ID")
309
299
  .option("--app <app-id>", "App ID (uses current app if not specified)")
310
300
  .option("--limit <n>", "Number of logs to show", "20")
301
+ .option("--source <source>", "Filter by call source: user, admin, test, or workflow")
302
+ .option("--status <status>", "Filter by upstream HTTP status (e.g. 200, 500)")
303
+ .option("--from <iso>", "Only logs at or after this ISO timestamp")
304
+ .option("--to <iso>", "Only logs at or before this ISO timestamp")
311
305
  .option("--json", "Output as JSON")
312
306
  .action(async (integrationId, options) => {
313
307
  const resolvedAppId = resolveAppId(undefined, options);
314
308
  const client = new ApiClient();
315
309
  try {
310
+ const validSources = new Set(["user", "admin", "test", "workflow"]);
311
+ if (options.source && !validSources.has(options.source)) {
312
+ error(`Invalid --source value '${options.source}'. Must be one of: user, admin, test, workflow.`);
313
+ process.exit(1);
314
+ }
316
315
  const logs = await client.listIntegrationLogs(resolvedAppId, integrationId, {
317
316
  limit: parseInt(options.limit),
317
+ ...(options.source && { source: options.source }),
318
+ ...(options.status && { status: options.status }),
319
+ ...(options.from && { from: options.from }),
320
+ ...(options.to && { to: options.to }),
318
321
  });
319
322
  if (options.json) {
320
- json(logs);
323
+ json(buildIntegrationEnvelope(logs));
321
324
  return;
322
325
  }
323
326
  if (!logs || logs.length === 0) {
@@ -326,10 +329,13 @@ Examples:
326
329
  }
327
330
  console.log(formatTable(logs, [
328
331
  { header: "TIME", key: "timestamp", format: formatDate },
332
+ { header: "SOURCE", key: "source", format: (v) => v || "user" },
329
333
  { header: "METHOD", key: "method" },
330
334
  { header: "PATH", key: "path" },
331
335
  { header: "STATUS", key: "status" },
332
336
  { header: "DURATION", key: "durationMs", format: formatDuration },
337
+ { header: "WORKFLOW", key: "workflowKey", format: (v) => v || "" },
338
+ { header: "RUN", key: "runId", format: (v) => (v ? formatId(v) : "") },
333
339
  { header: "TRACE", key: "traceId", format: formatId },
334
340
  ]));
335
341
  }
@@ -338,33 +344,56 @@ Examples:
338
344
  process.exit(1);
339
345
  }
340
346
  });
341
- // Secrets subcommand
342
- const secrets = integrations.command("secrets").description("Manage integration secrets");
343
- // List secrets
344
- secrets
347
+ // ============================================
348
+ // TESTS SUBCOMMAND
349
+ // ============================================
350
+ const tests = integrations
351
+ .command("tests")
352
+ .description("Run and inspect integration test cases")
353
+ .addHelpText("after", `
354
+ Test cases are authored in TOML at integrations/<key>.tests/<name>.toml and
355
+ applied with \`primitive config push\` (issue #2769); \`config fields integration\`
356
+ lists the fields. Deleting a case is removing its file and running
357
+ \`config push --prune\`.
358
+
359
+ Every verb here takes the integration's KEY or its ID (#3000). An identifier
360
+ that names no integration in the app fails; \`Total Tests: 0\` only ever means
361
+ the integration exists and has no cases.
362
+
363
+ Examples:
364
+ $ primitive integrations tests list <integration>
365
+ $ primitive integrations tests run <integration> <test-case-id>
366
+ $ primitive integrations tests run-all <integration>
367
+ $ primitive integrations tests run-all <integration> --test-cases 01ABC,01DEF,01GHI
368
+ `);
369
+ // List test cases
370
+ tests
345
371
  .command("list")
346
- .description("List secrets for an integration")
347
- .argument("<integration-id>", "Integration ID")
372
+ .description("List test cases for an integration")
373
+ .argument("<integration>", "Integration key or ID")
348
374
  .option("--app <app-id>", "App ID (uses current app if not specified)")
349
375
  .option("--json", "Output as JSON")
350
- .action(async (integrationId, options) => {
376
+ .action(async (integration, options) => {
351
377
  const resolvedAppId = resolveAppId(undefined, options);
352
378
  const client = new ApiClient();
353
379
  try {
354
- const secretsList = await client.listIntegrationSecrets(resolvedAppId, integrationId);
380
+ // #3000 — resolve BEFORE listing: the test-case endpoint answers an
381
+ // unknown block with an empty page, so an unresolved identifier would
382
+ // print "No test cases found." and exit 0.
383
+ const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
384
+ const { items } = await client.listTestCases(resolvedAppId, "integration", integrationId);
355
385
  if (options.json) {
356
- json(secretsList);
386
+ json(items);
357
387
  return;
358
388
  }
359
- if (!secretsList || secretsList.length === 0) {
360
- info("No secrets found.");
389
+ if (!items || items.length === 0) {
390
+ info("No test cases found.");
361
391
  return;
362
392
  }
363
- console.log(formatTable(secretsList, [
364
- { header: "ID", key: "secretId", format: formatId },
365
- { header: "VERSION", key: "version" },
366
- { header: "SUMMARY", key: "secretSummary" },
367
- { header: "STATUS", key: "status", format: formatStatus },
393
+ console.log(formatTable(items, [
394
+ { header: "ID", key: "testCaseId", format: formatId },
395
+ { header: "NAME", key: "name" },
396
+ { header: "CONFIG", key: "configId", format: (v) => v ? formatId(v) : "-" },
368
397
  { header: "CREATED", key: "createdAt", format: formatDate },
369
398
  ]));
370
399
  }
@@ -373,61 +402,252 @@ Examples:
373
402
  process.exit(1);
374
403
  }
375
404
  });
376
- // Add secret
377
- secrets
378
- .command("add")
379
- .description("Add a secret to an integration")
380
- .argument("<integration-id>", "Integration ID")
405
+ // Get test case
406
+ tests
407
+ .command("get")
408
+ .description("Get test case details")
409
+ .argument("<integration>", "Integration key or ID")
410
+ .argument("<test-case-id>", "Test Case ID")
381
411
  .option("--app <app-id>", "App ID (uses current app if not specified)")
382
- .option("--data <json>", "Secret data as JSON (e.g., '{\"apiKey\":\"...\"}' )")
383
- .option("--summary <text>", "Description of the secret")
384
412
  .option("--json", "Output as JSON")
385
- .action(async (integrationId, options) => {
413
+ .action(async (integration, testCaseId, options) => {
386
414
  const resolvedAppId = resolveAppId(undefined, options);
387
- if (!options.data) {
388
- error("--data is required (JSON object with secret values)");
415
+ const client = new ApiClient();
416
+ try {
417
+ const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
418
+ const result = await client.getTestCase(resolvedAppId, "integration", integrationId, testCaseId);
419
+ if (options.json) {
420
+ json(result);
421
+ return;
422
+ }
423
+ printResult("Test Case ID", result.testCaseId);
424
+ printResult("Name", result.name);
425
+ printResult("Config ID", result.configId || "-");
426
+ printResult("Created", formatDate(result.createdAt));
427
+ divider();
428
+ info("Input Variables:");
429
+ console.log(JSON.stringify(testCaseInputVariables(result.inputVariables), null, 2));
430
+ if (result.expectedOutputPattern) {
431
+ divider();
432
+ printResult("Expected Pattern", result.expectedOutputPattern);
433
+ }
434
+ if (result.expectedOutputContains) {
435
+ divider();
436
+ info("Expected Contains:");
437
+ try {
438
+ console.log(JSON.stringify(JSON.parse(result.expectedOutputContains), null, 2));
439
+ }
440
+ catch {
441
+ console.log(result.expectedOutputContains);
442
+ }
443
+ }
444
+ if (result.expectedJsonSubset) {
445
+ divider();
446
+ info("Expected JSON Subset:");
447
+ try {
448
+ console.log(JSON.stringify(JSON.parse(result.expectedJsonSubset), null, 2));
449
+ }
450
+ catch {
451
+ console.log(result.expectedJsonSubset);
452
+ }
453
+ }
454
+ if (result.evaluatorPromptId) {
455
+ divider();
456
+ printResult("Evaluator Prompt", result.evaluatorPromptId);
457
+ printResult("Evaluator Config", result.evaluatorConfigId || "-");
458
+ }
459
+ }
460
+ catch (err) {
461
+ error(err.message);
389
462
  process.exit(1);
390
463
  }
391
- let secretData;
464
+ });
465
+ // Run a single test case
466
+ tests
467
+ .command("run")
468
+ .description("Run a single test case")
469
+ .argument("<integration>", "Integration key or ID")
470
+ .argument("<test-case-id>", "Test Case ID")
471
+ .option("--app <app-id>", "App ID (uses current app if not specified)")
472
+ .option("--config <config-id>", "Override config ID")
473
+ .option("--json", "Output as JSON")
474
+ .action(async (integration, testCaseId, options) => {
475
+ const resolvedAppId = resolveAppId(undefined, options);
476
+ const client = new ApiClient();
392
477
  try {
393
- secretData = JSON.parse(options.data);
478
+ const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
479
+ // Get test case to retrieve its variables
480
+ const testCase = await client.getTestCase(resolvedAppId, "integration", integrationId, testCaseId);
481
+ // #2968 — the case's variables ARE the request the run issues, so a
482
+ // dropped `inputVariables` here is the config's bare defaults instead
483
+ // of the case's method, path and body. The server hands them back
484
+ // parsed; older servers hand back JSON text. #3158 — an input that
485
+ // cannot be read stops the run and says why, rather than issuing a
486
+ // request the case never authored.
487
+ const variables = requireTestCaseInputVariables(testCase.inputVariables, testCaseId);
488
+ const result = await client.executeBlockTest(resolvedAppId, "integration", integrationId, {
489
+ variables,
490
+ testCaseId,
491
+ configId: options.config || testCase.configId,
492
+ });
493
+ if (options.json) {
494
+ json(result);
495
+ return;
496
+ }
497
+ const passed = result.verification?.passed;
498
+ if (passed) {
499
+ success("Test PASSED");
500
+ }
501
+ else {
502
+ error("Test FAILED");
503
+ }
504
+ keyValue("Duration", formatDuration(result.metrics?.durationMs));
505
+ if (result.verification) {
506
+ divider();
507
+ info("Verification:");
508
+ const v = result.verification;
509
+ keyValue(" Passed", v.passed ? chalk.green("Yes") : chalk.red("No"));
510
+ keyValue(" Checks", `${v.summary?.passed || 0}/${v.summary?.total || 0} passed`);
511
+ if (v.checks && v.checks.length > 0) {
512
+ console.log();
513
+ for (const check of v.checks) {
514
+ const icon = check.passed ? chalk.green("\u2713") : chalk.red("\u2717");
515
+ console.log(` ${icon} ${check.name}`);
516
+ if (!check.passed && check.message) {
517
+ console.log(` ${chalk.dim(check.message)}`);
518
+ }
519
+ }
520
+ }
521
+ }
522
+ if (result.output) {
523
+ divider();
524
+ info("Output:");
525
+ console.log(typeof result.output === "string" ? result.output : JSON.stringify(result.output, null, 2));
526
+ }
527
+ if (result.error) {
528
+ divider();
529
+ error(`Error: ${result.error}`);
530
+ }
531
+ if (!passed) {
532
+ process.exit(1);
533
+ }
394
534
  }
395
- catch {
396
- error("Invalid JSON in --data");
535
+ catch (err) {
536
+ error(err.message);
397
537
  process.exit(1);
398
538
  }
539
+ });
540
+ // Run all test cases (or a specific group)
541
+ tests
542
+ .command("run-all")
543
+ .description("Run all test cases for an integration, or a specific subset")
544
+ .argument("<integration>", "Integration key or ID")
545
+ .option("--app <app-id>", "App ID (uses current app if not specified)")
546
+ .option("--config <config-id>", "Override config ID for all tests")
547
+ .option("--test-cases <ids>", "Comma-separated list of test case IDs to run (runs only these)")
548
+ .option("--json", "Output as JSON")
549
+ .action(async (integration, options) => {
550
+ const resolvedAppId = resolveAppId(undefined, options);
399
551
  const client = new ApiClient();
400
552
  try {
401
- const result = await client.addIntegrationSecret(resolvedAppId, integrationId, {
402
- secretData,
403
- secretSummary: options.summary,
553
+ // #3000 — resolve BEFORE announcing the run: an unresolved identifier
554
+ // came back as `Total Tests: 0 / Failed: 0` and exit 0, which reads as
555
+ // a pass in CI.
556
+ const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
557
+ // Parse test case IDs if provided
558
+ let testCaseIds;
559
+ if (options.testCases) {
560
+ testCaseIds = options.testCases.split(",").map((id) => id.trim()).filter(Boolean);
561
+ if (testCaseIds.length === 0) {
562
+ error("No valid test case IDs provided in --test-cases");
563
+ process.exit(1);
564
+ }
565
+ }
566
+ if (!options.json) {
567
+ if (testCaseIds) {
568
+ info(`Running ${testCaseIds.length} selected test case(s)...`);
569
+ }
570
+ else {
571
+ info("Running all test cases...");
572
+ }
573
+ }
574
+ const result = await client.runAllTestCases(resolvedAppId, "integration", integrationId, {
575
+ overrideConfigId: options.config,
576
+ testCaseIds,
404
577
  });
405
578
  if (options.json) {
406
579
  json(result);
407
580
  return;
408
581
  }
409
- success("Secret added.");
410
- keyValue("Secret ID", result?.secretId);
411
- keyValue("Version", result?.version);
582
+ const { summary, runs, comparisonGroup } = result;
583
+ divider();
584
+ keyValue("Comparison Group", comparisonGroup);
585
+ keyValue("Total Tests", summary.total);
586
+ keyValue("Passed", chalk.green(summary.passed));
587
+ keyValue("Failed", summary.failed > 0 ? chalk.red(summary.failed) : "0");
588
+ divider();
589
+ if (runs && runs.length > 0) {
590
+ for (const r of runs) {
591
+ const passed = r.verification?.passed;
592
+ const icon = passed ? chalk.green("\u2713") : chalk.red("\u2717");
593
+ const status = passed ? "PASSED" : "FAILED";
594
+ console.log(`${icon} ${r.testCaseName} - ${status}`);
595
+ if (!passed && r.verification?.details?.reason) {
596
+ console.log(` ${chalk.dim(r.verification.details.reason)}`);
597
+ }
598
+ }
599
+ }
600
+ // Exit with error code if any tests failed
601
+ if (summary.failed > 0) {
602
+ process.exit(1);
603
+ }
412
604
  }
413
605
  catch (err) {
414
606
  error(err.message);
415
607
  process.exit(1);
416
608
  }
417
609
  });
418
- // Archive secret
419
- secrets
420
- .command("archive")
421
- .description("Archive a secret")
422
- .argument("<integration-id>", "Integration ID")
423
- .argument("<secret-id>", "Secret ID")
610
+ // List test runs
611
+ tests
612
+ .command("runs")
613
+ .description("List recent test runs for an integration")
614
+ .argument("<integration>", "Integration key or ID")
424
615
  .option("--app <app-id>", "App ID (uses current app if not specified)")
425
- .action(async (integrationId, secretId, options) => {
616
+ .option("--limit <n>", "Maximum number of runs to show", "20")
617
+ .option("--group <group>", "Filter by comparison group")
618
+ .option("--json", "Output as JSON")
619
+ .action(async (integration, options) => {
426
620
  const resolvedAppId = resolveAppId(undefined, options);
427
621
  const client = new ApiClient();
428
622
  try {
429
- await client.archiveIntegrationSecret(resolvedAppId, integrationId, secretId);
430
- success("Secret archived.");
623
+ const { integrationId } = await resolveIntegrationSelector(client, resolvedAppId, integration);
624
+ const { items } = await client.listTestRuns(resolvedAppId, "integration", integrationId, {
625
+ limit: parseInt(options.limit),
626
+ comparisonGroup: options.group,
627
+ });
628
+ if (options.json) {
629
+ json(items);
630
+ return;
631
+ }
632
+ if (!items || items.length === 0) {
633
+ info("No test runs found.");
634
+ return;
635
+ }
636
+ console.log(formatTable(items, [
637
+ { header: "RUN ID", key: "runId", format: formatId },
638
+ { header: "TEST CASE ID", key: "testCaseId", format: (v) => v ? formatId(v) : "-" },
639
+ {
640
+ header: "PASSED",
641
+ key: "verificationPassed",
642
+ format: (v) => v === true
643
+ ? chalk.green("Yes")
644
+ : v === false
645
+ ? chalk.red("No")
646
+ : "-",
647
+ },
648
+ { header: "DURATION", key: "durationMs", format: formatDuration },
649
+ { header: "STARTED", key: "startedAt", format: formatDate },
650
+ ]));
431
651
  }
432
652
  catch (err) {
433
653
  error(err.message);