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
package/README.md CHANGED
@@ -5,9 +5,13 @@ Command-line interface for administering Primitive applications. This CLI provid
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install -g primitive-admin
8
+ pnpm add -g primitive-admin
9
9
  ```
10
10
 
11
+ pnpm is the recommended package manager. If you use npm instead, run
12
+ `npm install -g primitive-admin` — install with one manager only, or you end up
13
+ with two global copies.
14
+
11
15
  ### Development Setup
12
16
 
13
17
  From the **worklet root directory**:
@@ -55,10 +59,7 @@ The globally linked `primitive` command uses the compiled files in `cli/dist/`,
55
59
  # Login via browser OAuth
56
60
  primitive login
57
61
 
58
- # Set your working app context
59
- primitive use "My App"
60
-
61
- # List users in the current app
62
+ # List users in the app this project's environment names
62
63
  primitive users list
63
64
 
64
65
  # View help for any command
@@ -71,11 +72,15 @@ primitive apps --help
71
72
  The CLI uses browser-based OAuth for authentication. When you run `primitive login`, it opens your browser to authenticate via Google OAuth and stores credentials locally.
72
73
 
73
74
  ```bash
74
- # Login to the default server
75
+ # Login to the environment resolved from the project config, or — outside a
76
+ # project — to the default/PRIMITIVE_SERVER_URL server
75
77
  primitive login
76
78
 
77
- # Login to a custom server
78
- primitive login --server https://api.example.com
79
+ # Login to a specific named environment
80
+ primitive -e prod login
81
+
82
+ # Login to a custom server from outside a project
83
+ PRIMITIVE_SERVER_URL=https://api.example.com primitive login
79
84
 
80
85
  # View current session
81
86
  primitive whoami
@@ -87,39 +92,50 @@ primitive token
87
92
  primitive logout
88
93
  ```
89
94
 
90
- Credentials are stored in `~/.primitive/credentials.json` with mode 0600.
95
+ Inside a project, credentials are stored per environment in the gitignored
96
+ `<projectRoot>/.primitive/credentials.json`; a `login` run outside a project
97
+ writes `~/.primitive/credentials.json`. Both are mode 0600. Only `login`,
98
+ `logout`, `bootstrap` and `init` work outside a project — every other command
99
+ stops with an error naming the missing `primitive/config.json`, rather than
100
+ reading the global file (see [Outside a project](#outside-a-project)).
91
101
 
92
102
  ## App Context
93
103
 
94
- Most commands require an app ID. You can specify it in two ways:
104
+ Every environment names exactly one app, via `"appId"` in
105
+ `.primitive/config.json`. Selecting an environment selects its app, so most
106
+ commands need no app argument at all — and there is no separate, per-machine
107
+ "current app" that could point somewhere else.
95
108
 
96
- 1. **Flag**: `primitive users list --app 01HXYZ...`
97
- 2. **Context**: Set once with `primitive use`, then omit from commands
109
+ ```bash
110
+ # The app the selected environment names
111
+ primitive whoami
112
+ primitive env show
98
113
 
99
- Commands that only need an app ID (like `list`) also accept it as a positional argument:
114
+ # Point an environment at a different app: edit its "appId" in
115
+ # .primitive/config.json.
116
+ ```
117
+
118
+ Commands that read across apps still take an explicit one. Those that only need
119
+ an app ID (like `list`) accept it as a positional argument:
100
120
  ```bash
101
121
  primitive users list 01HXYZ...
102
122
  ```
103
123
 
104
- Commands with other required arguments use only `--app` for the app ID:
124
+ Commands with other required arguments use `--app`:
105
125
  ```bash
106
126
  primitive workflows get <workflow-id> --app 01HXYZ...
107
127
  ```
108
128
 
109
- ```bash
110
- # Interactive app selection
111
- primitive use
112
-
113
- # Set by name or ID
114
- primitive use "My App"
115
- primitive use 01HXYZ...
129
+ ### Outside a project
116
130
 
117
- # View current context
118
- primitive context
119
-
120
- # Clear context
121
- primitive context clear
122
- ```
131
+ With no project config up the directory tree there is no environment, so there
132
+ is nothing for an app-scoped command to target. Only `login`, `logout`,
133
+ `bootstrap` and `init` work there; everything else (`whoami`, `apps list`,
134
+ `env add`, `config pull`, …) exits non-zero with an error that names the
135
+ missing `primitive/config.json` and points at `primitive init`. The CLI never
136
+ falls back to `~/.primitive/credentials.json` for those commands, and no flag
137
+ redirects a command at another project's tree — run it from inside the project
138
+ whose environment names the app.
123
139
 
124
140
  ## Commands
125
141
 
@@ -129,17 +145,20 @@ Manage applications (requires admin access).
129
145
 
130
146
  ```bash
131
147
  primitive apps list # List all accessible apps
132
- primitive apps create "My App" # Create a new app
148
+ primitive apps create "My App" # Create a new app (mints the app id)
133
149
  primitive apps get <app-id> # Get app details
134
- primitive apps update <app-id> [opts] # Update app settings
135
150
  primitive apps delete <app-id> # Delete an app
