primitive-admin 1.0.61 → 1.0.62

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 (300) hide show
  1. package/README.md +125 -69
  2. package/assets/skill/skills/primitive-platform/SKILL.md +336 -37
  3. package/dist/bin/primitive.js +25 -14
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/analytics.js +36 -16
  6. package/dist/src/commands/analytics.js.map +1 -1
  7. package/dist/src/commands/apps.js +49 -188
  8. package/dist/src/commands/apps.js.map +1 -1
  9. package/dist/src/commands/blob-buckets.js +13 -153
  10. package/dist/src/commands/blob-buckets.js.map +1 -1
  11. package/dist/src/commands/collection-type-configs.js +14 -100
  12. package/dist/src/commands/collection-type-configs.js.map +1 -1
  13. package/dist/src/commands/collections.js +47 -8
  14. package/dist/src/commands/collections.js.map +1 -1
  15. package/dist/src/commands/config.d.ts +46 -0
  16. package/dist/src/commands/config.js +479 -0
  17. package/dist/src/commands/config.js.map +1 -0
  18. package/dist/src/commands/connections.js +12 -7
  19. package/dist/src/commands/connections.js.map +1 -1
  20. package/dist/src/commands/cron-triggers.js +84 -176
  21. package/dist/src/commands/cron-triggers.js.map +1 -1
  22. package/dist/src/commands/database-type-configs.d.ts +2 -0
  23. package/dist/src/commands/database-type-configs.js +171 -0
  24. package/dist/src/commands/database-type-configs.js.map +1 -0
  25. package/dist/src/commands/database-types.js +4 -4
  26. package/dist/src/commands/database-types.js.map +1 -1
  27. package/dist/src/commands/databases.d.ts +63 -0
  28. package/dist/src/commands/databases.js +649 -87
  29. package/dist/src/commands/databases.js.map +1 -1
  30. package/dist/src/commands/documents.js +869 -12
  31. package/dist/src/commands/documents.js.map +1 -1
  32. package/dist/src/commands/email-templates.js +18 -125
  33. package/dist/src/commands/email-templates.js.map +1 -1
  34. package/dist/src/commands/env.d.ts +12 -1
  35. package/dist/src/commands/env.js +98 -25
  36. package/dist/src/commands/env.js.map +1 -1
  37. package/dist/src/commands/feature-flags.d.ts +14 -0
  38. package/dist/src/commands/feature-flags.js +116 -0
  39. package/dist/src/commands/feature-flags.js.map +1 -0
  40. package/dist/src/commands/group-type-configs.js +14 -109
  41. package/dist/src/commands/group-type-configs.js.map +1 -1
  42. package/dist/src/commands/init.d.ts +9 -1
  43. package/dist/src/commands/init.js +1056 -277
  44. package/dist/src/commands/init.js.map +1 -1
  45. package/dist/src/commands/integrations.js +136 -421
  46. package/dist/src/commands/integrations.js.map +1 -1
  47. package/dist/src/commands/metadata-category-configs.d.ts +12 -0
  48. package/dist/src/commands/metadata-category-configs.js +112 -0
  49. package/dist/src/commands/metadata-category-configs.js.map +1 -0
  50. package/dist/src/commands/metadata.js +33 -141
  51. package/dist/src/commands/metadata.js.map +1 -1
  52. package/dist/src/commands/prompts.js +206 -563
  53. package/dist/src/commands/prompts.js.map +1 -1
  54. package/dist/src/commands/rule-sets.d.ts +1 -1
  55. package/dist/src/commands/rule-sets.js +16 -132
  56. package/dist/src/commands/rule-sets.js.map +1 -1
  57. package/dist/src/commands/scripts.js +67 -234
  58. package/dist/src/commands/scripts.js.map +1 -1
  59. package/dist/src/commands/sessions.js +17 -5
  60. package/dist/src/commands/sessions.js.map +1 -1
  61. package/dist/src/commands/sync-app-settings.d.ts +113 -70
  62. package/dist/src/commands/sync-app-settings.js +193 -242
  63. package/dist/src/commands/sync-app-settings.js.map +1 -1
  64. package/dist/src/commands/sync.d.ts +1932 -49
  65. package/dist/src/commands/sync.js +9521 -1769
  66. package/dist/src/commands/sync.js.map +1 -1
  67. package/dist/src/commands/tokens.js +8 -2
  68. package/dist/src/commands/tokens.js.map +1 -1
  69. package/dist/src/commands/users.js +92 -1
  70. package/dist/src/commands/users.js.map +1 -1
  71. package/dist/src/commands/vars.js +44 -58
  72. package/dist/src/commands/vars.js.map +1 -1
  73. package/dist/src/commands/webhooks.js +318 -156
  74. package/dist/src/commands/webhooks.js.map +1 -1
  75. package/dist/src/commands/workflows.d.ts +49 -12
  76. package/dist/src/commands/workflows.js +652 -1086
  77. package/dist/src/commands/workflows.js.map +1 -1
  78. package/dist/src/lib/access-rule-display.d.ts +21 -0
  79. package/dist/src/lib/access-rule-display.js +34 -0
  80. package/dist/src/lib/access-rule-display.js.map +1 -0
  81. package/dist/src/lib/api-client.d.ts +541 -61
  82. package/dist/src/lib/api-client.js +559 -102
  83. package/dist/src/lib/api-client.js.map +1 -1
  84. package/dist/src/lib/app-settings-descriptor.d.ts +180 -25
  85. package/dist/src/lib/app-settings-descriptor.js +403 -82
  86. package/dist/src/lib/app-settings-descriptor.js.map +1 -1
  87. package/dist/src/lib/canonical-json.d.ts +12 -0
  88. package/dist/src/lib/canonical-json.js +35 -0
  89. package/dist/src/lib/canonical-json.js.map +1 -0
  90. package/dist/src/lib/cli-manifest.d.ts +8 -0
  91. package/dist/src/lib/cli-manifest.js +1 -0
  92. package/dist/src/lib/cli-manifest.js.map +1 -1
  93. package/dist/src/lib/codegen-shared/generatedFiles.d.ts +6 -2
  94. package/dist/src/lib/codegen-shared/generatedFiles.js +9 -2
  95. package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
  96. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +6 -6
  97. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +8 -8
  98. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
  99. package/dist/src/lib/config-object-descriptor.d.ts +127 -0
  100. package/dist/src/lib/config-object-descriptor.js +658 -0
  101. package/dist/src/lib/config-object-descriptor.js.map +1 -0
  102. package/dist/src/lib/config-payload.d.ts +85 -0
  103. package/dist/src/lib/config-payload.js +116 -0
  104. package/dist/src/lib/config-payload.js.map +1 -0
  105. package/dist/src/lib/config-surface.d.ts +130 -0
  106. package/dist/src/lib/config-surface.js +300 -0
  107. package/dist/src/lib/config-surface.js.map +1 -0
  108. package/dist/src/lib/credentials-store.d.ts +10 -0
  109. package/dist/src/lib/credentials-store.js +23 -0
  110. package/dist/src/lib/credentials-store.js.map +1 -1
  111. package/dist/src/lib/data-input.d.ts +23 -0
  112. package/dist/src/lib/data-input.js +50 -0
  113. package/dist/src/lib/data-input.js.map +1 -0
  114. package/dist/src/lib/db-codegen/dbTemplates.js +1 -1
  115. package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
  116. package/dist/src/lib/db-codegen/dbTypeIR.d.ts +1 -1
  117. package/dist/src/lib/env-resolver-core.d.ts +147 -0
  118. package/dist/src/lib/env-resolver-core.js +265 -0
  119. package/dist/src/lib/env-resolver-core.js.map +1 -0
  120. package/dist/src/lib/env-resolver.d.ts +28 -6
  121. package/dist/src/lib/env-resolver.js +44 -32
  122. package/dist/src/lib/env-resolver.js.map +1 -1
  123. package/dist/src/lib/generated-allowlist.js +12 -0
  124. package/dist/src/lib/generated-allowlist.js.map +1 -1
  125. package/dist/src/lib/generated-config-surfaces.d.ts +682 -0
  126. package/dist/src/lib/generated-config-surfaces.js +4058 -0
  127. package/dist/src/lib/generated-config-surfaces.js.map +1 -0
  128. package/dist/src/lib/generated-template-lint.d.ts +212 -0
  129. package/dist/src/lib/generated-template-lint.js +624 -0
  130. package/dist/src/lib/generated-template-lint.js.map +1 -0
  131. package/dist/src/lib/init-adopt.d.ts +16 -0
  132. package/dist/src/lib/init-adopt.js +34 -0
  133. package/dist/src/lib/init-adopt.js.map +1 -0
  134. package/dist/src/lib/init-assets.d.ts +39 -0
  135. package/dist/src/lib/init-assets.js +97 -0
  136. package/dist/src/lib/init-assets.js.map +1 -0
  137. package/dist/src/lib/init-config.d.ts +44 -5
  138. package/dist/src/lib/init-config.js +80 -7
  139. package/dist/src/lib/init-config.js.map +1 -1
  140. package/dist/src/lib/init-ios-links.d.ts +50 -0
  141. package/dist/src/lib/init-ios-links.js +153 -0
  142. package/dist/src/lib/init-ios-links.js.map +1 -0
  143. package/dist/src/lib/init-plan.d.ts +80 -0
  144. package/dist/src/lib/init-plan.js +95 -0
  145. package/dist/src/lib/init-plan.js.map +1 -0
  146. package/dist/src/lib/init-production-env.d.ts +48 -0
  147. package/dist/src/lib/init-production-env.js +59 -0
  148. package/dist/src/lib/init-production-env.js.map +1 -0
  149. package/dist/src/lib/init-schema.d.ts +74 -0
  150. package/dist/src/lib/init-schema.js +358 -0
  151. package/dist/src/lib/init-schema.js.map +1 -0
  152. package/dist/src/lib/init-xcode.d.ts +33 -0
  153. package/dist/src/lib/init-xcode.js +114 -0
  154. package/dist/src/lib/init-xcode.js.map +1 -0
  155. package/dist/src/lib/integration-request-config.d.ts +30 -0
  156. package/dist/src/lib/integration-request-config.js +145 -0
  157. package/dist/src/lib/integration-request-config.js.map +1 -0
  158. package/dist/src/lib/local-state.d.ts +55 -0
  159. package/dist/src/lib/local-state.js +167 -0
  160. package/dist/src/lib/local-state.js.map +1 -0
  161. package/dist/src/lib/log-inspection.d.ts +568 -0
  162. package/dist/src/lib/log-inspection.js +639 -0
  163. package/dist/src/lib/log-inspection.js.map +1 -0
  164. package/dist/src/lib/migration-nag.d.ts +2 -2
  165. package/dist/src/lib/migration-nag.js +3 -3
  166. package/dist/src/lib/object-status-filter.d.ts +22 -0
  167. package/dist/src/lib/object-status-filter.js +45 -0
  168. package/dist/src/lib/object-status-filter.js.map +1 -0
  169. package/dist/src/lib/output.d.ts +24 -1
  170. package/dist/src/lib/output.js +42 -1
  171. package/dist/src/lib/output.js.map +1 -1
  172. package/dist/src/lib/package-manager.d.ts +140 -0
  173. package/dist/src/lib/package-manager.js +305 -0
  174. package/dist/src/lib/package-manager.js.map +1 -0
  175. package/dist/src/lib/paginate.d.ts +50 -0
  176. package/dist/src/lib/paginate.js +53 -0
  177. package/dist/src/lib/paginate.js.map +1 -1
  178. package/dist/src/lib/platform-owned.d.ts +29 -3
  179. package/dist/src/lib/platform-owned.js +42 -3
  180. package/dist/src/lib/platform-owned.js.map +1 -1
  181. package/dist/src/lib/project-config.js +13 -5
  182. package/dist/src/lib/project-config.js.map +1 -1
  183. package/dist/src/lib/query-operators.d.ts +1 -1
  184. package/dist/src/lib/query-operators.js +1 -1
  185. package/dist/src/lib/record-filter.d.ts +18 -0
  186. package/dist/src/lib/record-filter.js +55 -0
  187. package/dist/src/lib/record-filter.js.map +1 -0
  188. package/dist/src/lib/resolve-init-dev-port.d.ts +56 -0
  189. package/dist/src/lib/resolve-init-dev-port.js +55 -0
  190. package/dist/src/lib/resolve-init-dev-port.js.map +1 -0
  191. package/dist/src/lib/resolve-init-server.d.ts +64 -0
  192. package/dist/src/lib/resolve-init-server.js +77 -0
  193. package/dist/src/lib/resolve-init-server.js.map +1 -0
  194. package/dist/src/lib/resolve-platform.d.ts +43 -14
  195. package/dist/src/lib/resolve-platform.js +74 -12
  196. package/dist/src/lib/resolve-platform.js.map +1 -1
  197. package/dist/src/lib/run-status.d.ts +19 -0
  198. package/dist/src/lib/run-status.generated.d.ts +39 -0
  199. package/dist/src/lib/run-status.generated.js +66 -0
  200. package/dist/src/lib/run-status.generated.js.map +1 -0
  201. package/dist/src/lib/run-status.js +19 -0
  202. package/dist/src/lib/run-status.js.map +1 -0
  203. package/dist/src/lib/server-text-normalization.d.ts +51 -0
  204. package/dist/src/lib/server-text-normalization.js +90 -0
  205. package/dist/src/lib/server-text-normalization.js.map +1 -0
  206. package/dist/src/lib/server-url.d.ts +22 -0
  207. package/dist/src/lib/server-url.js +33 -0
  208. package/dist/src/lib/server-url.js.map +1 -0
  209. package/dist/src/lib/signing-secret-status.d.ts +81 -0
  210. package/dist/src/lib/signing-secret-status.js +116 -0
  211. package/dist/src/lib/signing-secret-status.js.map +1 -0
  212. package/dist/src/lib/skill-installer.js +6 -3
  213. package/dist/src/lib/skill-installer.js.map +1 -1
  214. package/dist/src/lib/snapshots.d.ts +2 -2
  215. package/dist/src/lib/snapshots.js +2 -2
  216. package/dist/src/lib/swift-codegen/dbGenerator.d.ts +15 -2
  217. package/dist/src/lib/swift-codegen/dbGenerator.js +250 -18
  218. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
  219. package/dist/src/lib/swift-codegen/generator.d.ts +11 -2
  220. package/dist/src/lib/swift-codegen/generator.js +181 -7
  221. package/dist/src/lib/swift-codegen/generator.js.map +1 -1
  222. package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +7 -3
  223. package/dist/src/lib/swift-codegen/siblingSymbols.js +4 -1
  224. package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -1
  225. package/dist/src/lib/sync-dir-selector.d.ts +21 -0
  226. package/dist/src/lib/sync-dir-selector.js +30 -0
  227. package/dist/src/lib/sync-dir-selector.js.map +1 -0
  228. package/dist/src/lib/sync-paths.d.ts +39 -0
  229. package/dist/src/lib/sync-paths.js +70 -2
  230. package/dist/src/lib/sync-paths.js.map +1 -1
  231. package/dist/src/lib/sync-resource-types.d.ts +138 -31
  232. package/dist/src/lib/sync-resource-types.js +241 -47
  233. package/dist/src/lib/sync-resource-types.js.map +1 -1
  234. package/dist/src/lib/sync-selectors.d.ts +95 -0
  235. package/dist/src/lib/sync-selectors.js +228 -0
  236. package/dist/src/lib/sync-selectors.js.map +1 -0
  237. package/dist/src/lib/template.d.ts +62 -4
  238. package/dist/src/lib/template.js +147 -39
  239. package/dist/src/lib/template.js.map +1 -1
  240. package/dist/src/lib/test-case-keys.d.ts +29 -0
  241. package/dist/src/lib/test-case-keys.js +55 -0
  242. package/dist/src/lib/test-case-keys.js.map +1 -0
  243. package/dist/src/lib/test-case-variables.d.ts +15 -0
  244. package/dist/src/lib/test-case-variables.js +29 -0
  245. package/dist/src/lib/test-case-variables.js.map +1 -0
  246. package/dist/src/lib/toml-database-config.d.ts +4 -4
  247. package/dist/src/lib/toml-database-config.js +27 -34
  248. package/dist/src/lib/toml-database-config.js.map +1 -1
  249. package/dist/src/lib/toml-metadata-config.d.ts +9 -5
  250. package/dist/src/lib/toml-metadata-config.js +40 -45
  251. package/dist/src/lib/toml-metadata-config.js.map +1 -1
  252. package/dist/src/lib/toml-native-form.d.ts +1 -1
  253. package/dist/src/lib/toml-native-form.js +1 -1
  254. package/dist/src/lib/toml-params-validator.d.ts +1 -1
  255. package/dist/src/lib/toml-params-validator.js +1 -1
  256. package/dist/src/lib/toml-scalar-edit.d.ts +43 -0
  257. package/dist/src/lib/toml-scalar-edit.js +283 -0
  258. package/dist/src/lib/toml-scalar-edit.js.map +1 -0
  259. package/dist/src/lib/user-selector.d.ts +24 -0
  260. package/dist/src/lib/user-selector.js +33 -0
  261. package/dist/src/lib/user-selector.js.map +1 -0
  262. package/dist/src/lib/version-check.d.ts +25 -0
  263. package/dist/src/lib/version-check.js +77 -8
  264. package/dist/src/lib/version-check.js.map +1 -1
  265. package/dist/src/lib/watch.d.ts +121 -0
  266. package/dist/src/lib/watch.js +169 -0
  267. package/dist/src/lib/watch.js.map +1 -0
  268. package/dist/src/lib/workflow-apply.d.ts +69 -45
  269. package/dist/src/lib/workflow-apply.js +99 -72
  270. package/dist/src/lib/workflow-apply.js.map +1 -1
  271. package/dist/src/lib/workflow-codegen/generator.js +4 -4
  272. package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
  273. package/dist/src/lib/workflow-codegen/invokerIR.d.ts +11 -0
  274. package/dist/src/lib/workflow-codegen/invokerIR.js +5 -0
  275. package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -1
  276. package/dist/src/lib/workflow-config-apply.d.ts +70 -0
  277. package/dist/src/lib/workflow-config-apply.js +137 -0
  278. package/dist/src/lib/workflow-config-apply.js.map +1 -0
  279. package/dist/src/lib/workflow-config-sidecar.d.ts +63 -0
  280. package/dist/src/lib/workflow-config-sidecar.js +96 -0
  281. package/dist/src/lib/workflow-config-sidecar.js.map +1 -0
  282. package/dist/src/lib/workflow-defaults.d.ts +29 -0
  283. package/dist/src/lib/workflow-defaults.js +41 -0
  284. package/dist/src/lib/workflow-defaults.js.map +1 -0
  285. package/dist/src/lib/workflow-include-preserve.d.ts +76 -0
  286. package/dist/src/lib/workflow-include-preserve.js +286 -0
  287. package/dist/src/lib/workflow-include-preserve.js.map +1 -0
  288. package/dist/src/lib/workflow-payload.d.ts +31 -20
  289. package/dist/src/lib/workflow-payload.js +100 -110
  290. package/dist/src/lib/workflow-payload.js.map +1 -1
  291. package/dist/src/lib/workflow-toml-validator.d.ts +37 -16
  292. package/dist/src/lib/workflow-toml-validator.js +141 -16
  293. package/dist/src/lib/workflow-toml-validator.js.map +1 -1
  294. package/dist/src/types/index.d.ts +78 -22
  295. package/dist/src/validators.d.ts +7 -7
  296. package/dist/src/validators.js +6 -6
  297. package/package.json +11 -6
  298. package/dist/src/commands/settings.d.ts +0 -15
  299. package/dist/src/commands/settings.js +0 -102
  300. package/dist/src/commands/settings.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Shared layout metadata for the per-entity resource types `sync pull` writes
