@capybara-hq/kernel 0.1.0-rc.0 → 0.1.0-rc.2
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/bootstrap.json +10 -6
- package/dist/admin/admin.controller.d.ts +17 -17
- package/dist/admin/admin.controller.js +43 -26
- package/dist/admin/admin.module.d.ts +3 -0
- package/dist/admin/admin.module.js +22 -0
- package/dist/admin/extensions.controller.d.ts +14 -14
- package/dist/admin/extensions.controller.js +30 -17
- package/dist/admin/setup-lock.d.ts +16 -0
- package/dist/admin/setup-lock.js +47 -0
- package/dist/admin/setup.controller.d.ts +8 -8
- package/dist/admin/setup.controller.js +27 -25
- package/dist/admin/setup.service.d.ts +19 -27
- package/dist/admin/setup.service.js +61 -61
- package/dist/agents/agent-lookup.d.ts +53 -0
- package/dist/agents/agent-lookup.js +179 -0
- package/dist/agents/agents.controller.d.ts +1 -1
- package/dist/agents/agents.controller.js +14 -8
- package/dist/agents/agents.module.d.ts +7 -0
- package/dist/agents/agents.module.js +41 -0
- package/dist/agents/agents.service.d.ts +39 -58
- package/dist/agents/agents.service.js +261 -329
- package/dist/agents/definition.d.ts +8 -0
- package/dist/agents/definition.js +8 -0
- package/dist/agents/models.controller.d.ts +1 -1
- package/dist/agents/models.controller.js +2 -2
- package/dist/agents/templates.controller.d.ts +1 -1
- package/dist/agents/templates.controller.js +2 -2
- package/dist/agents/templates.d.ts +6 -8
- package/dist/agents/templates.js +20 -4
- package/dist/app.d.ts +93 -0
- package/dist/app.js +150 -0
- package/dist/catalog/admin-catalog.controller.d.ts +3 -3
- package/dist/catalog/admin-catalog.controller.js +27 -13
- package/dist/catalog/catalog-content.d.ts +185 -0
- package/dist/catalog/catalog-content.js +323 -0
- package/dist/catalog/catalog-items.d.ts +186 -0
- package/dist/catalog/catalog-items.js +410 -0
- package/dist/catalog/catalog.module.d.ts +14 -0
- package/dist/catalog/catalog.module.js +71 -0
- package/dist/catalog/catalog.service.d.ts +34 -188
- package/dist/catalog/catalog.service.js +155 -489
- package/dist/catalog/cli.d.ts +3 -2
- package/dist/catalog/cli.js +13 -31
- package/dist/catalog/job-ids.d.ts +15 -0
- package/dist/catalog/job-ids.js +15 -0
- package/dist/catalog/jobs.d.ts +27 -0
- package/dist/catalog/jobs.js +70 -0
- package/dist/catalog/locks.d.ts +24 -0
- package/dist/catalog/locks.js +63 -0
- package/dist/catalog/marketplaces.controller.d.ts +4 -4
- package/dist/catalog/marketplaces.controller.js +22 -11
- package/dist/catalog/marketplaces.service.d.ts +30 -13
- package/dist/catalog/marketplaces.service.js +330 -256
- package/dist/catalog/org-catalog.controller.d.ts +4 -3
- package/dist/catalog/org-catalog.controller.js +29 -14
- package/dist/catalog/org-catalog.service.d.ts +32 -198
- package/dist/catalog/org-catalog.service.js +159 -400
- package/dist/catalog/plugin-import.d.ts +73 -34
- package/dist/catalog/plugin-import.js +356 -217
- package/dist/catalog/plugin-install.d.ts +83 -41
- package/dist/catalog/plugin-install.js +421 -269
- package/dist/catalog/plugin-upgrade.d.ts +59 -4
- package/dist/catalog/plugin-upgrade.js +407 -282
- package/dist/catalog/requests.service.d.ts +27 -15
- package/dist/catalog/requests.service.js +201 -145
- package/dist/catalog/upgrade-targets.d.ts +4 -7
- package/dist/channels/actions.d.ts +6 -4
- package/dist/channels/actions.js +1 -1
- package/dist/channels/cards.d.ts +2 -2
- package/dist/channels/channels.module.d.ts +40 -0
- package/dist/channels/channels.module.js +128 -0
- package/dist/channels/connections.controller.d.ts +1 -1
- package/dist/channels/connections.controller.js +11 -6
- package/dist/channels/connections.service.d.ts +43 -21
- package/dist/channels/connections.service.js +236 -131
- package/dist/channels/inbound.d.ts +34 -38
- package/dist/channels/inbound.js +107 -41
- package/dist/channels/job-ids.d.ts +10 -0
- package/dist/channels/job-ids.js +10 -0
- package/dist/channels/jobs.d.ts +85 -0
- package/dist/channels/jobs.js +157 -0
- package/dist/channels/outbound.d.ts +60 -82
- package/dist/channels/outbound.js +165 -193
- package/dist/channels/supervisor.d.ts +88 -46
- package/dist/channels/supervisor.js +230 -132
- package/dist/channels/threads.d.ts +29 -8
- package/dist/channels/threads.js +71 -13
- package/dist/channels/webhook.d.ts +20 -14
- package/dist/channels/webhook.js +51 -20
- package/dist/config/load.d.ts +3 -2
- package/dist/config/load.js +3 -2
- package/dist/config/nacos-source.js +11 -2
- package/dist/config/schema.d.ts +16 -1
- package/dist/config/schema.js +54 -7
- package/dist/conversations/access.d.ts +29 -0
- package/dist/conversations/access.js +86 -0
- package/dist/conversations/artifacts.d.ts +10 -10
- package/dist/conversations/artifacts.js +35 -9
- package/dist/conversations/attachments.controller.d.ts +1 -1
- package/dist/conversations/attachments.controller.js +8 -6
- package/dist/conversations/attachments.module.d.ts +7 -0
- package/dist/conversations/attachments.module.js +25 -0
- package/dist/conversations/attachments.service.d.ts +30 -22
- package/dist/conversations/attachments.service.js +119 -46
- package/dist/conversations/conversations.controller.d.ts +8 -7
- package/dist/conversations/conversations.controller.js +59 -29
- package/dist/conversations/conversations.module.d.ts +8 -0
- package/dist/conversations/conversations.module.js +69 -0
- package/dist/conversations/conversations.service.d.ts +40 -38
- package/dist/conversations/conversations.service.js +130 -140
- package/dist/conversations/event-log.d.ts +28 -18
- package/dist/conversations/event-log.js +74 -27
- package/dist/conversations/files.d.ts +10 -10
- package/dist/conversations/files.js +37 -11
- package/dist/conversations/idem-keys.d.ts +5 -0
- package/dist/conversations/idem-keys.js +5 -0
- package/dist/conversations/job-ids.d.ts +6 -0
- package/dist/conversations/job-ids.js +6 -0
- package/dist/conversations/outputs-read.d.ts +11 -11
- package/dist/conversations/outputs-read.js +31 -7
- package/dist/conversations/queue.d.ts +48 -56
- package/dist/conversations/queue.js +13 -289
- package/dist/conversations/queue.service.d.ts +60 -0
- package/dist/conversations/queue.service.js +343 -0
- package/dist/conversations/sandbox-status.d.ts +13 -10
- package/dist/conversations/sandbox-status.js +36 -8
- package/dist/conversations/titles.d.ts +71 -24
- package/dist/conversations/titles.js +159 -62
- package/dist/ctx/bus.js +9 -3
- package/dist/ctx/create-ctx.d.ts +6 -0
- package/dist/ctx/create-ctx.js +7 -9
- package/dist/ctx/lock.d.ts +7 -3
- package/dist/ctx/lock.js +9 -20
- package/dist/ctx/queue.js +3 -2
- package/dist/ctx/secrets.d.ts +10 -2
- package/dist/ctx/secrets.js +7 -3
- package/dist/db/kernel-schema.d.ts +2 -2
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +1 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +2 -0
- package/dist/evals/budget.d.ts +42 -21
- package/dist/evals/budget.js +114 -62
- package/dist/evals/evals.module.d.ts +31 -0
- package/dist/evals/evals.module.js +114 -0
- package/dist/evals/jobs.d.ts +20 -0
- package/dist/evals/jobs.js +45 -0
- package/dist/evals/run-replay.d.ts +56 -8
- package/dist/evals/run-replay.js +140 -80
- package/dist/evals/runs.controller.d.ts +1 -1
- package/dist/evals/runs.controller.js +17 -8
- package/dist/evals/runs.service.d.ts +23 -45
- package/dist/evals/runs.service.js +245 -234
- package/dist/evals/sets.controller.d.ts +1 -1
- package/dist/evals/sets.controller.js +17 -8
- package/dist/evals/sets.service.d.ts +22 -6
- package/dist/evals/sets.service.js +248 -194
- package/dist/evals/snapshot.d.ts +2 -2
- package/dist/evals/step-replay.d.ts +2 -2
- package/dist/evals/step-replay.js +1 -1
- package/dist/evals/trajectory.controller.d.ts +1 -1
- package/dist/evals/trajectory.controller.js +11 -7
- package/dist/evals/trajectory.service.d.ts +5 -4
- package/dist/evals/trajectory.service.js +30 -7
- package/dist/evals/worker.d.ts +44 -27
- package/dist/evals/worker.js +220 -120
- package/dist/extensions/admin-ops.d.ts +61 -33
- package/dist/extensions/admin-ops.js +248 -154
- package/dist/extensions/admin-view.d.ts +38 -27
- package/dist/extensions/admin-view.js +126 -55
- package/dist/extensions/approvals.d.ts +12 -8
- package/dist/extensions/approvals.js +73 -46
- package/dist/extensions/blobs.d.ts +27 -10
- package/dist/extensions/blobs.js +111 -45
- package/dist/extensions/bootstrap.d.ts +96 -42
- package/dist/extensions/bootstrap.js +303 -155
- package/dist/extensions/cli.d.ts +20 -10
- package/dist/extensions/cli.js +41 -96
- package/dist/extensions/config-issues.d.ts +7 -0
- package/dist/extensions/config-issues.js +31 -0
- package/dist/extensions/deployment-config-store.d.ts +49 -0
- package/dist/extensions/deployment-config-store.js +133 -0
- package/dist/extensions/deployment-config.d.ts +58 -67
- package/dist/extensions/deployment-config.js +202 -230
- package/dist/extensions/enabled.d.ts +5 -5
- package/dist/extensions/extensions.module.d.ts +8 -0
- package/dist/extensions/extensions.module.js +77 -0
- package/dist/extensions/hooks.d.ts +3 -2
- package/dist/extensions/hooks.js +1 -1
- package/dist/extensions/host.d.ts +72 -68
- package/dist/extensions/host.js +191 -152
- package/dist/extensions/installs.d.ts +49 -16
- package/dist/extensions/installs.js +128 -32
- package/dist/extensions/job-ids.d.ts +6 -0
- package/dist/extensions/job-ids.js +6 -0
- package/dist/extensions/lifecycle-topics.d.ts +18 -0
- package/dist/extensions/lifecycle-topics.js +18 -0
- package/dist/extensions/lifecycle.d.ts +35 -47
- package/dist/extensions/lifecycle.js +103 -39
- package/dist/extensions/locks.d.ts +33 -0
- package/dist/extensions/locks.js +86 -0
- package/dist/extensions/migrate-lock.d.ts +3 -4
- package/dist/extensions/org-config.controller.d.ts +1 -1
- package/dist/extensions/org-config.controller.js +8 -5
- package/dist/extensions/org-config.d.ts +48 -46
- package/dist/extensions/org-config.js +284 -226
- package/dist/extensions/registry.d.ts +50 -2
- package/dist/extensions/registry.js +89 -4
- package/dist/extensions/sources.d.ts +12 -8
- package/dist/extensions/sources.js +34 -13
- package/dist/files/files.module.d.ts +3 -0
- package/dist/files/files.module.js +22 -0
- package/dist/files/previewers.controller.d.ts +7 -2
- package/dist/files/previewers.controller.js +17 -9
- package/dist/files/previewers.d.ts +13 -18
- package/dist/files/previewers.js +83 -36
- package/dist/http/adapter.d.ts +3 -0
- package/dist/http/adapter.js +25 -0
- package/dist/http/api.module.d.ts +3 -110
- package/dist/http/api.module.js +47 -355
- package/dist/http/app.d.ts +11 -15
- package/dist/http/app.js +52 -47
- package/dist/http/error-filter.module.d.ts +5 -0
- package/dist/http/error-filter.module.js +18 -0
- package/dist/http/error.filter.js +2 -2
- package/dist/identity/accounts.d.ts +82 -29
- package/dist/identity/accounts.js +294 -175
- package/dist/identity/api-tokens.d.ts +11 -7
- package/dist/identity/api-tokens.js +71 -44
- package/dist/identity/audit.d.ts +7 -4
- package/dist/identity/audit.js +5 -1
- package/dist/identity/auth.controller.d.ts +11 -10
- package/dist/identity/auth.controller.js +31 -25
- package/dist/identity/auth.guard.d.ts +3 -3
- package/dist/identity/auth.guard.js +6 -4
- package/dist/identity/binding.d.ts +9 -11
- package/dist/identity/binding.js +41 -13
- package/dist/identity/enterprise-admin.d.ts +18 -12
- package/dist/identity/enterprise-admin.js +67 -13
- package/dist/identity/external-identity-lock.d.ts +17 -0
- package/dist/identity/external-identity-lock.js +39 -0
- package/dist/identity/external.d.ts +19 -15
- package/dist/identity/external.js +163 -125
- package/dist/identity/identity.module.d.ts +6 -0
- package/dist/identity/identity.module.js +56 -0
- package/dist/identity/me.controller.d.ts +16 -15
- package/dist/identity/me.controller.js +37 -31
- package/dist/identity/sessions.d.ts +12 -10
- package/dist/identity/sessions.js +74 -42
- package/dist/identity/settings.d.ts +20 -14
- package/dist/identity/settings.js +85 -57
- package/dist/identity/sso.controller.d.ts +7 -7
- package/dist/identity/sso.controller.js +13 -9
- package/dist/identity/sso.d.ts +9 -12
- package/dist/identity/sso.js +54 -24
- package/dist/inbox/inbox.module.d.ts +3 -0
- package/dist/inbox/inbox.module.js +22 -0
- package/dist/inbox/inbox.service.d.ts +7 -9
- package/dist/inbox/inbox.service.js +32 -11
- package/dist/index.d.ts +19 -12
- package/dist/index.js +13 -8
- package/dist/infra/cache/cache.module.d.ts +3 -0
- package/dist/infra/cache/cache.module.js +16 -0
- package/dist/infra/cache/cache.service.d.ts +21 -0
- package/dist/infra/cache/cache.service.js +80 -0
- package/dist/infra/cache/cacheable.decorator.d.ts +32 -0
- package/dist/infra/cache/cacheable.decorator.js +83 -0
- package/dist/infra/cli/kernel-cli.module.d.ts +66 -0
- package/dist/infra/cli/kernel-cli.module.js +165 -0
- package/dist/infra/close-within.d.ts +15 -0
- package/dist/infra/close-within.js +36 -0
- package/dist/infra/config/config.module.d.ts +13 -0
- package/dist/infra/config/config.module.js +39 -0
- package/dist/infra/config/kernel-config.service.d.ts +25 -0
- package/dist/infra/config/kernel-config.service.js +126 -0
- package/dist/infra/database/after-commit.d.ts +6 -0
- package/dist/infra/database/after-commit.js +9 -0
- package/dist/infra/database/database.module.d.ts +25 -0
- package/dist/infra/database/database.module.js +90 -0
- package/dist/infra/database/kernel-db.d.ts +22 -0
- package/dist/infra/database/kernel-db.js +65 -0
- package/dist/infra/database/transaction-host.d.ts +50 -0
- package/dist/infra/database/transaction-host.js +125 -0
- package/dist/infra/database/transactional.decorator.d.ts +15 -0
- package/dist/infra/database/transactional.decorator.js +27 -0
- package/dist/infra/database/xact-lock.d.ts +17 -0
- package/dist/infra/database/xact-lock.js +43 -0
- package/dist/infra/events/kernel-events.d.ts +96 -0
- package/dist/infra/events/kernel-events.js +65 -0
- package/dist/infra/health/health.controller.d.ts +26 -0
- package/dist/infra/health/health.controller.js +104 -0
- package/dist/infra/health/health.module.d.ts +9 -0
- package/dist/infra/health/health.module.js +24 -0
- package/dist/infra/health/health.options.d.ts +10 -0
- package/dist/infra/health/health.options.js +15 -0
- package/dist/infra/health/shutdown-state.d.ts +6 -0
- package/dist/infra/health/shutdown-state.js +2 -0
- package/dist/infra/lifecycle/graceful-shutdown.module.d.ts +6 -0
- package/dist/infra/lifecycle/graceful-shutdown.module.js +23 -0
- package/dist/infra/lifecycle/graceful-shutdown.service.d.ts +70 -0
- package/dist/infra/lifecycle/graceful-shutdown.service.js +135 -0
- package/dist/infra/lifecycle/process-guards.d.ts +52 -0
- package/dist/infra/lifecycle/process-guards.js +86 -0
- package/dist/infra/lifecycle/shutdown-signals.d.ts +30 -0
- package/dist/infra/lifecycle/shutdown-signals.js +48 -0
- package/dist/infra/lock/key-template.d.ts +13 -0
- package/dist/infra/lock/key-template.js +46 -0
- package/dist/infra/lock/lock.module.d.ts +3 -0
- package/dist/infra/lock/lock.module.js +16 -0
- package/dist/infra/lock/lock.service.d.ts +120 -0
- package/dist/infra/lock/lock.service.js +343 -0
- package/dist/infra/lock/shared-lease.d.ts +44 -0
- package/dist/infra/lock/shared-lease.js +121 -0
- package/dist/infra/lock/with-lock.decorator.d.ts +28 -0
- package/dist/infra/lock/with-lock.decorator.js +49 -0
- package/dist/infra/logging/logging.module.d.ts +16 -0
- package/dist/infra/logging/logging.module.js +34 -0
- package/dist/infra/queue/configured-processor.d.ts +18 -0
- package/dist/infra/queue/configured-processor.js +23 -0
- package/dist/infra/queue/job-failure.d.ts +18 -0
- package/dist/infra/queue/job-failure.js +26 -0
- package/dist/infra/queue/queue-shutdown.d.ts +27 -0
- package/dist/infra/queue/queue-shutdown.js +81 -0
- package/dist/infra/queue/queue.module.d.ts +16 -0
- package/dist/infra/queue/queue.module.js +61 -0
- package/dist/infra/queue/redis-connection.d.ts +7 -0
- package/dist/infra/queue/redis-connection.js +18 -0
- package/dist/infra/queue/retired-schedulers.d.ts +7 -0
- package/dist/infra/queue/retired-schedulers.js +9 -0
- package/dist/infra/queue/run-job.d.ts +16 -0
- package/dist/infra/queue/run-job.js +19 -0
- package/dist/infra/redis/redis.module.d.ts +24 -0
- package/dist/infra/redis/redis.module.js +87 -0
- package/dist/infra/schedule/cron-tick.d.ts +12 -0
- package/dist/infra/schedule/cron-tick.js +25 -0
- package/dist/infra/schedule/locked-cron.decorator.d.ts +27 -0
- package/dist/infra/schedule/locked-cron.decorator.js +53 -0
- package/dist/infra/schedule/locked-interval.d.ts +69 -0
- package/dist/infra/schedule/locked-interval.js +190 -0
- package/dist/infra/schedule/locked-tick.d.ts +90 -0
- package/dist/infra/schedule/locked-tick.js +137 -0
- package/dist/infra/schedule/schedule.module.d.ts +8 -0
- package/dist/infra/schedule/schedule.module.js +27 -0
- package/dist/infra/schedule/scheduled-runs.d.ts +69 -0
- package/dist/infra/schedule/scheduled-runs.js +163 -0
- package/dist/infra/swagger/swagger.d.ts +16 -0
- package/dist/infra/swagger/swagger.js +31 -0
- package/dist/infra/throttler/credential-throttler.d.ts +35 -0
- package/dist/infra/throttler/credential-throttler.js +77 -0
- package/dist/infra/throttler/named-throttlers.d.ts +31 -0
- package/dist/infra/throttler/named-throttlers.js +119 -0
- package/dist/infra/throttler/redis-throttler-storage.d.ts +38 -0
- package/dist/infra/throttler/redis-throttler-storage.js +130 -0
- package/dist/infra/throttler/throttler.guard.d.ts +23 -0
- package/dist/infra/throttler/throttler.guard.js +68 -0
- package/dist/infra/throttler/throttler.module.d.ts +15 -0
- package/dist/infra/throttler/throttler.module.js +53 -0
- package/dist/infra/tokens.d.ts +15 -0
- package/dist/infra/tokens.js +15 -0
- package/dist/infra/validation/create-zod-dto.d.ts +23 -0
- package/dist/infra/validation/create-zod-dto.js +35 -0
- package/dist/infra/validation/parse-with-zod.d.ts +7 -0
- package/dist/infra/validation/parse-with-zod.js +12 -0
- package/dist/infra/validation/validation.module.d.ts +3 -0
- package/dist/infra/validation/validation.module.js +16 -0
- package/dist/infra/validation/zod-params.d.ts +7 -0
- package/dist/infra/validation/zod-params.js +42 -0
- package/dist/infra/validation/zod-validation.pipe.d.ts +11 -0
- package/dist/infra/validation/zod-validation.pipe.js +31 -0
- package/dist/kernel.d.ts +9 -241
- package/dist/kernel.js +8 -1305
- package/dist/kernel.module.d.ts +17 -0
- package/dist/kernel.module.js +136 -0
- package/dist/lifecycle/kernel-lifecycle.d.ts +140 -0
- package/dist/lifecycle/kernel-lifecycle.js +451 -0
- package/dist/lifecycle/tokens.d.ts +3 -0
- package/dist/lifecycle/tokens.js +3 -0
- package/dist/log-config.d.ts +9 -0
- package/dist/log-config.js +27 -0
- package/dist/log-context.d.ts +34 -0
- package/dist/log-context.js +44 -0
- package/dist/log-loki.d.ts +34 -0
- package/dist/log-loki.js +145 -0
- package/dist/log.d.ts +41 -10
- package/dist/log.js +91 -17
- package/dist/models/models.module.d.ts +3 -0
- package/dist/models/models.module.js +24 -0
- package/dist/models/prices.d.ts +8 -2
- package/dist/models/prices.js +65 -37
- package/dist/models/purposes.controller.d.ts +1 -1
- package/dist/models/purposes.controller.js +5 -6
- package/dist/models/purposes.d.ts +35 -13
- package/dist/models/purposes.js +101 -51
- package/dist/net/public-address.js +3 -2
- package/dist/orgs/directory-sync.controller.d.ts +1 -1
- package/dist/orgs/directory-sync.controller.js +2 -2
- package/dist/orgs/directory-sync.d.ts +61 -31
- package/dist/orgs/directory-sync.js +212 -125
- package/dist/orgs/invitations.controller.d.ts +8 -8
- package/dist/orgs/invitations.controller.js +27 -26
- package/dist/orgs/invitations.service.d.ts +12 -9
- package/dist/orgs/invitations.service.js +130 -92
- package/dist/orgs/job-ids.d.ts +8 -0
- package/dist/orgs/job-ids.js +8 -0
- package/dist/orgs/members.service.d.ts +19 -12
- package/dist/orgs/members.service.js +161 -117
- package/dist/orgs/offboarding.d.ts +54 -57
- package/dist/orgs/offboarding.js +161 -71
- package/dist/orgs/org-lock.d.ts +28 -19
- package/dist/orgs/org-lock.js +81 -35
- package/dist/orgs/org.guard.d.ts +1 -1
- package/dist/orgs/org.guard.js +2 -2
- package/dist/orgs/orgs.controller.d.ts +13 -13
- package/dist/orgs/orgs.controller.js +29 -17
- package/dist/orgs/orgs.module.d.ts +6 -0
- package/dist/orgs/orgs.module.js +68 -0
- package/dist/orgs/orgs.service.d.ts +30 -19
- package/dist/orgs/orgs.service.js +139 -86
- package/dist/orgs/settings.controller.d.ts +1 -1
- package/dist/orgs/settings.controller.js +8 -6
- package/dist/orgs/settings.service.d.ts +14 -8
- package/dist/orgs/settings.service.js +75 -46
- package/dist/overrides.d.ts +56 -0
- package/dist/overrides.js +30 -0
- package/dist/roles/gateway-role.d.ts +43 -0
- package/dist/roles/gateway-role.js +98 -0
- package/dist/roles/gateway.module.d.ts +8 -0
- package/dist/roles/gateway.module.js +28 -0
- package/dist/roles/worker-role.d.ts +63 -0
- package/dist/roles/worker-role.js +144 -0
- package/dist/roles/worker.module.d.ts +14 -0
- package/dist/roles/worker.module.js +90 -0
- package/dist/runtime/abort.js +19 -2
- package/dist/runtime/checkpointer.d.ts +8 -3
- package/dist/runtime/checkpointer.js +87 -55
- package/dist/runtime/conversation-lock.d.ts +20 -11
- package/dist/runtime/conversation-lock.js +62 -72
- package/dist/runtime/hook-calls.d.ts +3 -3
- package/dist/runtime/hook-calls.js +1 -6
- package/dist/runtime/job-ids.d.ts +10 -0
- package/dist/runtime/job-ids.js +10 -0
- package/dist/runtime/langgraph-loop.js +1 -1
- package/dist/runtime/loop.d.ts +7 -0
- package/dist/runtime/loop.js +14 -0
- package/dist/runtime/maintenance-queue.d.ts +10 -0
- package/dist/runtime/maintenance-queue.js +10 -0
- package/dist/runtime/maintenance.d.ts +45 -74
- package/dist/runtime/maintenance.js +139 -136
- package/dist/runtime/model-call.d.ts +7 -4
- package/dist/runtime/model-call.js +24 -57
- package/dist/runtime/providers.d.ts +17 -6
- package/dist/runtime/providers.js +66 -25
- package/dist/runtime/quota.d.ts +17 -3
- package/dist/runtime/quota.js +27 -2
- package/dist/runtime/retired-schedulers.d.ts +7 -0
- package/dist/runtime/retired-schedulers.js +31 -0
- package/dist/runtime/run-control.d.ts +33 -0
- package/dist/runtime/run-control.js +77 -0
- package/dist/runtime/run-finish.d.ts +26 -17
- package/dist/runtime/run-finish.js +98 -51
- package/dist/runtime/run-jobs.d.ts +48 -0
- package/dist/runtime/run-jobs.js +95 -0
- package/dist/runtime/run-processors.d.ts +60 -0
- package/dist/runtime/run-processors.js +185 -0
- package/dist/runtime/run-queue.d.ts +32 -57
- package/dist/runtime/run-queue.js +291 -295
- package/dist/runtime/run-steps.d.ts +39 -0
- package/dist/runtime/run-steps.js +96 -0
- package/dist/runtime/run-worker.d.ts +121 -75
- package/dist/runtime/run-worker.js +340 -225
- package/dist/runtime/runtime.module.d.ts +10 -0
- package/dist/runtime/runtime.module.js +112 -0
- package/dist/runtime/step-log.d.ts +40 -0
- package/dist/runtime/step-log.js +94 -0
- package/dist/runtime/stream.controller.d.ts +5 -8
- package/dist/runtime/stream.controller.js +14 -12
- package/dist/runtime/stream.d.ts +24 -6
- package/dist/runtime/stream.js +78 -7
- package/dist/runtime/subagents/child.d.ts +3 -44
- package/dist/runtime/subagents/child.js +0 -79
- package/dist/runtime/subagents/definition.d.ts +4 -4
- package/dist/runtime/subagents/definition.js +2 -2
- package/dist/runtime/subagents/dispatch.d.ts +87 -6
- package/dist/runtime/subagents/dispatch.js +135 -140
- package/dist/runtime/subagents/limits.d.ts +9 -4
- package/dist/runtime/subagents/limits.js +4 -2
- package/dist/runtime/subagents/org-agents.d.ts +4 -4
- package/dist/runtime/subagents/org-agents.js +1 -1
- package/dist/runtime/subagents/progress.d.ts +2 -2
- package/dist/runtime/subagents/roster.d.ts +3 -3
- package/dist/runtime/subagents/roster.js +1 -1
- package/dist/runtime/subagents/skill-fork.d.ts +6 -7
- package/dist/runtime/subagents/skill-fork.js +16 -5
- package/dist/runtime/subagents/subagents.service.d.ts +40 -0
- package/dist/runtime/subagents/subagents.service.js +101 -0
- package/dist/runtime/usage-report.d.ts +94 -52
- package/dist/runtime/usage-report.js +200 -99
- package/dist/runtime/waits.d.ts +125 -57
- package/dist/runtime/waits.js +431 -208
- package/dist/sandbox/job-ids.d.ts +10 -0
- package/dist/sandbox/job-ids.js +10 -0
- package/dist/sandbox/jobs.d.ts +41 -0
- package/dist/sandbox/jobs.js +113 -0
- package/dist/sandbox/leases.d.ts +39 -31
- package/dist/sandbox/leases.js +117 -257
- package/dist/sandbox/providers.d.ts +19 -0
- package/dist/sandbox/providers.js +38 -0
- package/dist/sandbox/sandbox.module.d.ts +8 -0
- package/dist/sandbox/sandbox.module.js +30 -0
- package/dist/sandbox/sandbox.service.d.ts +24 -29
- package/dist/sandbox/sandbox.service.js +106 -75
- package/dist/skills/catalog.d.ts +33 -20
- package/dist/skills/catalog.js +96 -53
- package/dist/skills/changes.controller.d.ts +4 -4
- package/dist/skills/changes.controller.js +15 -9
- package/dist/skills/changes.service.d.ts +28 -18
- package/dist/skills/changes.service.js +421 -364
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +8 -5
- package/dist/skills/invoke.d.ts +16 -15
- package/dist/skills/invoke.js +48 -17
- package/dist/skills/skills.controller.d.ts +1 -1
- package/dist/skills/skills.controller.js +11 -6
- package/dist/skills/skills.module.d.ts +6 -0
- package/dist/skills/skills.module.js +30 -0
- package/dist/skills/skills.service.d.ts +47 -30
- package/dist/skills/skills.service.js +221 -158
- package/dist/storage/job-ids.d.ts +6 -0
- package/dist/storage/job-ids.js +6 -0
- package/dist/storage/purge.d.ts +22 -7
- package/dist/storage/purge.js +55 -3
- package/dist/storage/storage.module.d.ts +6 -0
- package/dist/storage/storage.module.js +23 -0
- package/dist/storage/storage.service.d.ts +18 -4
- package/dist/storage/storage.service.js +44 -3
- package/dist/tools/approvals.controller.d.ts +1 -1
- package/dist/tools/approvals.controller.js +12 -8
- package/dist/tools/approvals.service.d.ts +27 -25
- package/dist/tools/approvals.service.js +324 -258
- package/dist/tools/breaker.d.ts +2 -2
- package/dist/tools/breaker.js +21 -3
- package/dist/tools/builtins/ask-user.d.ts +2 -2
- package/dist/tools/builtins/ask-user.js +1 -1
- package/dist/tools/builtins/builtin-tools.d.ts +21 -0
- package/dist/tools/builtins/builtin-tools.js +80 -0
- package/dist/tools/builtins/read-tool-output.d.ts +2 -2
- package/dist/tools/builtins/read-tool-output.js +1 -1
- package/dist/tools/builtins/sandbox/bash.js +2 -2
- package/dist/tools/builtins/sandbox/common.d.ts +7 -4
- package/dist/tools/builtins/sandbox/common.js +5 -3
- package/dist/tools/builtins/sandbox/deliver.js +2 -2
- package/dist/tools/builtins/sandbox/edit.js +1 -1
- package/dist/tools/builtins/sandbox/glob.js +2 -2
- package/dist/tools/builtins/sandbox/grep.js +2 -2
- package/dist/tools/builtins/sandbox/read.js +1 -1
- package/dist/tools/builtins/sandbox/write.js +1 -1
- package/dist/tools/builtins/skill-load.d.ts +3 -3
- package/dist/tools/builtins/skill-load.js +1 -1
- package/dist/tools/canonical-json.d.ts +6 -0
- package/dist/tools/canonical-json.js +16 -0
- package/dist/tools/connector-content.controller.d.ts +1 -1
- package/dist/tools/connector-content.controller.js +11 -6
- package/dist/tools/connector-content.d.ts +12 -15
- package/dist/tools/connector-content.js +53 -18
- package/dist/tools/connectors.controller.d.ts +1 -1
- package/dist/tools/connectors.controller.js +21 -10
- package/dist/tools/connectors.service.d.ts +31 -13
- package/dist/tools/connectors.service.js +434 -344
- package/dist/tools/credentials.d.ts +17 -20
- package/dist/tools/credentials.js +55 -34
- package/dist/tools/drift.d.ts +29 -41
- package/dist/tools/drift.js +111 -79
- package/dist/tools/info.d.ts +12 -9
- package/dist/tools/info.js +33 -7
- package/dist/tools/job-ids.d.ts +13 -0
- package/dist/tools/job-ids.js +15 -0
- package/dist/tools/jobs.d.ts +24 -0
- package/dist/tools/jobs.js +69 -0
- package/dist/tools/oauth/flow-paths.d.ts +16 -0
- package/dist/tools/oauth/flow-paths.js +38 -0
- package/dist/tools/oauth/flow.d.ts +30 -30
- package/dist/tools/oauth/flow.js +109 -81
- package/dist/tools/oauth/oauth.controller.d.ts +3 -3
- package/dist/tools/oauth/oauth.controller.js +12 -9
- package/dist/tools/oauth/tokens.d.ts +11 -3
- package/dist/tools/oauth/tokens.js +15 -14
- package/dist/tools/outputs.d.ts +13 -4
- package/dist/tools/outputs.js +47 -3
- package/dist/tools/pipeline.d.ts +62 -46
- package/dist/tools/pipeline.js +145 -64
- package/dist/tools/policy.d.ts +2 -2
- package/dist/tools/questions.controller.d.ts +1 -1
- package/dist/tools/questions.controller.js +8 -5
- package/dist/tools/questions.service.d.ts +25 -24
- package/dist/tools/questions.service.js +201 -142
- package/dist/tools/registry.d.ts +30 -20
- package/dist/tools/registry.js +73 -37
- package/dist/tools/specs.d.ts +5 -4
- package/dist/tools/specs.js +3 -1
- package/dist/tools/tools.module.d.ts +10 -0
- package/dist/tools/tools.module.js +91 -0
- package/dist/ui/call-extension.d.ts +16 -0
- package/dist/ui/call-extension.js +38 -0
- package/dist/ui/embed-token.d.ts +9 -5
- package/dist/ui/embed-token.js +34 -6
- package/dist/ui/ui-stream.d.ts +22 -17
- package/dist/ui/ui-stream.js +72 -12
- package/dist/ui/ui.module.d.ts +7 -0
- package/dist/ui/ui.module.js +28 -0
- package/dist/ui/views.controller.d.ts +14 -12
- package/dist/ui/views.controller.js +32 -25
- package/dist/ui/views.d.ts +9 -57
- package/dist/ui/views.js +43 -45
- package/package.json +11 -2
- package/dist/http/health.controller.d.ts +0 -26
- package/dist/http/health.controller.js +0 -79
- package/dist/http/tokens.d.ts +0 -131
- package/dist/http/tokens.js +0 -131
- package/dist/http/zod.pipe.d.ts +0 -8
- package/dist/http/zod.pipe.js +0 -14
- package/dist/identity/rate-limit.d.ts +0 -55
- package/dist/identity/rate-limit.js +0 -121
- package/dist/sandbox/lifecycle.d.ts +0 -21
- package/dist/sandbox/lifecycle.js +0 -68
- /package/dist/http/{gateway.module.d.ts → gateway-routes.d.ts} +0 -0
- /package/dist/http/{gateway.module.js → gateway-routes.js} +0 -0
|
@@ -1,24 +1,47 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
1
10
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
11
|
import { PLUGIN_MANIFEST_FILE, parseSkillMd, SDK_VERSION, SKILL_ENTRY_FILE, } from "@capybara-hq/plugin-sdk";
|
|
12
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
3
13
|
import { sql } from "kysely";
|
|
4
14
|
import semver from "semver";
|
|
5
15
|
import { ApiError } from "../errors.js";
|
|
16
|
+
import { ExtensionAdminOps } from "../extensions/admin-ops.js";
|
|
6
17
|
import { writeSnapshot } from "../extensions/approvals.js";
|
|
18
|
+
import { ExtensionBlobs } from "../extensions/blobs.js";
|
|
19
|
+
import { ExtensionInstalls } from "../extensions/installs.js";
|
|
20
|
+
import { PluginApproveLock, PluginInstallLock } from "../extensions/locks.js";
|
|
7
21
|
import { unrunMigrations } from "../extensions/migrate-lock.js";
|
|
8
22
|
import { ExtensionPackageError, permissionSetOfPackage, readExtensionPackage, } from "../extensions/package.js";
|
|
9
23
|
import { diffPermissions, permissionKeys, WARNINGS_KEY_PREFIX, } from "../extensions/permission-set.js";
|
|
10
24
|
import { reviewHash as extensionReviewHash, migrationWarnings, permissionGroups, permissionKeyItems, } from "../extensions/permission-view.js";
|
|
25
|
+
import { ExtensionRegistry } from "../extensions/registry.js";
|
|
11
26
|
import { audit } from "../identity/audit.js";
|
|
12
|
-
import {
|
|
27
|
+
import { EnterpriseAdminLock } from "../identity/enterprise-admin.js";
|
|
28
|
+
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
29
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
30
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
31
|
+
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
32
|
+
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
13
33
|
import { packPackageTgz } from "../packages/tgz.js";
|
|
14
34
|
import { checkSkillFiles, SkillArchiveError } from "../skills/package.js";
|
|
35
|
+
import { StorageService } from "../storage/storage.service.js";
|
|
15
36
|
import { endpointCredentialIssues } from "../tools/endpoint.js";
|
|
16
37
|
import { canonicalJson } from "../tools/registry.js";
|
|
17
|
-
import {
|
|
38
|
+
import { findConnectorIn } from "./catalog-content.js";
|
|
39
|
+
import { assertPluginNameOwner, catalogObjectPrefix, itemView, permissionsMismatch, precheckCatalogImport, putCatalogFiles, templateProblems, writeCatalogVersion, } from "./catalog-items.js";
|
|
18
40
|
import { CLAUDE_PLUGIN_FILE, claudeContentDigest, } from "./claude/manifest.js";
|
|
19
41
|
import { CLAUDE_MCP_CONNECTOR } from "./claude/mcp.js";
|
|
20
42
|
import { item as reportItem, sortItems, } from "./claude/report.js";
|
|
21
43
|
import { isClaudePluginTree, translateClaudePlugin } from "./claude/translate.js";
|
|
44
|
+
import { CatalogItemLock } from "./locks.js";
|
|
22
45
|
import { PluginPackageError, packagePath, readPluginFiles, readPluginPackage, } from "./plugin-package.js";
|
|
23
46
|
import { maxSatisfying, satisfiesRange } from "./versions.js";
|
|
24
47
|
/**
|
|
@@ -67,6 +90,7 @@ const NOT_NPM = { provenance: { checked: false, reason: "not an npm package" } }
|
|
|
67
90
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
68
91
|
const notFound = () => new ApiError("plugin.staging_not_found", "This plugin import was not found or has expired (staged imports are kept for 24 hours); prepare it again");
|
|
69
92
|
const invalid = (problems) => new ApiError("catalog.invalid_manifest", `Invalid plugin package: ${problems[0] ?? "unknown problem"}`, problems.slice(0, 50));
|
|
93
|
+
const reviewStale = (review) => new ApiError("plugin.review_stale", `The review of plugin ${review.name} ${review.version} is out of date (it changed, or its extension on this deployment changed since it was prepared); review it again`);
|
|
70
94
|
const mismatch = (what) => new ApiError("marketplace.package_mismatch", `The downloaded package does not match the marketplace entry: ${what}`);
|
|
71
95
|
/**
|
|
72
96
|
* The API error of a plugin package that cannot be read in a catalog path: the pre-0.1.0 format ->
|
|
@@ -96,15 +120,75 @@ const fileOf = (path, data) => ({
|
|
|
96
120
|
sha256: createHash("sha256").update(data).digest("hex"),
|
|
97
121
|
data,
|
|
98
122
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
let PluginImport = class PluginImport {
|
|
124
|
+
kdb;
|
|
125
|
+
adminLock;
|
|
126
|
+
installLock;
|
|
127
|
+
approveLock;
|
|
128
|
+
itemLock;
|
|
129
|
+
config;
|
|
130
|
+
installs;
|
|
131
|
+
ops;
|
|
132
|
+
blobs;
|
|
133
|
+
registry;
|
|
134
|
+
log;
|
|
135
|
+
txHost;
|
|
136
|
+
/** Where plugin files go (the kernel's object storage; the CLI's own, see {@link useCliStorage}). */
|
|
137
|
+
files;
|
|
138
|
+
/**
|
|
139
|
+
* false: this process loads no connectors (the CLI), so a template of an unknown connector gets
|
|
140
|
+
* only the static endpoint checks and `endpointChecked: false`; the org install re-checks it
|
|
141
|
+
* against the loaded connector.
|
|
142
|
+
*/
|
|
143
|
+
connectorsLoaded = true;
|
|
144
|
+
constructor(kdb,
|
|
145
|
+
/** The enterprise admin lock (identity/enterprise-admin.ts): joins the caller's transaction. */
|
|
146
|
+
adminLock, installLock, approveLock, itemLock, config, storage, installs, ops,
|
|
147
|
+
/** Reads a package from the package store (confirm recomputes the permission set). */
|
|
148
|
+
blobs,
|
|
149
|
+
/** Config-declared names, loaded connectors and extension versions (the extension registry). */
|
|
150
|
+
registry, log, txHost) {
|
|
151
|
+
this.kdb = kdb;
|
|
152
|
+
this.adminLock = adminLock;
|
|
153
|
+
this.installLock = installLock;
|
|
154
|
+
this.approveLock = approveLock;
|
|
155
|
+
this.itemLock = itemLock;
|
|
156
|
+
this.config = config;
|
|
157
|
+
this.installs = installs;
|
|
158
|
+
this.ops = ops;
|
|
159
|
+
this.blobs = blobs;
|
|
160
|
+
this.registry = registry;
|
|
161
|
+
this.log = log;
|
|
162
|
+
this.txHost = txHost;
|
|
163
|
+
this.files = storage;
|
|
164
|
+
}
|
|
165
|
+
/** The kernel-schema handle of the current context (the transaction, else the pool). */
|
|
166
|
+
get db() {
|
|
167
|
+
return this.kdb.db;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* CLI only (like `ExtensionHost.noteInspected`): plugin files go to the object store the CLI set
|
|
171
|
+
* up itself, and connector templates get static checks only (the CLI loads no connector). Called
|
|
172
|
+
* once, right after the command's context is created.
|
|
173
|
+
*/
|
|
174
|
+
useCliStorage(storage) {
|
|
175
|
+
this.files = storage;
|
|
176
|
+
this.connectorsLoaded = false;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The enterprise-admin re-check under the lock, in the caller's transaction. `actor` null is the
|
|
180
|
+
* CLI (the operator of the deployment: no account to re-check, audits carry no actor), like
|
|
181
|
+
* `ExtensionInstalls.ingest`.
|
|
182
|
+
*/
|
|
183
|
+
async authorizeActor(actor) {
|
|
184
|
+
if (actor === null)
|
|
185
|
+
await this.adminLock.lock();
|
|
186
|
+
else
|
|
187
|
+
await this.adminLock.lockAndAuthorize(actor);
|
|
188
|
+
}
|
|
189
|
+
/** The re-check alone, in a transaction of its own (before anything is written). */
|
|
190
|
+
async authorize(actor) {
|
|
191
|
+
await this.authorizeActor(actor);
|
|
108
192
|
}
|
|
109
193
|
/**
|
|
110
194
|
* Reads, checks and stages a plugin (see the file header). Returns the staging id and review.
|
|
@@ -112,7 +196,7 @@ export class PluginImport {
|
|
|
112
196
|
* versioned and published by it (the version defaulting to `0.0.0-sha256.h<12>`, spec §5.3).
|
|
113
197
|
*/
|
|
114
198
|
async prepare(actor, bytes, source, opts = {}) {
|
|
115
|
-
const maxBytes = this.
|
|
199
|
+
const maxBytes = this.config.get().packages.maxBytes;
|
|
116
200
|
const pkg = await readingPackage(() => readPluginPackage(bytes, {
|
|
117
201
|
maxBytes,
|
|
118
202
|
hostSdkVersion: SDK_VERSION,
|
|
@@ -143,7 +227,7 @@ export class PluginImport {
|
|
|
143
227
|
entryVersion: opts.fallback.entryVersion,
|
|
144
228
|
}),
|
|
145
229
|
...(claude !== undefined && { overlay: claude }),
|
|
146
|
-
allowInsecureLoopback: this.
|
|
230
|
+
allowInsecureLoopback: this.config.get().marketplaces.allowInsecureLoopback,
|
|
147
231
|
}));
|
|
148
232
|
const translated = await readingPackage(async () => readPluginFiles(t.tree, {
|
|
149
233
|
hostSdkVersion: SDK_VERSION,
|
|
@@ -194,7 +278,7 @@ export class PluginImport {
|
|
|
194
278
|
* (required with an extension: it is stored in the package store); `size` is recorded.
|
|
195
279
|
*/
|
|
196
280
|
async prepareContents(actor, pkg, tgz, source, opts) {
|
|
197
|
-
const maxBytes = this.
|
|
281
|
+
const maxBytes = this.config.get().packages.maxBytes;
|
|
198
282
|
// 1. Every check (nothing written)
|
|
199
283
|
const m = pkg.manifest;
|
|
200
284
|
const packageName = packageNameOf(pkg);
|
|
@@ -208,7 +292,7 @@ export class PluginImport {
|
|
|
208
292
|
? await readingPackage(() => readExtensionPackage(bytes, { maxBytes, hostSdkVersion: SDK_VERSION }))
|
|
209
293
|
: undefined;
|
|
210
294
|
const content = this.checkContent(pkg, format);
|
|
211
|
-
const { existing, version } = await precheckCatalogImport(this.
|
|
295
|
+
const { existing, version } = await precheckCatalogImport(this.db, m.name, {
|
|
212
296
|
packageName,
|
|
213
297
|
version: m.version,
|
|
214
298
|
contentDigest: pkg.contentDigest,
|
|
@@ -219,14 +303,14 @@ export class PluginImport {
|
|
|
219
303
|
// The catalog name space is the extension name space: a declarative plugin cannot take a
|
|
220
304
|
// config-declared or another package's extension name either
|
|
221
305
|
this.assertNotDeclared(m.name);
|
|
222
|
-
await assertPluginNameOwner(this.
|
|
306
|
+
await assertPluginNameOwner(this.db, m.name, packageName);
|
|
223
307
|
let extension;
|
|
224
308
|
if (ext) {
|
|
225
309
|
extension = await this.reviewExtension(ext, await this.extensionState(m.name, packageName));
|
|
226
|
-
await assertDowngradable(this.
|
|
310
|
+
await assertDowngradable(this.db, extension, ext.migrationSql);
|
|
227
311
|
}
|
|
228
312
|
if (content.files.length > 0)
|
|
229
|
-
this.
|
|
313
|
+
this.files.assertAvailable();
|
|
230
314
|
const src = {
|
|
231
315
|
kind: source.kind,
|
|
232
316
|
ref: source.ref,
|
|
@@ -281,13 +365,13 @@ export class PluginImport {
|
|
|
281
365
|
};
|
|
282
366
|
review.reviewHash = pluginReviewHash(review, content.files);
|
|
283
367
|
// Re-check under the lock that the actor is still an enterprise admin before writing
|
|
284
|
-
await this.
|
|
368
|
+
await this.authorize(actor);
|
|
285
369
|
// 2. Write: the extension into the package store, files into object storage, the staging row
|
|
286
370
|
const stagingId = randomUUID();
|
|
287
371
|
const itemId = existing?.id ?? randomUUID();
|
|
288
372
|
if (ext) {
|
|
289
373
|
const bootstrap = src.kind === "bootstrap";
|
|
290
|
-
await this.
|
|
374
|
+
await this.installs.ingest(actor, bytes, bootstrap
|
|
291
375
|
? { source: "bootstrap", ref: src.ref }
|
|
292
376
|
: {
|
|
293
377
|
source: "catalog",
|
|
@@ -300,7 +384,7 @@ export class PluginImport {
|
|
|
300
384
|
let objectPrefix = null;
|
|
301
385
|
if (content.files.length > 0) {
|
|
302
386
|
objectPrefix = catalogObjectPrefix(itemId, version, stagingId);
|
|
303
|
-
await putCatalogFiles(this.
|
|
387
|
+
await putCatalogFiles(this.files, objectPrefix, content.files);
|
|
304
388
|
}
|
|
305
389
|
const keys = ext
|
|
306
390
|
? permissionKeys(permissionSetOfPackage(ext))
|
|
@@ -322,46 +406,50 @@ export class PluginImport {
|
|
|
322
406
|
...(license.text !== undefined && { licenseText: license.text }),
|
|
323
407
|
...(license.truncated && { licenseTruncated: true }),
|
|
324
408
|
};
|
|
325
|
-
await this.
|
|
326
|
-
await authorizeActor(trx, actor);
|
|
327
|
-
await trx
|
|
328
|
-
.insertInto("plugin_import_staging")
|
|
329
|
-
.values({
|
|
330
|
-
id: stagingId,
|
|
331
|
-
review: JSON.stringify(review),
|
|
332
|
-
manifest: JSON.stringify(staged),
|
|
333
|
-
object_prefix: objectPrefix,
|
|
334
|
-
source: JSON.stringify(src),
|
|
335
|
-
created_by: actor,
|
|
336
|
-
expires_at: new Date(Date.now() + PLUGIN_STAGING_TTL_MS),
|
|
337
|
-
})
|
|
338
|
-
.execute();
|
|
339
|
-
await audit(trx, {
|
|
340
|
-
...(actor !== null && { actorAccountId: actor }),
|
|
341
|
-
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
342
|
-
action: "catalog.plugin_staged",
|
|
343
|
-
target: stagingId,
|
|
344
|
-
detail: {
|
|
345
|
-
stagingId,
|
|
346
|
-
name: m.name,
|
|
347
|
-
version,
|
|
348
|
-
source: src.kind,
|
|
349
|
-
sourceRef: src.ref,
|
|
350
|
-
...(src.integrity !== undefined && { integrity: src.integrity }),
|
|
351
|
-
...(src.marketplaceId !== undefined && { marketplaceId: src.marketplaceId }),
|
|
352
|
-
reviewHash: review.reviewHash,
|
|
353
|
-
...(extension && {
|
|
354
|
-
extension: { sha256: extension.sha256, action: extension.action },
|
|
355
|
-
}),
|
|
356
|
-
},
|
|
357
|
-
});
|
|
358
|
-
});
|
|
409
|
+
await this.writeStaging(actor, stagingId, review, staged, objectPrefix, src, opts);
|
|
359
410
|
return { stagingId, review, permissionKeys: keys, permissionsMismatch: mismatch };
|
|
360
411
|
}
|
|
412
|
+
/** The staging row and the `catalog.plugin_staged` audit, the actor re-checked under the lock. */
|
|
413
|
+
async writeStaging(actor, stagingId, review, staged, objectPrefix, src, opts) {
|
|
414
|
+
const { extension } = review;
|
|
415
|
+
const t = this.db;
|
|
416
|
+
await this.authorizeActor(actor);
|
|
417
|
+
await t
|
|
418
|
+
.insertInto("plugin_import_staging")
|
|
419
|
+
.values({
|
|
420
|
+
id: stagingId,
|
|
421
|
+
review: JSON.stringify(review),
|
|
422
|
+
manifest: JSON.stringify(staged),
|
|
423
|
+
object_prefix: objectPrefix,
|
|
424
|
+
source: JSON.stringify(src),
|
|
425
|
+
created_by: actor,
|
|
426
|
+
expires_at: new Date(Date.now() + PLUGIN_STAGING_TTL_MS),
|
|
427
|
+
})
|
|
428
|
+
.execute();
|
|
429
|
+
await audit(t, {
|
|
430
|
+
...(actor !== null && { actorAccountId: actor }),
|
|
431
|
+
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
432
|
+
action: "catalog.plugin_staged",
|
|
433
|
+
target: stagingId,
|
|
434
|
+
detail: {
|
|
435
|
+
stagingId,
|
|
436
|
+
name: review.name,
|
|
437
|
+
version: staged.version,
|
|
438
|
+
source: src.kind,
|
|
439
|
+
sourceRef: src.ref,
|
|
440
|
+
...(src.integrity !== undefined && { integrity: src.integrity }),
|
|
441
|
+
...(src.marketplaceId !== undefined && { marketplaceId: src.marketplaceId }),
|
|
442
|
+
reviewHash: review.reviewHash,
|
|
443
|
+
...(extension && {
|
|
444
|
+
extension: { sha256: extension.sha256, action: extension.action },
|
|
445
|
+
}),
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
}
|
|
361
449
|
/** Fetches a plugin from the configured npm registry (verified by `dist.integrity`), then prepares it. */
|
|
362
450
|
async prepareNpm(actor, input, opts = {}) {
|
|
363
|
-
const got = await this.
|
|
364
|
-
const provenance = await this.
|
|
451
|
+
const got = await this.installs.fetchNpm(input);
|
|
452
|
+
const provenance = await this.installs.fetchProvenance({
|
|
365
453
|
package: input.package,
|
|
366
454
|
version: got.version,
|
|
367
455
|
integrity: got.integrity,
|
|
@@ -370,7 +458,7 @@ export class PluginImport {
|
|
|
370
458
|
kind: "npm",
|
|
371
459
|
ref: `${input.package}@${got.version}`,
|
|
372
460
|
integrity: got.integrity,
|
|
373
|
-
detail: { registry: new URL(this.
|
|
461
|
+
detail: { registry: new URL(this.config.get().packages.npmRegistry).origin },
|
|
374
462
|
}, { ...opts, expect: { packageName: input.package }, provenance: { provenance } });
|
|
375
463
|
return { stagingId: r.stagingId, review: r.review };
|
|
376
464
|
}
|
|
@@ -382,7 +470,7 @@ export class PluginImport {
|
|
|
382
470
|
async staged(stagingId) {
|
|
383
471
|
if (!UUID_RE.test(stagingId))
|
|
384
472
|
throw notFound();
|
|
385
|
-
const row = await this.
|
|
473
|
+
const row = await this.db
|
|
386
474
|
.selectFrom("plugin_import_staging")
|
|
387
475
|
.select(["id", "review", "manifest"])
|
|
388
476
|
.where("id", "=", stagingId)
|
|
@@ -404,7 +492,7 @@ export class PluginImport {
|
|
|
404
492
|
async confirm(actor, stagingId, input, opts = {}) {
|
|
405
493
|
if (!UUID_RE.test(stagingId))
|
|
406
494
|
throw notFound();
|
|
407
|
-
const row = await this.
|
|
495
|
+
const row = await this.db
|
|
408
496
|
.selectFrom("plugin_import_staging")
|
|
409
497
|
.selectAll()
|
|
410
498
|
.where("id", "=", stagingId)
|
|
@@ -415,114 +503,125 @@ export class PluginImport {
|
|
|
415
503
|
const review = row.review;
|
|
416
504
|
const staged = row.manifest;
|
|
417
505
|
const src = row.source;
|
|
418
|
-
const stale = () => new ApiError("plugin.review_stale", `The review of plugin ${review.name} ${review.version} is out of date (it changed, or its extension on this deployment changed since it was prepared); review it again`);
|
|
419
506
|
if (input.reviewHash !== review.reviewHash)
|
|
420
|
-
throw
|
|
507
|
+
throw reviewStale(review);
|
|
421
508
|
const manifest = withPinned(staged.manifest, review, input.pinnedSuggestions);
|
|
422
509
|
const reviewed = review.extension;
|
|
423
510
|
// Read the stored package outside the transaction (unless it was already installed as is)
|
|
424
511
|
const stored = reviewed && reviewed.action !== "keep" ? await this.readStored(reviewed.sha256) : undefined;
|
|
425
|
-
const committed = await this.
|
|
426
|
-
await authorizeActor(trx, actor);
|
|
427
|
-
const used = await trx
|
|
428
|
-
.deleteFrom("plugin_import_staging")
|
|
429
|
-
.where("id", "=", stagingId)
|
|
430
|
-
.where("expires_at", ">", sql `now()`)
|
|
431
|
-
.returning("id")
|
|
432
|
-
.executeTakeFirst();
|
|
433
|
-
if (!used)
|
|
434
|
-
throw notFound();
|
|
435
|
-
let now;
|
|
436
|
-
let previous;
|
|
437
|
-
if (reviewed) {
|
|
438
|
-
// The same per-name advisory lock as ExtensionAdminOps.install; under it the action is
|
|
439
|
-
// recomputed from the current deployment state (installed / upgraded / swapped since the
|
|
440
|
-
// review -> stale)
|
|
441
|
-
await sql `SELECT pg_advisory_xact_lock(hashtext(${`capybara.plugin-install:${reviewed.name}`}))`.execute(trx);
|
|
442
|
-
now = {
|
|
443
|
-
...reviewed,
|
|
444
|
-
...actionOf(await this.extensionState(reviewed.name, staged.packageName, trx), reviewed.sha256),
|
|
445
|
-
};
|
|
446
|
-
if (pluginReviewHash({ ...review, extension: now }, staged.files) !== review.reviewHash) {
|
|
447
|
-
throw stale();
|
|
448
|
-
}
|
|
449
|
-
// A foreseeable deploy failure (a downgrade to a version with unrun migrations) is refused
|
|
450
|
-
// before anything is written
|
|
451
|
-
if (input.deployExtension && now.action === "upgrade" && stored) {
|
|
452
|
-
await assertDowngradable(trx, now, stored.migrationSql);
|
|
453
|
-
}
|
|
454
|
-
if (now.action === "install" || (now.action === "upgrade" && input.deployExtension)) {
|
|
455
|
-
previous = await this.approve(trx, actor, review, staged, now, stored, opts);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
const m = manifest;
|
|
459
|
-
const itemId = await writeCatalogVersion(trx, {
|
|
460
|
-
actor,
|
|
461
|
-
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
462
|
-
name: m.name,
|
|
463
|
-
packageName: staged.packageName,
|
|
464
|
-
version: staged.version,
|
|
465
|
-
contentDigest: staged.contentDigest,
|
|
466
|
-
manifest: m,
|
|
467
|
-
listing: {
|
|
468
|
-
publisher: m.publisher,
|
|
469
|
-
description: m.description,
|
|
470
|
-
displayName: m.displayName ?? null,
|
|
471
|
-
},
|
|
472
|
-
newItemId: staged.itemId,
|
|
473
|
-
source: {
|
|
474
|
-
source: src.kind,
|
|
475
|
-
ref: src.ref,
|
|
476
|
-
...(src.integrity !== undefined && { integrity: src.integrity }),
|
|
477
|
-
...(src.detail !== undefined && { detail: src.detail }),
|
|
478
|
-
},
|
|
479
|
-
...(src.marketplaceId !== undefined && { marketplaceId: src.marketplaceId }),
|
|
480
|
-
objectPrefix: row.object_prefix,
|
|
481
|
-
extensionSha256: reviewed?.sha256 ?? null,
|
|
482
|
-
files: staged.files,
|
|
483
|
-
size: staged.size,
|
|
484
|
-
sourceFormat: staged.sourceFormat ?? "capybara",
|
|
485
|
-
translation: staged.translation ?? null,
|
|
486
|
-
licenseText: staged.licenseText ?? null,
|
|
487
|
-
licenseTruncated: staged.licenseTruncated === true,
|
|
488
|
-
auditDetail: {
|
|
489
|
-
stagingId,
|
|
490
|
-
deployExtension: input.deployExtension,
|
|
491
|
-
suggestedPinned: pinnedNames(manifest, review),
|
|
492
|
-
...(now && { extension: { name: now.name, version: now.version, action: now.action } }),
|
|
493
|
-
},
|
|
494
|
-
});
|
|
495
|
-
return { itemId, now, previous };
|
|
496
|
-
});
|
|
512
|
+
const committed = await this.commit(actor, { stagingId, review, staged, src, manifest, objectPrefix: row.object_prefix }, input, stored, opts);
|
|
497
513
|
const { now } = committed;
|
|
498
514
|
const deploy = input.deployExtension && now && now.action !== "keep"
|
|
499
515
|
? await this.deploy(actor, review, committed.itemId, now, committed.previous, opts, input.enable ?? true)
|
|
500
516
|
: null;
|
|
501
517
|
return { item: await this.itemView(committed.itemId), deploy };
|
|
502
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* The confirm's transaction: the staging row consumed, the extension's action recomputed under
|
|
521
|
+
* its install lock (stale -> `plugin.review_stale`), its snapshot approved, and the catalog
|
|
522
|
+
* version written under the item name's lock.
|
|
523
|
+
*/
|
|
524
|
+
async commit(actor, c, input, stored, opts) {
|
|
525
|
+
const { stagingId, review, staged, src, manifest } = c;
|
|
526
|
+
const reviewed = review.extension;
|
|
527
|
+
const stale = () => reviewStale(review);
|
|
528
|
+
await this.authorizeActor(actor);
|
|
529
|
+
const t = this.db;
|
|
530
|
+
const used = await t
|
|
531
|
+
.deleteFrom("plugin_import_staging")
|
|
532
|
+
.where("id", "=", stagingId)
|
|
533
|
+
.where("expires_at", ">", sql `now()`)
|
|
534
|
+
.returning("id")
|
|
535
|
+
.executeTakeFirst();
|
|
536
|
+
if (!used)
|
|
537
|
+
throw notFound();
|
|
538
|
+
let now;
|
|
539
|
+
let previous;
|
|
540
|
+
if (reviewed) {
|
|
541
|
+
// The same per-name advisory lock as ExtensionAdminOps.install; under it the action is
|
|
542
|
+
// recomputed from the current deployment state (installed / upgraded / swapped since the
|
|
543
|
+
// review -> stale)
|
|
544
|
+
await this.installLock.lock(reviewed.name);
|
|
545
|
+
now = {
|
|
546
|
+
...reviewed,
|
|
547
|
+
...actionOf(await this.extensionState(reviewed.name, staged.packageName), reviewed.sha256),
|
|
548
|
+
};
|
|
549
|
+
if (pluginReviewHash({ ...review, extension: now }, staged.files) !== review.reviewHash) {
|
|
550
|
+
throw stale();
|
|
551
|
+
}
|
|
552
|
+
// A foreseeable deploy failure (a downgrade to a version with unrun migrations) is refused
|
|
553
|
+
// before anything is written
|
|
554
|
+
if (input.deployExtension && now.action === "upgrade" && stored) {
|
|
555
|
+
await assertDowngradable(t, now, stored.migrationSql);
|
|
556
|
+
}
|
|
557
|
+
if (now.action === "install" || (now.action === "upgrade" && input.deployExtension)) {
|
|
558
|
+
previous = await this.approve(actor, review, staged, now, stored, opts);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const m = manifest;
|
|
562
|
+
await this.itemLock.lock(m.name);
|
|
563
|
+
const itemId = await writeCatalogVersion(t, {
|
|
564
|
+
actor,
|
|
565
|
+
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
566
|
+
name: m.name,
|
|
567
|
+
packageName: staged.packageName,
|
|
568
|
+
version: staged.version,
|
|
569
|
+
contentDigest: staged.contentDigest,
|
|
570
|
+
manifest: m,
|
|
571
|
+
listing: {
|
|
572
|
+
publisher: m.publisher,
|
|
573
|
+
description: m.description,
|
|
574
|
+
displayName: m.displayName ?? null,
|
|
575
|
+
},
|
|
576
|
+
newItemId: staged.itemId,
|
|
577
|
+
source: {
|
|
578
|
+
source: src.kind,
|
|
579
|
+
ref: src.ref,
|
|
580
|
+
...(src.integrity !== undefined && { integrity: src.integrity }),
|
|
581
|
+
...(src.detail !== undefined && { detail: src.detail }),
|
|
582
|
+
},
|
|
583
|
+
...(src.marketplaceId !== undefined && { marketplaceId: src.marketplaceId }),
|
|
584
|
+
objectPrefix: c.objectPrefix,
|
|
585
|
+
extensionSha256: reviewed?.sha256 ?? null,
|
|
586
|
+
files: staged.files,
|
|
587
|
+
size: staged.size,
|
|
588
|
+
sourceFormat: staged.sourceFormat ?? "capybara",
|
|
589
|
+
translation: staged.translation ?? null,
|
|
590
|
+
licenseText: staged.licenseText ?? null,
|
|
591
|
+
licenseTruncated: staged.licenseTruncated === true,
|
|
592
|
+
auditDetail: {
|
|
593
|
+
stagingId,
|
|
594
|
+
deployExtension: input.deployExtension,
|
|
595
|
+
suggestedPinned: pinnedNames(manifest, review),
|
|
596
|
+
...(now && { extension: { name: now.name, version: now.version, action: now.action } }),
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
return { itemId, now, previous };
|
|
600
|
+
}
|
|
503
601
|
/**
|
|
504
602
|
* Writes the extension's permission snapshot for the version being imported (source web; cli
|
|
505
603
|
* without an actor; bootstrap for the bootstrap step), after
|
|
506
604
|
* registering the name owner like ExtensionAdminOps.install (Ruling P3). Returns the snapshot it
|
|
507
605
|
* overwrote (null when there was none).
|
|
508
606
|
*/
|
|
509
|
-
async approve(
|
|
607
|
+
async approve(actor, review, staged, p, pkg, opts) {
|
|
510
608
|
const set = permissionSetOfPackage(pkg);
|
|
511
|
-
await
|
|
512
|
-
const
|
|
609
|
+
await this.approveLock.lock(p.name);
|
|
610
|
+
const t = this.db;
|
|
611
|
+
const snapRow = await t
|
|
513
612
|
.selectFrom("extension_permission_snapshots")
|
|
514
613
|
.selectAll()
|
|
515
614
|
.where("plugin", "=", p.name)
|
|
516
615
|
.forUpdate()
|
|
517
616
|
.executeTakeFirst();
|
|
518
|
-
await
|
|
617
|
+
await t
|
|
519
618
|
.insertInto("extension_name_owners")
|
|
520
619
|
.values({ name: p.name, package_name: staged.packageName })
|
|
521
620
|
.onConflict((oc) => oc.column("name").doNothing())
|
|
522
621
|
.execute();
|
|
523
|
-
await assertPluginNameOwner(
|
|
622
|
+
await assertPluginNameOwner(t, p.name, staged.packageName);
|
|
524
623
|
const { added, removed } = diffPermissions(snapRow?.permissions, set);
|
|
525
|
-
await writeSnapshot(
|
|
624
|
+
await writeSnapshot(t, p.name, p.version, set, {
|
|
526
625
|
source: review.source.kind === "bootstrap" ? "bootstrap" : actor === null ? "cli" : "web",
|
|
527
626
|
approvedBy: actor,
|
|
528
627
|
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
@@ -561,12 +660,12 @@ export class PluginImport {
|
|
|
561
660
|
? { code: e.code, message: e.message }
|
|
562
661
|
: { code: "internal", message: "Internal error" };
|
|
563
662
|
try {
|
|
564
|
-
await this.
|
|
663
|
+
await this.ops.install(p.name, p.sha256, actor, opts.actorTokenId, {
|
|
565
664
|
catalogItemId: itemId,
|
|
566
665
|
});
|
|
567
666
|
}
|
|
568
667
|
catch (e) {
|
|
569
|
-
this.
|
|
668
|
+
this.log.warn("installing a plugin's extension on the deployment failed", {
|
|
570
669
|
plugin: review.name,
|
|
571
670
|
err: e,
|
|
572
671
|
});
|
|
@@ -579,7 +678,7 @@ export class PluginImport {
|
|
|
579
678
|
}
|
|
580
679
|
}
|
|
581
680
|
catch (err) {
|
|
582
|
-
this.
|
|
681
|
+
this.log.error("cannot restore the permission snapshot of a plugin's extension", {
|
|
583
682
|
plugin: p.name,
|
|
584
683
|
err,
|
|
585
684
|
});
|
|
@@ -590,11 +689,11 @@ export class PluginImport {
|
|
|
590
689
|
if (!enable)
|
|
591
690
|
return { ...base, result: "installed" };
|
|
592
691
|
try {
|
|
593
|
-
await this.
|
|
692
|
+
await this.ops.enable(p.name, actor, opts.actorTokenId);
|
|
594
693
|
return { ...base, result: "enabled" };
|
|
595
694
|
}
|
|
596
695
|
catch (e) {
|
|
597
|
-
this.
|
|
696
|
+
this.log.warn("enabling a plugin's extension failed", { plugin: p.name, err: e });
|
|
598
697
|
return { ...base, result: "failed", ...failure(e) };
|
|
599
698
|
}
|
|
600
699
|
}
|
|
@@ -605,49 +704,45 @@ export class PluginImport {
|
|
|
605
704
|
* approved or changed it meanwhile it is left alone and false is returned.
|
|
606
705
|
*/
|
|
607
706
|
async restoreSnapshot(actor, review, p, prev, opts) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
707
|
+
const t = this.db;
|
|
708
|
+
await this.approveLock.lock(p.name);
|
|
709
|
+
const current = await t
|
|
710
|
+
.selectFrom("extension_permission_snapshots")
|
|
711
|
+
.select(["version", "approved_by"])
|
|
712
|
+
.where("plugin", "=", p.name)
|
|
713
|
+
.forUpdate()
|
|
714
|
+
.executeTakeFirst();
|
|
715
|
+
if (current?.version !== p.version || current.approved_by !== actor)
|
|
716
|
+
return false;
|
|
717
|
+
if (prev) {
|
|
718
|
+
await t
|
|
719
|
+
.updateTable("extension_permission_snapshots")
|
|
720
|
+
.set({
|
|
721
|
+
version: prev.version,
|
|
722
|
+
permissions: JSON.stringify(prev.permissions),
|
|
723
|
+
approved_by: prev.approvedBy,
|
|
724
|
+
approved_at: prev.approvedAt,
|
|
725
|
+
source: prev.source,
|
|
726
|
+
})
|
|
613
727
|
.where("plugin", "=", p.name)
|
|
614
|
-
.
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
await trx
|
|
633
|
-
.deleteFrom("extension_permission_snapshots")
|
|
634
|
-
.where("plugin", "=", p.name)
|
|
635
|
-
.execute();
|
|
636
|
-
}
|
|
637
|
-
await audit(trx, {
|
|
638
|
-
...(actor !== null && { actorAccountId: actor }),
|
|
639
|
-
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
640
|
-
action: "extension.permissions_restored",
|
|
641
|
-
target: p.name,
|
|
642
|
-
detail: {
|
|
643
|
-
plugin: p.name,
|
|
644
|
-
restoredVersion: prev?.version ?? null,
|
|
645
|
-
reason: "plugin_deploy_failed",
|
|
646
|
-
app: { name: review.name, version: review.version },
|
|
647
|
-
},
|
|
648
|
-
});
|
|
649
|
-
return true;
|
|
728
|
+
.execute();
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
await t.deleteFrom("extension_permission_snapshots").where("plugin", "=", p.name).execute();
|
|
732
|
+
}
|
|
733
|
+
await audit(t, {
|
|
734
|
+
...(actor !== null && { actorAccountId: actor }),
|
|
735
|
+
...(opts.actorTokenId !== undefined && { actorTokenId: opts.actorTokenId }),
|
|
736
|
+
action: "extension.permissions_restored",
|
|
737
|
+
target: p.name,
|
|
738
|
+
detail: {
|
|
739
|
+
plugin: p.name,
|
|
740
|
+
restoredVersion: prev?.version ?? null,
|
|
741
|
+
reason: "plugin_deploy_failed",
|
|
742
|
+
app: { name: review.name, version: review.version },
|
|
743
|
+
},
|
|
650
744
|
});
|
|
745
|
+
return true;
|
|
651
746
|
}
|
|
652
747
|
/**
|
|
653
748
|
* Deletes expired staging rows and their object prefixes (maintenance job `app-staging-cleanup`).
|
|
@@ -657,7 +752,7 @@ export class PluginImport {
|
|
|
657
752
|
async cleanupExpired() {
|
|
658
753
|
let total = 0;
|
|
659
754
|
for (;;) {
|
|
660
|
-
const batch = await this.
|
|
755
|
+
const batch = await this.db
|
|
661
756
|
.selectFrom("plugin_import_staging")
|
|
662
757
|
.select(["id", "object_prefix"])
|
|
663
758
|
.where("expires_at", "<=", sql `now()`)
|
|
@@ -669,35 +764,41 @@ export class PluginImport {
|
|
|
669
764
|
let progressed = 0;
|
|
670
765
|
for (const r of batch) {
|
|
671
766
|
try {
|
|
672
|
-
const done = await this.
|
|
673
|
-
const locked = await trx
|
|
674
|
-
.selectFrom("plugin_import_staging")
|
|
675
|
-
.select("id")
|
|
676
|
-
.where("id", "=", r.id)
|
|
677
|
-
.where("expires_at", "<=", sql `now()`)
|
|
678
|
-
.forUpdate()
|
|
679
|
-
.skipLocked()
|
|
680
|
-
.executeTakeFirst();
|
|
681
|
-
if (!locked)
|
|
682
|
-
return false;
|
|
683
|
-
if (r.object_prefix)
|
|
684
|
-
await this.d.storage.deployment().deletePrefix(r.object_prefix);
|
|
685
|
-
await trx.deleteFrom("plugin_import_staging").where("id", "=", r.id).execute();
|
|
686
|
-
return true;
|
|
687
|
-
});
|
|
767
|
+
const done = await this.cleanupOne(r);
|
|
688
768
|
if (done) {
|
|
689
769
|
total++;
|
|
690
770
|
progressed++;
|
|
691
771
|
}
|
|
692
772
|
}
|
|
693
773
|
catch (err) {
|
|
694
|
-
this.
|
|
774
|
+
this.log.warn("cannot clean up an expired plugin import", { stagingId: r.id, err });
|
|
695
775
|
}
|
|
696
776
|
}
|
|
697
777
|
if (progressed === 0 || batch.length < CLEANUP_BATCH)
|
|
698
778
|
return total;
|
|
699
779
|
}
|
|
700
780
|
}
|
|
781
|
+
/**
|
|
782
|
+
* One expired staging row (row lock, `SKIP LOCKED`): its objects, then the row; false when another
|
|
783
|
+
* replica has it or it is gone.
|
|
784
|
+
*/
|
|
785
|
+
async cleanupOne(r) {
|
|
786
|
+
const t = this.db;
|
|
787
|
+
const locked = await t
|
|
788
|
+
.selectFrom("plugin_import_staging")
|
|
789
|
+
.select("id")
|
|
790
|
+
.where("id", "=", r.id)
|
|
791
|
+
.where("expires_at", "<=", sql `now()`)
|
|
792
|
+
.forUpdate()
|
|
793
|
+
.skipLocked()
|
|
794
|
+
.executeTakeFirst();
|
|
795
|
+
if (!locked)
|
|
796
|
+
return false;
|
|
797
|
+
if (r.object_prefix)
|
|
798
|
+
await this.files.deployment().deletePrefix(r.object_prefix);
|
|
799
|
+
await t.deleteFrom("plugin_import_staging").where("id", "=", r.id).execute();
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
701
802
|
// ---------------------------------------------------------------------------------------------
|
|
702
803
|
/** npm / marketplace imports: the package must be the one that was asked for. */
|
|
703
804
|
checkExpected(pkg, expect, format = "capybara") {
|
|
@@ -723,7 +824,7 @@ export class PluginImport {
|
|
|
723
824
|
}
|
|
724
825
|
/** A config-declared extension's name cannot be taken by an imported plugin. */
|
|
725
826
|
assertNotDeclared(name) {
|
|
726
|
-
const declared = this.
|
|
827
|
+
const declared = this.registry.declared().get(name);
|
|
727
828
|
if (declared === "config") {
|
|
728
829
|
throw new ApiError("extension.config_declared", `Extension ${name} is declared in the startup config (extensions); remove it there before importing a plugin with this name`);
|
|
729
830
|
}
|
|
@@ -783,10 +884,10 @@ export class PluginImport {
|
|
|
783
884
|
// The result depends on which connectors the replica serving this request has loaded right
|
|
784
885
|
// now: it is the import-time gate, not the last word (an org install checks again against the
|
|
785
886
|
// connector of the moment)
|
|
786
|
-
const loaded = this.
|
|
887
|
+
const loaded = findConnectorIn(this.registry, t.plugin, t.connector);
|
|
787
888
|
if (loaded) {
|
|
788
889
|
problems.push(...templateProblems(loaded, t, at));
|
|
789
|
-
const v = this.
|
|
890
|
+
const v = this.registry.manifests().find((x) => x.name === t.plugin)?.version;
|
|
790
891
|
if (t.pluginVersion !== undefined &&
|
|
791
892
|
v !== undefined &&
|
|
792
893
|
!satisfiesRange(v, t.pluginVersion)) {
|
|
@@ -794,7 +895,7 @@ export class PluginImport {
|
|
|
794
895
|
}
|
|
795
896
|
}
|
|
796
897
|
else if (local.has(t.plugin) ||
|
|
797
|
-
this.
|
|
898
|
+
!this.connectorsLoaded ||
|
|
798
899
|
(format === "claude-code" && t.plugin === CLAUDE_MCP_CONNECTOR.plugin)) {
|
|
799
900
|
// The connector comes with this plugin or a dependency (or this process loads no
|
|
800
901
|
// connectors, or a translated Claude template targets connector-mcp, which may not be
|
|
@@ -848,7 +949,7 @@ export class PluginImport {
|
|
|
848
949
|
const deps = m.dependencies ?? [];
|
|
849
950
|
if (deps.length === 0)
|
|
850
951
|
return [];
|
|
851
|
-
const rows = await this.
|
|
952
|
+
const rows = await this.db
|
|
852
953
|
.selectFrom("catalog_items as i")
|
|
853
954
|
.innerJoin("catalog_item_versions as v", "v.item_id", "i.id")
|
|
854
955
|
.select(["i.name", "v.version", "v.imported_at"])
|
|
@@ -867,8 +968,8 @@ export class PluginImport {
|
|
|
867
968
|
* The extension's state on the deployment; installed from another npm package ->
|
|
868
969
|
* `extension.name_conflict`.
|
|
869
970
|
*/
|
|
870
|
-
async extensionState(name, packageName
|
|
871
|
-
const r = await db
|
|
971
|
+
async extensionState(name, packageName) {
|
|
972
|
+
const r = await this.db
|
|
872
973
|
.selectFrom("extension_installs")
|
|
873
974
|
.innerJoin("extension_packages", "extension_packages.sha256", "extension_installs.sha256")
|
|
874
975
|
.select([
|
|
@@ -888,7 +989,7 @@ export class PluginImport {
|
|
|
888
989
|
/** The review of the extension: permissions, the change against the snapshot, warnings, action. */
|
|
889
990
|
async reviewExtension(pkg, state) {
|
|
890
991
|
const name = pkg.section.name;
|
|
891
|
-
const snap = await this.
|
|
992
|
+
const snap = await this.db
|
|
892
993
|
.selectFrom("extension_permission_snapshots")
|
|
893
994
|
.select("permissions")
|
|
894
995
|
.where("plugin", "=", name)
|
|
@@ -912,26 +1013,64 @@ export class PluginImport {
|
|
|
912
1013
|
};
|
|
913
1014
|
}
|
|
914
1015
|
async readStored(sha256) {
|
|
915
|
-
const bytes = await this.
|
|
1016
|
+
const bytes = await this.blobs.get(sha256);
|
|
916
1017
|
return readingPackage(() => readExtensionPackage(bytes, {
|
|
917
|
-
maxBytes: this.
|
|
1018
|
+
maxBytes: this.config.get().packages.maxBytes,
|
|
918
1019
|
hostSdkVersion: SDK_VERSION,
|
|
919
1020
|
}));
|
|
920
1021
|
}
|
|
921
1022
|
async itemView(itemId) {
|
|
922
|
-
const item = await this.
|
|
1023
|
+
const item = await this.db
|
|
923
1024
|
.selectFrom("catalog_items")
|
|
924
1025
|
.selectAll()
|
|
925
1026
|
.where("id", "=", itemId)
|
|
926
1027
|
.executeTakeFirstOrThrow();
|
|
927
|
-
const versions = await this.
|
|
1028
|
+
const versions = await this.db
|
|
928
1029
|
.selectFrom("catalog_item_versions")
|
|
929
1030
|
.select(["version", "source", "imported_at"])
|
|
930
1031
|
.where("item_id", "=", itemId)
|
|
931
1032
|
.execute();
|
|
932
1033
|
return itemView(item, versions);
|
|
933
1034
|
}
|
|
934
|
-
}
|
|
1035
|
+
};
|
|
1036
|
+
__decorate([
|
|
1037
|
+
Transactional({ propagation: "mandatory" })
|
|
1038
|
+
], PluginImport.prototype, "authorizeActor", null);
|
|
1039
|
+
__decorate([
|
|
1040
|
+
Transactional()
|
|
1041
|
+
], PluginImport.prototype, "authorize", null);
|
|
1042
|
+
__decorate([
|
|
1043
|
+
Transactional()
|
|
1044
|
+
], PluginImport.prototype, "writeStaging", null);
|
|
1045
|
+
__decorate([
|
|
1046
|
+
Transactional()
|
|
1047
|
+
], PluginImport.prototype, "commit", null);
|
|
1048
|
+
__decorate([
|
|
1049
|
+
Transactional({ propagation: "mandatory" })
|
|
1050
|
+
], PluginImport.prototype, "approve", null);
|
|
1051
|
+
__decorate([
|
|
1052
|
+
Transactional()
|
|
1053
|
+
], PluginImport.prototype, "restoreSnapshot", null);
|
|
1054
|
+
__decorate([
|
|
1055
|
+
Transactional()
|
|
1056
|
+
], PluginImport.prototype, "cleanupOne", null);
|
|
1057
|
+
PluginImport = __decorate([
|
|
1058
|
+
Injectable(),
|
|
1059
|
+
__param(0, Inject(KernelDb)),
|
|
1060
|
+
__param(1, Inject(EnterpriseAdminLock)),
|
|
1061
|
+
__param(2, Inject(PluginInstallLock)),
|
|
1062
|
+
__param(3, Inject(PluginApproveLock)),
|
|
1063
|
+
__param(4, Inject(CatalogItemLock)),
|
|
1064
|
+
__param(5, Inject(KernelConfigService)),
|
|
1065
|
+
__param(6, Inject(StorageService)),
|
|
1066
|
+
__param(7, Inject(ExtensionInstalls)),
|
|
1067
|
+
__param(8, Inject(ExtensionAdminOps)),
|
|
1068
|
+
__param(9, Inject(ExtensionBlobs)),
|
|
1069
|
+
__param(10, Inject(ExtensionRegistry)),
|
|
1070
|
+
__param(11, Inject(KERNEL_LOGGER)),
|
|
1071
|
+
__param(12, Inject(TransactionHost))
|
|
1072
|
+
], PluginImport);
|
|
1073
|
+
export { PluginImport };
|
|
935
1074
|
/**
|
|
936
1075
|
* plugin.json as stored on the version: skills and connector templates listed explicitly (what was
|
|
937
1076
|
* scanned when the manifest omitted them), `pinned` kept from the listing.
|