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.
- package/README.md +444 -106
- package/assets/skill/skills/primitive-platform/SKILL.md +811 -0
- package/dist/bin/primitive.d.ts +2 -0
- package/dist/bin/primitive.js +373 -21
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.d.ts +2 -0
- package/dist/src/commands/admins.js +128 -19
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.d.ts +2 -0
- package/dist/src/commands/analytics.js +700 -55
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.d.ts +2 -0
- package/dist/src/commands/apps.js +54 -96
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +196 -105
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/blob-buckets.d.ts +2 -0
- package/dist/src/commands/blob-buckets.js +330 -0
- package/dist/src/commands/blob-buckets.js.map +1 -0
- package/dist/src/commands/catalog.d.ts +2 -0
- package/dist/src/commands/catalog.js +37 -38
- package/dist/src/commands/catalog.js.map +1 -1
- package/dist/src/commands/collection-type-configs.d.ts +2 -0
- package/dist/src/commands/collection-type-configs.js +84 -0
- package/dist/src/commands/collection-type-configs.js.map +1 -0
- package/dist/src/commands/collections.d.ts +2 -0
- package/dist/src/commands/collections.js +565 -0
- package/dist/src/commands/collections.js.map +1 -0
- package/dist/src/commands/comparisons.d.ts +2 -0
- package/dist/src/commands/comparisons.js +6 -6
- package/dist/src/commands/comparisons.js.map +1 -1
- package/dist/src/commands/config.d.ts +46 -0
- package/dist/src/commands/config.js +465 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/connections.d.ts +2 -0
- package/dist/src/commands/connections.js +100 -0
- package/dist/src/commands/connections.js.map +1 -0
- package/dist/src/commands/cron-triggers.d.ts +2 -0
- package/dist/src/commands/cron-triggers.js +265 -0
- package/dist/src/commands/cron-triggers.js.map +1 -0
- package/dist/src/commands/database-type-configs.d.ts +2 -0
- package/dist/src/commands/database-type-configs.js +163 -0
- package/dist/src/commands/database-type-configs.js.map +1 -0
- package/dist/src/commands/database-types.d.ts +2 -0
- package/dist/src/commands/database-types.js +171 -0
- package/dist/src/commands/database-types.js.map +1 -0
- package/dist/src/commands/databases.d.ts +65 -0
- package/dist/src/commands/databases.js +1859 -238
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +2 -0
- package/dist/src/commands/documents.js +2062 -19
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.d.ts +2 -0
- package/dist/src/commands/email-templates.js +174 -0
- package/dist/src/commands/email-templates.js.map +1 -0
- package/dist/src/commands/env.d.ts +23 -0
- package/dist/src/commands/env.js +385 -0
- package/dist/src/commands/env.js.map +1 -0
- 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/functions.d.ts +20 -0
- package/dist/src/commands/functions.js +672 -0
- package/dist/src/commands/functions.js.map +1 -0
- package/dist/src/commands/group-type-configs.d.ts +2 -0
- package/dist/src/commands/group-type-configs.js +86 -0
- package/dist/src/commands/group-type-configs.js.map +1 -0
- package/dist/src/commands/groups.d.ts +2 -0
- package/dist/src/commands/groups.js +39 -108
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/guides.d.ts +223 -0
- package/dist/src/commands/guides.js +617 -65
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/init.d.ts +37 -0
- package/dist/src/commands/init.js +1693 -208
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.d.ts +2 -0
- package/dist/src/commands/integrations.js +402 -182
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/llm.d.ts +2 -0
- package/dist/src/commands/llm.js +13 -8
- package/dist/src/commands/llm.js.map +1 -1
- package/dist/src/commands/locks.d.ts +8 -0
- package/dist/src/commands/locks.js +160 -0
- package/dist/src/commands/locks.js.map +1 -0
- 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.d.ts +2 -0
- package/dist/src/commands/metadata.js +281 -0
- package/dist/src/commands/metadata.js.map +1 -0
- package/dist/src/commands/prompts.d.ts +2 -0
- package/dist/src/commands/prompts.js +275 -621
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.d.ts +3 -0
- package/dist/src/commands/rule-sets.js +137 -147
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/scripts.d.ts +30 -0
- package/dist/src/commands/scripts.js +679 -0
- package/dist/src/commands/scripts.js.map +1 -0
- package/dist/src/commands/secrets.d.ts +2 -0
- package/dist/src/commands/secrets.js +108 -0
- package/dist/src/commands/secrets.js.map +1 -0
- package/dist/src/commands/sessions.d.ts +2 -0
- package/dist/src/commands/sessions.js +75 -0
- package/dist/src/commands/sessions.js.map +1 -0
- package/dist/src/commands/settings.d.ts +18 -0
- package/dist/src/commands/settings.js +54 -0
- package/dist/src/commands/settings.js.map +1 -0
- package/dist/src/commands/skill.d.ts +2 -0
- package/dist/src/commands/skill.js +29 -0
- package/dist/src/commands/skill.js.map +1 -0
- package/dist/src/commands/sync-app-settings.d.ts +158 -0
- package/dist/src/commands/sync-app-settings.js +328 -0
- package/dist/src/commands/sync-app-settings.js.map +1 -0
- package/dist/src/commands/sync.d.ts +2514 -0
- package/dist/src/commands/sync.js +16106 -848
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.d.ts +2 -0
- package/dist/src/commands/tokens.js +130 -21
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.d.ts +2 -0
- package/dist/src/commands/users.js +532 -23
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/vars.d.ts +8 -0
- package/dist/src/commands/vars.js +96 -0
- package/dist/src/commands/vars.js.map +1 -0
- package/dist/src/commands/waitlist.d.ts +2 -0
- package/dist/src/commands/waitlist.js +10 -10
- package/dist/src/commands/waitlist.js.map +1 -1
- package/dist/src/commands/webhooks.d.ts +2 -0
- package/dist/src/commands/webhooks.js +562 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/commands/workflows.d.ts +116 -0
- package/dist/src/commands/workflows.js +1638 -729
- 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 +2147 -0
- package/dist/src/lib/api-client.js +2042 -160
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-match-guard.d.ts +44 -0
- package/dist/src/lib/app-match-guard.js +72 -0
- package/dist/src/lib/app-match-guard.js.map +1 -0
- package/dist/src/lib/app-settings-descriptor.d.ts +263 -0
- package/dist/src/lib/app-settings-descriptor.js +584 -0
- package/dist/src/lib/app-settings-descriptor.js.map +1 -0
- package/dist/src/lib/auth-flow.d.ts +8 -0
- package/dist/src/lib/batch.d.ts +26 -0
- package/dist/src/lib/batch.js +32 -0
- package/dist/src/lib/batch.js.map +1 -0
- package/dist/src/lib/block-layout.d.ts +160 -0
- package/dist/src/lib/block-layout.js +451 -0
- package/dist/src/lib/block-layout.js.map +1 -0
- package/dist/src/lib/block-selector.d.ts +58 -0
- package/dist/src/lib/block-selector.js +92 -0
- package/dist/src/lib/block-selector.js.map +1 -0
- 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/channel.d.ts +30 -0
- package/dist/src/lib/channel.js +68 -0
- package/dist/src/lib/channel.js.map +1 -0
- package/dist/src/lib/cli-manifest.d.ts +68 -0
- package/dist/src/lib/cli-manifest.js +71 -0
- package/dist/src/lib/cli-manifest.js.map +1 -0
- package/dist/src/lib/codegen-shared/generatedFiles.d.ts +101 -0
- package/dist/src/lib/codegen-shared/generatedFiles.js +191 -0
- package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -0
- package/dist/src/lib/codegen-shared/prettierStable.d.ts +262 -0
- package/dist/src/lib/codegen-shared/prettierStable.js +610 -0
- package/dist/src/lib/codegen-shared/prettierStable.js.map +1 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +38 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +46 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -0
- package/dist/src/lib/config-json-field.d.ts +28 -0
- package/dist/src/lib/config-json-field.js +56 -0
- package/dist/src/lib/config-json-field.js.map +1 -0
- package/dist/src/lib/config-object-descriptor.d.ts +127 -0
- package/dist/src/lib/config-object-descriptor.js +696 -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 +140 -0
- package/dist/src/lib/config-surface.js +317 -0
- package/dist/src/lib/config-surface.js.map +1 -0
- package/dist/src/lib/config-toml.d.ts +10 -0
- package/dist/src/lib/config-toml.js +42 -0
- package/dist/src/lib/config-toml.js.map +1 -0
- package/dist/src/lib/config.d.ts +71 -0
- package/dist/src/lib/config.js +71 -68
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/confirm-prompt.d.ts +83 -0
- package/dist/src/lib/confirm-prompt.js +110 -0
- package/dist/src/lib/confirm-prompt.js.map +1 -0
- package/dist/src/lib/constants.d.ts +11 -0
- package/dist/src/lib/constants.js +12 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/crash-handlers.d.ts +20 -0
- package/dist/src/lib/crash-handlers.js +49 -0
- package/dist/src/lib/crash-handlers.js.map +1 -0
- package/dist/src/lib/credentials-store.d.ts +104 -0
- package/dist/src/lib/credentials-store.js +336 -0
- package/dist/src/lib/credentials-store.js.map +1 -0
- package/dist/src/lib/csv.d.ts +47 -0
- package/dist/src/lib/csv.js +172 -0
- package/dist/src/lib/csv.js.map +1 -0
- 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/dbFingerprint.d.ts +10 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js +17 -0
- package/dist/src/lib/db-codegen/dbFingerprint.js.map +1 -0
- package/dist/src/lib/db-codegen/dbGenerator.d.ts +67 -0
- package/dist/src/lib/db-codegen/dbGenerator.js +170 -0
- package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/db-codegen/dbNaming.d.ts +87 -0
- package/dist/src/lib/db-codegen/dbNaming.js +180 -0
- package/dist/src/lib/db-codegen/dbNaming.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTemplates.d.ts +272 -0
- package/dist/src/lib/db-codegen/dbTemplates.js +480 -0
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTsTypes.d.ts +73 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js +139 -0
- package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -0
- package/dist/src/lib/db-codegen/dbTypeIR.d.ts +146 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js +517 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.d.ts +112 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js +211 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js.map +1 -0
- package/dist/src/lib/document-export-permissions.d.ts +30 -0
- package/dist/src/lib/document-export-permissions.js +54 -0
- package/dist/src/lib/document-export-permissions.js.map +1 -0
- package/dist/src/lib/env-resolver-core.d.ts +253 -0
- package/dist/src/lib/env-resolver-core.js +459 -0
- package/dist/src/lib/env-resolver-core.js.map +1 -0
- package/dist/src/lib/env-resolver.d.ts +99 -0
- package/dist/src/lib/env-resolver.js +153 -0
- package/dist/src/lib/env-resolver.js.map +1 -0
- package/dist/src/lib/fetch.d.ts +5 -0
- package/dist/src/lib/function-bundle.d.ts +141 -0
- package/dist/src/lib/function-bundle.js +333 -0
- package/dist/src/lib/function-bundle.js.map +1 -0
- package/dist/src/lib/function-collect.d.ts +123 -0
- package/dist/src/lib/function-collect.js +594 -0
- package/dist/src/lib/function-collect.js.map +1 -0
- package/dist/src/lib/function-db-types.d.ts +187 -0
- package/dist/src/lib/function-db-types.js +782 -0
- package/dist/src/lib/function-db-types.js.map +1 -0
- package/dist/src/lib/function-document-types.d.ts +50 -0
- package/dist/src/lib/function-document-types.js +163 -0
- package/dist/src/lib/function-document-types.js.map +1 -0
- package/dist/src/lib/function-grants-preflight.d.ts +64 -0
- package/dist/src/lib/function-grants-preflight.js +100 -0
- package/dist/src/lib/function-grants-preflight.js.map +1 -0
- package/dist/src/lib/function-log-tail.d.ts +83 -0
- package/dist/src/lib/function-log-tail.js +115 -0
- package/dist/src/lib/function-log-tail.js.map +1 -0
- package/dist/src/lib/function-schema-codegen.d.ts +118 -0
- package/dist/src/lib/function-schema-codegen.js +402 -0
- package/dist/src/lib/function-schema-codegen.js.map +1 -0
- package/dist/src/lib/function-sync.d.ts +263 -0
- package/dist/src/lib/function-sync.js +604 -0
- package/dist/src/lib/function-sync.js.map +1 -0
- package/dist/src/lib/function-triggers.d.ts +66 -0
- package/dist/src/lib/function-triggers.js +285 -0
- package/dist/src/lib/function-triggers.js.map +1 -0
- package/dist/src/lib/function-typecheck.d.ts +86 -0
- package/dist/src/lib/function-typecheck.js +370 -0
- package/dist/src/lib/function-typecheck.js.map +1 -0
- package/dist/src/lib/generated-allowlist.d.ts +28 -0
- package/dist/src/lib/generated-allowlist.js +281 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -0
- package/dist/src/lib/generated-config-surfaces.d.ts +1445 -0
- package/dist/src/lib/generated-config-surfaces.js +5836 -0
- package/dist/src/lib/generated-config-surfaces.js.map +1 -0
- package/dist/src/lib/generated-sdk-types.d.ts +12 -0
- package/dist/src/lib/generated-sdk-types.js +13 -0
- package/dist/src/lib/generated-sdk-types.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/generated-workflow-model-fields.d.ts +20 -0
- package/dist/src/lib/generated-workflow-model-fields.js +53 -0
- package/dist/src/lib/generated-workflow-model-fields.js.map +1 -0
- package/dist/src/lib/google-client-secret-status.d.ts +35 -0
- package/dist/src/lib/google-client-secret-status.js +56 -0
- package/dist/src/lib/google-client-secret-status.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 +98 -0
- package/dist/src/lib/init-config.js +186 -0
- package/dist/src/lib/init-config.js.map +1 -0
- 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 +91 -0
- package/dist/src/lib/init-ios-links.js +219 -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 +34 -0
- package/dist/src/lib/init-xcode.js +138 -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/ios-app-id.d.ts +34 -0
- package/dist/src/lib/ios-app-id.js +69 -0
- package/dist/src/lib/ios-app-id.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 +136 -0
- package/dist/src/lib/local-test-cases.js.map +1 -0
- package/dist/src/lib/log-inspection.d.ts +680 -0
- package/dist/src/lib/log-inspection.js +784 -0
- package/dist/src/lib/log-inspection.js.map +1 -0
- package/dist/src/lib/migration-nag.d.ts +49 -0
- package/dist/src/lib/migration-nag.js +164 -0
- package/dist/src/lib/migration-nag.js.map +1 -0
- 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 +109 -0
- package/dist/src/lib/output.js +191 -8
- 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 +83 -0
- package/dist/src/lib/paginate.js +95 -0
- package/dist/src/lib/paginate.js.map +1 -0
- package/dist/src/lib/platform-owned.d.ts +63 -0
- package/dist/src/lib/platform-owned.js +85 -0
- package/dist/src/lib/platform-owned.js.map +1 -0
- package/dist/src/lib/project-config.d.ts +122 -0
- package/dist/src/lib/project-config.js +244 -0
- package/dist/src/lib/project-config.js.map +1 -0
- package/dist/src/lib/query-operators.d.ts +43 -0
- package/dist/src/lib/query-operators.js +80 -0
- package/dist/src/lib/query-operators.js.map +1 -0
- 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/refresh-admin-credentials.d.ts +65 -0
- package/dist/src/lib/refresh-admin-credentials.js +103 -0
- package/dist/src/lib/refresh-admin-credentials.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 +74 -0
- package/dist/src/lib/resolve-platform.js +105 -0
- package/dist/src/lib/resolve-platform.js.map +1 -0
- 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.d.ts +25 -0
- package/dist/src/lib/skill-installer.js +266 -0
- package/dist/src/lib/skill-installer.js.map +1 -0
- package/dist/src/lib/snapshots.d.ts +98 -0
- package/dist/src/lib/snapshots.js +294 -0
- package/dist/src/lib/snapshots.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +113 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js +914 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.d.ts +42 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.js +100 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.js.map +1 -0
- package/dist/src/lib/swift-codegen/generator.d.ts +94 -0
- package/dist/src/lib/swift-codegen/generator.js +440 -0
- package/dist/src/lib/swift-codegen/generator.js.map +1 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +72 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js +644 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +94 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.js +155 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -0
- package/dist/src/lib/swift-codegen/swiftNaming.d.ts +85 -0
- package/dist/src/lib/swift-codegen/swiftNaming.js +198 -0
- package/dist/src/lib/swift-codegen/swiftNaming.js.map +1 -0
- 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 +123 -0
- package/dist/src/lib/sync-paths.js +193 -0
- package/dist/src/lib/sync-paths.js.map +1 -0
- package/dist/src/lib/sync-resource-types.d.ts +563 -0
- package/dist/src/lib/sync-resource-types.js +1073 -0
- package/dist/src/lib/sync-resource-types.js.map +1 -0
- 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 +170 -0
- package/dist/src/lib/template.js +484 -68
- 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 +29 -0
- package/dist/src/lib/test-case-variables.js +71 -0
- package/dist/src/lib/test-case-variables.js.map +1 -0
- package/dist/src/lib/token-inject.d.ts +56 -0
- package/dist/src/lib/token-inject.js +204 -0
- package/dist/src/lib/token-inject.js.map +1 -0
- package/dist/src/lib/toml-database-config.d.ts +123 -0
- package/dist/src/lib/toml-database-config.js +544 -0
- package/dist/src/lib/toml-database-config.js.map +1 -0
- package/dist/src/lib/toml-metadata-config.d.ts +151 -0
- package/dist/src/lib/toml-metadata-config.js +476 -0
- package/dist/src/lib/toml-metadata-config.js.map +1 -0
- package/dist/src/lib/toml-native-form.d.ts +46 -0
- package/dist/src/lib/toml-native-form.js +78 -0
- package/dist/src/lib/toml-native-form.js.map +1 -0
- package/dist/src/lib/toml-params-validator.d.ts +129 -0
- package/dist/src/lib/toml-params-validator.js +298 -0
- package/dist/src/lib/toml-params-validator.js.map +1 -0
- 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 +35 -0
- package/dist/src/lib/version-check.js +241 -0
- package/dist/src/lib/version-check.js.map +1 -0
- 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 +110 -0
- package/dist/src/lib/workflow-apply.js +164 -0
- package/dist/src/lib/workflow-apply.js.map +1 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.d.ts +129 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js +269 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js.map +1 -0
- package/dist/src/lib/workflow-codegen/generator.d.ts +96 -0
- package/dist/src/lib/workflow-codegen/generator.js +361 -0
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -0
- package/dist/src/lib/workflow-codegen/invokerIR.d.ts +94 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js +76 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -0
- package/dist/src/lib/workflow-codegen/naming.d.ts +33 -0
- package/dist/src/lib/workflow-codegen/naming.js +81 -0
- package/dist/src/lib/workflow-codegen/naming.js.map +1 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +80 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.js +303 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -0
- 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-field-descriptor.d.ts +91 -0
- package/dist/src/lib/workflow-field-descriptor.js +153 -0
- package/dist/src/lib/workflow-field-descriptor.js.map +1 -0
- package/dist/src/lib/workflow-fragments.d.ts +64 -0
- package/dist/src/lib/workflow-fragments.js +342 -0
- package/dist/src/lib/workflow-fragments.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 +98 -0
- package/dist/src/lib/workflow-payload.js +178 -0
- package/dist/src/lib/workflow-payload.js.map +1 -0
- package/dist/src/lib/workflow-toml-validator.d.ts +207 -0
- package/dist/src/lib/workflow-toml-validator.js +762 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -0
- package/dist/src/lib/workflow-usage.d.ts +198 -0
- package/dist/src/lib/workflow-usage.js +312 -0
- package/dist/src/lib/workflow-usage.js.map +1 -0
- package/dist/src/types/index.d.ts +591 -0
- package/dist/src/validators.d.ts +65 -0
- package/dist/src/validators.js +64 -0
- package/dist/src/validators.js.map +1 -0
- package/package.json +34 -9
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from "fs";
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
const CLAUDE_DIR = join(homedir(), ".claude");
|
|
9
|
+
const SKILLS_DIR = join(CLAUDE_DIR, "skills");
|
|
10
|
+
const SKILL_DIR = join(SKILLS_DIR, "primitive-platform");
|
|
11
|
+
const SKILL_FILE = join(SKILL_DIR, "SKILL.md");
|
|
12
|
+
const HASH_FILE = join(SKILL_DIR, ".version");
|
|
13
|
+
// Internal skill (Primitive-Labs members only). Not bundled with the CLI —
|
|
14
|
+
// fetched from the private js-bao-wss repo via `gh`, so repo access is the gate.
|
|
15
|
+
const INTERNAL_SKILL_NAME = "primitive-platform-internal";
|
|
16
|
+
const INTERNAL_SKILL_DIR = join(SKILLS_DIR, INTERNAL_SKILL_NAME);
|
|
17
|
+
const INTERNAL_SKILL_FILE = join(INTERNAL_SKILL_DIR, "SKILL.md");
|
|
18
|
+
const INTERNAL_VERSION_FILE = join(INTERNAL_SKILL_DIR, ".version");
|
|
19
|
+
const INTERNAL_SKILL_REPO_PATH = "repos/Primitive-Labs/js-bao-wss/contents/internal-skills/primitive-platform-internal/SKILL.md";
|
|
20
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
function getBundledSkillPath() {
|
|
22
|
+
// In dist: dist/src/lib/skill-installer.js -> ../../../assets/...
|
|
23
|
+
// In source (tsx): src/lib/skill-installer.ts -> ../../assets/...
|
|
24
|
+
const distPath = fileURLToPath(new URL("../../../assets/skill/skills/primitive-platform/SKILL.md", import.meta.url));
|
|
25
|
+
if (existsSync(distPath))
|
|
26
|
+
return distPath;
|
|
27
|
+
return fileURLToPath(new URL("../../assets/skill/skills/primitive-platform/SKILL.md", import.meta.url));
|
|
28
|
+
}
|
|
29
|
+
function getCliVersion() {
|
|
30
|
+
// Same dual-path layout as getBundledSkillPath: dist/src/lib -> package root
|
|
31
|
+
// is three levels up; src/lib (tsx) -> two levels up.
|
|
32
|
+
// Both candidates can exist (from source, ../../../ is the repo root), so
|
|
33
|
+
// require the CLI's package name to pick the right one.
|
|
34
|
+
for (const rel of ["../../../package.json", "../../package.json"]) {
|
|
35
|
+
try {
|
|
36
|
+
const path = fileURLToPath(new URL(rel, import.meta.url));
|
|
37
|
+
if (!existsSync(path))
|
|
38
|
+
continue;
|
|
39
|
+
const pkg = JSON.parse(readFileSync(path, "utf-8"));
|
|
40
|
+
if (pkg.name === "primitive-admin" && typeof pkg.version === "string") {
|
|
41
|
+
return pkg.version;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// try next path
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
function computeHash(content) {
|
|
51
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 12);
|
|
52
|
+
}
|
|
53
|
+
function getInstalledHash() {
|
|
54
|
+
try {
|
|
55
|
+
if (!existsSync(HASH_FILE))
|
|
56
|
+
return null;
|
|
57
|
+
return readFileSync(HASH_FILE, "utf-8").trim();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if the skill is currently installed.
|
|
65
|
+
*/
|
|
66
|
+
export function isSkillInstalled() {
|
|
67
|
+
return getInstalledHash() !== null;
|
|
68
|
+
}
|
|
69
|
+
function getInternalStamp() {
|
|
70
|
+
try {
|
|
71
|
+
if (!existsSync(INTERNAL_VERSION_FILE))
|
|
72
|
+
return null;
|
|
73
|
+
const stamp = JSON.parse(readFileSync(INTERNAL_VERSION_FILE, "utf-8"));
|
|
74
|
+
if (typeof stamp.cliVersion === "string" && typeof stamp.hash === "string") {
|
|
75
|
+
return stamp;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function writeInternalStamp(stamp) {
|
|
84
|
+
writeFileSync(INTERNAL_VERSION_FILE, JSON.stringify(stamp, null, 2));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Fetch the internal skill from the private js-bao-wss repo (main branch)
|
|
88
|
+
* via `gh`. Returns null if gh is missing, unauthenticated, or the caller
|
|
89
|
+
* lacks access to the repo — access failure is how non-members are gated.
|
|
90
|
+
*/
|
|
91
|
+
async function fetchInternalSkill() {
|
|
92
|
+
try {
|
|
93
|
+
const { execFile } = await import("child_process");
|
|
94
|
+
const { promisify } = await import("util");
|
|
95
|
+
const { stdout } = await promisify(execFile)("gh", ["api", "-H", "Accept: application/vnd.github.raw", INTERNAL_SKILL_REPO_PATH], { timeout: 15000, maxBuffer: 4 * 1024 * 1024 });
|
|
96
|
+
// Sanity check: must be the skill file, not an error payload.
|
|
97
|
+
if (!stdout.startsWith("---") || !stdout.includes(`name: ${INTERNAL_SKILL_NAME}`)) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return stdout;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function writeInternalSkill(content, cliVersion) {
|
|
107
|
+
const hash = computeHash(content);
|
|
108
|
+
mkdirSync(INTERNAL_SKILL_DIR, { recursive: true });
|
|
109
|
+
writeFileSync(INTERNAL_SKILL_FILE, content);
|
|
110
|
+
writeInternalStamp({ cliVersion, hash });
|
|
111
|
+
return hash;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Refresh an already-installed internal skill if the CLI version changed
|
|
115
|
+
* since the last attempt. One fetch per CLI release: the stamp is advanced
|
|
116
|
+
* even when the fetch fails, so an offline or revoked user isn't retried
|
|
117
|
+
* on every command (an explicit `primitive skill install` always refetches).
|
|
118
|
+
*/
|
|
119
|
+
async function refreshInternalSkill() {
|
|
120
|
+
const stamp = getInternalStamp();
|
|
121
|
+
if (!stamp)
|
|
122
|
+
return; // not installed — explicit install only
|
|
123
|
+
const cliVersion = getCliVersion();
|
|
124
|
+
if (!cliVersion || stamp.cliVersion === cliVersion)
|
|
125
|
+
return;
|
|
126
|
+
const content = await fetchInternalSkill();
|
|
127
|
+
if (content) {
|
|
128
|
+
const hash = writeInternalSkill(content, cliVersion);
|
|
129
|
+
if (hash !== stamp.hash) {
|
|
130
|
+
// Diagnostic, not payload: post-command notices must stay off stdout so
|
|
131
|
+
// `primitive <verb> --json | jq .` parses (#2357). Same stream choice as
|
|
132
|
+
// the update banner in version-check.ts.
|
|
133
|
+
console.error(chalk.dim("Updated Primitive internal skill for Claude Code"));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
writeInternalStamp({ ...stamp, cliVersion });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Auto-update an already-installed skill if a newer version is bundled.
|
|
142
|
+
* Called after command execution for non-init, non-skill commands.
|
|
143
|
+
* If the skill is not installed, shows a non-blocking hint instead.
|
|
144
|
+
* Never throws — fails silently like version-check.
|
|
145
|
+
*/
|
|
146
|
+
export async function checkSkillStatus() {
|
|
147
|
+
try {
|
|
148
|
+
const bundledPath = getBundledSkillPath();
|
|
149
|
+
if (!existsSync(bundledPath))
|
|
150
|
+
return;
|
|
151
|
+
if (!existsSync(CLAUDE_DIR))
|
|
152
|
+
return;
|
|
153
|
+
const bundledContent = await readFile(bundledPath, "utf-8");
|
|
154
|
+
const bundledHash = computeHash(bundledContent);
|
|
155
|
+
const installedHash = getInstalledHash();
|
|
156
|
+
if (installedHash) {
|
|
157
|
+
// Already installed — silently auto-update if needed
|
|
158
|
+
if (installedHash !== bundledHash) {
|
|
159
|
+
mkdirSync(SKILL_DIR, { recursive: true });
|
|
160
|
+
writeFileSync(SKILL_FILE, bundledContent);
|
|
161
|
+
writeFileSync(HASH_FILE, bundledHash);
|
|
162
|
+
console.error(chalk.dim("Updated Primitive platform skill for Claude Code"));
|
|
163
|
+
}
|
|
164
|
+
// Internal skill (if installed) refreshes from the private repo, at
|
|
165
|
+
// most once per CLI release.
|
|
166
|
+
await refreshInternalSkill();
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// Not installed — show a non-blocking hint
|
|
170
|
+
console.error(chalk.dim(`Claude Code skill available — run ${chalk.cyan("primitive skill install")} to set up`));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Never let skill check affect CLI operation
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Explicitly install or reinstall the skill. Shows output.
|
|
179
|
+
* Also installs the internal skill when the caller has access to the
|
|
180
|
+
* private repo (Primitive-Labs members); silently skipped otherwise.
|
|
181
|
+
*/
|
|
182
|
+
export async function installSkillExplicit() {
|
|
183
|
+
const bundledPath = getBundledSkillPath();
|
|
184
|
+
if (!existsSync(bundledPath)) {
|
|
185
|
+
console.error(chalk.red("Skill assets not found. Reinstall the CLI."));
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (!existsSync(CLAUDE_DIR)) {
|
|
189
|
+
console.error(chalk.red("Claude Code not found (~/.claude does not exist)."));
|
|
190
|
+
console.error(chalk.dim("Install Claude Code first: https://claude.ai/code"));
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
const bundledContent = readFileSync(bundledPath, "utf-8");
|
|
194
|
+
const bundledHash = computeHash(bundledContent);
|
|
195
|
+
mkdirSync(SKILL_DIR, { recursive: true });
|
|
196
|
+
writeFileSync(SKILL_FILE, bundledContent);
|
|
197
|
+
writeFileSync(HASH_FILE, bundledHash);
|
|
198
|
+
console.log(chalk.green("Primitive platform skill installed for Claude Code."));
|
|
199
|
+
console.log(chalk.dim(`Location: ${SKILL_FILE}`));
|
|
200
|
+
console.log(chalk.dim(`Version: ${bundledHash}`));
|
|
201
|
+
const wasInstalled = getInternalStamp() !== null;
|
|
202
|
+
const internalContent = await fetchInternalSkill();
|
|
203
|
+
if (internalContent) {
|
|
204
|
+
const hash = writeInternalSkill(internalContent, getCliVersion() ?? "unknown");
|
|
205
|
+
console.log(chalk.green("Primitive internal skill installed (Primitive-Labs members)."));
|
|
206
|
+
console.log(chalk.dim(`Location: ${INTERNAL_SKILL_FILE}`));
|
|
207
|
+
console.log(chalk.dim(`Version: ${hash}`));
|
|
208
|
+
}
|
|
209
|
+
else if (wasInstalled) {
|
|
210
|
+
// Keep the existing copy; just tell the user the refresh didn't happen.
|
|
211
|
+
console.log(chalk.yellow("Could not refresh the internal skill (gh unavailable or no repo access); keeping the installed copy."));
|
|
212
|
+
}
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Uninstall the skill (and the internal skill, if present).
|
|
217
|
+
*/
|
|
218
|
+
export function uninstallSkill() {
|
|
219
|
+
if (!existsSync(SKILL_DIR) && !existsSync(INTERNAL_SKILL_DIR)) {
|
|
220
|
+
console.log(chalk.dim("Skill is not installed."));
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
if (existsSync(SKILL_DIR)) {
|
|
224
|
+
rmSync(SKILL_DIR, { recursive: true });
|
|
225
|
+
console.log(chalk.green("Primitive platform skill uninstalled."));
|
|
226
|
+
}
|
|
227
|
+
if (existsSync(INTERNAL_SKILL_DIR)) {
|
|
228
|
+
rmSync(INTERNAL_SKILL_DIR, { recursive: true });
|
|
229
|
+
console.log(chalk.green("Primitive internal skill uninstalled."));
|
|
230
|
+
}
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Show current skill installation status.
|
|
235
|
+
*/
|
|
236
|
+
export function skillStatus() {
|
|
237
|
+
const installedHash = getInstalledHash();
|
|
238
|
+
const bundledPath = getBundledSkillPath();
|
|
239
|
+
const bundledHash = existsSync(bundledPath)
|
|
240
|
+
? computeHash(readFileSync(bundledPath, "utf-8"))
|
|
241
|
+
: null;
|
|
242
|
+
if (!installedHash) {
|
|
243
|
+
console.log(chalk.yellow("Skill is not installed."));
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
console.log(chalk.green("Skill is installed."));
|
|
247
|
+
console.log(chalk.dim(` Location: ${SKILL_FILE}`));
|
|
248
|
+
console.log(chalk.dim(` Version: ${installedHash}`));
|
|
249
|
+
}
|
|
250
|
+
if (bundledHash) {
|
|
251
|
+
console.log(chalk.dim(` Bundled: ${bundledHash}`));
|
|
252
|
+
if (installedHash && installedHash !== bundledHash) {
|
|
253
|
+
console.log(chalk.yellow(" Update available — run: primitive skill install"));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const internalStamp = getInternalStamp();
|
|
257
|
+
if (internalStamp) {
|
|
258
|
+
console.log(chalk.green("Internal skill is installed (Primitive-Labs members)."));
|
|
259
|
+
console.log(chalk.dim(` Location: ${INTERNAL_SKILL_FILE}`));
|
|
260
|
+
console.log(chalk.dim(` Version: ${internalStamp.hash} (fetched for CLI ${internalStamp.cliVersion})`));
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
console.log(chalk.dim("Internal skill is not installed (Primitive-Labs members: primitive skill install)."));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=skill-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-installer.js","sourceRoot":"","sources":["../../../src/lib/skill-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync snapshots — point-in-time backups of a sync directory taken before a
|
|
3
|
+
* destructive `config pull` overwrites local TOML state (issue #578, Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* A snapshot is a full recursive copy of the live sync tree (including
|
|
6
|
+
* `.sync-state.json`, the content-hash baseline) into a timestamped slot
|
|
7
|
+
* under the snapshots root:
|
|
8
|
+
*
|
|
9
|
+
* <snapshotsRoot>/<YYYY-MM-DDTHH-MM-SS>/
|
|
10
|
+
* <full pre-pull copy of the sync tree, incl. .sync-state.json>
|
|
11
|
+
* .snapshot-complete # integrity marker, written LAST
|
|
12
|
+
* .audit-id # ULID cross-link (Phase 2; absent in P1)
|
|
13
|
+
*
|
|
14
|
+
* The `.snapshot-complete` marker is written last so a partial/interrupted
|
|
15
|
+
* copy is detectable: `restoreSnapshot` refuses any snapshot missing it.
|
|
16
|
+
*
|
|
17
|
+
* Snapshots fail LOUD — `createSnapshot` throws if it can't write a complete
|
|
18
|
+
* snapshot. The caller (config pull) aborts before touching any local file so we
|
|
19
|
+
* never perform a destructive pull without a recoverable backup.
|
|
20
|
+
*
|
|
21
|
+
* Restore is staged-then-swapped: the snapshot is materialized into a sibling
|
|
22
|
+
* temp dir, then the live `configDir` is atomically replaced, so a mid-restore
|
|
23
|
+
* crash never leaves a half-written tree.
|
|
24
|
+
*/
|
|
25
|
+
/** Marker file written LAST inside a snapshot to prove it completed. */
|
|
26
|
+
export declare const SNAPSHOT_COMPLETE_MARKER = ".snapshot-complete";
|
|
27
|
+
/** Cross-link to the audit entry that produced the snapshot (Phase 2). */
|
|
28
|
+
export declare const SNAPSHOT_AUDIT_ID_MARKER = ".audit-id";
|
|
29
|
+
export interface SnapshotResult {
|
|
30
|
+
/** Snapshot id — the timestamp directory name (YYYY-MM-DDTHH-MM-SS). */
|
|
31
|
+
id: string;
|
|
32
|
+
/** Absolute path to the snapshot directory. */
|
|
33
|
+
path: string;
|
|
34
|
+
}
|
|
35
|
+
export interface SnapshotInfo {
|
|
36
|
+
/** Snapshot id — the timestamp directory name. */
|
|
37
|
+
id: string;
|
|
38
|
+
/** Absolute path to the snapshot directory. */
|
|
39
|
+
path: string;
|
|
40
|
+
/** Whether the `.snapshot-complete` marker is present. */
|
|
41
|
+
complete: boolean;
|
|
42
|
+
/** The audit entry id this snapshot is cross-linked to, if any. */
|
|
43
|
+
auditId: string | null;
|
|
44
|
+
/** Creation time (from the directory mtime). */
|
|
45
|
+
createdAt: Date;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Snapshot the current `syncDir` into a new timestamped slot under
|
|
49
|
+
* `snapshotsRoot`. Returns the created snapshot, or `null` when there's
|
|
50
|
+
* nothing to back up (missing/empty `syncDir`).
|
|
51
|
+
*
|
|
52
|
+
* Fails LOUD: throws if the copy or marker write fails. The partial snapshot
|
|
53
|
+
* dir is best-effort cleaned up before rethrowing so a failed snapshot never
|
|
54
|
+
* leaves a marker-less husk behind.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createSnapshot(syncDir: string, snapshotsRoot: string, opts?: {
|
|
57
|
+
auditId?: string;
|
|
58
|
+
now?: Date;
|
|
59
|
+
}): SnapshotResult | null;
|
|
60
|
+
/**
|
|
61
|
+
* List snapshots under `snapshotsRoot`, newest-first. Returns an empty array
|
|
62
|
+
* if the root doesn't exist. Each entry reports whether it's complete and any
|
|
63
|
+
* cross-linked audit id.
|
|
64
|
+
*/
|
|
65
|
+
export declare function listSnapshots(snapshotsRoot: string): SnapshotInfo[];
|
|
66
|
+
/**
|
|
67
|
+
* Resolve a snapshot by id within `snapshotsRoot`. Accepts either the full
|
|
68
|
+
* timestamp directory name OR a unique prefix of at least `minPrefix`
|
|
69
|
+
* characters (default 8). Returns the matching snapshot, or throws a clear
|
|
70
|
+
* error on no-match / ambiguous-prefix.
|
|
71
|
+
*
|
|
72
|
+
* When `id` is omitted, resolves to the most recent COMPLETE snapshot.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveSnapshot(snapshotsRoot: string, id: string | undefined, minPrefix?: number): SnapshotInfo;
|
|
75
|
+
/**
|
|
76
|
+
* Restore a snapshot into `syncDir`, replacing whatever is there.
|
|
77
|
+
*
|
|
78
|
+
* Refuses to restore a snapshot missing the `.snapshot-complete` marker
|
|
79
|
+
* (partial/corrupted snapshot). The internal marker files (`.snapshot-complete`,
|
|
80
|
+
* `.audit-id`) are NOT copied into the restored tree.
|
|
81
|
+
*
|
|
82
|
+
* Staged-then-swapped: the snapshot is materialized into a sibling temp dir,
|
|
83
|
+
* then `syncDir` is atomically replaced, so a mid-restore crash never leaves a
|
|
84
|
+
* half-written tree.
|
|
85
|
+
*
|
|
86
|
+
* Nothing has to survive the swap. Backups live under the project's
|
|
87
|
+
* machine-local `.primitive/`, outside the committed tree entirely, so the
|
|
88
|
+
* `preserveDir` parameter this took went with `--dir` (#3154) — it existed
|
|
89
|
+
* only for the case where the snapshots root sat inside the directory being
|
|
90
|
+
* replaced.
|
|
91
|
+
*/
|
|
92
|
+
export declare function restoreSnapshot(snapshotPath: string, syncDir: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Prune snapshots older than `retentionDays` from `snapshotsRoot`. Only the
|
|
95
|
+
* given slot is touched (cross-slot retention is independent — each slot has
|
|
96
|
+
* its own snapshots root). No-op if the root doesn't exist.
|
|
97
|
+
*/
|
|
98
|
+
export declare function pruneSnapshots(snapshotsRoot: string, retentionDays?: number): void;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync snapshots — point-in-time backups of a sync directory taken before a
|
|
3
|
+
* destructive `config pull` overwrites local TOML state (issue #578, Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* A snapshot is a full recursive copy of the live sync tree (including
|
|
6
|
+
* `.sync-state.json`, the content-hash baseline) into a timestamped slot
|
|
7
|
+
* under the snapshots root:
|
|
8
|
+
*
|
|
9
|
+
* <snapshotsRoot>/<YYYY-MM-DDTHH-MM-SS>/
|
|
10
|
+
* <full pre-pull copy of the sync tree, incl. .sync-state.json>
|
|
11
|
+
* .snapshot-complete # integrity marker, written LAST
|
|
12
|
+
* .audit-id # ULID cross-link (Phase 2; absent in P1)
|
|
13
|
+
*
|
|
14
|
+
* The `.snapshot-complete` marker is written last so a partial/interrupted
|
|
15
|
+
* copy is detectable: `restoreSnapshot` refuses any snapshot missing it.
|
|
16
|
+
*
|
|
17
|
+
* Snapshots fail LOUD — `createSnapshot` throws if it can't write a complete
|
|
18
|
+
* snapshot. The caller (config pull) aborts before touching any local file so we
|
|
19
|
+
* never perform a destructive pull without a recoverable backup.
|
|
20
|
+
*
|
|
21
|
+
* Restore is staged-then-swapped: the snapshot is materialized into a sibling
|
|
22
|
+
* temp dir, then the live `configDir` is atomically replaced, so a mid-restore
|
|
23
|
+
* crash never leaves a half-written tree.
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync, readdirSync, statSync, writeFileSync, readFileSync, cpSync, rmSync, renameSync, mkdirSync, } from "fs";
|
|
26
|
+
import { join, dirname } from "path";
|
|
27
|
+
/** Marker file written LAST inside a snapshot to prove it completed. */
|
|
28
|
+
export const SNAPSHOT_COMPLETE_MARKER = ".snapshot-complete";
|
|
29
|
+
/** Cross-link to the audit entry that produced the snapshot (Phase 2). */
|
|
30
|
+
export const SNAPSHOT_AUDIT_ID_MARKER = ".audit-id";
|
|
31
|
+
/**
|
|
32
|
+
* Produce the timestamp directory name for a snapshot, e.g.
|
|
33
|
+
* `2026-06-01T17-42-18`. Colons (illegal on Windows, awkward everywhere) are
|
|
34
|
+
* replaced with hyphens; milliseconds and the trailing `Z` are dropped.
|
|
35
|
+
*/
|
|
36
|
+
function snapshotTimestamp(now = new Date()) {
|
|
37
|
+
// 2026-06-01T17:42:18.401Z -> 2026-06-01T17-42-18
|
|
38
|
+
return now.toISOString().replace(/\.\d+Z$/, "").replace(/:/g, "-");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns true if `dir` exists and contains at least one entry. A fresh
|
|
42
|
+
* project (no prior sync dir, or an empty one) has nothing to back up.
|
|
43
|
+
*/
|
|
44
|
+
function dirHasContent(dir) {
|
|
45
|
+
if (!existsSync(dir))
|
|
46
|
+
return false;
|
|
47
|
+
try {
|
|
48
|
+
return readdirSync(dir).length > 0;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Snapshot the current `syncDir` into a new timestamped slot under
|
|
56
|
+
* `snapshotsRoot`. Returns the created snapshot, or `null` when there's
|
|
57
|
+
* nothing to back up (missing/empty `syncDir`).
|
|
58
|
+
*
|
|
59
|
+
* Fails LOUD: throws if the copy or marker write fails. The partial snapshot
|
|
60
|
+
* dir is best-effort cleaned up before rethrowing so a failed snapshot never
|
|
61
|
+
* leaves a marker-less husk behind.
|
|
62
|
+
*/
|
|
63
|
+
export function createSnapshot(syncDir, snapshotsRoot, opts = {}) {
|
|
64
|
+
if (!dirHasContent(syncDir)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const id = snapshotTimestamp(opts.now);
|
|
68
|
+
const dest = join(snapshotsRoot, id);
|
|
69
|
+
// Guard against an id collision (two pulls within the same second). Append a
|
|
70
|
+
// numeric suffix until we find a free slot so a rapid second pull can't
|
|
71
|
+
// clobber the first snapshot.
|
|
72
|
+
let finalId = id;
|
|
73
|
+
let finalDest = dest;
|
|
74
|
+
let suffix = 1;
|
|
75
|
+
while (existsSync(finalDest)) {
|
|
76
|
+
finalId = `${id}-${suffix}`;
|
|
77
|
+
finalDest = join(snapshotsRoot, finalId);
|
|
78
|
+
suffix += 1;
|
|
79
|
+
}
|
|
80
|
+
// The backups root is machine-local, under `.primitive/backups/<env>/<appId>/`,
|
|
81
|
+
// and the tree it copies is the committed `primitive/<env>/`. The two are
|
|
82
|
+
// disjoint, so the copy can never recurse into itself — the staged-into-a-
|
|
83
|
+
// temp-dir fork this used to need existed only for `--dir`, whose snapshots
|
|
84
|
+
// root sat INSIDE the tree it was snapshotting (#3154).
|
|
85
|
+
try {
|
|
86
|
+
mkdirSync(snapshotsRoot, { recursive: true });
|
|
87
|
+
// Full recursive copy. `dereference: false` keeps symlinks from being
|
|
88
|
+
// silently followed (edge case: symlinks inside the sync tree).
|
|
89
|
+
cpSync(syncDir, finalDest, { recursive: true, dereference: false });
|
|
90
|
+
if (opts.auditId) {
|
|
91
|
+
writeFileSync(join(finalDest, SNAPSHOT_AUDIT_ID_MARKER), opts.auditId);
|
|
92
|
+
}
|
|
93
|
+
// Integrity marker written LAST — its presence proves the copy finished.
|
|
94
|
+
writeFileSync(join(finalDest, SNAPSHOT_COMPLETE_MARKER), new Date().toISOString());
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
// Best-effort cleanup of the partial snapshot so we don't leave an
|
|
98
|
+
// incomplete (marker-less) directory around.
|
|
99
|
+
try {
|
|
100
|
+
rmSync(finalDest, { recursive: true, force: true });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// ignore cleanup failure
|
|
104
|
+
}
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
return { id: finalId, path: finalDest };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* List snapshots under `snapshotsRoot`, newest-first. Returns an empty array
|
|
111
|
+
* if the root doesn't exist. Each entry reports whether it's complete and any
|
|
112
|
+
* cross-linked audit id.
|
|
113
|
+
*/
|
|
114
|
+
export function listSnapshots(snapshotsRoot) {
|
|
115
|
+
if (!existsSync(snapshotsRoot))
|
|
116
|
+
return [];
|
|
117
|
+
let names;
|
|
118
|
+
try {
|
|
119
|
+
names = readdirSync(snapshotsRoot);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
const infos = [];
|
|
125
|
+
for (const name of names) {
|
|
126
|
+
const path = join(snapshotsRoot, name);
|
|
127
|
+
let stat;
|
|
128
|
+
try {
|
|
129
|
+
stat = statSync(path);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (!stat.isDirectory())
|
|
135
|
+
continue;
|
|
136
|
+
const complete = existsSync(join(path, SNAPSHOT_COMPLETE_MARKER));
|
|
137
|
+
let auditId = null;
|
|
138
|
+
const auditPath = join(path, SNAPSHOT_AUDIT_ID_MARKER);
|
|
139
|
+
if (existsSync(auditPath)) {
|
|
140
|
+
try {
|
|
141
|
+
auditId = readFileSync(auditPath, "utf-8").trim() || null;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
auditId = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
infos.push({ id: name, path, complete, auditId, createdAt: stat.mtime });
|
|
148
|
+
}
|
|
149
|
+
// Newest first. The id is a sortable timestamp string, so a reverse string
|
|
150
|
+
// sort matches chronological order (and stays correct for the `-N` suffixed
|
|
151
|
+
// collision variants within the same second).
|
|
152
|
+
infos.sort((a, b) => (a.id < b.id ? 1 : a.id > b.id ? -1 : 0));
|
|
153
|
+
return infos;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Resolve a snapshot by id within `snapshotsRoot`. Accepts either the full
|
|
157
|
+
* timestamp directory name OR a unique prefix of at least `minPrefix`
|
|
158
|
+
* characters (default 8). Returns the matching snapshot, or throws a clear
|
|
159
|
+
* error on no-match / ambiguous-prefix.
|
|
160
|
+
*
|
|
161
|
+
* When `id` is omitted, resolves to the most recent COMPLETE snapshot.
|
|
162
|
+
*/
|
|
163
|
+
export function resolveSnapshot(snapshotsRoot, id, minPrefix = 8) {
|
|
164
|
+
const all = listSnapshots(snapshotsRoot);
|
|
165
|
+
if (all.length === 0) {
|
|
166
|
+
throw new Error(`No snapshots found in ${snapshotsRoot}`);
|
|
167
|
+
}
|
|
168
|
+
if (!id) {
|
|
169
|
+
const mostRecentComplete = all.find((s) => s.complete);
|
|
170
|
+
if (!mostRecentComplete) {
|
|
171
|
+
throw new Error(`No complete snapshots found in ${snapshotsRoot} (all are missing the ${SNAPSHOT_COMPLETE_MARKER} marker).`);
|
|
172
|
+
}
|
|
173
|
+
return mostRecentComplete;
|
|
174
|
+
}
|
|
175
|
+
// Exact match wins.
|
|
176
|
+
const exact = all.find((s) => s.id === id);
|
|
177
|
+
if (exact)
|
|
178
|
+
return exact;
|
|
179
|
+
// Prefix match (must be unique and >= minPrefix chars).
|
|
180
|
+
if (id.length < minPrefix) {
|
|
181
|
+
throw new Error(`Snapshot id "${id}" is too short — provide at least ${minPrefix} characters or the full timestamp.`);
|
|
182
|
+
}
|
|
183
|
+
const matches = all.filter((s) => s.id.startsWith(id));
|
|
184
|
+
if (matches.length === 0) {
|
|
185
|
+
throw new Error(`No snapshot matches "${id}" in ${snapshotsRoot}`);
|
|
186
|
+
}
|
|
187
|
+
if (matches.length > 1) {
|
|
188
|
+
throw new Error(`Snapshot prefix "${id}" is ambiguous (${matches.length} matches: ${matches
|
|
189
|
+
.map((m) => m.id)
|
|
190
|
+
.join(", ")}). Provide more characters.`);
|
|
191
|
+
}
|
|
192
|
+
return matches[0];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Restore a snapshot into `syncDir`, replacing whatever is there.
|
|
196
|
+
*
|
|
197
|
+
* Refuses to restore a snapshot missing the `.snapshot-complete` marker
|
|
198
|
+
* (partial/corrupted snapshot). The internal marker files (`.snapshot-complete`,
|
|
199
|
+
* `.audit-id`) are NOT copied into the restored tree.
|
|
200
|
+
*
|
|
201
|
+
* Staged-then-swapped: the snapshot is materialized into a sibling temp dir,
|
|
202
|
+
* then `syncDir` is atomically replaced, so a mid-restore crash never leaves a
|
|
203
|
+
* half-written tree.
|
|
204
|
+
*
|
|
205
|
+
* Nothing has to survive the swap. Backups live under the project's
|
|
206
|
+
* machine-local `.primitive/`, outside the committed tree entirely, so the
|
|
207
|
+
* `preserveDir` parameter this took went with `--dir` (#3154) — it existed
|
|
208
|
+
* only for the case where the snapshots root sat inside the directory being
|
|
209
|
+
* replaced.
|
|
210
|
+
*/
|
|
211
|
+
export function restoreSnapshot(snapshotPath, syncDir) {
|
|
212
|
+
if (!existsSync(snapshotPath)) {
|
|
213
|
+
throw new Error(`Snapshot not found: ${snapshotPath}`);
|
|
214
|
+
}
|
|
215
|
+
if (!existsSync(join(snapshotPath, SNAPSHOT_COMPLETE_MARKER))) {
|
|
216
|
+
throw new Error(`Refusing to restore: snapshot ${snapshotPath} is missing the ${SNAPSHOT_COMPLETE_MARKER} marker (partial/corrupted snapshot).`);
|
|
217
|
+
}
|
|
218
|
+
const parent = dirname(syncDir);
|
|
219
|
+
mkdirSync(parent, { recursive: true });
|
|
220
|
+
const unique = `${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
221
|
+
const stageDir = join(parent, `.primitive-restore-stage-${unique}`);
|
|
222
|
+
const oldDir = join(parent, `.primitive-restore-old-${unique}`);
|
|
223
|
+
try {
|
|
224
|
+
// Materialize the snapshot into the staging dir.
|
|
225
|
+
cpSync(snapshotPath, stageDir, { recursive: true, dereference: false });
|
|
226
|
+
// Drop the snapshot-internal marker files from the restored tree.
|
|
227
|
+
for (const marker of [SNAPSHOT_COMPLETE_MARKER, SNAPSHOT_AUDIT_ID_MARKER]) {
|
|
228
|
+
const markerPath = join(stageDir, marker);
|
|
229
|
+
if (existsSync(markerPath)) {
|
|
230
|
+
rmSync(markerPath, { force: true });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Atomic-ish swap: move the live dir aside, move staging into place, then
|
|
234
|
+
// delete the old dir. Same-filesystem renames are atomic.
|
|
235
|
+
if (existsSync(syncDir)) {
|
|
236
|
+
renameSync(syncDir, oldDir);
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
renameSync(stageDir, syncDir);
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
// Swap failed — try to roll the original back so we never leave the
|
|
243
|
+
// user with no sync dir at all.
|
|
244
|
+
if (existsSync(oldDir) && !existsSync(syncDir)) {
|
|
245
|
+
try {
|
|
246
|
+
renameSync(oldDir, syncDir);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
// ignore rollback failure; original error is more useful
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
throw err;
|
|
253
|
+
}
|
|
254
|
+
// Success — remove the displaced original.
|
|
255
|
+
if (existsSync(oldDir)) {
|
|
256
|
+
rmSync(oldDir, { recursive: true, force: true });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
// Clean up any leftover staging/old dirs on failure.
|
|
261
|
+
for (const dir of [stageDir, oldDir]) {
|
|
262
|
+
if (existsSync(dir)) {
|
|
263
|
+
try {
|
|
264
|
+
rmSync(dir, { recursive: true, force: true });
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// ignore
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Prune snapshots older than `retentionDays` from `snapshotsRoot`. Only the
|
|
275
|
+
* given slot is touched (cross-slot retention is independent — each slot has
|
|
276
|
+
* its own snapshots root). No-op if the root doesn't exist.
|
|
277
|
+
*/
|
|
278
|
+
export function pruneSnapshots(snapshotsRoot, retentionDays = 28) {
|
|
279
|
+
if (!existsSync(snapshotsRoot))
|
|
280
|
+
return;
|
|
281
|
+
const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
|
|
282
|
+
for (const info of listSnapshots(snapshotsRoot)) {
|
|
283
|
+
if (info.createdAt.getTime() < cutoff) {
|
|
284
|
+
try {
|
|
285
|
+
rmSync(info.path, { recursive: true, force: true });
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// Best-effort prune — a failure to delete one stale snapshot must not
|
|
289
|
+
// abort the pull that triggered the prune.
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=snapshots.js.map
|