136
151
  ```
137
152
 
138
- **Update options:**
139
- - `--name <name>` - App display name
140
- - `--mode <mode>` - Access mode: public, invite-only, waitlist
141
- - `--base-url <url>` - Application base URL
142
- - `--waitlist` / `--no-waitlist` - Enable/disable waitlist
153
+ App settings are configuration, so they are authored in `app.toml` and applied
154
+ with `config push` (issue #2645) there is no `apps update`:
155
+
156
+ ```bash
157
+ primitive apps get # what the server is running
158
+ primitive config pull --only app # write those settings into app.toml
159
+ primitive config set app app.mode=invite-only
160
+ primitive config push --only app # apply the edit
161
+ ```
143
162
  - `--google-oauth` / `--no-google-oauth` - Enable/disable Google OAuth
144
163
  - `--passkey` / `--no-passkey` - Enable/disable passkey auth
145
164
  - `--magic-link` / `--no-magic-link` - Enable/disable magic link auth
@@ -150,12 +169,13 @@ Manage users within an app.
150
169
 
151
170
  ```bash
152
171
  primitive users list [app-id] # List users
172
+ primitive users create <email> [--role admin|member] # Create/add user by email
153
173
  primitive users invite [app-id] <email> [--role admin] # Invite user
154
174
  primitive users remove [app-id] <user-id> # Remove user
155
175
  primitive users set-role [app-id] <user-id> <role> # Change role
156
176
  primitive users transfer-owner [app-id] <new-owner-id> # Transfer ownership
157
- primitive users invitations list [app-id] # List pending invitations
158
- primitive users invitations delete [app-id] <inv-id> # Delete invitation
177
+ primitive users mint-jwt <user-id> [--role <role>] # Mint test JWT (dev/test only)
178
+ primitive users invitations [app-id] # List pending invitations
159
179
  ```
160
180
 
161
181
  ### Waitlist
@@ -175,57 +195,72 @@ Manage HTTP integrations (external API connections).
175
195
 
176
196
  ```bash
177
197
  primitive integrations list [app-id] # List integrations
178
- primitive integrations create [app-id] [options] # Create integration
179
198
  primitive integrations get <integration-id> # Get details
180
- primitive integrations update <id> [options] # Update integration
181
- primitive integrations delete <id> # Soft delete
182
199
  primitive integrations test <id> # Test connection
183
200
  primitive integrations logs <id> # View invocation logs
184
201
  ```
185
202
 
186
- **Create options:**
187
- - `--from-file <path>` - Load from TOML file
188
- - `--key <key>` - Integration key (identifier)
189
- - `--name <name>` - Display name
190
- - `--base-url <url>` - Base URL for API calls
191
- - `--timeout <ms>` - Request timeout in milliseconds
203
+ An integration is authored in `integrations/<key>.toml` and applied with
204
+ `config push` creating, updating and deleting one are all edits to that file:
205
+
206
+ ```bash
207
+ primitive config fields integration # its keys, types, defaults
208
+ primitive config create integration weather-api # scaffold the file
209
+ primitive config push --only integration/weather-api
210
+ ```
192
211
 
193
212
  **Secrets management:**
213
+
214
+ Integration-scoped secrets are **retired** — the `primitive integrations secrets`
215
+ command group no longer exists. Use app-level secrets instead
216
+ (`primitive secrets set <KEY> --value <value>`) and reference them in integration
217
+ config via `{{secrets.KEY}}`. See the **Secrets** section below.
218
+
219
+ ### Secrets
220
+
221
+ Manage encrypted app secrets (API keys, tokens, credentials). Values are encrypted at rest and never displayed after creation.
222
+
194
223
  ```bash
195
- primitive integrations secrets list <integration-id>
196
- primitive integrations secrets add <id> --data '{"apiKey":"..."}'
197
- primitive integrations secrets archive <id> <secret-id>
224
+ primitive secrets list [--app <app-id>] # List secrets (values never shown)
225
+ primitive secrets set <KEY> --value <value> [--summary <text>] # Create or update a secret
226
+ primitive secrets delete <KEY> # Delete a secret
198
227
  ```
199
228
 
229
+ **Examples:**
230
+ ```bash
231
+ primitive secrets set OPENAI_API_KEY --value "sk-..." --summary "Production key"
232
+ primitive secrets set STRIPE_SECRET --value "sk_live_..."
233
+ primitive secrets list --json
234
+ primitive secrets delete STRIPE_SECRET
235
+ ```
236
+
237
+ Keys must be uppercase letters, digits, and underscores (e.g., `OPENAI_API_KEY`). Max 100 secrets per app, 2 KB per value. The `set` command is an upsert — it creates or updates automatically. Use `{{secrets.KEY}}` in workflows and `secrets.KEY` in CEL rules.
238
+
200
239
  ### Prompts
201
240
 
202
241
  Manage LLM prompt configurations.
203
242
 
204
243
  ```bash
205
244
  primitive prompts list [app-id] # List prompts
206
- primitive prompts create [app-id] [options] # Create prompt
207
245
  primitive prompts get <prompt-id> # Get details
