@capybara-hq/kernel 0.1.0-rc.3 → 0.1.0-rc.5
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 +61 -5
- package/dist/admin/admin.controller.d.ts +47 -16
- package/dist/admin/admin.controller.js +44 -19
- package/dist/admin/extensions.controller.d.ts +24 -3
- package/dist/admin/extensions.controller.js +48 -8
- package/dist/admin/setup-lock.d.ts +1 -1
- package/dist/admin/setup-lock.js +1 -1
- package/dist/admin/setup.controller.d.ts +1 -1
- package/dist/admin/setup.controller.js +1 -1
- package/dist/admin/setup.service.d.ts +4 -4
- package/dist/admin/setup.service.js +8 -8
- package/dist/agents/agent-lookup.d.ts +19 -0
- package/dist/agents/agent-lookup.js +21 -0
- package/dist/agents/agent-profile.service.d.ts +29 -0
- package/dist/agents/agent-profile.service.js +117 -0
- package/dist/agents/agents.controller.d.ts +168 -3
- package/dist/agents/agents.controller.js +201 -12
- package/dist/agents/agents.module.d.ts +4 -1
- package/dist/agents/agents.module.js +36 -6
- package/dist/agents/agents.service.d.ts +64 -27
- package/dist/agents/agents.service.js +199 -74
- package/dist/agents/definition.d.ts +53 -0
- package/dist/agents/definition.js +55 -0
- package/dist/agents/from-template.d.ts +106 -0
- package/dist/agents/from-template.js +649 -0
- package/dist/agents/from-template.service.d.ts +60 -0
- package/dist/agents/from-template.service.js +161 -0
- package/dist/agents/instruction-files.d.ts +60 -0
- package/dist/agents/instruction-files.js +111 -0
- package/dist/agents/models.controller.d.ts +9 -3
- package/dist/agents/models.controller.js +19 -4
- package/dist/agents/org-templates.d.ts +176 -0
- package/dist/agents/org-templates.js +827 -0
- package/dist/agents/pending-connector-requests.d.ts +77 -0
- package/dist/agents/pending-connector-requests.js +215 -0
- package/dist/agents/pending-connectors.controller.d.ts +39 -0
- package/dist/agents/pending-connectors.controller.js +91 -0
- package/dist/agents/pending-connectors.service.d.ts +62 -0
- package/dist/agents/pending-connectors.service.js +282 -0
- package/dist/agents/profile.d.ts +96 -0
- package/dist/agents/profile.js +51 -0
- package/dist/agents/readiness.controller.d.ts +26 -0
- package/dist/agents/readiness.controller.js +56 -0
- package/dist/agents/templates.controller.d.ts +86 -5
- package/dist/agents/templates.controller.js +171 -7
- package/dist/agents/templates.d.ts +127 -23
- package/dist/agents/templates.js +476 -53
- package/dist/background/background.controller.d.ts +38 -0
- package/dist/background/background.controller.js +87 -0
- package/dist/background/background.module.d.ts +10 -0
- package/dist/background/background.module.js +39 -0
- package/dist/background/finish.d.ts +44 -0
- package/dist/background/finish.js +94 -0
- package/dist/background/launch-lock.d.ts +15 -0
- package/dist/background/launch-lock.js +40 -0
- package/dist/background/launch.d.ts +36 -0
- package/dist/background/launch.js +70 -0
- package/dist/background/poll.job.d.ts +56 -0
- package/dist/background/poll.job.js +190 -0
- package/dist/background/render.d.ts +23 -0
- package/dist/background/render.js +48 -0
- package/dist/background/session.d.ts +48 -0
- package/dist/background/session.js +79 -0
- package/dist/background/status.d.ts +35 -0
- package/dist/background/status.js +57 -0
- package/dist/background/stop.d.ts +68 -0
- package/dist/background/stop.js +243 -0
- package/dist/background/store.d.ts +162 -0
- package/dist/background/store.js +357 -0
- package/dist/background/store.module.d.ts +6 -0
- package/dist/background/store.module.js +22 -0
- package/dist/background/tasks.service.d.ts +77 -0
- package/dist/background/tasks.service.js +211 -0
- package/dist/background/wake-rules.d.ts +66 -0
- package/dist/background/wake-rules.js +113 -0
- package/dist/background/wake.d.ts +30 -0
- package/dist/background/wake.js +63 -0
- package/dist/catalog/admin-catalog.controller.d.ts +129 -30
- package/dist/catalog/admin-catalog.controller.js +213 -42
- package/dist/catalog/catalog-content.d.ts +58 -32
- package/dist/catalog/catalog-content.js +34 -8
- package/dist/catalog/catalog-import.module.d.ts +7 -0
- package/dist/catalog/catalog-import.module.js +60 -0
- package/dist/catalog/catalog-items.d.ts +111 -7
- package/dist/catalog/catalog-items.js +279 -13
- package/dist/catalog/catalog-scope.service.d.ts +260 -0
- package/dist/catalog/catalog-scope.service.js +1116 -0
- package/dist/catalog/catalog.module.d.ts +7 -9
- package/dist/catalog/catalog.module.js +41 -31
- package/dist/catalog/catalog.service.d.ts +101 -29
- package/dist/catalog/catalog.service.js +104 -106
- package/dist/catalog/claude/agents.js +2 -0
- package/dist/catalog/cli.d.ts +11 -1
- package/dist/catalog/cli.js +26 -1
- package/dist/catalog/component-promotion.d.ts +96 -0
- package/dist/catalog/component-promotion.js +395 -0
- package/dist/catalog/component-scope.controller.d.ts +152 -0
- package/dist/catalog/component-scope.controller.js +287 -0
- package/dist/catalog/component-scope.service.d.ts +303 -0
- package/dist/catalog/component-scope.service.js +936 -0
- package/dist/catalog/component-state.d.ts +174 -0
- package/dist/catalog/component-state.js +437 -0
- package/dist/catalog/job-ids.d.ts +30 -0
- package/dist/catalog/job-ids.js +25 -0
- package/dist/catalog/marketplace-fetch.d.ts +1 -1
- package/dist/catalog/marketplaces.controller.d.ts +22 -5
- package/dist/catalog/marketplaces.controller.js +56 -7
- package/dist/catalog/marketplaces.service.d.ts +54 -14
- package/dist/catalog/marketplaces.service.js +71 -22
- package/dist/catalog/org-catalog.controller.d.ts +125 -34
- package/dist/catalog/org-catalog.controller.js +181 -65
- package/dist/catalog/org-catalog.service.d.ts +65 -33
- package/dist/catalog/org-catalog.service.js +324 -157
- package/dist/catalog/org-extension-switch.d.ts +41 -0
- package/dist/catalog/org-extension-switch.js +115 -0
- package/dist/catalog/org-extension.controller.d.ts +119 -0
- package/dist/catalog/org-extension.controller.js +266 -0
- package/dist/catalog/org-plugin-uploads.controller.d.ts +98 -0
- package/dist/catalog/org-plugin-uploads.controller.js +213 -0
- package/dist/catalog/org-plugin-uploads.d.ts +63 -0
- package/dist/catalog/org-plugin-uploads.js +116 -0
- package/dist/catalog/owned-items.d.ts +184 -0
- package/dist/catalog/owned-items.js +789 -0
- package/dist/catalog/owned-plugin-cleanup.d.ts +56 -0
- package/dist/catalog/owned-plugin-cleanup.js +194 -0
- package/dist/catalog/ownership.d.ts +172 -0
- package/dist/catalog/ownership.js +326 -0
- package/dist/catalog/platform-components.d.ts +221 -0
- package/dist/catalog/platform-components.js +761 -0
- package/dist/catalog/platform-migration.d.ts +115 -0
- package/dist/catalog/platform-migration.js +582 -0
- package/dist/catalog/plugin-import.d.ts +178 -34
- package/dist/catalog/plugin-import.js +623 -83
- package/dist/catalog/plugin-install.d.ts +185 -41
- package/dist/catalog/plugin-install.js +758 -126
- package/dist/catalog/plugin-upgrade.d.ts +260 -225
- package/dist/catalog/plugin-upgrade.js +1148 -1137
- package/dist/catalog/request-rules.d.ts +65 -0
- package/dist/catalog/request-rules.js +217 -0
- package/dist/catalog/requests.service.d.ts +193 -118
- package/dist/catalog/requests.service.js +526 -343
- package/dist/catalog/reserved-names.d.ts +8 -0
- package/dist/catalog/reserved-names.js +42 -0
- package/dist/catalog/scope-orgs.d.ts +21 -0
- package/dist/catalog/scope-orgs.js +67 -0
- package/dist/catalog/scope-state.d.ts +35 -0
- package/dist/catalog/scope-state.js +87 -0
- package/dist/catalog/scope-sync-workers.d.ts +7 -0
- package/dist/catalog/scope-sync-workers.js +29 -0
- package/dist/catalog/scope-sync.d.ts +176 -0
- package/dist/catalog/scope-sync.js +576 -0
- package/dist/catalog/scope.d.ts +42 -0
- package/dist/catalog/scope.js +42 -0
- package/dist/catalog/unshare.d.ts +22 -0
- package/dist/catalog/unshare.js +118 -0
- package/dist/channels/actions.js +1 -0
- package/dist/channels/cards.js +21 -3
- package/dist/channels/channels.module.js +2 -0
- package/dist/channels/connections.service.d.ts +16 -1
- package/dist/channels/connections.service.js +38 -4
- package/dist/channels/inbound.d.ts +9 -1
- package/dist/channels/inbound.js +67 -5
- package/dist/channels/phrases.d.ts +35 -0
- package/dist/channels/phrases.js +29 -0
- package/dist/channels/threads.d.ts +5 -0
- package/dist/channels/threads.js +8 -0
- package/dist/config/docs.js +3 -1
- package/dist/config/schema.d.ts +24 -2
- package/dist/config/schema.js +145 -19
- package/dist/conversations/access.d.ts +6 -4
- package/dist/conversations/access.js +29 -5
- package/dist/conversations/agent-tree.d.ts +46 -0
- package/dist/conversations/agent-tree.js +92 -0
- package/dist/conversations/attachments.service.d.ts +30 -0
- package/dist/conversations/attachments.service.js +130 -5
- package/dist/conversations/conversations.controller.d.ts +79 -23
- package/dist/conversations/conversations.controller.js +141 -50
- package/dist/conversations/conversations.module.d.ts +1 -1
- package/dist/conversations/conversations.module.js +10 -7
- package/dist/conversations/conversations.service.d.ts +108 -9
- package/dist/conversations/conversations.service.js +237 -30
- package/dist/conversations/environment-status.d.ts +24 -0
- package/dist/conversations/environment-status.js +71 -0
- package/dist/conversations/event-log.d.ts +21 -6
- package/dist/conversations/event-log.js +70 -1
- package/dist/conversations/events.d.ts +140 -0
- package/dist/conversations/events.js +142 -13
- package/dist/conversations/queue.d.ts +3 -1
- package/dist/conversations/queue.js +13 -2
- package/dist/conversations/queue.service.d.ts +1 -1
- package/dist/conversations/queue.service.js +8 -1
- package/dist/conversations/titles.d.ts +12 -3
- package/dist/conversations/titles.js +36 -8
- package/dist/conversations/tree.d.ts +17 -0
- package/dist/conversations/tree.js +42 -0
- package/dist/ctx/create-ctx.d.ts +5 -0
- package/dist/ctx/create-ctx.js +15 -5
- package/dist/db/kernel-schema.d.ts +420 -20
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +3 -0
- package/dist/environments/access.d.ts +41 -0
- package/dist/environments/access.js +77 -0
- package/dist/environments/conversation-environments.d.ts +61 -0
- package/dist/environments/conversation-environments.js +170 -0
- package/dist/environments/dto.d.ts +25 -0
- package/dist/environments/dto.js +12 -0
- package/dist/environments/environments.controller.d.ts +33 -0
- package/dist/environments/environments.controller.js +110 -0
- package/dist/environments/environments.module.d.ts +8 -0
- package/dist/environments/environments.module.js +27 -0
- package/dist/environments/environments.service.d.ts +153 -0
- package/dist/environments/environments.service.js +541 -0
- package/dist/environments/legacy-cleanup.job.d.ts +34 -0
- package/dist/environments/legacy-cleanup.job.js +141 -0
- package/dist/errors.d.ts +90 -2
- package/dist/errors.js +90 -2
- package/dist/evals/reconstruct.d.ts +18 -9
- package/dist/evals/reconstruct.js +26 -7
- package/dist/evals/run-replay.d.ts +7 -2
- package/dist/evals/run-replay.js +42 -7
- package/dist/evals/step-replay.d.ts +2 -5
- package/dist/evals/step-replay.js +13 -7
- package/dist/evals/trajectory.js +1 -1
- package/dist/evals/trajectory.service.d.ts +8 -3
- package/dist/evals/trajectory.service.js +26 -14
- package/dist/evals/worker.d.ts +5 -5
- package/dist/evals/worker.js +9 -3
- package/dist/extensions/admin-ops.d.ts +36 -10
- package/dist/extensions/admin-ops.js +67 -42
- package/dist/extensions/admin-view.d.ts +39 -10
- package/dist/extensions/admin-view.js +111 -20
- package/dist/extensions/blobs.js +1 -0
- package/dist/extensions/bootstrap.d.ts +17 -4
- package/dist/extensions/bootstrap.js +70 -9
- package/dist/extensions/cli.d.ts +12 -0
- package/dist/extensions/cli.js +11 -2
- package/dist/extensions/config-issues.d.ts +13 -1
- package/dist/extensions/config-issues.js +22 -5
- package/dist/extensions/config-json-schema.d.ts +43 -7
- package/dist/extensions/config-json-schema.js +124 -58
- package/dist/extensions/deployment-config-store.d.ts +6 -0
- package/dist/extensions/deployment-config.d.ts +78 -8
- package/dist/extensions/deployment-config.js +172 -34
- package/dist/extensions/display-name.d.ts +22 -0
- package/dist/extensions/display-name.js +77 -0
- package/dist/extensions/effective-config.d.ts +127 -0
- package/dist/extensions/effective-config.js +368 -0
- package/dist/extensions/extensions.module.js +14 -2
- package/dist/extensions/hooks.d.ts +37 -4
- package/dist/extensions/hooks.js +82 -16
- package/dist/extensions/host.d.ts +45 -2
- package/dist/extensions/host.js +112 -16
- package/dist/extensions/installs.d.ts +20 -8
- package/dist/extensions/installs.js +37 -15
- package/dist/extensions/org-config.d.ts +81 -6
- package/dist/extensions/org-config.js +195 -44
- package/dist/extensions/org-levels.d.ts +37 -0
- package/dist/extensions/org-levels.js +71 -0
- package/dist/extensions/org-overrides.d.ts +151 -0
- package/dist/extensions/org-overrides.js +524 -0
- package/dist/extensions/package.d.ts +14 -1
- package/dist/extensions/package.js +51 -2
- package/dist/extensions/permission-view.d.ts +19 -4
- package/dist/extensions/permission-view.js +4 -4
- package/dist/extensions/plugin-items.d.ts +21 -0
- package/dist/extensions/plugin-items.js +42 -0
- package/dist/extensions/point-defaults.controller.d.ts +34 -0
- package/dist/extensions/point-defaults.controller.js +71 -0
- package/dist/extensions/point-defaults.d.ts +71 -0
- package/dist/extensions/point-defaults.js +234 -0
- package/dist/extensions/registry.d.ts +1 -1
- package/dist/extensions/registry.js +2 -0
- package/dist/extensions/resolve.d.ts +5 -1
- package/dist/extensions/resolve.js +15 -2
- package/dist/files/previewers.d.ts +8 -1
- package/dist/files/previewers.js +35 -6
- package/dist/http/api.module.js +31 -3
- package/dist/http/app.d.ts +11 -2
- package/dist/http/app.js +31 -5
- package/dist/http/nest-logger.d.ts +6 -5
- package/dist/http/nest-logger.js +24 -10
- package/dist/identity/accounts.d.ts +29 -29
- package/dist/identity/accounts.js +47 -47
- package/dist/identity/audit.d.ts +2 -1
- package/dist/identity/auth.controller.js +9 -5
- package/dist/identity/auth.guard.d.ts +13 -5
- package/dist/identity/auth.guard.js +26 -9
- package/dist/identity/cookies.d.ts +20 -5
- package/dist/identity/cookies.js +44 -6
- package/dist/identity/identity.module.d.ts +1 -1
- package/dist/identity/identity.module.js +4 -4
- package/dist/identity/me.controller.d.ts +5 -1
- package/dist/identity/me.controller.js +12 -3
- package/dist/identity/principal.d.ts +3 -3
- package/dist/identity/principal.js +3 -3
- package/dist/identity/sessions.d.ts +12 -0
- package/dist/identity/sessions.js +45 -0
- package/dist/identity/settings.d.ts +22 -11
- package/dist/identity/settings.js +53 -18
- package/dist/identity/{enterprise-admin.d.ts → super-admin.d.ts} +5 -5
- package/dist/identity/{enterprise-admin.js → super-admin.js} +24 -24
- package/dist/inbox/inbox.module.d.ts +4 -1
- package/dist/inbox/inbox.module.js +7 -3
- package/dist/inbox/inbox.service.d.ts +62 -3
- package/dist/inbox/inbox.service.js +74 -4
- package/dist/inbox/org-notices.d.ts +63 -0
- package/dist/inbox/org-notices.js +91 -0
- package/dist/inbox/platform-inbox.controller.d.ts +23 -0
- package/dist/inbox/platform-inbox.controller.js +58 -0
- package/dist/inbox/platform-inbox.service.d.ts +151 -0
- package/dist/inbox/platform-inbox.service.js +263 -0
- package/dist/inbox/platform-notices.d.ts +19 -0
- package/dist/inbox/platform-notices.js +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/infra/cli/kernel-cli.module.js +9 -1
- package/dist/infra/config/kernel-config.service.js +27 -1
- package/dist/infra/database/database.module.js +1 -0
- package/dist/infra/database/xact-lock.d.ts +1 -1
- package/dist/infra/database/xact-lock.js +1 -1
- package/dist/infra/events/kernel-events.d.ts +19 -2
- package/dist/infra/lifecycle/process-guards.js +4 -0
- package/dist/infra/logging/logging.module.d.ts +4 -2
- package/dist/infra/logging/logging.module.js +24 -6
- package/dist/infra/queue/add-job-once.d.ts +14 -0
- package/dist/infra/queue/add-job-once.js +16 -0
- package/dist/infra/queue/redis-connection.d.ts +6 -0
- package/dist/infra/queue/redis-connection.js +7 -0
- package/dist/infra/redis/redis.module.js +6 -2
- package/dist/infra/tokens.d.ts +6 -1
- package/dist/infra/tokens.js +6 -1
- package/dist/kernel.module.js +6 -0
- package/dist/lifecycle/kernel-lifecycle.d.ts +1 -1
- package/dist/lifecycle/kernel-lifecycle.js +4 -4
- package/dist/log.d.ts +13 -1
- package/dist/log.js +93 -17
- package/dist/models/prices.d.ts +5 -5
- package/dist/models/prices.js +4 -4
- package/dist/models/purposes.controller.d.ts +6 -4
- package/dist/models/purposes.controller.js +13 -7
- package/dist/models/purposes.d.ts +43 -9
- package/dist/models/purposes.js +48 -18
- package/dist/orgs/directory-sync.d.ts +14 -5
- package/dist/orgs/directory-sync.js +41 -17
- package/dist/orgs/offboarding.d.ts +12 -8
- package/dist/orgs/offboarding.js +54 -33
- package/dist/orgs/org-lock.d.ts +5 -0
- package/dist/orgs/org-lock.js +13 -0
- package/dist/orgs/org.guard.d.ts +10 -0
- package/dist/orgs/org.guard.js +43 -32
- package/dist/orgs/orgs.module.js +3 -0
- package/dist/orgs/orgs.service.d.ts +20 -7
- package/dist/orgs/orgs.service.js +32 -12
- package/dist/orgs/roles.d.ts +1 -1
- package/dist/orgs/roles.js +5 -1
- package/dist/orgs/settings.controller.d.ts +1 -1
- package/dist/orgs/settings.service.d.ts +20 -3
- package/dist/orgs/settings.service.js +19 -4
- package/dist/overrides.d.ts +3 -0
- package/dist/overrides.js +2 -0
- package/dist/platform/actor.d.ts +48 -0
- package/dist/platform/actor.js +100 -0
- package/dist/platform/agent-docs.d.ts +18 -0
- package/dist/platform/agent-docs.js +59 -0
- package/dist/platform/availability.d.ts +14 -0
- package/dist/platform/availability.js +43 -0
- package/dist/platform/errors.d.ts +11 -0
- package/dist/platform/errors.js +26 -0
- package/dist/platform/exclusions.d.ts +12 -0
- package/dist/platform/exclusions.js +1387 -0
- package/dist/platform/method.d.ts +6 -0
- package/dist/platform/method.js +15 -0
- package/dist/platform/operation.d.ts +92 -0
- package/dist/platform/operation.js +35 -0
- package/dist/platform/ops/agent-templates.ops.d.ts +14 -0
- package/dist/platform/ops/agent-templates.ops.js +92 -0
- package/dist/platform/ops/agents.ops.d.ts +19 -0
- package/dist/platform/ops/agents.ops.js +294 -0
- package/dist/platform/ops/connectors.ops.d.ts +15 -0
- package/dist/platform/ops/connectors.ops.js +126 -0
- package/dist/platform/ops/errors.d.ts +11 -0
- package/dist/platform/ops/errors.js +22 -0
- package/dist/platform/ops/extensions.ops.d.ts +19 -0
- package/dist/platform/ops/extensions.ops.js +116 -0
- package/dist/platform/ops/marketplaces.ops.d.ts +16 -0
- package/dist/platform/ops/marketplaces.ops.js +157 -0
- package/dist/platform/ops/paging.d.ts +14 -0
- package/dist/platform/ops/paging.js +20 -0
- package/dist/platform/ops/platform.ops.d.ts +23 -0
- package/dist/platform/ops/platform.ops.js +158 -0
- package/dist/platform/ops/plugins.ops.d.ts +33 -0
- package/dist/platform/ops/plugins.ops.js +377 -0
- package/dist/platform/ops/requests.ops.d.ts +14 -0
- package/dist/platform/ops/requests.ops.js +153 -0
- package/dist/platform/ops/role.d.ts +4 -0
- package/dist/platform/ops/role.js +10 -0
- package/dist/platform/ops/skills.ops.d.ts +13 -0
- package/dist/platform/ops/skills.ops.js +98 -0
- package/dist/platform/ops/summary.d.ts +10 -0
- package/dist/platform/ops/summary.js +18 -0
- package/dist/platform/platform-ops.module.d.ts +7 -0
- package/dist/platform/platform-ops.module.js +55 -0
- package/dist/platform/platform.module.d.ts +8 -0
- package/dist/platform/platform.module.js +25 -0
- package/dist/platform/redact-orgs.d.ts +7 -0
- package/dist/platform/redact-orgs.js +52 -0
- package/dist/platform/registry.d.ts +30 -0
- package/dist/platform/registry.js +111 -0
- package/dist/roles/worker-role.d.ts +6 -4
- package/dist/roles/worker-role.js +14 -7
- package/dist/roles/worker.module.d.ts +1 -1
- package/dist/roles/worker.module.js +15 -1
- package/dist/runtime/context/build.d.ts +11 -7
- package/dist/runtime/context/build.js +46 -19
- package/dist/runtime/context/claude-tools.d.ts +3 -1
- package/dist/runtime/context/claude-tools.js +8 -6
- package/dist/runtime/context/compaction.js +13 -0
- package/dist/runtime/context/reminders.d.ts +2 -0
- package/dist/runtime/context/reminders.js +2 -0
- package/dist/runtime/context/skills.js +9 -2
- package/dist/runtime/context/tool-changes.d.ts +27 -0
- package/dist/runtime/context/tool-changes.js +60 -0
- package/dist/runtime/hook-calls.js +2 -0
- package/dist/runtime/langgraph-loop.d.ts +3 -1
- package/dist/runtime/langgraph-loop.js +36 -17
- package/dist/runtime/loop.d.ts +34 -5
- package/dist/runtime/maintenance.d.ts +9 -4
- package/dist/runtime/maintenance.js +35 -8
- package/dist/runtime/model-call.d.ts +46 -8
- package/dist/runtime/model-call.js +72 -21
- package/dist/runtime/providers.d.ts +6 -0
- package/dist/runtime/providers.js +8 -0
- package/dist/runtime/run-control.d.ts +11 -1
- package/dist/runtime/run-control.js +12 -0
- package/dist/runtime/run-drafts.d.ts +85 -0
- package/dist/runtime/run-drafts.js +230 -0
- package/dist/runtime/run-jobs.d.ts +3 -5
- package/dist/runtime/run-jobs.js +3 -7
- package/dist/runtime/run-queue.d.ts +59 -2
- package/dist/runtime/run-queue.js +311 -38
- package/dist/runtime/run-worker.d.ts +11 -5
- package/dist/runtime/run-worker.js +69 -33
- package/dist/runtime/runtime.module.js +11 -3
- package/dist/runtime/step-log.d.ts +15 -4
- package/dist/runtime/step-log.js +24 -7
- package/dist/runtime/stream.controller.d.ts +23 -1
- package/dist/runtime/stream.controller.js +60 -3
- package/dist/runtime/stream.d.ts +4 -1
- package/dist/runtime/stream.js +27 -3
- package/dist/runtime/subagents/child.d.ts +55 -7
- package/dist/runtime/subagents/child.js +105 -7
- package/dist/runtime/subagents/definition.d.ts +12 -3
- package/dist/runtime/subagents/definition.js +44 -28
- package/dist/runtime/subagents/deliveries.d.ts +71 -0
- package/dist/runtime/subagents/deliveries.js +228 -0
- package/dist/runtime/subagents/dispatch.d.ts +115 -26
- package/dist/runtime/subagents/dispatch.js +212 -141
- package/dist/runtime/subagents/limits.d.ts +24 -5
- package/dist/runtime/subagents/limits.js +40 -6
- package/dist/runtime/subagents/messages.d.ts +95 -0
- package/dist/runtime/subagents/messages.js +328 -0
- package/dist/runtime/subagents/preamble.d.ts +4 -4
- package/dist/runtime/subagents/preamble.js +9 -7
- package/dist/runtime/subagents/progress.d.ts +8 -6
- package/dist/runtime/subagents/progress.js +11 -6
- package/dist/runtime/subagents/render.d.ts +30 -0
- package/dist/runtime/subagents/render.js +53 -0
- package/dist/runtime/subagents/roster.d.ts +24 -7
- package/dist/runtime/subagents/roster.js +47 -11
- package/dist/runtime/subagents/skill-fork.d.ts +3 -2
- package/dist/runtime/subagents/skill-fork.js +8 -4
- package/dist/runtime/subagents/status.d.ts +14 -0
- package/dist/runtime/subagents/status.js +23 -0
- package/dist/runtime/subagents/subagents.service.d.ts +7 -4
- package/dist/runtime/subagents/subagents.service.js +11 -6
- package/dist/runtime/usage-report.d.ts +2 -1
- package/dist/runtime/usage-report.js +19 -13
- package/dist/runtime/waits.d.ts +145 -36
- package/dist/runtime/waits.js +423 -109
- package/dist/sandbox/jobs.d.ts +40 -13
- package/dist/sandbox/jobs.js +57 -20
- package/dist/sandbox/leases.d.ts +37 -54
- package/dist/sandbox/leases.js +71 -115
- package/dist/sandbox/providers.d.ts +2 -2
- package/dist/sandbox/providers.js +1 -1
- package/dist/sandbox/sandbox.module.d.ts +3 -2
- package/dist/sandbox/sandbox.module.js +10 -4
- package/dist/sandbox/sandbox.service.d.ts +282 -129
- package/dist/sandbox/sandbox.service.js +736 -381
- package/dist/skills/catalog.d.ts +3 -2
- package/dist/skills/catalog.js +21 -43
- package/dist/skills/changes.controller.d.ts +7 -0
- package/dist/skills/changes.controller.js +19 -1
- package/dist/skills/invoke.js +8 -3
- package/dist/skills/package.d.ts +20 -1
- package/dist/skills/package.js +28 -1
- package/dist/skills/skills.controller.d.ts +39 -4
- package/dist/skills/skills.controller.js +88 -10
- package/dist/skills/skills.module.js +10 -1
- package/dist/skills/skills.service.d.ts +106 -26
- package/dist/skills/skills.service.js +421 -75
- package/dist/skills/usable.d.ts +81 -0
- package/dist/skills/usable.js +379 -0
- package/dist/tools/approvals.service.d.ts +20 -2
- package/dist/tools/approvals.service.js +25 -4
- package/dist/tools/builtin-names.d.ts +41 -7
- package/dist/tools/builtin-names.js +59 -7
- package/dist/tools/builtins/agent.d.ts +23 -21
- package/dist/tools/builtins/agent.js +62 -55
- package/dist/tools/builtins/builtin-tools.d.ts +19 -1
- package/dist/tools/builtins/builtin-tools.js +59 -2
- package/dist/tools/builtins/handback.d.ts +28 -0
- package/dist/tools/builtins/handback.js +53 -0
- package/dist/tools/builtins/platform.d.ts +34 -0
- package/dist/tools/builtins/platform.js +362 -0
- package/dist/tools/builtins/sandbox/bash.d.ts +1 -1
- package/dist/tools/builtins/sandbox/bash.js +241 -4
- package/dist/tools/builtins/sandbox/common.d.ts +69 -27
- package/dist/tools/builtins/sandbox/common.js +87 -48
- package/dist/tools/builtins/sandbox/deliver.js +1 -1
- package/dist/tools/builtins/sandbox/edit.js +2 -2
- package/dist/tools/builtins/sandbox/glob.js +2 -2
- package/dist/tools/builtins/sandbox/grep.js +2 -4
- package/dist/tools/builtins/sandbox/index.d.ts +3 -1
- package/dist/tools/builtins/sandbox/index.js +7 -1
- package/dist/tools/builtins/sandbox/read.js +1 -1
- package/dist/tools/builtins/sandbox/task-output.d.ts +74 -0
- package/dist/tools/builtins/sandbox/task-output.js +329 -0
- package/dist/tools/builtins/sandbox/task-stop.d.ts +10 -0
- package/dist/tools/builtins/sandbox/task-stop.js +113 -0
- package/dist/tools/builtins/sandbox/write.js +2 -2
- package/dist/tools/builtins/send-message.d.ts +56 -0
- package/dist/tools/builtins/send-message.js +100 -0
- package/dist/tools/builtins/skill-load.d.ts +22 -14
- package/dist/tools/builtins/skill-load.js +86 -57
- package/dist/tools/builtins/skill-write.js +1 -1
- package/dist/tools/builtins/web/errors.d.ts +8 -0
- package/dist/tools/builtins/web/errors.js +53 -0
- package/dist/tools/builtins/web/extract.d.ts +62 -0
- package/dist/tools/builtins/web/extract.js +271 -0
- package/dist/tools/builtins/web/fetch.d.ts +55 -0
- package/dist/tools/builtins/web/fetch.js +175 -0
- package/dist/tools/builtins/web/index.d.ts +13 -0
- package/dist/tools/builtins/web/index.js +12 -0
- package/dist/tools/builtins/web/page-cache.d.ts +25 -0
- package/dist/tools/builtins/web/page-cache.js +77 -0
- package/dist/tools/builtins/web/search.d.ts +25 -0
- package/dist/tools/builtins/web/search.js +210 -0
- package/dist/tools/builtins/web/url.d.ts +17 -0
- package/dist/tools/builtins/web/url.js +43 -0
- package/dist/tools/connectors.controller.d.ts +10 -0
- package/dist/tools/connectors.controller.js +12 -0
- package/dist/tools/connectors.service.d.ts +46 -5
- package/dist/tools/connectors.service.js +94 -15
- package/dist/tools/extension-tools.controller.d.ts +14 -0
- package/dist/tools/extension-tools.controller.js +37 -0
- package/dist/tools/info.d.ts +42 -1
- package/dist/tools/info.js +64 -1
- package/dist/tools/oauth/flow-paths.d.ts +1 -1
- package/dist/tools/oauth/flow-paths.js +1 -1
- package/dist/tools/org-tool-switches.d.ts +74 -0
- package/dist/tools/org-tool-switches.js +184 -0
- package/dist/tools/pipeline.d.ts +46 -40
- package/dist/tools/pipeline.js +202 -364
- package/dist/tools/policy.d.ts +1 -1
- package/dist/tools/policy.js +36 -16
- package/dist/tools/registry.d.ts +120 -8
- package/dist/tools/registry.js +112 -19
- package/dist/tools/tools.module.js +24 -2
- package/dist/tools/validate.js +1 -1
- package/dist/ui/views.d.ts +2 -1
- package/dist/ui/views.js +17 -3
- package/package.json +3 -3
- package/src/migrations/0064_account_last_org.sql +7 -0
- package/src/migrations/0065_conversation_archive.sql +8 -0
- package/src/migrations/0066_extension_display_name.sql +4 -0
- package/src/migrations/0067_agent_profiles.sql +20 -0
- package/src/migrations/0068_agent_avatar_uploads.sql +7 -0
- package/src/migrations/0069_attachments_agent_idx.sql +3 -0
- package/src/migrations/0070_background_tasks.sql +37 -0
- package/src/migrations/0071_background_tasks_reserve.sql +6 -0
- package/src/migrations/0072_background_tasks_stopping.sql +5 -0
- package/src/migrations/0073_org_extension_point_defaults.sql +11 -0
- package/src/migrations/0074_subagent_tree.sql +50 -0
- package/src/migrations/0075_plugin_scope.sql +61 -0
- package/src/migrations/0076_skills_created_by_nullable.sql +6 -0
- package/src/migrations/0077_scope_requests.sql +52 -0
- package/src/migrations/0078_scope_grant_switches.sql +18 -0
- package/src/migrations/0079_scope_live_install_switches.sql +19 -0
- package/src/migrations/0080_rename_enterprise_admin.sql +18 -0
- package/src/migrations/0081_platform_components.sql +129 -0
- package/src/migrations/0082_platform_migration.sql +33 -0
- package/src/migrations/0083_plugin_scope_sync_failures.sql +15 -0
- package/src/migrations/0084_org_owned_items.sql +85 -0
- package/src/migrations/0085_agent_templates_phase4.sql +45 -0
- package/src/migrations/0086_org_layering.sql +30 -0
- package/src/migrations/0087_approval_summary.sql +6 -0
- package/src/migrations/0088_environments.sql +80 -0
- package/dist/catalog/upgrade-targets.d.ts +0 -56
- package/dist/catalog/upgrade-targets.js +0 -90
- package/dist/conversations/sandbox-status.d.ts +0 -24
- package/dist/conversations/sandbox-status.js +0 -52
- package/dist/extensions/org-config.controller.d.ts +0 -24
- package/dist/extensions/org-config.controller.js +0 -62
|
@@ -0,0 +1,576 @@
|
|
|
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
|
+
};
|
|
10
|
+
import { getQueueToken, OnWorkerEvent, WorkerHost } from "@nestjs/bullmq";
|
|
11
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
12
|
+
import { ApiError } from "../errors.js";
|
|
13
|
+
import { ExtensionLifecycle } from "../extensions/lifecycle.js";
|
|
14
|
+
import { ExtensionRegistry } from "../extensions/registry.js";
|
|
15
|
+
import { audit } from "../identity/audit.js";
|
|
16
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
17
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
18
|
+
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
19
|
+
import { LockService } from "../infra/lock/lock.service.js";
|
|
20
|
+
import { runJob } from "../infra/queue/run-job.js";
|
|
21
|
+
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
22
|
+
import { connectorTemplatesOn, templateIdOfPath } from "./component-state.js";
|
|
23
|
+
import { isUsable } from "./ownership.js";
|
|
24
|
+
import { PluginInstaller } from "./plugin-install.js";
|
|
25
|
+
import { wantedOn } from "./scope.js";
|
|
26
|
+
import { ScopeNoLongerWanted, ScopeStillWanted } from "./scope-state.js";
|
|
27
|
+
/**
|
|
28
|
+
* The plugin scope sync (plugin and component management spec §5, phase 1): converges every org
|
|
29
|
+
* to each platform plugin's scope. In phase 1 "on in an org" is the org's plugin install, so for
|
|
30
|
+
* each (item, org) the sync:
|
|
31
|
+
* - wanted on (`wantedOn`, or a live install in the org depends on it: rule 9) and no live install
|
|
32
|
+
* -> installs it as the kernel itself (actor null, audits `via: "scope"`), unless the install
|
|
33
|
+
* needs the org's input (connector templates, or a required org config of its extension not set):
|
|
34
|
+
* that is `needs_config`, derived by the org catalog, never attempted here;
|
|
35
|
+
* - wanted off and a live install -> uninstalls it (`via: "scope"`; the person who changed the
|
|
36
|
+
* scope or the switch confirmed the preview); the connectors the install created stay as the
|
|
37
|
+
* org's own (spec §5 rule 8); a dependency install it took along that its own scope still wants
|
|
38
|
+
* on stays as a standalone install (the installer's rule), the others are synced again.
|
|
39
|
+
* The decision is made outside the org row lock; the installer re-checks the scope under it for a
|
|
40
|
+
* `via: "scope"` install or uninstall, so a person's switch committed meanwhile wins.
|
|
41
|
+
* The sync writes no switch row: those record people's choices, and `wantedOn` honours them for
|
|
42
|
+
* every scope (an org that switched an `all` item off stays off, also across a scope change away
|
|
43
|
+
* and back, layering spec §4). Builtin items are left alone (on everywhere through their required
|
|
44
|
+
* extension). A failed install, uninstall or dependency install is logged, audited
|
|
45
|
+
* `plugin.scope_sync_failed`, kept as the pair's open failure (`plugin_scope_sync_failures`, the
|
|
46
|
+
* super admin's inbox, until a later sync of the pair does not fail) and not retried until the next
|
|
47
|
+
* enqueue. An error outside those steps (a read, the failure write itself) ends the attempt without
|
|
48
|
+
* touching the pair's row, so an older failure stays open.
|
|
49
|
+
* Every worker start enqueues every live item once ({@link PluginScopeSync.enqueueAll}), which
|
|
50
|
+
* also catches a lost enqueue.
|
|
51
|
+
*
|
|
52
|
+
* Jobs (queue {@link PLUGIN_SCOPE_QUEUE}): one per item and scope version
|
|
53
|
+
* (`scope-item-<itemId>-<scope_version>`, every org), one per org (`scope-org-<orgId>`, every item,
|
|
54
|
+
* enqueued after the org is created). Both are removed when done, so the next enqueue with the same
|
|
55
|
+
* id is not swallowed. Pairs of one org are serialized across replicas by a Redis lock per org; the
|
|
56
|
+
* installer's org row lock and its one-live-install rule are the backstop.
|
|
57
|
+
*/
|
|
58
|
+
/** The scope sync queue (no `:` in the name). */
|
|
59
|
+
export const PLUGIN_SCOPE_QUEUE = "cap-kernel-plugin-scope";
|
|
60
|
+
/** The job converging one item in every org. */
|
|
61
|
+
export const SCOPE_ITEM_JOB = "scope-item";
|
|
62
|
+
/** The job converging every item in one org. */
|
|
63
|
+
export const SCOPE_ORG_JOB = "scope-org";
|
|
64
|
+
/** One item job per scope version (no `:`: item ids are UUIDs). */
|
|
65
|
+
export const scopeItemJobId = (itemId, version) => `scope-item-${itemId}-${version}`;
|
|
66
|
+
/** One org job at a time per org. */
|
|
67
|
+
export const scopeOrgJobId = (orgId) => `scope-org-${orgId}`;
|
|
68
|
+
/**
|
|
69
|
+
* The delayed retry `n` of an item job whose extension this replica had not loaded yet (ruling
|
|
70
|
+
* P3-38); deterministic, so replicas deferring the same item add it once.
|
|
71
|
+
*/
|
|
72
|
+
export const scopeRetryJobId = (itemId, version, n) => `scope-item-${itemId}-${version}-r${n}`;
|
|
73
|
+
/** How many delayed retries an item job gets while its extension is not loaded here (P3-38). */
|
|
74
|
+
export const SCOPE_LOAD_RETRIES = 6;
|
|
75
|
+
/** The delay of each such retry. */
|
|
76
|
+
export const SCOPE_LOAD_RETRY_DELAY_MS = 5_000;
|
|
77
|
+
/** How long a pair waits for this replica's reconcile before deferring (P3-38). */
|
|
78
|
+
export const SCOPE_RECONCILE_WAIT_MS = 10_000;
|
|
79
|
+
/**
|
|
80
|
+
* Awaits this replica's extension reconcile for at most `ms` (a slower one carries on in the
|
|
81
|
+
* background); a failure only warns.
|
|
82
|
+
*/
|
|
83
|
+
export async function reconcileWithin(lifecycle, reason, ms, log) {
|
|
84
|
+
let timer;
|
|
85
|
+
try {
|
|
86
|
+
await Promise.race([
|
|
87
|
+
lifecycle.reconcile(reason),
|
|
88
|
+
new Promise((resolve) => {
|
|
89
|
+
timer = setTimeout(resolve, ms);
|
|
90
|
+
}),
|
|
91
|
+
]);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
log.warn("reconciling extensions on this replica failed", { reason, err });
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
if (timer !== undefined)
|
|
98
|
+
clearTimeout(timer);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** The item job of a scope version (what {@link PluginScopeSync.enqueueItem} adds). */
|
|
102
|
+
export function scopeItemJob(itemId, version) {
|
|
103
|
+
return {
|
|
104
|
+
name: SCOPE_ITEM_JOB,
|
|
105
|
+
data: { kind: "item", itemId },
|
|
106
|
+
opts: {
|
|
107
|
+
jobId: scopeItemJobId(itemId, version),
|
|
108
|
+
attempts: 1,
|
|
109
|
+
removeOnComplete: true,
|
|
110
|
+
removeOnFail: true,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/** How long one org's pairs wait for each other (an install can take a while). */
|
|
115
|
+
const ORG_LOCK_TTL_MS = 60_000;
|
|
116
|
+
const ORG_LOCK_WAIT_MS = 10 * 60_000;
|
|
117
|
+
/** The worker's concurrency. */
|
|
118
|
+
export const PLUGIN_SCOPE_CONCURRENCY = 2;
|
|
119
|
+
const LIVE = ["installing", "installed", "upgrading"];
|
|
120
|
+
let PluginScopeSync = class PluginScopeSync {
|
|
121
|
+
kdb;
|
|
122
|
+
queue;
|
|
123
|
+
installer;
|
|
124
|
+
registry;
|
|
125
|
+
lifecycle;
|
|
126
|
+
locks;
|
|
127
|
+
log;
|
|
128
|
+
txHost;
|
|
129
|
+
constructor(kdb, queue, installer, registry,
|
|
130
|
+
/** This replica's reconcile, awaited (bounded) before deferring an install (P3-38). */
|
|
131
|
+
lifecycle, locks, log, txHost) {
|
|
132
|
+
this.kdb = kdb;
|
|
133
|
+
this.queue = queue;
|
|
134
|
+
this.installer = installer;
|
|
135
|
+
this.registry = registry;
|
|
136
|
+
this.lifecycle = lifecycle;
|
|
137
|
+
this.locks = locks;
|
|
138
|
+
this.log = log;
|
|
139
|
+
this.txHost = txHost;
|
|
140
|
+
}
|
|
141
|
+
get db() {
|
|
142
|
+
return this.kdb.db;
|
|
143
|
+
}
|
|
144
|
+
/** Enqueues the sync of an item in every org, once per scope version. Call after the commit. */
|
|
145
|
+
async enqueueItem(itemId) {
|
|
146
|
+
const row = await this.db
|
|
147
|
+
.selectFrom("catalog_items")
|
|
148
|
+
.select("scope_version")
|
|
149
|
+
.where("id", "=", itemId)
|
|
150
|
+
.executeTakeFirst();
|
|
151
|
+
if (!row)
|
|
152
|
+
return;
|
|
153
|
+
const job = scopeItemJob(itemId, row.scope_version);
|
|
154
|
+
await this.queue.add(job.name, job.data, job.opts);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Enqueues the sync of every live, not builtin item (a worker start): retries what failed or was
|
|
158
|
+
* never enqueued (a lost `afterCommit` enqueue, a migrated scope). The job ids are the items'
|
|
159
|
+
* scope versions, so replicas starting together add each one once.
|
|
160
|
+
*/
|
|
161
|
+
async enqueueAll() {
|
|
162
|
+
const items = await this.db
|
|
163
|
+
.selectFrom("catalog_items")
|
|
164
|
+
.select("id")
|
|
165
|
+
.where("deleted_at", "is", null)
|
|
166
|
+
.where("builtin", "=", false)
|
|
167
|
+
.orderBy("id")
|
|
168
|
+
.execute();
|
|
169
|
+
for (const i of items)
|
|
170
|
+
await this.enqueueItem(i.id);
|
|
171
|
+
}
|
|
172
|
+
/** Enqueues the sync of every item in an org (a new org). Call after the commit. */
|
|
173
|
+
async enqueueOrg(orgId) {
|
|
174
|
+
await this.queue.add(SCOPE_ORG_JOB, { kind: "org", orgId }, { jobId: scopeOrgJobId(orgId), attempts: 1, removeOnComplete: true, removeOnFail: true });
|
|
175
|
+
}
|
|
176
|
+
/** One job: every org of an item, or every item of an org; `signal` stops between pairs. */
|
|
177
|
+
async process(data, signal) {
|
|
178
|
+
const pairs = data.kind === "item"
|
|
179
|
+
? (await this.db
|
|
180
|
+
.selectFrom("orgs")
|
|
181
|
+
.select("id")
|
|
182
|
+
.where("deleted_at", "is", null)
|
|
183
|
+
.orderBy("id")
|
|
184
|
+
.execute()).map((o) => [data.itemId, o.id])
|
|
185
|
+
: (await this.db
|
|
186
|
+
.selectFrom("catalog_items")
|
|
187
|
+
.select("id")
|
|
188
|
+
.where("deleted_at", "is", null)
|
|
189
|
+
.where("builtin", "=", false)
|
|
190
|
+
.orderBy("id")
|
|
191
|
+
.execute()).map((i) => [i.id, data.orgId]);
|
|
192
|
+
const retry = data.kind === "item" ? (data.retry ?? 0) : 0;
|
|
193
|
+
const finalTry = data.kind === "item" && retry >= SCOPE_LOAD_RETRIES;
|
|
194
|
+
const deferred = new Set();
|
|
195
|
+
for (const [itemId, orgId] of pairs) {
|
|
196
|
+
if (signal?.aborted)
|
|
197
|
+
return;
|
|
198
|
+
try {
|
|
199
|
+
const r = await this.syncPair(itemId, orgId, signal, { finalTry });
|
|
200
|
+
if (r === "deferred")
|
|
201
|
+
deferred.add(itemId);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
this.log.warn("plugin scope sync of a pair failed", { itemId, orgId, err });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// An extension this replica had not loaded yet: the item again after a delay (P3-38)
|
|
208
|
+
for (const itemId of deferred) {
|
|
209
|
+
try {
|
|
210
|
+
await this.enqueueRetry(itemId, retry + 1);
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
this.log.warn("enqueueing a delayed plugin scope sync failed", { itemId, err });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** The delayed retry `n` of an item job (deterministic id, P3-38). */
|
|
218
|
+
async enqueueRetry(itemId, n) {
|
|
219
|
+
const row = await this.db
|
|
220
|
+
.selectFrom("catalog_items")
|
|
221
|
+
.select("scope_version")
|
|
222
|
+
.where("id", "=", itemId)
|
|
223
|
+
.executeTakeFirst();
|
|
224
|
+
if (!row)
|
|
225
|
+
return;
|
|
226
|
+
await this.queue.add(SCOPE_ITEM_JOB, { kind: "item", itemId, retry: n }, {
|
|
227
|
+
jobId: scopeRetryJobId(itemId, row.scope_version, n),
|
|
228
|
+
delay: SCOPE_LOAD_RETRY_DELAY_MS,
|
|
229
|
+
attempts: 1,
|
|
230
|
+
removeOnComplete: true,
|
|
231
|
+
removeOnFail: true,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Whether the install of the item's `version` may go ahead on this replica (P3-38): its
|
|
236
|
+
* extension is loaded here, or it is not enabled on the deployment (the install reports
|
|
237
|
+
* `catalog.not_deployed` as before). Enabled but not loaded here: this replica's reconcile is
|
|
238
|
+
* awaited (bounded); still not loaded -> false, unless this is the last try.
|
|
239
|
+
*/
|
|
240
|
+
async extensionReady(itemId, version, finalTry) {
|
|
241
|
+
const v = await this.db
|
|
242
|
+
.selectFrom("catalog_item_versions")
|
|
243
|
+
.select("manifest")
|
|
244
|
+
.where("item_id", "=", itemId)
|
|
245
|
+
.where("version", "=", version)
|
|
246
|
+
.executeTakeFirst();
|
|
247
|
+
const m = v?.manifest;
|
|
248
|
+
if (!m?.extension)
|
|
249
|
+
return true;
|
|
250
|
+
const loaded = () => this.registry.manifests().some((x) => x.name === m.name);
|
|
251
|
+
if (loaded())
|
|
252
|
+
return true;
|
|
253
|
+
const install = await this.db
|
|
254
|
+
.selectFrom("extension_installs")
|
|
255
|
+
.select("desired_state")
|
|
256
|
+
.where("name", "=", m.name)
|
|
257
|
+
.executeTakeFirst();
|
|
258
|
+
if (install?.desired_state !== "enabled")
|
|
259
|
+
return true;
|
|
260
|
+
await reconcileWithin(this.lifecycle, `scope-sync:${m.name}`, SCOPE_RECONCILE_WAIT_MS, this.log);
|
|
261
|
+
return loaded() || finalTry;
|
|
262
|
+
}
|
|
263
|
+
/** Converges one (item, org), under the org's sync lock; `signal` ends the wait for it. */
|
|
264
|
+
syncPair(itemId, orgId, signal, opts = {}) {
|
|
265
|
+
return this.locks.run(`plugin-scope-org-${orgId}`, {
|
|
266
|
+
ttlMs: ORG_LOCK_TTL_MS,
|
|
267
|
+
waitMs: ORG_LOCK_WAIT_MS,
|
|
268
|
+
...(signal !== undefined && { signal }),
|
|
269
|
+
}, () => this.syncRecorded(itemId, orgId, opts.finalTry === true));
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* {@link syncLocked} plus the pair's open failure (`plugin_scope_sync_failures`, the super
|
|
273
|
+
* admin's inbox): an attempt that failed records it, any other attempt clears it. An attempt
|
|
274
|
+
* that throws (outside the recorded steps) leaves the row as it was.
|
|
275
|
+
*/
|
|
276
|
+
async syncRecorded(itemId, orgId, finalTry = false) {
|
|
277
|
+
const attempt = { failed: false, finalTry };
|
|
278
|
+
const result = await this.syncLocked(itemId, orgId, attempt);
|
|
279
|
+
// a deferred pair changed nothing: an older failure stays open
|
|
280
|
+
if (!attempt.failed && result !== "deferred") {
|
|
281
|
+
await this.db
|
|
282
|
+
.deleteFrom("plugin_scope_sync_failures")
|
|
283
|
+
.where("item_id", "=", itemId)
|
|
284
|
+
.where("org_id", "=", orgId)
|
|
285
|
+
.execute();
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
async syncLocked(itemId, orgId, attempt) {
|
|
290
|
+
const item = await this.db
|
|
291
|
+
.selectFrom("catalog_items")
|
|
292
|
+
.select([
|
|
293
|
+
"id",
|
|
294
|
+
"scope",
|
|
295
|
+
"builtin",
|
|
296
|
+
"disabled",
|
|
297
|
+
"deleted_at",
|
|
298
|
+
"awaiting_confirmation",
|
|
299
|
+
"latest_version",
|
|
300
|
+
"platform_synced_version",
|
|
301
|
+
])
|
|
302
|
+
.where("id", "=", itemId)
|
|
303
|
+
.where("deleted_at", "is", null)
|
|
304
|
+
.executeTakeFirst();
|
|
305
|
+
const org = await this.db
|
|
306
|
+
.selectFrom("orgs")
|
|
307
|
+
.select("id")
|
|
308
|
+
.where("id", "=", orgId)
|
|
309
|
+
.where("deleted_at", "is", null)
|
|
310
|
+
.executeTakeFirst();
|
|
311
|
+
if (!item || !org || item.builtin)
|
|
312
|
+
return "unchanged";
|
|
313
|
+
const [listed, sw, live] = await Promise.all([
|
|
314
|
+
this.db
|
|
315
|
+
.selectFrom("catalog_item_scope_orgs")
|
|
316
|
+
.select("item_id")
|
|
317
|
+
.where("item_id", "=", itemId)
|
|
318
|
+
.where("org_id", "=", orgId)
|
|
319
|
+
.executeTakeFirst(),
|
|
320
|
+
this.db
|
|
321
|
+
.selectFrom("catalog_item_org_switches")
|
|
322
|
+
.select("enabled")
|
|
323
|
+
.where("item_id", "=", itemId)
|
|
324
|
+
.where("org_id", "=", orgId)
|
|
325
|
+
.executeTakeFirst(),
|
|
326
|
+
this.db
|
|
327
|
+
.selectFrom("plugin_installs")
|
|
328
|
+
.select(["id", "status"])
|
|
329
|
+
.where("org_id", "=", orgId)
|
|
330
|
+
.where("item_id", "=", itemId)
|
|
331
|
+
.where("status", "in", [...LIVE])
|
|
332
|
+
.executeTakeFirst(),
|
|
333
|
+
]);
|
|
334
|
+
const wanted = wantedOn(item, listed !== undefined, sw?.enabled ?? null) ||
|
|
335
|
+
(live !== undefined && (await this.dependedOn(orgId, live.id)));
|
|
336
|
+
if (wanted) {
|
|
337
|
+
if (live) {
|
|
338
|
+
// A platform update may have added dependencies: installed here (rule 9, Task 7)
|
|
339
|
+
if (live.status === "installed") {
|
|
340
|
+
try {
|
|
341
|
+
await this.installer.addMissingDependencies(orgId, live.id);
|
|
342
|
+
}
|
|
343
|
+
catch (e) {
|
|
344
|
+
await this.failed(orgId, itemId, "dependencies", e, attempt);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return "unchanged";
|
|
348
|
+
}
|
|
349
|
+
// Never installed while not usable: an org upload still waiting for the super admin
|
|
350
|
+
// (ruling P3-9) has nothing confirmed to install
|
|
351
|
+
if (!isUsable(item))
|
|
352
|
+
return "unchanged";
|
|
353
|
+
// The platform's version (one per deployment, Task 7); the latest import before the first sync
|
|
354
|
+
const version = item.platform_synced_version ?? item.latest_version;
|
|
355
|
+
try {
|
|
356
|
+
if (!(await this.extensionReady(itemId, version, attempt.finalTry)))
|
|
357
|
+
return "deferred";
|
|
358
|
+
if (await this.needsInput(orgId, itemId, version))
|
|
359
|
+
return "needs_config";
|
|
360
|
+
await this.installer.install(orgId, null, itemId, version, {}, { via: "scope" });
|
|
361
|
+
return "installed";
|
|
362
|
+
}
|
|
363
|
+
catch (e) {
|
|
364
|
+
// A person switched it off (or the scope changed) after this decision: the installer's
|
|
365
|
+
// re-check under the org row lock refused it, nothing written
|
|
366
|
+
if (e instanceof ScopeNoLongerWanted)
|
|
367
|
+
return "unchanged";
|
|
368
|
+
// Another install of this item got there first (a person, or a dependency): converged
|
|
369
|
+
if (e instanceof ApiError &&
|
|
370
|
+
(e.code === "plugin.already_installed" || e.code === "plugin.install_in_progress")) {
|
|
371
|
+
return "unchanged";
|
|
372
|
+
}
|
|
373
|
+
await this.failed(orgId, itemId, "install", e, attempt);
|
|
374
|
+
return "unchanged";
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Wanted off: only a settled install is removed (one still installing or upgrading waits for
|
|
378
|
+
// the next enqueue)
|
|
379
|
+
if (live?.status !== "installed")
|
|
380
|
+
return "unchanged";
|
|
381
|
+
const deps = await this.createdDependencies(live.id);
|
|
382
|
+
try {
|
|
383
|
+
await this.installer.uninstall(orgId, null, live.id, { via: "scope" });
|
|
384
|
+
}
|
|
385
|
+
catch (e) {
|
|
386
|
+
// A person switched it on (or the scope changed, or another install came to depend on it)
|
|
387
|
+
// after this decision: the installer's re-check under the org row lock refused it
|
|
388
|
+
if (e instanceof ScopeStillWanted)
|
|
389
|
+
return "unchanged";
|
|
390
|
+
await this.failed(orgId, itemId, "uninstall", e, attempt);
|
|
391
|
+
return "unchanged";
|
|
392
|
+
}
|
|
393
|
+
// Dependency installs it took along may be wanted on by their own scope: synced again
|
|
394
|
+
for (const dep of deps) {
|
|
395
|
+
if (dep !== itemId)
|
|
396
|
+
await this.syncRecorded(dep, orgId);
|
|
397
|
+
}
|
|
398
|
+
return "removed";
|
|
399
|
+
}
|
|
400
|
+
/** Whether a live install of the org depends on this install (spec §5 rule 9). */
|
|
401
|
+
async dependedOn(orgId, installId) {
|
|
402
|
+
const row = await this.db
|
|
403
|
+
.selectFrom("plugin_install_components as c")
|
|
404
|
+
.innerJoin("plugin_installs as a", "a.id", "c.install_id")
|
|
405
|
+
.select("a.id")
|
|
406
|
+
.where("a.org_id", "=", orgId)
|
|
407
|
+
.where("a.status", "in", [...LIVE])
|
|
408
|
+
.where("c.kind", "=", "plugin")
|
|
409
|
+
.where("c.ref", "=", installId)
|
|
410
|
+
.executeTakeFirst();
|
|
411
|
+
return row !== undefined;
|
|
412
|
+
}
|
|
413
|
+
/** The items of the dependency installs this install created. */
|
|
414
|
+
async createdDependencies(installId) {
|
|
415
|
+
// `ref` is text: the child install ids are read first, then their items
|
|
416
|
+
const refs = await this.db
|
|
417
|
+
.selectFrom("plugin_install_components")
|
|
418
|
+
.select("ref")
|
|
419
|
+
.where("install_id", "=", installId)
|
|
420
|
+
.where("kind", "=", "plugin")
|
|
421
|
+
.where("created", "=", true)
|
|
422
|
+
.execute();
|
|
423
|
+
if (refs.length === 0)
|
|
424
|
+
return [];
|
|
425
|
+
const rows = await this.db
|
|
426
|
+
.selectFrom("plugin_installs")
|
|
427
|
+
.select("item_id")
|
|
428
|
+
.where("id", "in", refs.map((r) => r.ref))
|
|
429
|
+
.execute();
|
|
430
|
+
return rows.map((r) => r.item_id);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Whether installing the item (with the dependencies the org lacks) needs the org's input: a
|
|
434
|
+
* connector template, or an extension whose org config is required and not set in the org. The
|
|
435
|
+
* same rule as the org catalog's `needs_config`, applied to the whole tree.
|
|
436
|
+
*/
|
|
437
|
+
async needsInput(orgId, itemId, version) {
|
|
438
|
+
const v = await this.db
|
|
439
|
+
.selectFrom("catalog_item_versions")
|
|
440
|
+
.select("manifest")
|
|
441
|
+
.where("item_id", "=", itemId)
|
|
442
|
+
.where("version", "=", version)
|
|
443
|
+
.executeTakeFirst();
|
|
444
|
+
const root = v?.manifest;
|
|
445
|
+
if (root === undefined)
|
|
446
|
+
return false;
|
|
447
|
+
if (await this.manifestNeedsInput(orgId, root, itemId))
|
|
448
|
+
return true;
|
|
449
|
+
// the dependencies the install would bring (planning reads no input of the org)
|
|
450
|
+
const plan = await this.installer.plan(orgId, null, itemId, version, null, "", undefined);
|
|
451
|
+
const visit = async (p) => {
|
|
452
|
+
if (await this.manifestNeedsInput(orgId, p.manifest, p.itemId))
|
|
453
|
+
return true;
|
|
454
|
+
for (const d of p.dependencies)
|
|
455
|
+
if (d.plan && (await visit(d.plan)))
|
|
456
|
+
return true;
|
|
457
|
+
return false;
|
|
458
|
+
};
|
|
459
|
+
return visit(plan);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Whether installing plugin `itemId` (manifest `m`) needs the org's input: a connector template
|
|
463
|
+
* on in the org (ruling P2-6: templates switched off there, outside their own scope or disabled
|
|
464
|
+
* make no connector), or a required org config of its extension not set yet.
|
|
465
|
+
*/
|
|
466
|
+
async manifestNeedsInput(orgId, m, itemId) {
|
|
467
|
+
const ids = (m.connectorTemplates ?? []).map((t) => templateIdOfPath(t.path));
|
|
468
|
+
if ((await connectorTemplatesOn(this.db, orgId, itemId, ids)).size > 0)
|
|
469
|
+
return true;
|
|
470
|
+
if (!m.extension)
|
|
471
|
+
return false;
|
|
472
|
+
const ext = this.registry.manifests().find((x) => x.name === m.name);
|
|
473
|
+
const schema = ext?.config?.org;
|
|
474
|
+
if (schema === undefined || schema.safeParse({}).success)
|
|
475
|
+
return false;
|
|
476
|
+
const configured = await this.db
|
|
477
|
+
.selectFrom("extension_org_configs")
|
|
478
|
+
.select("plugin")
|
|
479
|
+
.where("org_id", "=", orgId)
|
|
480
|
+
.where("plugin", "=", m.name)
|
|
481
|
+
.where("config", "is not", null)
|
|
482
|
+
.executeTakeFirst();
|
|
483
|
+
return configured === undefined;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Logs and audits a failed install or uninstall (`plugin.scope_sync_failed`, actor null) and
|
|
487
|
+
* records it as the pair's open failure (the super admin's inbox).
|
|
488
|
+
*/
|
|
489
|
+
async failed(orgId, itemId, op, e, attempt) {
|
|
490
|
+
attempt.failed = true;
|
|
491
|
+
const code = e instanceof ApiError ? e.code : "internal";
|
|
492
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
493
|
+
this.log.warn("plugin scope sync failed", { orgId, itemId, op, code, err: e });
|
|
494
|
+
await this.recordFailure(orgId, itemId, op, code, message);
|
|
495
|
+
}
|
|
496
|
+
async recordFailure(orgId, itemId, op, code, message) {
|
|
497
|
+
await audit(this.db, {
|
|
498
|
+
actorAccountId: null,
|
|
499
|
+
orgId,
|
|
500
|
+
action: "plugin.scope_sync_failed",
|
|
501
|
+
target: itemId,
|
|
502
|
+
detail: { via: "scope", op, code, message },
|
|
503
|
+
});
|
|
504
|
+
const failure = { op, code, message, failed_at: new Date() };
|
|
505
|
+
await this.db
|
|
506
|
+
.insertInto("plugin_scope_sync_failures")
|
|
507
|
+
.values({ item_id: itemId, org_id: orgId, ...failure })
|
|
508
|
+
.onConflict((oc) => oc.columns(["item_id", "org_id"]).doUpdateSet(failure))
|
|
509
|
+
.execute();
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
__decorate([
|
|
513
|
+
Transactional({ propagation: "requires_new" })
|
|
514
|
+
], PluginScopeSync.prototype, "recordFailure", null);
|
|
515
|
+
PluginScopeSync = __decorate([
|
|
516
|
+
Injectable(),
|
|
517
|
+
__param(0, Inject(KernelDb)),
|
|
518
|
+
__param(1, Inject(getQueueToken(PLUGIN_SCOPE_QUEUE))),
|
|
519
|
+
__param(2, Inject(PluginInstaller)),
|
|
520
|
+
__param(3, Inject(ExtensionRegistry)),
|
|
521
|
+
__param(4, Inject(ExtensionLifecycle)),
|
|
522
|
+
__param(5, Inject(LockService)),
|
|
523
|
+
__param(6, Inject(KERNEL_LOGGER)),
|
|
524
|
+
__param(7, Inject(TransactionHost))
|
|
525
|
+
], PluginScopeSync);
|
|
526
|
+
export { PluginScopeSync };
|
|
527
|
+
/** The consumer of {@link PLUGIN_SCOPE_QUEUE}: {@link PluginScopeSync}. */
|
|
528
|
+
let PluginScopeSyncProcessor = class PluginScopeSyncProcessor extends WorkerHost {
|
|
529
|
+
sync;
|
|
530
|
+
log;
|
|
531
|
+
stopping = new AbortController();
|
|
532
|
+
constructor(sync, log) {
|
|
533
|
+
super();
|
|
534
|
+
this.sync = sync;
|
|
535
|
+
this.log = log;
|
|
536
|
+
}
|
|
537
|
+
process(job) {
|
|
538
|
+
return runJob(PLUGIN_SCOPE_QUEUE, job, () => this.sync.process(job.data, this.stopping.signal));
|
|
539
|
+
}
|
|
540
|
+
/** Starts consuming (worker role, after the extensions loaded; built with `autorun: false`). */
|
|
541
|
+
start() {
|
|
542
|
+
void this.worker.run().catch((err) => this.error(err));
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Enqueues every live item's sync once (the worker role, after the start gate opened), in the
|
|
546
|
+
* background; a failure is only logged (the next worker start, or the next change, enqueues).
|
|
547
|
+
*/
|
|
548
|
+
resync() {
|
|
549
|
+
void this.sync
|
|
550
|
+
.enqueueAll()
|
|
551
|
+
.catch((err) => this.log.error("plugin scope resync failed", { err }));
|
|
552
|
+
}
|
|
553
|
+
/** Stops between pairs and closes the worker. */
|
|
554
|
+
async close() {
|
|
555
|
+
this.stopping.abort();
|
|
556
|
+
await this.worker.close();
|
|
557
|
+
}
|
|
558
|
+
failed(job, err) {
|
|
559
|
+
this.log.error("plugin scope job failed", { name: job?.name, jobId: job?.id, err });
|
|
560
|
+
}
|
|
561
|
+
error(err) {
|
|
562
|
+
this.log.error("plugin scope worker error", { err });
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
__decorate([
|
|
566
|
+
OnWorkerEvent("failed")
|
|
567
|
+
], PluginScopeSyncProcessor.prototype, "failed", null);
|
|
568
|
+
__decorate([
|
|
569
|
+
OnWorkerEvent("error")
|
|
570
|
+
], PluginScopeSyncProcessor.prototype, "error", null);
|
|
571
|
+
PluginScopeSyncProcessor = __decorate([
|
|
572
|
+
Injectable(),
|
|
573
|
+
__param(0, Inject(PluginScopeSync)),
|
|
574
|
+
__param(1, Inject(KERNEL_LOGGER))
|
|
575
|
+
], PluginScopeSyncProcessor);
|
|
576
|
+
export { PluginScopeSyncProcessor };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Who a platform plugin is offered to: every org, an opt-in set, or the listed orgs. */
|
|
2
|
+
export type PluginScope = "all" | "optional" | "named";
|
|
3
|
+
/**
|
|
4
|
+
* The effective state of a plugin in one org. `not_offered`: a `named` item that does not list the
|
|
5
|
+
* org but is shown to other orgs, which may request access (spec §5.1). `awaiting_confirmation`:
|
|
6
|
+
* the org's own upload with an extension, until the super admin confirms it (ruling P3-9).
|
|
7
|
+
*/
|
|
8
|
+
export type OrgPluginState = "on" | "off" | "needs_config" | "unavailable" | "not_offered"
|
|
9
|
+
/** The org's own upload, waiting for the super admin's confirmation (owner only, P3-9). */
|
|
10
|
+
| "awaiting_confirmation";
|
|
11
|
+
/**
|
|
12
|
+
* Whether the item should be on in the org. Builtin is on unless disabled and its switch is
|
|
13
|
+
* ignored. Otherwise `all` is on unless disabled or the org switched it off (layering spec §4),
|
|
14
|
+
* `optional` is on only with an explicit `true` switch, and `named` is on for a listed org unless
|
|
15
|
+
* its switch is `false`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function wantedOn(item: {
|
|
18
|
+
scope: PluginScope;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
builtin: boolean;
|
|
21
|
+
}, inList: boolean, sw: boolean | null): boolean;
|
|
22
|
+
/** Whether the org may see the item at all: a named item only for the orgs on its list. */
|
|
23
|
+
export declare function visibleTo(item: {
|
|
24
|
+
scope: PluginScope;
|
|
25
|
+
}, inList: boolean): boolean;
|
|
26
|
+
/** Whether the org admin may switch the item: every item but a builtin one (layering spec §4). */
|
|
27
|
+
export declare function switchable(item: {
|
|
28
|
+
scope: PluginScope;
|
|
29
|
+
builtin: boolean;
|
|
30
|
+
}): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Whether an org outside a `named` item's list sees it as requestable: shown to other orgs, not
|
|
33
|
+
* builtin (a builtin item is `all`) and through the share gate (ruling P3-16: an org-owned item its
|
|
34
|
+
* owner has not made shareable stays hidden, whatever its stored `shown_to_others`).
|
|
35
|
+
*/
|
|
36
|
+
export declare function requestable(item: {
|
|
37
|
+
scope: PluginScope;
|
|
38
|
+
builtin: boolean;
|
|
39
|
+
shown_to_others: boolean;
|
|
40
|
+
owner_org_id: string | null;
|
|
41
|
+
shareable: boolean;
|
|
42
|
+
}, inList: boolean): boolean;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin scope rules (plugin and component management spec §5). Pure functions only: the
|
|
3
|
+
* caller reads the item's scope, disabled and builtin flags, the org's list membership and its
|
|
4
|
+
* explicit switch, and these functions decide the effective state.
|
|
5
|
+
*/
|
|
6
|
+
import { shareGate } from "./ownership.js";
|
|
7
|
+
/**
|
|
8
|
+
* Whether the item should be on in the org. Builtin is on unless disabled and its switch is
|
|
9
|
+
* ignored. Otherwise `all` is on unless disabled or the org switched it off (layering spec §4),
|
|
10
|
+
* `optional` is on only with an explicit `true` switch, and `named` is on for a listed org unless
|
|
11
|
+
* its switch is `false`.
|
|
12
|
+
*/
|
|
13
|
+
export function wantedOn(item, inList, sw) {
|
|
14
|
+
if (item.disabled)
|
|
15
|
+
return false;
|
|
16
|
+
if (item.builtin)
|
|
17
|
+
return true;
|
|
18
|
+
switch (item.scope) {
|
|
19
|
+
case "all":
|
|
20
|
+
return sw !== false;
|
|
21
|
+
case "optional":
|
|
22
|
+
return sw === true;
|
|
23
|
+
case "named":
|
|
24
|
+
return inList && sw !== false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Whether the org may see the item at all: a named item only for the orgs on its list. */
|
|
28
|
+
export function visibleTo(item, inList) {
|
|
29
|
+
return item.scope !== "named" || inList;
|
|
30
|
+
}
|
|
31
|
+
/** Whether the org admin may switch the item: every item but a builtin one (layering spec §4). */
|
|
32
|
+
export function switchable(item) {
|
|
33
|
+
return !item.builtin;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Whether an org outside a `named` item's list sees it as requestable: shown to other orgs, not
|
|
37
|
+
* builtin (a builtin item is `all`) and through the share gate (ruling P3-16: an org-owned item its
|
|
38
|
+
* owner has not made shareable stays hidden, whatever its stored `shown_to_others`).
|
|
39
|
+
*/
|
|
40
|
+
export function requestable(item, inList) {
|
|
41
|
+
return (!item.builtin && item.scope === "named" && !inList && item.shown_to_others && shareGate(item));
|
|
42
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
2
|
+
import { type ComponentRow } from "./component-state.js";
|
|
3
|
+
import type { PluginScope } from "./scope.js";
|
|
4
|
+
/**
|
|
5
|
+
* Narrows an org-owned plugin (row locked by the caller) whose scope is `optional` / `all` to
|
|
6
|
+
* `named` = owner + the live orgs with a live install or a switch on. Bumps `scope_version` and
|
|
7
|
+
* audits `catalog.scope_changed`; returns whether the scope changed (the caller enqueues the item's
|
|
8
|
+
* scope sync after the commit).
|
|
9
|
+
*/
|
|
10
|
+
export declare function narrowItemOnUnshare(db: KernelSchemaDb, actor: string | null, item: {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
scope: PluginScope;
|
|
14
|
+
owner_org_id: string | null;
|
|
15
|
+
}): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Narrows an org-owned component with its own `optional` / `all` scope (row locked by the caller)
|
|
18
|
+
* to `named` = owner + the live orgs where it is on now ({@link componentOn}). A component that
|
|
19
|
+
* follows its plugin is narrowed with the plugin. Bumps `scope_version`, audits
|
|
20
|
+
* `component.scope_changed`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function narrowComponentOnUnshare(db: KernelSchemaDb, actor: string | null, c: ComponentRow): Promise<boolean>;
|