2
+ * Shared layout metadata for the per-entity resource types `config pull` writes
3
3
  * into a sync slot (issue #1659).
4
4
  *
5
- * `sync pull` writes one file per server entity and records what it wrote in
5
+ * `config pull` writes one file per server entity and records what it wrote in
6
6
  * `.primitive-sync.json` (`SyncState.entities[<slot>]`). Until #1659 it never
7
7
  * removed a local file whose entity had disappeared server-side, so the next
8
- * `sync push` — which treats local TOML as the source of truth — silently
8
+ * `config push` — which treats local TOML as the source of truth — silently
9
9
  * re-created the just-deleted entity.
10
10
  *
11
- * This module holds the narrow descriptor the prune pass and `sync diff` share:
11
+ * This module holds the narrow descriptor the prune pass and `config diff` share:
12
12
  * directory, extension, state slot, key→filename derivation, and the sidecar
13
13
  * test-directory block type. The pull write loops deliberately stay as they are
14
14
  * — this table is layout metadata, not a write framework.
@@ -16,6 +16,12 @@
16
16
  import type { SyncState } from "../types/index.js";
17
17
  import type { ApiClient } from "./api-client.js";
18
18
  export type SyncEntitySlot = keyof SyncState["entities"];
19
+ /**
20
+ * A block whose test cases round-trip as a `<key>.tests/` sidecar. Integrations
21
+ * joined the other three in #2769 — their cases used to live server-side only,
22
+ * which made them the one configuration surface with no file to review.
23
+ */
24
+ export type TestBlockType = "prompt" | "workflow" | "script" | "integration";
19
25
  export interface SyncResourceType {
20
26
  /** Singular name used in pull/diff output, e.g. `"rule-set"`. */
21
27
  label: string;
@@ -26,7 +32,7 @@ export interface SyncResourceType {
26
32
  /** Slot in `SyncState.entities` recording what a prior pull managed. */
27
33
  stateSlot: SyncEntitySlot;
28
34
  /**
29
- * Entity key → the file basename `sync pull` writes for it. This must match
35
+ * Entity key → the file basename `config pull` writes for it. This must match
30
36
  * the write side exactly, so prune only ever targets a file pull created.
31
37
  */
32
38
  fileFromKey(key: string): string;
@@ -35,7 +41,15 @@ export interface SyncResourceType {
35
41
  * Pruning an entity also removes its test directory and the matching
36
42
  * `entities.testCases` records.
37
43
  */
38
- testBlockType?: "prompt" | "workflow" | "script";
44
+ testBlockType?: TestBlockType;
45
+ /**
46
+ * Directory holding the entity's named configuration bodies, when the type
47
+ * has them (#2645: `workflows/<key>.configs/`). Pruning the entity removes it
48
+ * for the same reason it removes `<key>.tests/` — the configs belonged to a
49
+ * block that is gone, and a surviving directory would re-create them on the
50
+ * next push.
51
+ */
52
+ namedConfigsDirFromKey?(key: string): string;
39
53
  /**
40
54
  * Whether this type's server listing returns *every* key, so "absent from the
41
55
  * listing" really means "gone from the server".
@@ -43,7 +57,7 @@ export interface SyncResourceType {
43
57
  * Prune deletes files, so a successful fetch is not enough — the response also
44
58
  * has to be complete. Two shapes make a listing complete: the cursor-paginating
45
59
  * admin endpoints (integrations/webhooks/prompts/workflows — server returns
46
- * `nextCursor` and `sync pull` drains it with `fetchAll`), and the config
60
+ * `nextCursor` and `config pull` drains it with `fetchAll`), and the config
47
61
  * listings that drain every DynamoDB page server-side via `queryAllPages`
48
62
  * (#1668). Before #1668 the config listings returned a single 100-row page with
49
63
  * a 200 and no cursor, so an app past the page boundary got a silently
@@ -60,7 +74,7 @@ export interface SyncResourceType {
60
74
  * version marker: the CLI npm publish is coupled to the production deploy (so
61
75
  * new-CLI-vs-old-server is a narrow window), the worst case is git-recoverable
62
76
  * local file deletion touching nothing server-side, and it only affects apps
63
- * with >100 entities of one config type — whose `sync pull` was already
77
+ * with >100 entities of one config type — whose `config pull` was already
64
78
  * silently incomplete before this change.
65
79
  *
66
80
  * The flag remains as a guard: a future type whose listing is not yet complete
@@ -81,13 +95,13 @@ export declare function ruleSetFileKey(ruleSet: {
81
95
  /**
82
96
  * Every per-entity resource type in a sync slot. `app.toml` and `vars.toml` are
83
97
  * root singletons, not per-entity directories, so they are not listed here —
84
- * var removal is already handled within-file by `sync push` (`planVarsPush`).
98
+ * var removal is already handled within-file by `config push` (`planVarsPush`).
85
99
  */
86
100
  export declare const SYNC_RESOURCE_TYPES: SyncResourceType[];
87
101
  /**
88
102
  * Outcome of a server fetch that establishes which entities of a type exist.
89
103
  *
90
- * `sync pull` historically swallowed several list errors with `.catch(() => [])`,
104
+ * `config pull` historically swallowed several list errors with `.catch(() => [])`,
91
105
  * which makes a transient 401/500/network error indistinguishable from "the app
92
106
  * has none of these". Pruning off that empty list would delete every local file
93
107
  * of the type, so prune consumes this explicit outcome instead.
@@ -112,6 +126,24 @@ export declare function attemptFetch<T>(fn: () => Promise<T>): Promise<{
112
126
  * able to steer an `unlinkSync` outside the sync slot.
113
127
  */
114
128
  export declare function isSafeSyncFilename(filename: string): boolean;
129
+ /**
130
+ * Whether a test-case attachment filename may be written to (or read from) the
131
+ * sidecar attachment directory (#2769).
132
+ *
133
+ * Attachment names come from the SERVER: pull writes each one into
134
+ * `<key>.tests/<slug>/`, so a stored name carrying a separator or a `..`
135
+ * segment would place a file outside the sync tree entirely. The rule is the
136
+ * same one state-derived filenames follow, plus a refusal of any leading-dot
137
+ * traversal spelling.
138
+ */
139
+ export declare function isSafeAttachmentFilename(filename: string): boolean;
140
+ /**
141
+ * The absolute path an attachment may be written to, or `null` when the name is
142
+ * unsafe or resolves outside `attachDir` (#2769). Both halves matter: the name
143
+ * check states the rule, and the resolved-path check enforces it against
144
+ * platform quirks the name check cannot anticipate.
145
+ */
146
+ export declare function attachmentWritePath(attachDir: string, filename: string): string | null;
115
147
  export interface PrunePlan {
116
148
  /** Entity keys whose managed file should be removed. */
117
149
  keys: string[];
@@ -141,7 +173,7 @@ export interface PrunePlan {
141
173
  * `SyncState.entities[<slot>]`, so a previous pull wrote its file) and is
142
174
  * **absent from the server keys** this pull fetched. A local file that was
143
175
  * never in prior state was hand-authored — it is left alone and reported by
144
- * `sync diff` as new.
176
+ * `config diff` as new.
145
177
  *
146
178
  * Pure and side-effect-free (the caller owns the `unlinkSync`) so the safety
147
179
  * rules are unit-testable without a live server.
@@ -175,7 +207,7 @@ export declare function preserveUnwrittenEntries<T>(written: Record<string, T>,
175
207
  * a command.
176
208
  *
177
209
  * `includeUntracked` decides whether an untracked file counts as a change:
178
- * - `true` (default) suits "am I about to overwrite something?" — `sync revert`
210
+ * - `true` (default) suits "am I about to overwrite something?" — `config revert`
179
211
  * would clobber an untracked file just the same.
180
212
  * - `false` suits "did the operator edit this file?" — an untracked file is the
181
213
  * ordinary state of a pulled file in a sync dir that was never committed, and
@@ -196,10 +228,18 @@ export declare function hasUncommittedChanges(path: string, options?: {
196
228
  * way to be absent from the export is to have been deleted.
197
229
  */
198
230
  export declare const ABSENT_FROM_EXPORT = "absent from sync export (deleted on server)";
199
- /** `sync diff` status for a local file whose managed entity is gone. */
231
+ /** `config diff` status for a local file whose managed entity is gone. */
200
232
  export declare const LOCAL_ONLY_ABSENT = "local only (absent from export)";
201
- /** `sync diff` status for a local file the operator authored themselves. */
233
+ /** `config diff` status for a local file the operator authored themselves. */
202
234
  export declare const LOCAL_ONLY_NEW = "local only";
235
+ /**
236
+ * `config diff` status for a local file `config push` would refuse (#2880).
237
+ *
238
+ * Its own status rather than a hint on a Synced row: the whole point is that
239
+ * the file is NOT pushable, and the counts a caller reads to decide "is there
240
+ * anything to do?" have to say so.
241
+ */
242
+ export declare const VALIDATION_ERROR = "validation error";
203
243
  /**
204
244
  * Classify a local file that has no matching server entity (issue #1659).
205
245
  *
@@ -225,7 +265,7 @@ export interface PruneResult {
225
265
  *
226
266
  * A file with uncommitted git edits is kept and reported instead: the operator
227
267
  * may be mid-way through authoring a change they meant to push. Everything
228
- * removed here is recoverable from the pre-pull snapshot via `sync revert`.
268
+ * removed here is recoverable from the pre-pull snapshot via `config revert`.
229
269
  */
230
270
  export declare function applyPrune(options: {
231
271
  configDir: string;
@@ -246,7 +286,7 @@ export declare const addressById: PruneAddressOf;
246
286
  export declare const addressByKey: PruneAddressOf;
247
287
  /**
248
288
  * Live modified timestamp used by the drift check. Most admin/app detail
249
- * endpoints serialize `modifiedAt` at the top level (the same field `sync pull`
289
+ * endpoints serialize `modifiedAt` at the top level (the same field `config pull`
250
290
  * records into state), with `updatedAt` as a defensive fallback. Two detail
251
291
  * endpoints nest the entity under a wrapper key and need their own extractors
252
292
  * below (`workflowPruneModifiedAt`, `emailTemplatePruneModifiedAt`) so the
@@ -265,10 +305,26 @@ export declare const workflowPruneModifiedAt: (detail: any) => string | undefine
265
305
  * Email-template detail-read extractor. `getEmailTemplate` returns
266
306
  * `{ emailType, label, hasOverride, override, default, variables }`; the
267
307
  * editable copy `sync` manages — and its `modifiedAt` — live under `override`
268
- * (null when there is no override). `sync pull` likewise records
308
+ * (null when there is no override). `config pull` likewise records
269
309
  * `template.override?.modifiedAt`, so the drift check must read the same path.
270
310
  */
271
311
  export declare const emailTemplatePruneModifiedAt: (detail: any) => string | undefined;
312
+ /**
313
+ * Split a metadata-category key into the `resourceType`/`category` pair it
314
+ * names, or `null` when it is not exactly two non-empty components joined by a
315
+ * single `#`.
316
+ *
317
+ * Load-bearing for prune (#2762). Prune point-reads a candidate BEFORE deciding
318
+ * what to do with it, and only a missing address short-circuits that fetch — so
319
+ * a corrupt state key that still produced an address would be read with
320
+ * `undefined` in the request path, and the resulting 404 would be classified
321
+ * "already gone", silently dropping the state entry. Failing here instead
322
+ * routes such a key to the `no-id` skip: no client call, state retained.
323
+ */
324
+ export declare function parseMetadataCategoryKey(key: string): {
325
+ resourceType: string;
326
+ category: string;
327
+ } | null;
272
328
  /**
273
329
  * How to confirm and delete one resource type during push-prune. Narrow by
274
330
  * design (state slot + address + detail-fetch + drift field + delete) rather
@@ -279,7 +335,7 @@ export interface PushPruneSpec {
279
335
  resourceType: SyncResourceType;
280
336
  /**
281
337
  * Derive the entity key a local managed file declares — the SAME derivation
282
- * the type's `sync push` loop uses (`<in-file identity> || basename`). Prune
338
+ * the type's `config push` loop uses (`<in-file identity> || basename`). Prune
283
339
  * collects the set of these across every file in the type's directory and
284
340
  * treats a prior-state key as a candidate only when NO local file declares
285
341
  * it. This must mirror push exactly: a file renamed but keeping its internal
@@ -294,16 +350,23 @@ export interface PushPruneSpec {
294
350
  modifiedAtOf: (detail: any) => string | undefined;
295
351
  /**
296
352
  * Delete the confirmed entity; rejects with `ConflictError` (409) when the
297
- * entity is still referenced. `null` for a type whose CLI delete surface has
298
- * not landed yet (metadata-category-configs, gated on #1426): a candidate of
299
- * such a type is reported "no delete surface yet" rather than deleted.
353
+ * entity is still referenced. `null` for a type with no delete surface, whose
354
+ * candidates are reported "no delete surface" rather than deleted — a
355
+ * fail-safe no shipped spec uses since #2762 wired the last one.
300
356
  */
301
357
  deleteEntity: ((client: ApiClient, appId: string, address: string) => Promise<void>) | null;
358
+ /**
359
+ * A consequence of deleting this type the prune plan must state before the
360
+ * operator confirms — printed under the item's "will delete" line, in
361
+ * `--dry-run` too. Only metadata-category-configs carry one: their stored
362
+ * values survive the definition and become unreachable (#2762).
363
+ */
364
+ deleteCaveat?: string;
302
365
  }
303
366
  /**
304
367
  * Every resource type push-prune can retire. Id-addressed types (integrations,
305
368
  * webhooks, cron-triggers, blob-buckets, prompts, workflows, transforms,
306
- * rule-sets) fetch/delete by the stored id; key-addressed types (database-types,
369
+ * rule-sets) fetch/delete by the stored id; key-addressed types (database-type-configs,
307
370
  * group-type-configs, collection-type-configs, email-templates) by the key.
308
371
  *
309
372
  * `--force` (the CLI's existing "override baseline drift" flag) only relaxes the
@@ -314,11 +377,11 @@ export interface PushPruneSpec {
314
377
  export declare const PUSH_PRUNE_SPECS: PushPruneSpec[];
315
378
  /**
316
379
  * The set of entity keys the local managed files of a type declare — collected
317
- * the way `sync push` derives keys: parse every file in the type's directory
380
+ * the way `config push` derives keys: parse every file in the type's directory
318
381
  * and read its declared identity (`<in-file key> || basename`), NOT by assuming
319
382
  * the file lives at its canonical `<key>.toml` path.
320
383
  *
321
- * This is the crux of the #1655 destructive-delete fix. `sync push` accepts a
384
+ * This is the crux of the #1655 destructive-delete fix. `config push` accepts a
322
385
  * managed file at a **noncanonical filename** (e.g. `prompts/custom.toml` with
323
386
  * `prompt.key = "greeting"`) and still updates the `greeting` entity. Collecting
324
387
  * declared keys — rather than checking whether `greeting.toml` exists — means a
@@ -337,11 +400,11 @@ export declare function collectLocalDeclaredKeys(input: {
337
400
  *
338
401
  * A key is a candidate iff it was in the prior state slot (a prior pull managed
339
402
  * it) AND **no** local file in the type's directory declares that key (via
340
- * {@link collectLocalDeclaredKeys}, mirroring how `sync push` derives keys). A
403
+ * {@link collectLocalDeclaredKeys}, mirroring how `config push` derives keys). A
341
404
  * key still declared by some file — even one renamed away from the canonical
342
- * `<key>.toml` path — is left alone, since `sync push` would update it, not
405
+ * `<key>.toml` path — is left alone, since `config push` would update it, not
343
406
  * delete it (issue #1655). A file whose key was never in prior state was
344
- * hand-authored and is left for `sync push` to create; it is never a candidate.
407
+ * hand-authored and is left for `config push` to create; it is never a candidate.
345
408
  */
346
409
  export declare function collectPushPruneCandidates(input: {
347
410
  spec: PushPruneSpec;
@@ -365,7 +428,10 @@ export interface PushPruneFetch {
365
428
  export type PushPruneSkipReason =
366
429
  /** State entry has no usable id/key (corrupt or partial state). */
367
430
  "no-id"
368
- /** Type has no CLI delete surface yet (metadata-category-configs, #1426). */
431
+ /**
432
+ * The spec carries no delete surface. A fail-safe: since #2762 every shipped
433
+ * spec can delete, so this arm only fires for a type wired without one.
434
+ */
369
435
  | "unsupported"
370
436
  /** Live `modifiedAt` differs from prior state — edited out-of-band. */
371
437
  | "drift"
@@ -404,6 +470,47 @@ export declare function decidePushPruneCandidate(input: {
404
470
  fetch: PushPruneFetch;
405
471
  force: boolean;
406
472
  }): PushPruneDecision;
473
+ /**
474
+ * What a failed prune DELETE call means for the entity's sync-state slot.
475
+ *
476
+ * `raced-absent` — the entity was deleted out-of-band between the point read
477
+ * and this call. The desired state is met, so the delete counts as success and
478
+ * its stale slot goes; anything else keeps the slot so a re-run retries.
479
+ */
480
+ export type PruneDeleteFailure = "raced-absent" | "blocked" | "failed";
481
+ /**
482
+ * Classify an error thrown by a prune delete — one arm for every type.
483
+ *
484
+ * Keyed on the status alone (`ConflictError` is an `ApiError` with 409), so no
485
+ * per-type carve-out can creep into the push command's delete loop and make the
486
+ * race recovery true for some types and not others (#2762).
487
+ */
488
+ export declare function classifyPruneDeleteFailure(err: unknown): PruneDeleteFailure;
489
+ /** One line of the `config push --prune` plan, ready to color and print. */
490
+ export interface PrunePlanLine {
491
+ kind: "delete" | "absent" | "skip";
492
+ /** The status prefix the CLI colors: "will delete", "skipped — …". */
493
+ status: string;
494
+ /** The uncolored remainder: `<type>: <key>`. */
495
+ detail: string;
496
+ /** An extra line printed under this one — the type's `deleteCaveat`. */
497
+ note?: string;
498
+ }
499
+ /**
500
+ * Render the prune plan the operator reads before the batch confirmation.
501
+ *
502
+ * Pure, and here rather than in `sync.ts`, so what the plan states about a type
503
+ * is testable without a server — specifically that a type's `deleteCaveat`
504
+ * (metadata's orphaned values, which used to live in the retired verb's confirm
505
+ * prompt) appears under its delete lines and nowhere else. `config push` renders
506
+ * the plan ONCE, before the `--dry-run` branch, so both paths print the same
507
+ * lines (#2762).
508
+ */
509
+ export declare function formatPrunePlan(items: Array<{
510
+ spec: PushPruneSpec;
511
+ key: string;
512
+ decision: PushPruneDecision;
513
+ }>): PrunePlanLine[];
407
514
  /**
408
515
  * Remove a pruned block's sidecar `<key>.tests/` directory and its
409
516
  * `entities.testCases` state records. The main file is already gone (that is
@@ -423,13 +530,13 @@ export declare function removePrunedSidecar(options: {
423
530
  removed: string[];
424
531
  removedTestCaseKeys: string[];
425
532
  };
426
- /** `sync diff` status for a managed remote entity whose local file is gone. */
533
+ /** `config diff` status for a managed remote entity whose local file is gone. */
427
534
  export declare const REMOTE_ONLY_WILL_DELETE = "remote only (will delete with push --prune)";
428
- /** `sync diff` status for a server entity that was never synced (hand-created). */
535
+ /** `config diff` status for a server entity that was never synced (hand-created). */
429
536
  export declare const REMOTE_ONLY_UNMANAGED = "remote only (left alone)";
430
537
  /**
431
538
  * Classify a "remote only" entity (present server-side, no local file) for
432
- * `sync diff` (issue #1655). A key the prior pull managed means the operator
539
+ * `config diff` (issue #1655). A key the prior pull managed means the operator
433
540
  * deleted its local file and `push --prune` will delete the remote entity; a key
434
541
  * never synced was authored on the server and is left alone. Prior sync state is
435
542
  * the discriminator, exactly as it is for the local-only / pull-prune split.