208
- primitive prompts update <id> [options] # Update prompt
209
- primitive prompts delete <id> # Soft delete
210
246
  primitive prompts execute <id> --vars '{}' # Execute prompt
211
247
  primitive prompts preview <id> --vars '{}' # Preview rendered template
212
248
  ```
213
249
 
214
- **Create options:**
215
- - `--from-file <path>` - Load from TOML file
216
- - `--key <key>` - Prompt key (identifier)
217
- - `--name <name>` - Display name
218
- - `--provider <provider>` - LLM provider (openrouter, gemini)
219
- - `--model <model>` - Model name
220
- - `--system-prompt <text>` - System prompt
221
- - `--user-template <text>` - User prompt template
250
+ A prompt is authored in `prompts/<key>.toml` and applied with `config push`:
251
+
252
+ ```bash
253
+ primitive config create prompt summarizer
254
+ primitive config push --only prompt/summarizer
255
+ ```
256
+
257
+ **Configs (prompt variations)** are `[[configs]]` entries in that same file —
258
+ `active = true` marks the live one, `status = "archived"` retires one, and
259
+ duplicating is copying the block under a new `name`. The CLI reads them:
222
260
 
223
- **Configs (prompt variations):**
224
261
  ```bash
225
262
  primitive prompts configs list <prompt-id>
226
- primitive prompts configs create <prompt-id> [options]
227
- primitive prompts configs activate <prompt-id> <config-id>
228
- primitive prompts configs duplicate <prompt-id> <config-id>
263
+ primitive prompts configs get <prompt> <config>
229
264
  ```
230
265
 
231
266
  ### Workflows
@@ -234,20 +269,103 @@ Manage multi-step workflow definitions.
234
269
 
235
270
  ```bash
236
271
  primitive workflows list [app-id] # List workflows
237
- primitive workflows create [app-id] --from-file wf.toml # Create workflow
238
272
  primitive workflows get <workflow-id> # Get details
239
- primitive workflows update <id> [options] # Update metadata
240
- primitive workflows draft update <id> --from-file wf.toml # Update draft
241
- primitive workflows publish <id> # Publish draft
242
273
  primitive workflows preview <id> --input '{}' # Preview execution
274
+ primitive workflows disable <id> # Take it out of service now
275
+ primitive workflows enable <id> # Put it back
243
276
  ```
244
277
 
278
+ A workflow is authored in `workflows/<key>.toml` (named config bodies in
279
+ `workflows/<key>.configs/<name>.toml`) and applied with `config push`:
280
+
281
+ ```bash
282
+ primitive config create workflow process-doc
283
+ primitive config push --only workflow/process-doc
284
+ ```
285
+
286
+ Revisions are read-only history from the retired legacy path (issue #2768:
287
+ `workflows publish` and its endpoint are gone). A workflow created before the
288
+ configuration model — one with no active config — is migrated by authoring
289
+ `workflows/<key>.configs/<name>.toml`, setting `activeConfigName = "<name>"` in
290
+ `workflows/<key>.toml`, and pushing.
291
+
245
292
  **Run management:**
246
293
  ```bash
247
294
  primitive workflows runs list <workflow-id>
248
295
  primitive workflows runs status <workflow-id> <run-id>
