primitive-admin 1.0.61 → 1.0.63
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.
- package/README.md +125 -69
- package/assets/skill/skills/primitive-platform/SKILL.md +336 -37
- package/dist/bin/primitive.js +25 -14
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/analytics.js +36 -16
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.js +52 -188
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/blob-buckets.js +13 -153
- package/dist/src/commands/blob-buckets.js.map +1 -1
- package/dist/src/commands/collection-type-configs.js +14 -100
- package/dist/src/commands/collection-type-configs.js.map +1 -1
- package/dist/src/commands/collections.js +47 -8
- package/dist/src/commands/collections.js.map +1 -1
- package/dist/src/commands/config.d.ts +46 -0
- package/dist/src/commands/config.js +479 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/connections.js +12 -7
- package/dist/src/commands/connections.js.map +1 -1
- package/dist/src/commands/cron-triggers.js +84 -176
- package/dist/src/commands/cron-triggers.js.map +1 -1
- package/dist/src/commands/database-type-configs.d.ts +2 -0
- package/dist/src/commands/database-type-configs.js +171 -0
- package/dist/src/commands/database-type-configs.js.map +1 -0
- package/dist/src/commands/database-types.js +4 -4
- package/dist/src/commands/database-types.js.map +1 -1
- package/dist/src/commands/databases.d.ts +63 -0
- package/dist/src/commands/databases.js +649 -87
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.js +869 -12
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.js +21 -128
- package/dist/src/commands/email-templates.js.map +1 -1
- package/dist/src/commands/env.d.ts +12 -1
- package/dist/src/commands/env.js +115 -26
- package/dist/src/commands/env.js.map +1 -1
- package/dist/src/commands/feature-flags.d.ts +14 -0
- package/dist/src/commands/feature-flags.js +116 -0
- package/dist/src/commands/feature-flags.js.map +1 -0
- package/dist/src/commands/group-type-configs.js +14 -109
- package/dist/src/commands/group-type-configs.js.map +1 -1
- package/dist/src/commands/init.d.ts +24 -1
- package/dist/src/commands/init.js +1194 -279
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.js +166 -435
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/metadata-category-configs.d.ts +12 -0
- package/dist/src/commands/metadata-category-configs.js +112 -0
- package/dist/src/commands/metadata-category-configs.js.map +1 -0
- package/dist/src/commands/metadata.js +33 -141
- package/dist/src/commands/metadata.js.map +1 -1
- package/dist/src/commands/prompts.js +206 -563
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +1 -1
- package/dist/src/commands/rule-sets.js +16 -132
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/scripts.d.ts +10 -0
- package/dist/src/commands/scripts.js +203 -241
- package/dist/src/commands/scripts.js.map +1 -1
- package/dist/src/commands/sessions.js +17 -5
- package/dist/src/commands/sessions.js.map +1 -1
- package/dist/src/commands/sync-app-settings.d.ts +113 -70
- package/dist/src/commands/sync-app-settings.js +193 -242
- package/dist/src/commands/sync-app-settings.js.map +1 -1
- package/dist/src/commands/sync.d.ts +1904 -51
- package/dist/src/commands/sync.js +9468 -1790
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.js +8 -2
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.js +92 -1
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/vars.js +44 -58
- package/dist/src/commands/vars.js.map +1 -1
- package/dist/src/commands/webhooks.js +318 -156
- package/dist/src/commands/webhooks.js.map +1 -1
- package/dist/src/commands/workflows.d.ts +49 -12
- package/dist/src/commands/workflows.js +652 -1086
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/access-rule-display.d.ts +21 -0
- package/dist/src/lib/access-rule-display.js +34 -0
- package/dist/src/lib/access-rule-display.js.map +1 -0
- package/dist/src/lib/api-client.d.ts +541 -61
- package/dist/src/lib/api-client.js +559 -102
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.d.ts +180 -25
- package/dist/src/lib/app-settings-descriptor.js +403 -82
- package/dist/src/lib/app-settings-descriptor.js.map +1 -1
- package/dist/src/lib/canonical-json.d.ts +12 -0
- package/dist/src/lib/canonical-json.js +35 -0
- package/dist/src/lib/canonical-json.js.map +1 -0
- package/dist/src/lib/cli-manifest.d.ts +8 -0
- package/dist/src/lib/cli-manifest.js +1 -0
- package/dist/src/lib/cli-manifest.js.map +1 -1
- package/dist/src/lib/codegen-shared/generatedFiles.d.ts +6 -2
- package/dist/src/lib/codegen-shared/generatedFiles.js +9 -2
- package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +6 -6
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +8 -8
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
- package/dist/src/lib/config-object-descriptor.d.ts +127 -0
- package/dist/src/lib/config-object-descriptor.js +658 -0
- package/dist/src/lib/config-object-descriptor.js.map +1 -0
- package/dist/src/lib/config-payload.d.ts +85 -0
- package/dist/src/lib/config-payload.js +116 -0
- package/dist/src/lib/config-payload.js.map +1 -0
- package/dist/src/lib/config-surface.d.ts +130 -0
- package/dist/src/lib/config-surface.js +300 -0
- package/dist/src/lib/config-surface.js.map +1 -0
- package/dist/src/lib/credentials-store.d.ts +10 -0
- package/dist/src/lib/credentials-store.js +23 -0
- package/dist/src/lib/credentials-store.js.map +1 -1
- package/dist/src/lib/data-input.d.ts +23 -0
- package/dist/src/lib/data-input.js +50 -0
- package/dist/src/lib/data-input.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTemplates.js +1 -1
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTypeIR.d.ts +1 -1
- package/dist/src/lib/env-resolver-core.d.ts +187 -0
- package/dist/src/lib/env-resolver-core.js +325 -0
- package/dist/src/lib/env-resolver-core.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +28 -6
- package/dist/src/lib/env-resolver.js +44 -32
- package/dist/src/lib/env-resolver.js.map +1 -1
- package/dist/src/lib/generated-allowlist.js +12 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -1
- package/dist/src/lib/generated-config-surfaces.d.ts +682 -0
- package/dist/src/lib/generated-config-surfaces.js +4058 -0
- package/dist/src/lib/generated-config-surfaces.js.map +1 -0
- package/dist/src/lib/generated-template-lint.d.ts +212 -0
- package/dist/src/lib/generated-template-lint.js +624 -0
- package/dist/src/lib/generated-template-lint.js.map +1 -0
- package/dist/src/lib/init-adopt.d.ts +16 -0
- package/dist/src/lib/init-adopt.js +34 -0
- package/dist/src/lib/init-adopt.js.map +1 -0
- package/dist/src/lib/init-assets.d.ts +39 -0
- package/dist/src/lib/init-assets.js +97 -0
- package/dist/src/lib/init-assets.js.map +1 -0
- package/dist/src/lib/init-client-platforms.d.ts +14 -0
- package/dist/src/lib/init-client-platforms.js +71 -0
- package/dist/src/lib/init-client-platforms.js.map +1 -0
- package/dist/src/lib/init-config.d.ts +44 -5
- package/dist/src/lib/init-config.js +80 -7
- package/dist/src/lib/init-config.js.map +1 -1
- package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
- package/dist/src/lib/init-email-redirect-uris.js +46 -0
- package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
- package/dist/src/lib/init-ios-links.d.ts +90 -0
- package/dist/src/lib/init-ios-links.js +218 -0
- package/dist/src/lib/init-ios-links.js.map +1 -0
- package/dist/src/lib/init-plan.d.ts +80 -0
- package/dist/src/lib/init-plan.js +95 -0
- package/dist/src/lib/init-plan.js.map +1 -0
- package/dist/src/lib/init-production-env.d.ts +48 -0
- package/dist/src/lib/init-production-env.js +59 -0
- package/dist/src/lib/init-production-env.js.map +1 -0
- package/dist/src/lib/init-schema.d.ts +74 -0
- package/dist/src/lib/init-schema.js +358 -0
- package/dist/src/lib/init-schema.js.map +1 -0
- package/dist/src/lib/init-xcode.d.ts +33 -0
- package/dist/src/lib/init-xcode.js +114 -0
- package/dist/src/lib/init-xcode.js.map +1 -0
- package/dist/src/lib/integration-request-config.d.ts +30 -0
- package/dist/src/lib/integration-request-config.js +145 -0
- package/dist/src/lib/integration-request-config.js.map +1 -0
- package/dist/src/lib/integration-selector.d.ts +42 -0
- package/dist/src/lib/integration-selector.js +46 -0
- package/dist/src/lib/integration-selector.js.map +1 -0
- package/dist/src/lib/local-state.d.ts +55 -0
- package/dist/src/lib/local-state.js +167 -0
- package/dist/src/lib/local-state.js.map +1 -0
- package/dist/src/lib/local-test-cases.d.ts +63 -0
- package/dist/src/lib/local-test-cases.js +135 -0
- package/dist/src/lib/local-test-cases.js.map +1 -0
- package/dist/src/lib/log-inspection.d.ts +568 -0
- package/dist/src/lib/log-inspection.js +639 -0
- package/dist/src/lib/log-inspection.js.map +1 -0
- package/dist/src/lib/migration-nag.d.ts +2 -2
- package/dist/src/lib/migration-nag.js +3 -3
- package/dist/src/lib/object-status-filter.d.ts +22 -0
- package/dist/src/lib/object-status-filter.js +45 -0
- package/dist/src/lib/object-status-filter.js.map +1 -0
- package/dist/src/lib/output.d.ts +24 -1
- package/dist/src/lib/output.js +42 -1
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/package-manager.d.ts +140 -0
- package/dist/src/lib/package-manager.js +305 -0
- package/dist/src/lib/package-manager.js.map +1 -0
- package/dist/src/lib/paginate.d.ts +50 -0
- package/dist/src/lib/paginate.js +53 -0
- package/dist/src/lib/paginate.js.map +1 -1
- package/dist/src/lib/platform-owned.d.ts +29 -3
- package/dist/src/lib/platform-owned.js +42 -3
- package/dist/src/lib/platform-owned.js.map +1 -1
- package/dist/src/lib/project-config.d.ts +8 -0
- package/dist/src/lib/project-config.js +30 -5
- package/dist/src/lib/project-config.js.map +1 -1
- package/dist/src/lib/query-operators.d.ts +1 -1
- package/dist/src/lib/query-operators.js +1 -1
- package/dist/src/lib/record-filter.d.ts +18 -0
- package/dist/src/lib/record-filter.js +55 -0
- package/dist/src/lib/record-filter.js.map +1 -0
- package/dist/src/lib/resolve-init-dev-port.d.ts +56 -0
- package/dist/src/lib/resolve-init-dev-port.js +55 -0
- package/dist/src/lib/resolve-init-dev-port.js.map +1 -0
- package/dist/src/lib/resolve-init-server.d.ts +64 -0
- package/dist/src/lib/resolve-init-server.js +77 -0
- package/dist/src/lib/resolve-init-server.js.map +1 -0
- package/dist/src/lib/resolve-platform.d.ts +43 -14
- package/dist/src/lib/resolve-platform.js +74 -12
- package/dist/src/lib/resolve-platform.js.map +1 -1
- package/dist/src/lib/run-status.d.ts +19 -0
- package/dist/src/lib/run-status.generated.d.ts +39 -0
- package/dist/src/lib/run-status.generated.js +66 -0
- package/dist/src/lib/run-status.generated.js.map +1 -0
- package/dist/src/lib/run-status.js +19 -0
- package/dist/src/lib/run-status.js.map +1 -0
- package/dist/src/lib/server-text-normalization.d.ts +51 -0
- package/dist/src/lib/server-text-normalization.js +90 -0
- package/dist/src/lib/server-text-normalization.js.map +1 -0
- package/dist/src/lib/server-url.d.ts +22 -0
- package/dist/src/lib/server-url.js +33 -0
- package/dist/src/lib/server-url.js.map +1 -0
- package/dist/src/lib/signing-secret-status.d.ts +81 -0
- package/dist/src/lib/signing-secret-status.js +116 -0
- package/dist/src/lib/signing-secret-status.js.map +1 -0
- package/dist/src/lib/skill-installer.js +6 -3
- package/dist/src/lib/skill-installer.js.map +1 -1
- package/dist/src/lib/snapshots.d.ts +2 -2
- package/dist/src/lib/snapshots.js +2 -2
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +15 -2
- package/dist/src/lib/swift-codegen/dbGenerator.js +250 -18
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
- package/dist/src/lib/swift-codegen/generator.d.ts +11 -2
- package/dist/src/lib/swift-codegen/generator.js +181 -7
- package/dist/src/lib/swift-codegen/generator.js.map +1 -1
- package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +7 -3
- package/dist/src/lib/swift-codegen/siblingSymbols.js +4 -1
- package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -1
- package/dist/src/lib/sync-dir-selector.d.ts +21 -0
- package/dist/src/lib/sync-dir-selector.js +30 -0
- package/dist/src/lib/sync-dir-selector.js.map +1 -0
- package/dist/src/lib/sync-paths.d.ts +39 -0
- package/dist/src/lib/sync-paths.js +70 -2
- package/dist/src/lib/sync-paths.js.map +1 -1
- package/dist/src/lib/sync-resource-types.d.ts +138 -31
- package/dist/src/lib/sync-resource-types.js +241 -47
- package/dist/src/lib/sync-resource-types.js.map +1 -1
- package/dist/src/lib/sync-selectors.d.ts +95 -0
- package/dist/src/lib/sync-selectors.js +228 -0
- package/dist/src/lib/sync-selectors.js.map +1 -0
- package/dist/src/lib/template.d.ts +62 -4
- package/dist/src/lib/template.js +147 -39
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/test-case-file-names.d.ts +40 -0
- package/dist/src/lib/test-case-file-names.js +91 -0
- package/dist/src/lib/test-case-file-names.js.map +1 -0
- package/dist/src/lib/test-case-keys.d.ts +29 -0
- package/dist/src/lib/test-case-keys.js +55 -0
- package/dist/src/lib/test-case-keys.js.map +1 -0
- package/dist/src/lib/test-case-variables.d.ts +15 -0
- package/dist/src/lib/test-case-variables.js +29 -0
- package/dist/src/lib/test-case-variables.js.map +1 -0
- package/dist/src/lib/toml-database-config.d.ts +4 -4
- package/dist/src/lib/toml-database-config.js +27 -34
- package/dist/src/lib/toml-database-config.js.map +1 -1
- package/dist/src/lib/toml-metadata-config.d.ts +9 -5
- package/dist/src/lib/toml-metadata-config.js +40 -45
- package/dist/src/lib/toml-metadata-config.js.map +1 -1
- package/dist/src/lib/toml-native-form.d.ts +1 -1
- package/dist/src/lib/toml-native-form.js +1 -1
- package/dist/src/lib/toml-params-validator.d.ts +1 -1
- package/dist/src/lib/toml-params-validator.js +1 -1
- package/dist/src/lib/toml-scalar-edit.d.ts +43 -0
- package/dist/src/lib/toml-scalar-edit.js +283 -0
- package/dist/src/lib/toml-scalar-edit.js.map +1 -0
- package/dist/src/lib/user-selector.d.ts +24 -0
- package/dist/src/lib/user-selector.js +33 -0
- package/dist/src/lib/user-selector.js.map +1 -0
- package/dist/src/lib/version-check.d.ts +25 -0
- package/dist/src/lib/version-check.js +77 -8
- package/dist/src/lib/version-check.js.map +1 -1
- package/dist/src/lib/watch.d.ts +121 -0
- package/dist/src/lib/watch.js +169 -0
- package/dist/src/lib/watch.js.map +1 -0
- package/dist/src/lib/web-url.d.ts +40 -0
- package/dist/src/lib/web-url.js +76 -0
- package/dist/src/lib/web-url.js.map +1 -0
- package/dist/src/lib/workflow-apply.d.ts +69 -45
- package/dist/src/lib/workflow-apply.js +99 -72
- package/dist/src/lib/workflow-apply.js.map +1 -1
- package/dist/src/lib/workflow-codegen/generator.js +4 -4
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
- package/dist/src/lib/workflow-codegen/invokerIR.d.ts +11 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js +5 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -1
- package/dist/src/lib/workflow-config-apply.d.ts +70 -0
- package/dist/src/lib/workflow-config-apply.js +137 -0
- package/dist/src/lib/workflow-config-apply.js.map +1 -0
- package/dist/src/lib/workflow-config-sidecar.d.ts +63 -0
- package/dist/src/lib/workflow-config-sidecar.js +96 -0
- package/dist/src/lib/workflow-config-sidecar.js.map +1 -0
- package/dist/src/lib/workflow-defaults.d.ts +29 -0
- package/dist/src/lib/workflow-defaults.js +41 -0
- package/dist/src/lib/workflow-defaults.js.map +1 -0
- package/dist/src/lib/workflow-include-preserve.d.ts +76 -0
- package/dist/src/lib/workflow-include-preserve.js +286 -0
- package/dist/src/lib/workflow-include-preserve.js.map +1 -0
- package/dist/src/lib/workflow-payload.d.ts +31 -20
- package/dist/src/lib/workflow-payload.js +100 -110
- package/dist/src/lib/workflow-payload.js.map +1 -1
- package/dist/src/lib/workflow-toml-validator.d.ts +37 -16
- package/dist/src/lib/workflow-toml-validator.js +141 -16
- package/dist/src/lib/workflow-toml-validator.js.map +1 -1
- package/dist/src/types/index.d.ts +78 -22
- package/dist/src/validators.d.ts +7 -7
- package/dist/src/validators.js +6 -6
- package/package.json +11 -6
- package/dist/src/commands/settings.d.ts +0 -15
- package/dist/src/commands/settings.js +0 -102
- package/dist/src/commands/settings.js.map +0 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep `[[include]]` fragment structure alive across `config pull` (issue #2416).
|
|
3
|
+
*
|
|
4
|
+
* Fragments are a CLI-only authoring form: `expandWorkflowTomlData()` splices
|
|
5
|
+
* the referenced fragments into a flat `[[steps]]` list and the server only
|
|
6
|
+
* ever stores that expansion (see `workflow-fragments.ts`). `config pull`
|
|
7
|
+
* serializes the server's flat steps straight back to disk, so before this
|
|
8
|
+
* module a pull unconditionally overwrote a fragment-authored file with its
|
|
9
|
+
* own expansion — the `[[include]]` blocks were gone and had to be rebuilt by
|
|
10
|
+
* hand, even when `config diff` reported the file as synced.
|
|
11
|
+
*
|
|
12
|
+
* `reconcileWorkflowIncludes()` decides what pull should write for one
|
|
13
|
+
* workflow file. It only ever engages for a local file that actually carries
|
|
14
|
+
* an `include` key; everything else takes the unchanged "write what the server
|
|
15
|
+
* gave us" path.
|
|
16
|
+
*
|
|
17
|
+
* - **skip** — the local file expands to exactly what the server is running.
|
|
18
|
+
* There is nothing to apply, so leave the fragment source (and its
|
|
19
|
+
* comments and formatting) untouched. One thing still has to be applied to
|
|
20
|
+
* an otherwise-unchanged file: a retired inline `[[configs]]` list (#2733).
|
|
21
|
+
* Pull rewrites every other workflow file off it, and push rejects a file
|
|
22
|
+
* that still carries one, so a plain skip left the fragment source in a
|
|
23
|
+
* shape push refuses — pull → push of an untouched tree failed. Such a
|
|
24
|
+
* file takes the write-merged path with only the list removed.
|
|
25
|
+
* - **write-merged** — the server drifted, but its step list still *starts*
|
|
26
|
+
* with exactly the steps the local includes expand to. The drift is
|
|
27
|
+
* therefore expressible in fragment form: re-emit the file with the
|
|
28
|
+
* original `[[include]]` blocks and put the remaining server steps in the
|
|
29
|
+
* workflow's own `[[steps]]` list. Re-expanding that file reproduces the
|
|
30
|
+
* server's step list in order, so the next `config diff` reads as synced.
|
|
31
|
+
* - **write-expanded** — the fragment-derived prefix no longer matches what
|
|
32
|
+
* the server is running (a fragment's steps were edited or removed
|
|
33
|
+
* server-side), so no fragment-preserving file could reproduce it. Fall
|
|
34
|
+
* back to the historical behavior — write the fully expanded form — and
|
|
35
|
+
* say why, so the operator knows the fragment source was replaced rather
|
|
36
|
+
* than silently losing it.
|
|
37
|
+
*
|
|
38
|
+
* The order rule comes from the expander: it emits every fragment's steps
|
|
39
|
+
* first (in `include` order) and then the workflow's own `[[steps]]`. So a
|
|
40
|
+
* fragment-preserving file can only represent a server step list whose leading
|
|
41
|
+
* steps are exactly the fragment expansion. Server steps inserted *between*
|
|
42
|
+
* fragment steps are not representable and take the write-expanded path.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Hashes an already-parsed (and, for a local file, already-expanded) workflow
|
|
46
|
+
* TOML object to its canonical content hash. Injected by the caller so this
|
|
47
|
+
* module uses exactly the same normalization `config diff` does
|
|
48
|
+
* (`hashWorkflowTomlForDiff` in `commands/sync.ts`) without importing the
|
|
49
|
+
* command module back into `lib/`.
|
|
50
|
+
*/
|
|
51
|
+
export type WorkflowTomlHasher = (parsed: any) => string;
|
|
52
|
+
export interface IncludeReconcileOutcome {
|
|
53
|
+
/**
|
|
54
|
+
* `write-expanded`: write the server's serialized TOML unchanged (the
|
|
55
|
+
* pre-#2416 behavior). `skip`: leave the local file alone. `write-merged`:
|
|
56
|
+
* write `content`, which preserves the local `[[include]]` blocks.
|
|
57
|
+
*/
|
|
58
|
+
action: "write-expanded" | "skip" | "write-merged";
|
|
59
|
+
/** TOML to write. Only set when `action` is `write-merged`. */
|
|
60
|
+
content?: string;
|
|
61
|
+
/** Human-readable note for the pull log. Absent when there's nothing to say. */
|
|
62
|
+
message?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface ReconcileWorkflowIncludesOptions {
|
|
65
|
+
/** Workflow key, used only for log messages. */
|
|
66
|
+
workflowKey: string;
|
|
67
|
+
/** Absolute path of the local workflow TOML (also resolves the fragments dir). */
|
|
68
|
+
localPath: string;
|
|
69
|
+
/** Current contents of that file, or `undefined` when it doesn't exist yet. */
|
|
70
|
+
localContent: string | undefined;
|
|
71
|
+
/** The TOML `config pull` would write, from `serializeWorkflow()`. */
|
|
72
|
+
remoteToml: string;
|
|
73
|
+
/** Canonical content hash for a parsed workflow TOML. */
|
|
74
|
+
hashParsedToml: WorkflowTomlHasher;
|
|
75
|
+
}
|
|
76
|
+
export declare function reconcileWorkflowIncludes(options: ReconcileWorkflowIncludesOptions): IncludeReconcileOutcome;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep `[[include]]` fragment structure alive across `config pull` (issue #2416).
|
|
3
|
+
*
|
|
4
|
+
* Fragments are a CLI-only authoring form: `expandWorkflowTomlData()` splices
|
|
5
|
+
* the referenced fragments into a flat `[[steps]]` list and the server only
|
|
6
|
+
* ever stores that expansion (see `workflow-fragments.ts`). `config pull`
|
|
7
|
+
* serializes the server's flat steps straight back to disk, so before this
|
|
8
|
+
* module a pull unconditionally overwrote a fragment-authored file with its
|
|
9
|
+
* own expansion — the `[[include]]` blocks were gone and had to be rebuilt by
|
|
10
|
+
* hand, even when `config diff` reported the file as synced.
|
|
11
|
+
*
|
|
12
|
+
* `reconcileWorkflowIncludes()` decides what pull should write for one
|
|
13
|
+
* workflow file. It only ever engages for a local file that actually carries
|
|
14
|
+
* an `include` key; everything else takes the unchanged "write what the server
|
|
15
|
+
* gave us" path.
|
|
16
|
+
*
|
|
17
|
+
* - **skip** — the local file expands to exactly what the server is running.
|
|
18
|
+
* There is nothing to apply, so leave the fragment source (and its
|
|
19
|
+
* comments and formatting) untouched. One thing still has to be applied to
|
|
20
|
+
* an otherwise-unchanged file: a retired inline `[[configs]]` list (#2733).
|
|
21
|
+
* Pull rewrites every other workflow file off it, and push rejects a file
|
|
22
|
+
* that still carries one, so a plain skip left the fragment source in a
|
|
23
|
+
* shape push refuses — pull → push of an untouched tree failed. Such a
|
|
24
|
+
* file takes the write-merged path with only the list removed.
|
|
25
|
+
* - **write-merged** — the server drifted, but its step list still *starts*
|
|
26
|
+
* with exactly the steps the local includes expand to. The drift is
|
|
27
|
+
* therefore expressible in fragment form: re-emit the file with the
|
|
28
|
+
* original `[[include]]` blocks and put the remaining server steps in the
|
|
29
|
+
* workflow's own `[[steps]]` list. Re-expanding that file reproduces the
|
|
30
|
+
* server's step list in order, so the next `config diff` reads as synced.
|
|
31
|
+
* - **write-expanded** — the fragment-derived prefix no longer matches what
|
|
32
|
+
* the server is running (a fragment's steps were edited or removed
|
|
33
|
+
* server-side), so no fragment-preserving file could reproduce it. Fall
|
|
34
|
+
* back to the historical behavior — write the fully expanded form — and
|
|
35
|
+
* say why, so the operator knows the fragment source was replaced rather
|
|
36
|
+
* than silently losing it.
|
|
37
|
+
*
|
|
38
|
+
* The order rule comes from the expander: it emits every fragment's steps
|
|
39
|
+
* first (in `include` order) and then the workflow's own `[[steps]]`. So a
|
|
40
|
+
* fragment-preserving file can only represent a server step list whose leading
|
|
41
|
+
* steps are exactly the fragment expansion. Server steps inserted *between*
|
|
42
|
+
* fragment steps are not representable and take the write-expanded path.
|
|
43
|
+
*/
|
|
44
|
+
import { parseConfigToml, stringifyConfigToml } from "./config-toml.js";
|
|
45
|
+
import { expandWorkflowTomlData } from "./workflow-fragments.js";
|
|
46
|
+
import { canonicalJsonStringify } from "./canonical-json.js";
|
|
47
|
+
export function reconcileWorkflowIncludes(options) {
|
|
48
|
+
const { workflowKey, localPath, localContent, remoteToml, hashParsedToml } = options;
|
|
49
|
+
const label = `workflows/${workflowKey}.toml`;
|
|
50
|
+
if (localContent === undefined) {
|
|
51
|
+
return { action: "write-expanded" };
|
|
52
|
+
}
|
|
53
|
+
let localParsed;
|
|
54
|
+
try {
|
|
55
|
+
localParsed = parseConfigToml(localContent);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// An unparseable local file carries no structure worth preserving — pull
|
|
59
|
+
// replaces it, exactly as it did before.
|
|
60
|
+
return { action: "write-expanded" };
|
|
61
|
+
}
|
|
62
|
+
if (localParsed === null ||
|
|
63
|
+
typeof localParsed !== "object" ||
|
|
64
|
+
!("include" in localParsed)) {
|
|
65
|
+
return { action: "write-expanded" };
|
|
66
|
+
}
|
|
67
|
+
let expandedLocal;
|
|
68
|
+
try {
|
|
69
|
+
expandedLocal = expandWorkflowTomlData(localParsed, localPath);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
return {
|
|
73
|
+
action: "write-expanded",
|
|
74
|
+
message: `${label}: could not expand its [[include]] fragments ` +
|
|
75
|
+
`(${err?.message ?? err}); wrote the fully expanded form from the server.`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const remoteParsed = parseConfigToml(remoteToml);
|
|
79
|
+
// Nothing to apply: the fragment source already describes what's running —
|
|
80
|
+
// except for a retired inline `[[configs]]` list, which pull has to take out
|
|
81
|
+
// on its way past (#2733).
|
|
82
|
+
if (hashParsedToml(expandedLocal) === hashParsedToml(remoteParsed)) {
|
|
83
|
+
if (hasRetiredInlineConfigs(localParsed)) {
|
|
84
|
+
return {
|
|
85
|
+
action: "write-merged",
|
|
86
|
+
content: withoutRetiredInlineConfigs({
|
|
87
|
+
localContent,
|
|
88
|
+
localParsed,
|
|
89
|
+
localPath,
|
|
90
|
+
remoteHash: hashParsedToml(remoteParsed),
|
|
91
|
+
hashParsedToml,
|
|
92
|
+
}),
|
|
93
|
+
message: `${label}: removed the retired [[configs]] list (#2645) and kept ` +
|
|
94
|
+
`the local [[include]] fragment source. Named configurations are ` +
|
|
95
|
+
`authored one per file at workflows/${workflowKey}.configs/<name>.toml.`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
action: "skip",
|
|
100
|
+
message: `${label}: unchanged — kept the local [[include]] fragment source.`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const ownSteps = Array.isArray(localParsed.steps) ? localParsed.steps : [];
|
|
104
|
+
const expandedSteps = Array.isArray(expandedLocal.steps)
|
|
105
|
+
? expandedLocal.steps
|
|
106
|
+
: [];
|
|
107
|
+
const remoteSteps = Array.isArray(remoteParsed.steps)
|
|
108
|
+
? remoteParsed.steps
|
|
109
|
+
: [];
|
|
110
|
+
const fragmentCount = expandedSteps.length - ownSteps.length;
|
|
111
|
+
if (fragmentCount < 0) {
|
|
112
|
+
// Defensive: the expander always emits fragment steps plus own steps.
|
|
113
|
+
return { action: "write-expanded" };
|
|
114
|
+
}
|
|
115
|
+
const mismatch = findFragmentPrefixMismatch(expandedSteps.slice(0, fragmentCount), remoteSteps);
|
|
116
|
+
if (mismatch) {
|
|
117
|
+
return {
|
|
118
|
+
action: "write-expanded",
|
|
119
|
+
message: `${label}: the running workflow no longer starts with the steps its ` +
|
|
120
|
+
`[[include]] fragments expand to (${mismatch}), so the fragment ` +
|
|
121
|
+
`structure can't be preserved. Wrote the fully expanded form — ` +
|
|
122
|
+
`re-author the includes by hand if you want them back.`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const remainingSteps = remoteSteps.slice(fragmentCount);
|
|
126
|
+
// Rebuild the file from the server's content with the local include blocks
|
|
127
|
+
// spliced back in. `workflow` first, then `include`, then the steps the
|
|
128
|
+
// fragments don't cover, then everything else the server serialized
|
|
129
|
+
// (`configs`, `[expr.cel]`, the declared-access manifest, ...).
|
|
130
|
+
const data = {};
|
|
131
|
+
if ("workflow" in remoteParsed) {
|
|
132
|
+
data.workflow = remoteParsed.workflow;
|
|
133
|
+
}
|
|
134
|
+
data.include = localParsed.include;
|
|
135
|
+
if (remainingSteps.length > 0) {
|
|
136
|
+
data.steps = remainingSteps;
|
|
137
|
+
}
|
|
138
|
+
for (const [key, value] of Object.entries(remoteParsed)) {
|
|
139
|
+
if (!(key in data) && key !== "steps") {
|
|
140
|
+
data[key] = value;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
action: "write-merged",
|
|
145
|
+
content: stringifyConfigToml(data),
|
|
146
|
+
message: `${label}: kept ${fragmentCount} step(s) from [[include]] fragments; ` +
|
|
147
|
+
`wrote ${remainingSteps.length} server step(s) the fragments don't cover.`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Whether the local file carries the inline `[[configs]]` list #2645 retired.
|
|
152
|
+
* Matches the push validator's rule exactly (`validateRetiredInlineConfigs` in
|
|
153
|
+
* `workflow-toml-validator.ts`): a non-empty array at the document root. An
|
|
154
|
+
* empty one is not rejected by push, so pull has no reason to touch the file
|
|
155
|
+
* over it.
|
|
156
|
+
*/
|
|
157
|
+
function hasRetiredInlineConfigs(localParsed) {
|
|
158
|
+
return Array.isArray(localParsed.configs) && localParsed.configs.length > 0;
|
|
159
|
+
}
|
|
160
|
+
/** A `[[configs]]` header line, the only form a retired list can be authored in as a table array. */
|
|
161
|
+
const RETIRED_CONFIGS_HEADER = /^\[\[\s*configs\s*\]\]\s*(#.*)?$/;
|
|
162
|
+
/** `[configs.x]` / `[[configs.x]]` — a subtable of the entry being removed. */
|
|
163
|
+
const RETIRED_CONFIGS_SUBTABLE = /^\[\[?\s*configs\s*\./;
|
|
164
|
+
/**
|
|
165
|
+
* The local file with its retired `[[configs]]` blocks taken out, preserving
|
|
166
|
+
* every other byte — comments, key order and formatting included. That matters
|
|
167
|
+
* here more than anywhere else in this module: the file is otherwise in sync,
|
|
168
|
+
* so re-emitting it would reformat an operator's hand-authored source for a
|
|
169
|
+
* change that only deletes a block nothing reads.
|
|
170
|
+
*
|
|
171
|
+
* Returns `undefined` when the list is not authored as `[[configs]]` blocks
|
|
172
|
+
* (an inline `configs = [ … ]` array, say), which the caller handles by
|
|
173
|
+
* re-emitting the parsed document instead.
|
|
174
|
+
*/
|
|
175
|
+
function stripRetiredInlineConfigsText(content) {
|
|
176
|
+
const kept = [];
|
|
177
|
+
/**
|
|
178
|
+
* Blank and comment lines seen since the last line that definitely belongs to
|
|
179
|
+
* the block being removed. A comment sitting between the retired list and the
|
|
180
|
+
* next table almost always documents *that* table, so it is handed back when
|
|
181
|
+
* the table arrives instead of being deleted with the block; trivia followed
|
|
182
|
+
* by another config line documented the removed entry and is dropped.
|
|
183
|
+
*/
|
|
184
|
+
let trivia = [];
|
|
185
|
+
let removing = false;
|
|
186
|
+
let removedAny = false;
|
|
187
|
+
/** Give the pending trivia back, from its first comment line onwards. */
|
|
188
|
+
const keepTrivia = () => {
|
|
189
|
+
const firstComment = trivia.findIndex((line) => line.trim().startsWith("#"));
|
|
190
|
+
// Blank-only trivia is just the separator the removed block left behind.
|
|
191
|
+
if (firstComment >= 0)
|
|
192
|
+
kept.push(...trivia.slice(firstComment));
|
|
193
|
+
trivia = [];
|
|
194
|
+
};
|
|
195
|
+
for (const line of content.split("\n")) {
|
|
196
|
+
const trimmed = line.trim();
|
|
197
|
+
if (RETIRED_CONFIGS_HEADER.test(trimmed)) {
|
|
198
|
+
trivia = [];
|
|
199
|
+
removing = true;
|
|
200
|
+
removedAny = true;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (removing) {
|
|
204
|
+
// The block runs to the next top-level table header; a `configs.*`
|
|
205
|
+
// subtable belongs to the entry being removed and goes with it.
|
|
206
|
+
if (RETIRED_CONFIGS_SUBTABLE.test(trimmed)) {
|
|
207
|
+
trivia = [];
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (!trimmed.startsWith("[")) {
|
|
211
|
+
if (trimmed === "" || trimmed.startsWith("#"))
|
|
212
|
+
trivia.push(line);
|
|
213
|
+
else
|
|
214
|
+
trivia = [];
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
keepTrivia();
|
|
218
|
+
removing = false;
|
|
219
|
+
}
|
|
220
|
+
kept.push(line);
|
|
221
|
+
}
|
|
222
|
+
if (removing)
|
|
223
|
+
keepTrivia();
|
|
224
|
+
if (!removedAny)
|
|
225
|
+
return undefined;
|
|
226
|
+
const stripped = kept.join("\n");
|
|
227
|
+
// A block that ran to the end of the file takes the final newline with it.
|
|
228
|
+
return content.endsWith("\n") && !stripped.endsWith("\n")
|
|
229
|
+
? `${stripped}\n`
|
|
230
|
+
: stripped;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* What pull writes for an in-sync fragment source that still carries the
|
|
234
|
+
* retired list: the same file minus the `[[configs]]` blocks.
|
|
235
|
+
*
|
|
236
|
+
* The textual strip is verified before it is used — the result has to parse,
|
|
237
|
+
* carry no `configs` any more, and still expand to exactly the server's
|
|
238
|
+
* content hash. Anything else (an inline-array form, a shape the line scan
|
|
239
|
+
* misreads) falls back to re-emitting the parsed document without its
|
|
240
|
+
* `configs` key, which loses comments but is correct by construction.
|
|
241
|
+
*/
|
|
242
|
+
function withoutRetiredInlineConfigs(options) {
|
|
243
|
+
const { localContent, localParsed, localPath, remoteHash, hashParsedToml } = options;
|
|
244
|
+
const stripped = stripRetiredInlineConfigsText(localContent);
|
|
245
|
+
if (stripped !== undefined) {
|
|
246
|
+
try {
|
|
247
|
+
const reparsed = parseConfigToml(stripped);
|
|
248
|
+
if (!hasRetiredInlineConfigs(reparsed) &&
|
|
249
|
+
hashParsedToml(expandWorkflowTomlData(reparsed, localPath)) ===
|
|
250
|
+
remoteHash) {
|
|
251
|
+
return stripped;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// Fall through to the re-emit below.
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const { configs: _retired, ...rest } = localParsed;
|
|
259
|
+
return stringifyConfigToml(rest);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Returns a human-readable description of the first place the server's step
|
|
263
|
+
* list departs from the fragment-derived prefix, or `undefined` when the
|
|
264
|
+
* prefix matches exactly.
|
|
265
|
+
*/
|
|
266
|
+
function findFragmentPrefixMismatch(fragmentSteps, remoteSteps) {
|
|
267
|
+
if (remoteSteps.length < fragmentSteps.length) {
|
|
268
|
+
return `the server has ${remoteSteps.length} step(s), fewer than the ${fragmentSteps.length} the fragments produce`;
|
|
269
|
+
}
|
|
270
|
+
for (let i = 0; i < fragmentSteps.length; i++) {
|
|
271
|
+
if (canonicalJsonStringify(fragmentSteps[i]) !==
|
|
272
|
+
canonicalJsonStringify(remoteSteps[i])) {
|
|
273
|
+
const expectedId = describeStepId(fragmentSteps[i]);
|
|
274
|
+
const actualId = describeStepId(remoteSteps[i]);
|
|
275
|
+
return expectedId === actualId
|
|
276
|
+
? `step ${i + 1} '${expectedId}' differs`
|
|
277
|
+
: `step ${i + 1} is '${actualId}' where the fragments produce '${expectedId}'`;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
function describeStepId(step) {
|
|
283
|
+
const id = step?.id;
|
|
284
|
+
return typeof id === "string" && id.length > 0 ? id : "<no id>";
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=workflow-include-preserve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-include-preserve.js","sourceRoot":"","sources":["../../../src/lib/workflow-include-preserve.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Background: the CLI built the create/update workflow payload in THREE
|
|
5
5
|
* separate hand-enumerated literals — `workflows create --from-file`
|
|
6
|
-
* (`cli/src/commands/workflows.ts`), the `
|
|
7
|
-
* (`cli/src/commands/sync.ts`), and the `
|
|
6
|
+
* (`cli/src/commands/workflows.ts`), the `config push` create branch
|
|
7
|
+
* (`cli/src/commands/sync.ts`), and the `config push` update branch (the metadata
|
|
8
8
|
* PATCH in `cli/src/lib/workflow-apply.ts`). Because each site listed the
|
|
9
9
|
* `[workflow]` fields by hand, they drifted apart: a field added to one path was
|
|
10
10
|
* silently dropped by the others. `status` was the 4th field lost this way
|
|
@@ -27,18 +27,30 @@
|
|
|
27
27
|
* Presence semantics, by mode:
|
|
28
28
|
* - create: optional strings coalesce absent/empty → `undefined` (omit; the
|
|
29
29
|
* server default applies). `capabilities` forwards the raw array (absent →
|
|
30
|
-
* omit). Schemas omit when absent.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
30
|
+
* omit). Schemas omit when absent. Booleans are raw pass-through so an
|
|
31
|
+
* explicit `false` is preserved and only a truly-absent key drops.
|
|
32
|
+
* - update: ALWAYS-SEND (#2743). The workflow TOML fully describes the
|
|
33
|
+
* workflow, so every update-mode field carries a definite value and
|
|
34
|
+
* `undefined` never appears: a defaulted scalar (`status`, the queue
|
|
35
|
+
* limits, `dequeueOrder`, `requiresClientApply`) sends its concrete model
|
|
36
|
+
* default when the file omits it, and a nullable field (`description`,
|
|
37
|
+
* `accessRule`, `runAs`, `capabilities`, the schemas, `lock`) sends `null`.
|
|
38
|
+
* Deleting a line from the file therefore CONVERGES the server rather than
|
|
39
|
+
* silently leaving the old value live (#1567's bug class). Optional strings
|
|
40
|
+
* keep their `"" → null` coalescing, so an explicit clear and an omission
|
|
41
|
+
* land on the same wire value.
|
|
42
|
+
*
|
|
43
|
+
* Defaulted scalars deliberately travel as their default, not as `null`: a
|
|
44
|
+
* server predating #2743 coerces a queue-limit `null` to `0`, while an
|
|
45
|
+
* explicit default converges identically on both. The shared map lives in
|
|
46
|
+
* `workflow-defaults.ts` (the diff normalizer reads the same copy).
|
|
47
|
+
*
|
|
48
|
+
* Omit-preserve survives only as the SERVER's contract for other clients
|
|
49
|
+
* (web-admin): the PATCH still leaves an absent key alone.
|
|
50
|
+
* - `syncCallable` is OMITTED from the builder in `mode: "update"`: its
|
|
51
|
+
* ordering relative to the steps write is `applyWorkflowBody`'s to decide
|
|
52
|
+
* (#807 — enabling must validate against the NEW steps, so it is deferred
|
|
53
|
+
* to a second PATCH; disabling rides the first PATCH). See that module.
|
|
42
54
|
*/
|
|
43
55
|
export type WorkflowPayloadMode = "create" | "update";
|
|
44
56
|
/**
|
|
@@ -68,13 +80,12 @@ export type WorkflowExpressionsPayload = {
|
|
|
68
80
|
*/
|
|
69
81
|
export declare function parseWorkflowExpressionsToml(tomlData: any): WorkflowExpressionsPayload | undefined;
|
|
70
82
|
/**
|
|
71
|
-
* The `[workflow]`-derived keys the builder emits, per mode
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
83
|
+
* The `[workflow]`-derived keys the builder emits, per mode — read from the
|
|
84
|
+
* vendored definition (#2644), not restated here. A field added to
|
|
85
|
+
* `src/config-surface/workflow.ts` is pushed with no edit to this file, which
|
|
86
|
+
* is what closes the recurring "CLI silently drops a new server field" bug.
|
|
75
87
|
*/
|
|
76
|
-
export declare
|
|
77
|
-
export declare const WORKFLOW_PAYLOAD_FIELDS_UPDATE: ReadonlyArray<string>;
|
|
88
|
+
export declare function workflowPayloadFields(mode: WorkflowPayloadMode): string[];
|
|
78
89
|
/**
|
|
79
90
|
* Build the workflow payload's `[workflow]`-derived fields from a parsed TOML
|
|
80
91
|
* `[workflow]` table. `workflow` is `tomlData.workflow` (already merged with any
|