249
296
  ```
250
297
 
298
+ **Workflow TOML push-time validation (issue #685):** `primitive config push` —
299
+ the only command that sends a workflow TOML since #2645 — runs the
300
+ file through `cli/src/lib/workflow-toml-validator.ts` before sending it to
301
+ the server. For a step whose `kind` the CLI knows about, the validator
302
+ rejects any top-level field outside the allowlist — most commonly catching
303
+ the footgun where `[steps.<id>.request]` is written under `[[steps]]` (TOML
304
+ places the sub-table under `steps[N][<id>]`, not the intended
305
+ `steps[N].request`, so the runtime silently runs the step with an empty
306
+ `request` block). The correct form for the most-recent step is
307
+ `[steps.request]`. For a step whose `kind` the CLI does NOT know (an older
308
+ CLI run against a newer server that registered a new step kind), the
309
+ per-field check is skipped — so a valid new-kind field is never falsely
310
+ rejected — while the kind-agnostic misnested-header footgun detector still
311
+ fires (issue #998).
312
+
313
+ **The allowlist is generated, not hand-maintained (issue #998):** The field
314
+ union and the known-kind set live in the committed artifact
315
+ `cli/src/lib/generated-allowlist.ts`, generated from the server step runners
316
+ (`src/workflows/steps/*.ts`) and the universal `BaseStepDefinition` shape by
317
+ `cli/scripts/gen-allowlist.mjs`. The generator runs automatically at CLI
318
+ `prebuild`; regenerate manually with `node cli/scripts/gen-allowlist.mjs`
319
+ (or `pnpm -C cli gen:allowlist`). The union is derived from what each runner
320
+ *reads* off the step config — not from what the `*StepDefinition` type
321
+ declares (types over-declare and would weaken the footgun detector). A
322
+ freshness guard (`node cli/scripts/gen-allowlist.mjs --check`, also asserted
323
+ by `cli/tests/unit/workflow-toml-validator-drift-guard.test.ts`) fails if the
324
+ committed artifact drifts from a fresh scan, so the historical hand-edit
325
+ drift (#685/#802/#971) cannot recur. When you add a new step kind or a runner
326
+ starts reading a new field, just regenerate and commit the artifact — there is
327
+ no hand-maintained list to update.
328
+
329
+ **A configuration object's field surface has ONE definition (issue #2644):**
330
+ `src/config-surface/` on the server records, per configuration object, which
331
+ `models.yaml` fields exist, which TOML key each carries, which modes the server
332
+ accepts it in, and — for a field with real behavior — the handler that owns it.
333
+ The server's create/update handlers take their accepted key set from it
334
+ (`pickWritableFields`), and `cli/scripts/gen-config-surfaces.mjs` vendors the
335
+ same modules into the committed artifact
336
+ `cli/src/lib/generated-config-surfaces.ts`, which the CLI's push builder, pull
337
+ serializer and TOML key validation read. The generator runs automatically at CLI
338
+ `prebuild`; regenerate manually with `node cli/scripts/gen-config-surfaces.mjs`
339
+ (or `pnpm -C cli gen:config-surfaces`).
340
+
341
+ Three hard-fail checks live in `cli/tests/unit/config-surface-drift-guard.test.ts`:
342
+ freshness (`--check`, a byte comparison), coverage (every model field of every
343
+ registered object is either exposed or classified `notExposed` **with a
344
+ reason**), and registry existence (every `SYNC_RESOURCE_TYPES` label has a
345
+ definition — the migration's `PENDING_MIGRATION` exemption list is gone, so
346
+ there is nowhere to park one). Add a
347
+ field to `models.yaml` and the CLI unit suite fails until you regenerate and
348
+ classify it — so the CLI can no longer silently drop a new server-side field.
349
+ This supersedes the workflow-only descriptor and generator from #2326.
350
+
351
+ **Template expressions are linted at push time (issue #2689):** the validator
352
+ also inspects every `{{ }}` expression on a step and rejects the ones that can
353
+ never resolve — an unknown root (`{{ inputs.userId }}`; the valid roots are
354
+ `input`, `steps`, `outputs`, `meta`, `secrets`, `vars`, plus the contextual
355
+ `selected`/`user`/`md`, the built-ins `now`/`today`/`uuid`/`ulid`, and — inside a
356
+ forEach step's body only — `iteration`/`loop` and the loop's binding name) or a
357
+ reference to a `steps.<id>` / `outputs.<name>` the file does not declare. An
358
+ expression that is only sometimes present is marked optional with
359
+ `| default: ''` or a trailing `|| ''`, and anything statically undecidable (a
360
+ dynamic bracket key) is left to the run-time check. The lint itself is a
361
+ verbatim generated copy of the server module
362
+ `src/workflows/runner/template-static-lint.ts` at
363
+ `cli/src/lib/generated-template-lint.ts` (`cli/scripts/gen-template-lint.mjs`,
364
+ run at `prebuild`, with a `--check` freshness mode asserted by
365
+ `cli/tests/unit/template-lint-drift-guard.test.ts`), so the CLI's push-time
366
+ verdict and the server's save-time verdict come from the same code.
367
+
368
+
251
369
  ### Tokens
252
370
 
253
371
  Manage long-lived API access tokens for headless/server authentication.
@@ -263,7 +381,7 @@ primitive tokens revoke <token-id> [app-id] # Revoke t
263
381
  **Create options:**
264
382
  - `--name <name>` - Token name (required)
265
383
  - `--user <user-id>` - App user ID to associate the token with (required)
266
- - `--ttl <duration>` - Token lifetime (e.g., 7d, 30d, 4w, 3m, 1y). Omit for never-expiring
384
+ - `--ttl <duration>` - Token lifetime (e.g., 30m, 2h, 7d, 30d, 4w, 3mo, 1y). Omit for never-expiring. Units: `m`/`min`=minutes (≤1440), `h`=hours (≤24), `d`=days, `w`=weeks, `mo`=months, `y`=years. **Note:** as of #420 `m` means minutes (was months); use `mo` for months.
267
385
 
268
386
  ### Databases
269
387
 
@@ -273,6 +391,7 @@ Manage online databases and permissions. `list` returns databases the user has d
273
391
  primitive databases list [app-id] # List databases (direct access)
274
392
  primitive databases create <title> [app-id] # Create database
275
393
  primitive databases get <database-id> [app-id] # Get details
394
+ primitive databases update <database-id> [options] # Update title or type
276
395
  primitive databases delete <database-id> [app-id] # Delete database
277
396
  ```
278
397
 
@@ -283,18 +402,48 @@ primitive databases permissions grant <database-id> --user-id <uid> --permission
283
402
  primitive databases permissions revoke <database-id> <user-id> [app-id]
284
403
  ```
285
404
 
286
- **Group permissions on databases:**
405
+ Permission values: `owner` (set at creation), `manager`
406
+
407
+ **Metadata:**
287
408
  ```bash
288
- primitive databases group-permissions list <database-id>
289
- primitive databases group-permissions grant <database-id> --group-type <type> --group-id <id> --permission <perm>
290
- primitive databases group-permissions revoke <database-id> <group-type> <group-id>
409
+ primitive databases metadata update <database-id> --data '{"key":"value"}' # Merge-update metadata
291
410
  ```
292
411
 
293
- Permission values: `owner`, `read-write`, `reader`
412
+ **Operations:**
413
+ ```bash
414
+ primitive databases operations list <database-id> [app-id] # List registered operations
415
+ primitive databases operations execute <database-id> <op-name> --params '{}' # Execute operation
416
+ primitive databases operations execute <database-id> <op-name> --token <jwt> # Execute as specific user
417
+ ```
418
+
419
+ The `--token` flag lets you execute an operation as a specific user using a test JWT from `users mint-jwt`. Useful for testing access rules.
420
+
421
+ Under `--json`, the printed shape is the operation's own. A `query` — and a `pipeline` whose `returnField` names a query step — prints the CLI's list envelope `{ items, hasMore, nextCursor? }`, the same shape as `databases records query --json`. Every other operation type prints unchanged: `count` → `{ count }`, `aggregate` → `{ result }`, mutation → `{ results }`, `applyToQuery` → `{ matched, affected, failed, … }`, and a `returnField = "all"` pipeline → `{ steps: { … } }` with each step's own keys left alone. `--timing` adds `_timing` alongside whichever shape you get.
422
+
423
+ **Records (schema introspection):**
424
+ ```bash
425
+ primitive databases records models <database-id> [app-id] # List model names
426
+ primitive databases records describe <database-id> <model> [app-id] # Show inferred schema
427
+ ```
428
+
429
+ **Indexes:**
430
+ ```bash
431
+ primitive databases indexes list <database-id> [--model <name>] # List indexes
432
+ primitive databases indexes create <database-id> <model> <field> [options] # Create index
433
+ primitive databases indexes drop <database-id> <model> <field> # Drop index
434
+ ```
435
+
436
+ **Export / Import:**
437
+ ```bash
438
+ primitive databases export [app-id] <database-id> --output <dir> # Export records, indexes, constraints
439
+ primitive databases import [app-id] <path> --overwrite --dry-run # Import from export directory
440
+ ```
441
+
442
+ Export creates a directory with `metadata.json`, `records.jsonl`, `indexes.json`, and `constraints.json`. Import restores records and indexes into a new or existing database. Database type config (operations, triggers, access rules) is managed separately via `primitive config` — run `config push` on the target app before importing.
294
443
 
295
444
  ### Documents
296
445
 
297
- Manage document ownership and group permissions.
446
+ Manage document ownership, group permissions, and export/import.
298
447
 
299
448
  ```bash
300
449
  primitive documents transfer-owner [app-id] <document-id> <new-owner-id> # Transfer ownership
@@ -309,6 +458,15 @@ primitive documents group-permissions revoke <document-id> <group-type> <group-i
309
458
 
310
459
  Permission values: `read-write`, `reader`
311
460
 
461
+ **Export / Import:**
462
+ ```bash
463
+ primitive documents export [app-id] <document-id> --output <dir> # Export Yjs state, blobs, permissions, aliases
464
+ primitive documents export-all [app-id] --user-id <id> --owned-only # Export all docs for a user
465
+ primitive documents import [app-id] <path> --overwrite --aliases overwrite|skip --dry-run # Import from export
466
+ ```
467
+
468
+ Export creates a directory per document with `metadata.json`, `document.yjs` (Yjs state), `permissions.json` (for reference), and `blobs/` (attachments). Permissions are exported for reference but not restored during import — the importing admin is the new owner and manages sharing in the target app. Document IDs are preserved across import. User-scoped aliases can be restored with `--aliases overwrite` (update existing) or `--aliases skip` (keep existing, default).
469
+
312
470
  ### Groups
313
471
 
314
472
  Manage groups, members, and memberships.
@@ -336,26 +494,44 @@ primitive groups memberships <user-id> [app-id] # List user's group mem
336
494
 
337
495
  **Group resource access:**
338
496
  ```bash
339
- primitive groups databases <group-type> <group-id> # List databases a group can access
340
497
  primitive groups documents <group-type> <group-id> # List documents a group can access
341
498
  ```
342
499
 
343
- Group permissions on databases and documents are managed via `primitive databases group-permissions` and `primitive documents group-permissions` respectively (see [Databases](#databases) and [Documents](#documents) above).
500
+ Group permissions on documents are managed via `primitive documents group-permissions` (see [Documents](#documents) above).
344
501
 
345
502
  ### Analytics
346
503
 
347
504
  View usage analytics for an app.
348
505
 
349
506
  ```bash
350
- primitive analytics overview [app-id] # Activity overview
351
- primitive analytics top-users [app-id] # Most active users
352
- primitive analytics user [app-id] <user-ulid> # User activity details
353
- primitive analytics integrations [app-id] # Integration metrics
507
+ # Overview & active users
508
+ primitive analytics overview [app-id] # DAU / WAU / MAU + growth
509
+ primitive analytics daily-active [app-id] # Daily active users time series
510
+ primitive analytics rolling-active [app-id] # Rolling active users (28 points)
511
+ primitive analytics cohort-retention [app-id] # Weekly cohort retention matrix
512
+
513
+ # Users
514
+ primitive analytics top-users [app-id] # Most active users
515
+ primitive analytics user-search [app-id] --query <q> # Search by email or ULID
516
+ primitive analytics user-detail <user-ulid> [app-id] # User activity breakdown
517
+ primitive analytics user-snapshot <user-ulid> [app-id] # Latest context snapshot
518
+
519
+ # Events
520
+ primitive analytics events [app-id] # Paginated event feed
521
+ primitive analytics events-grouped [app-id] # Events grouped by dimension
522
+
523
+ # Features
524
+ primitive analytics integrations [app-id] # Integration usage metrics
525
+ primitive analytics workflows [app-id] # Top workflows by runs
526
+ primitive analytics prompts [app-id] # Top prompts by executions
354
527
  ```
355
528
 
356
- **Options:**
357
- - `--window-days <n>` - Time window (default: 30)
358
- - `--limit <n>` - Result limit for top-users
529
+ **Common options:**
530
+ - `--window-days <n>` - Time window in days (default varies per command)
531
+ - `--limit <n>` - Result limit (top-users, workflows, prompts)
532
+ - `--group-by <dim>` - Dimension for events-grouped (action, feature, route, country, deviceType, plan, day)
533
+ - `--page <n>` - Page number for events feed (0-based)
534
+ - `--json` - Output raw JSON
359
535
 
360
536
  ### Admins (Super-Admin Only)
361
537
 
@@ -392,19 +568,22 @@ primitive catalog integrations update <catalog-id> [options]
392
568
  primitive catalog integrations delete <catalog-id>
393
569
  ```
394
570
 
395
- ### Sync (TOML Configuration)
571
+ ### Config (TOML Configuration)
396
572
 
397
- Sync app configuration to/from TOML files for version control.
573
+ Author app configuration as TOML files and reconcile them with the server.
398
574
 
399
575
  ```bash
400
- primitive sync init [app-id] --dir ./config # Initialize config directory
401
- primitive sync pull [app-id] --dir ./config # Pull remote config to local
402
- primitive sync push [app-id] --dir ./config # Push local config to remote
403
- primitive sync diff [app-id] --dir ./config # Show differences
576
+ primitive config init # Scaffold the environment's config directory
577
+ primitive config pull # Pull remote config into it
578
+ primitive config push # Push it to the server
579
+ primitive config diff # Show differences
404
580
  ```
405
581
 
582
+ The directory is the selected environment's committed tree,
583
+ `primitive/<env>/`, and there is no flag that relocates it or points it at
584
+ another app: select a different environment with `--env <name>` (#3154).
585
+
406
586
  **Options:**
407
- - `--dir <path>` - Config directory (default: ./config)
408
587
  - `--dry-run` - Show changes without applying (push only)
409
588
  - `--force` - Overwrite remote changes (push only)
410
589
 
@@ -436,7 +615,9 @@ baseUrl = "https://myapp.com"
436
615
  [auth]
437
616
  googleOAuthEnabled = true
438
617
  passkeyEnabled = true
439
- magicLinkEnabled = false
618
+ emailSignInEnabled = true # one email carrying a code and a link
619
+ appleSignInEnabled = true # Sign in with Apple
620
+ appleAudiences = ["com.example.MyApp"] # allowed Apple audiences
440
621
 
441
622
  [cors]
442
623
  mode = "custom"
@@ -444,6 +625,19 @@ allowedOrigins = ["https://myapp.com"]
444
625
  allowCredentials = true
445
626
  ```
446
627
 
628
+ Notes on `[auth]`:
629
+
630
+ - Only keys you actually list are pushed. Omitting a key leaves the server's
631
+ current value untouched — it is **not** reset to `false`. To turn a method
632
+ off, set it explicitly (e.g. `emailSignInEnabled = false`).
633
+ - An unrecognized `[auth]` key (for example a typo like `googleOauthEnabled`)
634
+ produces a warning on `push` and is ignored, rather than being silently
635
+ dropped. The push still applies the recognized keys.
636
+ - `appleAudiences = []` and an omitted `appleAudiences` both mean "no
637
+ audiences" (the server stores them the same way), so `pull` omits the key
638
+ when there are no audiences. A `[] ` round-trip reading back as an omitted
639
+ key is expected, not data loss.
640
+
447
641
  ### Example: integrations/weather-api.toml
448
642
 
449
643
  ```toml
@@ -451,7 +645,6 @@ allowCredentials = true
451
645
  key = "weather-api"
452
646
  displayName = "Weather API"
453
647
  description = "OpenWeatherMap integration"
454
- status = "active"
455
648
  timeoutMs = 30000
456
649
 
457
650
  [requestConfig]
@@ -467,7 +660,6 @@ allowedPaths = ["/weather", "/forecast"]
467
660
  key = "summarizer"
468
661
  displayName = "Text Summarizer"
469
662
  description = "Summarizes input text"
470
- status = "active"
471
663
 
472
664
  [[configs]]
473
665
  name = "default"
@@ -500,6 +692,133 @@ primitive apps list
500
692
  primitive apps list --json | jq '.[0].appId'
501
693
  ```
502
694
 
695
+ ### Stdout vs. stderr
696
+
697
+ The CLI follows the same convention as `git`, `kubectl`, `aws`, and `gh`:
698
+
699
+ - **stdout** carries the *data* the command produced — JSON documents under
700
+ `--json`, tabular listings (`apps list`), raw values (`primitive token`),
701
+ and the primary `label: value` fields a `get` / `show` / `describe` command
702
+ emits (e.g. `primitive integrations get <id>`).
703
+ - **stderr** carries *diagnostics* — status text (`✓ Created…`,
704
+ `i Waiting for completion...`), warnings (`!` markers), progress lines, and
705
+ the `key: value` summaries shown *after* a side-effecting command runs
706
+ (e.g. the `Webhook ID: …` confirmation printed by `webhooks create`).
707
+
708
+ This means `primitive <cmd> --json | jq` always works, regardless of any
709
+ status / warning / progress text the command may print along the way.
710
+ It also means `primitive integrations get <id> > out.txt` writes the
711
+ integration's fields to `out.txt` while the status diagnostics still appear
712
+ on the terminal via stderr.
713
+
714
+ Conversely, redirecting stderr (`primitive <cmd> 2>/dev/null`) silences
715
+ diagnostics — including success checkmarks like `✓ Pushed 3 changes` — so
716
+ prefer `2>&1 >file.txt` if you want the full transcript.
717
+
718
+ For contributors writing new commands, the output helpers in
719
+ `cli/src/lib/output.ts` make the data-vs-diagnostic split explicit: use
720
+ `json()` and `result(label, value)` for data the caller asked for, and
721
+ `success()` / `info()` / `warn()` / `keyValue()` / `divider()` / `heading()`
722
+ for diagnostics about what the command did.
723
+
724
+ ## Programmatic surfaces
725
+
726
+ ### `primitive help --json` — command manifest
727
+
728
+ `primitive help --json` prints a machine-readable manifest of the full command
729
+ tree (commands, subcommands, positional args, options, aliases, global options,
730
+ and the CLI version) to **stdout** as a single JSON document, then exits `0`. It
731
+ is hidden/undocumented in human `--help` output, auth-free, and runs entirely
732
+ offline (no project config, no credentials, no network) — so it works in any
733
+ directory, including one with no `.primitive/`.
734
+
735
+ ```bash
736
+ primitive help --json | jq '.commands[] | select(.name=="sync") | .commands[].name'
737
+ ```
738
+
739
+ Shape (`schemaVersion: 1`):
740
+
741
+ ```jsonc
742
+ {
743
+ "schemaVersion": 1,
744
+ "name": "primitive",
745
+ "version": "1.0.49",
746
+ "globalOptions": [ { "flags": "-e, --env <name>", "description": "…", "required": true, "defaultValue": null, "hidden": false } ],
747
+ "commands": [
748
+ {
749
+ "name": "sync",
750
+ "description": "…",
751
+ "aliases": [],
752
+ "args": [],
753
+ "options": [],
754
+ "commands": [
755
+ {
756
+ "name": "push",
757
+ "description": "…",
758
+ "aliases": [],
759
+ "args": [],
760
+ "options": [ { "flags": "--dry-run", "description": "…", "required": false, "defaultValue": null, "hidden": false } ],
761
+ "commands": []
762
+ }
763
+ ]
764
+ }
765
+ ]
766
+ }
767
+ ```
768
+
769
+ `hidden` marks a deprecated alias that still works but is not part of the
770
+ supported surface (it is omitted from human `--help` too). Tooling that treats
771
+ the manifest as an allowlist — the docs CLI gate does — should skip those flags.
772
+
773
+ `schemaVersion` is the contract knob: consumers assert the shape they understand
774
+ and fail loud if a future CLI bumps it (a breaking change for downstream tooling
775
+ such as docs CI that drift-gates documented invocations against the published
776
+ CLI).
777
+
778
+ ### `primitive-admin/validators` — TOML validators
779
+
780
+ The TOML validators that `config push` runs as its load-bearing gate are exported
781
+ from the `primitive-admin/validators` subpath (ESM-only, with types) so external
782
+ tooling can validate exactly the way the published CLI does — instead of
783
+ re-implementing the flow and silently drifting.
784
+
785
+ ```ts
786
+ import {
787
+ validateWorkflowTomlSource, // source-level wrapper (parse → expand → validate)
788
+ validateWorkflowToml, // raw: pure fn over already-parsed TOML
789
+ formatWorkflowTomlErrors,
790
+ validateOperations, // raw: pure fn over already-parsed operations[]
791
+ formatIssue,
792
+ } from "primitive-admin/validators";
793
+ ```
794
+
795
+ Two contracts:
796
+
797
+ - **`validateWorkflowTomlSource(raw, filePath)`** — pass the **raw TOML source
798
+ string** and the workflow's path. It runs the *identical* parse →
799
+ `expandWorkflowTomlData()` (`include` fragment expansion) → `validateWorkflowToml`
800
+ → `formatWorkflowTomlErrors` path that `config push` runs, so it cannot diverge
801
+ from `config push` on workflow `include` fragments. Returns
802
+ `{ errors, formatted }` (`formatted` is `null` when valid). Fragment files
803
+ resolve relative to `<filePath>/../../workflow-fragments/`, matching the CLI.
804
+
805
+ - **The raw validators** (`validateWorkflowToml`, `validateOperations`,
806
+ `formatWorkflowTomlErrors`, `formatIssue`) are **pure functions over
807
+ already-parsed TOML** — they do *not* read files or parse TOML. The consumer
808
+ parses (e.g. with `smol-toml`) and, for workflows, performs any `include`
809
+ expansion itself. There is **no coupling on a specific TOML parser version**:
810
+ pass whatever parsed object / `operations[]` you already have.
811
+
812
+ ```ts
813
+ import * as TOML from "smol-toml";
814
+ const data = TOML.parse(raw);
815
+ const errs = validateWorkflowToml(data);
816
+ if (errs.length) throw new Error(formatWorkflowTomlErrors(path, errs));
817
+ ```
818
+
819
+ Internal helpers (`collectParamRefs`, `declaredParamNames`,
820
+ `locateOperationLine`) are intentionally **not** exported.
821
+
503
822
  ## Exit Codes
504
823
 
505
824
  - `0` - Success
@@ -508,15 +827,30 @@ primitive apps list --json | jq '.[0].appId'
508
827
 
509
828
  ## Environment Variables
510
829
 
511
- - `PRIMITIVE_SERVER_URL` - Server URL for login (defaults to `https://primitiveapi.com`)
830
+ - `PRIMITIVE_SERVER_URL` - Server URL for `login` outside a project (defaults to `https://primitiveapi.com`)
512
831
 
513
- **Server URL priority:**
514
- 1. `--server` flag (highest priority)
515
- 2. `PRIMITIVE_SERVER_URL` environment variable
516
- 3. Default: `https://primitiveapi.com`
832
+ **Login server resolution:**
833
+ 1. Project mode (`.primitive/config.json` present): the active environment's
834
+ `apiUrl`. Select the environment with `-e <name>`, `PRIMITIVE_ENV`,
835
+ `primitive env use <name>` (this machine's selection, stored in the
836
+ gitignored `.primitive/local.json`), or the committed `defaultEnvironment`
837
+ — in that order. An unresolvable environment fails loudly — `login`
838
+ never silently falls back to production.
839
+ 2. Outside a project (no project config): `PRIMITIVE_SERVER_URL`, else the
840
+ default `https://primitiveapi.com`.
841
+
842
+ > `login` no longer accepts `-s/--server` (removed in a breaking change). Use
843
+ > `-e <env>` in a project, or `PRIMITIVE_SERVER_URL` for local dev / scripts.
844
+ > `init` and `bootstrap` keep their own `-s/--server` (they run before a
845
+ > project config exists).
517
846
 
518
847
  ## Development
519
848
 
849
+ Before adding or changing a command, read [`docs/cli-design.md`](../docs/cli-design.md)
850
+ in the repo root — the CLI's design rules (which verbs each kind of noun carries,
851
+ TOML-only authoring, deletion and naming rules, what a breaking change obliges).
852
+ It is internal maintainer guidance and is not published.
853
+
520
854
  ```bash
521
855
  # Run without building (uses tsx)
522
856
  pnpm run cli:dev -- login
@@ -570,12 +904,13 @@ cli/tests/
570
904
  config.test.ts # Credentials and config management
571
905
  output.test.ts # Output formatting functions
572
906
  integration/
573
- api-client.test.ts # API client HTTP tests
574
- commands.test.ts # CLI command tests
575
- tokens.test.ts # Token lifecycle tests
576
- databases.test.ts # Database CRUD, permissions, group permissions tests
577
- documents.test.ts # Document group permissions, group resource listing tests
578
- groups.test.ts # Group CRUD, members, memberships tests
907
+ api-client.test.ts # API client HTTP tests
908
+ commands.test.ts # CLI command tests
909
+ tokens.test.ts # Token lifecycle tests
910
+ databases.test.ts # Database CRUD, permissions, group permissions tests
911
+ documents.test.ts # Document group permissions, group resource listing tests
912
+ groups.test.ts # Group CRUD, members, memberships tests
913
+ classroom-e2e.test.ts # End-to-end classroom app workflow (types, rules, operations, access)
579
914
  ```
580
915
 
581
916
  ## Troubleshooting
@@ -583,8 +918,11 @@ cli/tests/
583
918
  ### "Not logged in" error
584
919
  Run `primitive login` to authenticate.
585
920
 
586
- ### "No app specified" error
587
- Either pass an app ID as an argument, use `--app <id>`, or set context with `primitive use`.
921
+ ### "No primitive/config.json found" error
922
+ The command ran outside a Primitive project. Every app-scoped command reads its
923
+ server, app and configuration tree from the project's environment, so `cd` into
924
+ the project (any subdirectory works) or create one with `primitive init`. There
925
+ is no global fallback and no flag that points the command elsewhere.
588
926
 
589
927
  ### Token expired
590
928
  The CLI automatically refreshes tokens. If issues persist, try `primitive logout` then `primitive login`.