@capybara-hq/kernel 0.1.0-rc.4 → 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 +39 -13
- package/dist/admin/admin.controller.js +33 -17
- package/dist/admin/extensions.controller.d.ts +16 -2
- package/dist/admin/extensions.controller.js +26 -6
- 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 +16 -0
- package/dist/agents/agent-lookup.js +11 -0
- package/dist/agents/agents.controller.d.ts +76 -1
- package/dist/agents/agents.controller.js +90 -11
- package/dist/agents/agents.module.d.ts +4 -1
- package/dist/agents/agents.module.js +32 -6
- package/dist/agents/agents.service.d.ts +51 -22
- package/dist/agents/agents.service.js +172 -70
- package/dist/agents/definition.d.ts +49 -0
- package/dist/agents/definition.js +45 -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/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/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 +475 -52
- package/dist/background/background.module.js +8 -1
- package/dist/background/finish.d.ts +3 -2
- package/dist/background/launch-lock.d.ts +4 -3
- package/dist/background/launch-lock.js +4 -3
- package/dist/background/poll.job.d.ts +9 -6
- package/dist/background/poll.job.js +30 -22
- package/dist/background/session.d.ts +13 -2
- package/dist/background/session.js +13 -0
- package/dist/background/stop.d.ts +12 -6
- package/dist/background/stop.js +57 -39
- package/dist/background/store.d.ts +18 -6
- package/dist/background/store.js +12 -6
- package/dist/background/tasks.service.d.ts +15 -5
- package/dist/background/tasks.service.js +42 -17
- package/dist/background/wake-rules.d.ts +27 -18
- package/dist/background/wake-rules.js +52 -22
- package/dist/background/wake.d.ts +13 -11
- package/dist/background/wake.js +20 -14
- 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/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 +622 -82
- 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 +1147 -1136
- 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 +20 -2
- package/dist/channels/channels.module.js +2 -0
- 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/config/docs.js +3 -1
- package/dist/config/schema.d.ts +6 -2
- package/dist/config/schema.js +46 -22
- package/dist/conversations/access.d.ts +6 -4
- package/dist/conversations/access.js +27 -5
- package/dist/conversations/agent-tree.d.ts +46 -0
- package/dist/conversations/agent-tree.js +92 -0
- package/dist/conversations/conversations.controller.d.ts +43 -18
- package/dist/conversations/conversations.controller.js +79 -38
- package/dist/conversations/conversations.module.d.ts +1 -1
- package/dist/conversations/conversations.module.js +7 -7
- package/dist/conversations/conversations.service.d.ts +69 -12
- package/dist/conversations/conversations.service.js +106 -27
- package/dist/conversations/environment-status.d.ts +24 -0
- package/dist/conversations/environment-status.js +71 -0
- package/dist/conversations/event-log.d.ts +20 -5
- package/dist/conversations/event-log.js +60 -0
- package/dist/conversations/events.d.ts +84 -2
- package/dist/conversations/events.js +91 -17
- package/dist/conversations/queue.service.d.ts +1 -1
- package/dist/conversations/queue.service.js +5 -0
- package/dist/conversations/titles.d.ts +5 -3
- package/dist/conversations/titles.js +21 -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 +362 -18
- 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 +82 -2
- package/dist/errors.js +82 -2
- package/dist/evals/reconstruct.d.ts +18 -9
- package/dist/evals/reconstruct.js +26 -7
- package/dist/evals/run-replay.d.ts +4 -2
- package/dist/evals/run-replay.js +16 -4
- package/dist/evals/step-replay.d.ts +2 -5
- package/dist/evals/step-replay.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 +65 -42
- package/dist/extensions/admin-view.d.ts +37 -10
- package/dist/extensions/admin-view.js +103 -20
- 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/deployment-config.d.ts +28 -5
- package/dist/extensions/deployment-config.js +48 -7
- package/dist/extensions/effective-config.d.ts +127 -0
- package/dist/extensions/effective-config.js +368 -0
- package/dist/extensions/extensions.module.js +8 -2
- package/dist/extensions/hooks.d.ts +37 -4
- package/dist/extensions/hooks.js +82 -16
- package/dist/extensions/host.d.ts +19 -1
- package/dist/extensions/host.js +30 -7
- package/dist/extensions/installs.d.ts +20 -8
- package/dist/extensions/installs.js +37 -15
- package/dist/extensions/org-config.d.ts +75 -6
- package/dist/extensions/org-config.js +184 -32
- 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/permission-view.d.ts +16 -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.d.ts +12 -5
- package/dist/extensions/point-defaults.js +37 -9
- 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 +23 -3
- package/dist/http/app.d.ts +11 -2
- package/dist/http/app.js +31 -5
- 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.guard.d.ts +13 -5
- package/dist/identity/auth.guard.js +26 -9
- package/dist/identity/identity.module.d.ts +1 -1
- package/dist/identity/identity.module.js +4 -4
- package/dist/identity/me.controller.js +1 -1
- package/dist/identity/principal.d.ts +3 -3
- package/dist/identity/principal.js +3 -3
- 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 +1 -1
- package/dist/index.js +1 -1
- package/dist/infra/cli/kernel-cli.module.js +9 -1
- package/dist/infra/config/kernel-config.service.js +21 -1
- 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 +11 -2
- package/dist/infra/queue/add-job-once.d.ts +14 -0
- package/dist/infra/queue/add-job-once.js +16 -0
- 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/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 +20 -9
- package/dist/models/purposes.js +17 -8
- package/dist/orgs/directory-sync.d.ts +14 -5
- package/dist/orgs/directory-sync.js +41 -17
- package/dist/orgs/offboarding.d.ts +9 -7
- package/dist/orgs/offboarding.js +28 -17
- 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 +15 -3
- package/dist/orgs/settings.service.js +6 -2
- 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 +9 -1
- package/dist/runtime/context/build.d.ts +6 -4
- package/dist/runtime/context/build.js +26 -7
- package/dist/runtime/context/claude-tools.d.ts +2 -1
- package/dist/runtime/context/claude-tools.js +5 -4
- package/dist/runtime/context/compaction.js +9 -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 +35 -17
- package/dist/runtime/loop.d.ts +32 -4
- package/dist/runtime/maintenance.d.ts +7 -4
- package/dist/runtime/maintenance.js +23 -8
- package/dist/runtime/model-call.d.ts +30 -8
- package/dist/runtime/model-call.js +69 -19
- 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 +37 -3
- package/dist/runtime/run-queue.js +188 -11
- package/dist/runtime/run-worker.d.ts +11 -5
- package/dist/runtime/run-worker.js +54 -31
- package/dist/runtime/runtime.module.js +3 -0
- package/dist/runtime/step-log.d.ts +9 -4
- package/dist/runtime/step-log.js +8 -5
- 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 +43 -29
- 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.js +17 -12
- package/dist/runtime/waits.d.ts +140 -37
- package/dist/runtime/waits.js +394 -106
- 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 +4 -3
- package/dist/sandbox/sandbox.service.d.ts +229 -134
- package/dist/sandbox/sandbox.service.js +630 -409
- 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 +23 -4
- package/dist/tools/builtin-names.d.ts +21 -5
- package/dist/tools/builtin-names.js +30 -5
- 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 +6 -2
- package/dist/tools/builtins/builtin-tools.js +37 -12
- 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.js +13 -3
- package/dist/tools/builtins/sandbox/common.d.ts +43 -24
- package/dist/tools/builtins/sandbox/common.js +80 -45
- 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 +1 -1
- package/dist/tools/builtins/sandbox/index.js +1 -1
- package/dist/tools/builtins/sandbox/read.js +1 -1
- package/dist/tools/builtins/sandbox/task-output.d.ts +14 -3
- package/dist/tools/builtins/sandbox/task-output.js +30 -5
- package/dist/tools/builtins/sandbox/task-stop.js +2 -1
- 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/extract.js +5 -1
- package/dist/tools/builtins/web/fetch.js +1 -0
- package/dist/tools/builtins/web/search.js +1 -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/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 +187 -364
- package/dist/tools/policy.d.ts +1 -1
- package/dist/tools/policy.js +36 -16
- package/dist/tools/registry.d.ts +98 -5
- package/dist/tools/registry.js +87 -9
- package/dist/tools/tools.module.js +12 -2
- package/dist/ui/views.d.ts +2 -1
- package/dist/ui/views.js +17 -3
- package/package.json +3 -3
- 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 -32
- package/dist/extensions/org-config.controller.js +0 -70
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { type PluginScope } from "../catalog/scope.js";
|
|
1
2
|
import { type Keyring } from "../ctx/secrets.js";
|
|
3
|
+
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
2
4
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
3
5
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
4
6
|
import { KernelEvents } from "../infra/events/kernel-events.js";
|
|
@@ -6,6 +8,7 @@ import type { KernelLogger } from "../log.js";
|
|
|
6
8
|
import { OrgLock } from "../orgs/org-lock.js";
|
|
7
9
|
import { type ConfigIssue, toIssues } from "./config-issues.js";
|
|
8
10
|
import { type JsonSchema } from "./config-json-schema.js";
|
|
11
|
+
import { EffectiveConfigs } from "./effective-config.js";
|
|
9
12
|
import { ExtensionHost } from "./host.js";
|
|
10
13
|
import { ExtensionInstalls } from "./installs.js";
|
|
11
14
|
import { type PermissionGroup } from "./permission-view.js";
|
|
@@ -37,7 +40,26 @@ export interface OrgExtensionView {
|
|
|
37
40
|
* disabled here (`extension.required`); its org config, when it has one, can still be set.
|
|
38
41
|
*/
|
|
39
42
|
required: boolean;
|
|
43
|
+
/** The catalog plugin the extension ships in and its scope (builtin counts as `all`); null without one. */
|
|
44
|
+
catalogItem: {
|
|
45
|
+
itemId: string;
|
|
46
|
+
scope: PluginScope;
|
|
47
|
+
} | null;
|
|
48
|
+
/** The org admin can switch it (the plugin's switch): never for an `all` / builtin plugin. */
|
|
49
|
+
switchable: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* The two-level deployment config (spec A §5.3, §5.4): `following` the platform, a `copy` of the
|
|
52
|
+
* overridable fields, or `none` (the extension has no overridable field, or is unavailable).
|
|
53
|
+
*/
|
|
54
|
+
overrideState: "following" | "copy" | "none";
|
|
55
|
+
/**
|
|
56
|
+
* The org must configure the extension before it works here (spec A §6): its effective config
|
|
57
|
+
* is not valid, or a required org-only field is missing. Always false when unavailable.
|
|
58
|
+
*/
|
|
59
|
+
needsConfig: boolean;
|
|
40
60
|
}
|
|
61
|
+
/** The extension points an extension provides, from its permission list's `provides` group. */
|
|
62
|
+
export declare function providesOf(view: Pick<OrgExtensionView, "permissions">): string[];
|
|
41
63
|
/** `put` 的输入:`config` 中的密钥字段缺省 = 保留原值、`null` = 清除、其他值 = 新值。 */
|
|
42
64
|
export interface OrgExtensionInput {
|
|
43
65
|
enabled?: boolean | undefined;
|
|
@@ -48,7 +70,7 @@ export interface OrgExtensionInput {
|
|
|
48
70
|
/** `put` 的内部选项(不来自 HTTP)。 */
|
|
49
71
|
export interface OrgExtensionPutOptions {
|
|
50
72
|
/**
|
|
51
|
-
* Enable through this
|
|
73
|
+
* Enable through this platform catalog item (the extension's own item, or an app item: plugins
|
|
52
74
|
* in an app follow the app item's policy, C22). When omitted, judged by every source item in
|
|
53
75
|
* `extension_catalog_sources` (the strictest wins); an extension not installed through the catalog
|
|
54
76
|
* is not bound by catalog policy.
|
|
@@ -69,6 +91,13 @@ export interface OrgExtensionPutOptions {
|
|
|
69
91
|
ifDisabled?: {
|
|
70
92
|
skipped: boolean;
|
|
71
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* Check the role and the config (the given `config`, or with `enabled: true` the stored one,
|
|
96
|
+
* merged with the stored secrets, against the schema) and write nothing: lets a caller that must
|
|
97
|
+
* do another write first fail without a side effect. The rules for newly enabling (catalog policy,
|
|
98
|
+
* dependencies) are left to that write: the plugin install that enables it checks them.
|
|
99
|
+
*/
|
|
100
|
+
validateOnly?: boolean;
|
|
72
101
|
}
|
|
73
102
|
/**
|
|
74
103
|
* Org-level extension config: enablement and the `config.org` config stored per org.
|
|
@@ -90,6 +119,8 @@ export declare class OrgExtensionConfigs {
|
|
|
90
119
|
private readonly events;
|
|
91
120
|
/** Secret values handled (written or decrypted) are masked in the logs after the commit. */
|
|
92
121
|
private readonly log;
|
|
122
|
+
/** The effective deployment config of each org (spec A §6): read for `needsConfig`. */
|
|
123
|
+
private readonly effective;
|
|
93
124
|
/** Test seam only: a deterministic interleaving point after the config rows are read, before the secrets. */
|
|
94
125
|
afterConfigRowRead: (() => Promise<void>) | undefined;
|
|
95
126
|
constructor(kdb: KernelDb, txHost: TransactionHost, keyring: Keyring, host: ExtensionHost,
|
|
@@ -100,7 +131,9 @@ export declare class OrgExtensionConfigs {
|
|
|
100
131
|
/** `extension.org-disabled` after a disable commits (channel connections drop at once). */
|
|
101
132
|
events: KernelEvents,
|
|
102
133
|
/** Secret values handled (written or decrypted) are masked in the logs after the commit. */
|
|
103
|
-
log: KernelLogger
|
|
134
|
+
log: KernelLogger,
|
|
135
|
+
/** The effective deployment config of each org (spec A §6): read for `needsConfig`. */
|
|
136
|
+
effective: EffectiveConfigs);
|
|
104
137
|
/** The kernel-schema handle of the current transaction. */
|
|
105
138
|
private get db();
|
|
106
139
|
/** 把一份组织配置里的密钥值登记到日志打码(无密钥时无操作);调用方须在事务提交后调用。 */
|
|
@@ -108,12 +141,34 @@ export declare class OrgExtensionConfigs {
|
|
|
108
141
|
/** After a write committed: a disabled extension's channel connections drop at once. */
|
|
109
142
|
private afterPut;
|
|
110
143
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
144
|
+
* The state of every loaded extension the org sees, in load order (no row: `enabled` false,
|
|
145
|
+
* `config` null), then the installed extensions not loaded right now (disabled on the deployment
|
|
146
|
+
* and the like) as `available: false`, sorted by name.
|
|
113
147
|
*/
|
|
114
148
|
list(orgId: string): Promise<OrgExtensionView[]>;
|
|
149
|
+
/**
|
|
150
|
+
* Fills `overrideState` and the platform half of `needsConfig` (spec A §6) for the views of
|
|
151
|
+
* extensions with overridable fields (the others always run with the platform's config, which
|
|
152
|
+
* loaded valid). Reads the org's copy rows once and the effective config of each such extension.
|
|
153
|
+
*/
|
|
154
|
+
private withLayers;
|
|
115
155
|
/** `REPEATABLE READ` read-only: the config rows and the secrets come from one snapshot. */
|
|
116
156
|
private listSnapshot;
|
|
157
|
+
/**
|
|
158
|
+
* How an `enabled` write of this extension is handled: `direct` through {@link put} (a required
|
|
159
|
+
* bootstrap plugin keeps `extension.required`; an extension without a live item is config-declared;
|
|
160
|
+
* several live items keep the direct write, the strictest source rules applying), `locked` (a live
|
|
161
|
+
* item is builtin and the write switches off: `plugin.scope_locked`), or `item` (the single plugin
|
|
162
|
+
* whose org switch it is).
|
|
163
|
+
*/
|
|
164
|
+
switchPlan(plugin: string, enabled: boolean): Promise<{
|
|
165
|
+
kind: "direct";
|
|
166
|
+
} | {
|
|
167
|
+
kind: "locked";
|
|
168
|
+
} | {
|
|
169
|
+
kind: "item";
|
|
170
|
+
itemId: string;
|
|
171
|
+
}>;
|
|
117
172
|
/**
|
|
118
173
|
* Writes enablement and / or config. The actor's role is re-read under the org row lock (needs
|
|
119
174
|
* `org.extensions.manage`).
|
|
@@ -125,8 +180,16 @@ export declare class OrgExtensionConfigs {
|
|
|
125
180
|
* - The merged full config (or, without `config`, the existing config when the result is enabled)
|
|
126
181
|
* does not satisfy the schema -> `extension.config_invalid`.
|
|
127
182
|
*/
|
|
128
|
-
put(orgId: string, plugin: string, input: OrgExtensionInput,
|
|
183
|
+
put(orgId: string, plugin: string, input: OrgExtensionInput,
|
|
184
|
+
/** null: the kernel itself (the plugin scope sync installing a plugin), no role check. */
|
|
185
|
+
actorAccountId: string | null, actorTokenId?: string, opts?: OrgExtensionPutOptions): Promise<OrgExtensionView>;
|
|
129
186
|
private write;
|
|
187
|
+
/**
|
|
188
|
+
* The rules of a write that switches: newly enabling an extension from the platform catalog
|
|
189
|
+
* re-checks the item policy and grants (C22; one already enabled is unaffected), enabling needs
|
|
190
|
+
* the dependencies enabled, disabling (without `force`) no enabled dependents.
|
|
191
|
+
*/
|
|
192
|
+
private assertSwitchRules;
|
|
130
193
|
/**
|
|
131
194
|
* 读取并解密某插件在该组织下的完整配置(供运行时按组织构造插件实例)。
|
|
132
195
|
* A required bootstrap plugin is enabled without a row (its stored config, or `{}`, is validated).
|
|
@@ -150,7 +213,7 @@ export declare class OrgExtensionConfigs {
|
|
|
150
213
|
* 在调用方事务里停用(应用安装的回滚与卸载用;调用方已锁组织行并复核角色):不检查依赖方,配置保留,
|
|
151
214
|
* 审计 `org.plugin_config.updated`(带 reason)。提交后调用方须再调 {@link afterDisable}。
|
|
152
215
|
*/
|
|
153
|
-
disableIn(orgId: string, plugin: string, actorAccountId: string, reason: string): Promise<boolean>;
|
|
216
|
+
disableIn(orgId: string, plugin: string, actorAccountId: string | null, reason: string): Promise<boolean>;
|
|
154
217
|
/** {@link disableIn} 的事务提交之后:通知停用(断开该插件的渠道连接等)。 */
|
|
155
218
|
afterDisable(orgId: string, plugin: string): Promise<void>;
|
|
156
219
|
/** 该组织已启用的插件名(只含当前已加载的插件;待批准的不算;必需的引导插件始终算启用)。 */
|
|
@@ -175,3 +238,9 @@ export declare class OrgExtensionConfigs {
|
|
|
175
238
|
/** 该组织在 `kernel` 命名空间下已设置的插件配置密钥键(不解密)。 */
|
|
176
239
|
private setSecretKeys;
|
|
177
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Whether the org sees `plugin` in its extension list (a required bootstrap plugin always; else
|
|
243
|
+
* under its catalog items' scope, as {@link OrgExtensionConfigs.list} filters). `db` may be a
|
|
244
|
+
* transaction.
|
|
245
|
+
*/
|
|
246
|
+
export declare function extensionVisibleTo(db: KernelSchemaDb, orgId: string, plugin: string): Promise<boolean>;
|
|
@@ -9,7 +9,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
9
9
|
};
|
|
10
10
|
import { EXTENSION_POINTS, parseExtensionPoint, } from "@capybara-hq/plugin-sdk";
|
|
11
11
|
import { Inject, Injectable } from "@nestjs/common";
|
|
12
|
-
import { assertItemInstallable, assertPluginSourcesInstallable, disabledPluginItems, pluginItemDisabled, } from "../catalog/
|
|
12
|
+
import { assertItemInstallable, assertPluginSourcesInstallable, disabledPluginItems, pluginItemDisabled, } from "../catalog/request-rules.js";
|
|
13
|
+
import { visibleTo } from "../catalog/scope.js";
|
|
13
14
|
import { changedPaths, configFields, getPath, secretValues } from "../config/fields.js";
|
|
14
15
|
import { createSecrets } from "../ctx/secrets.js";
|
|
15
16
|
import { ApiError } from "../errors.js";
|
|
@@ -23,14 +24,36 @@ import { KERNEL_LOGGER, KEYRING } from "../infra/tokens.js";
|
|
|
23
24
|
import { OrgLock } from "../orgs/org-lock.js";
|
|
24
25
|
import { toIssues } from "./config-issues.js";
|
|
25
26
|
import { configMessages, safeConfigFormSchema } from "./config-json-schema.js";
|
|
27
|
+
import { EffectiveConfigs } from "./effective-config.js";
|
|
26
28
|
import { enabledExtensionsQuery, requiredExtensions } from "./enabled.js";
|
|
27
29
|
import { ExtensionHost } from "./host.js";
|
|
28
30
|
import { ExtensionInstalls } from "./installs.js";
|
|
31
|
+
import { fieldLevels } from "./org-levels.js";
|
|
29
32
|
import { permissionGroups } from "./permission-view.js";
|
|
33
|
+
import { itemLocked, pluginItemsOf } from "./plugin-items.js";
|
|
30
34
|
export { toIssues };
|
|
31
35
|
/** 内核自己的 secrets 命名空间(plugin-sdk 把 `kernel` 列为保留插件名,插件不会与之相撞)。 */
|
|
32
36
|
const SECRETS_NAMESPACE = "kernel";
|
|
33
37
|
const secretKey = (plugin, path) => `plugin-config:${plugin}:${path}`;
|
|
38
|
+
/** The extension points an extension provides, from its permission list's `provides` group. */
|
|
39
|
+
export function providesOf(view) {
|
|
40
|
+
return view.permissions.filter((g) => g.category === "provides").flatMap((g) => g.items);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The scope part of an org view: the extension's primary plugin and whether the org can switch it.
|
|
44
|
+
* With several source items, a builtin one locks the extension on (scope `all`); an `all` one does
|
|
45
|
+
* not (layering spec §4).
|
|
46
|
+
*/
|
|
47
|
+
function scopeFields(items, required) {
|
|
48
|
+
const primary = items?.[0];
|
|
49
|
+
if (!primary)
|
|
50
|
+
return { catalogItem: null, switchable: !required };
|
|
51
|
+
const locked = required || items.some(itemLocked);
|
|
52
|
+
return {
|
|
53
|
+
catalogItem: { itemId: primary.id, scope: locked ? "all" : primary.scope },
|
|
54
|
+
switchable: !locked,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
34
57
|
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
35
58
|
/** 按点路径设值,缺失的中间对象自动创建;中间节点不是对象时放弃(交给 schema 校验报错)。 */
|
|
36
59
|
function setDeep(obj, path, value) {
|
|
@@ -80,6 +103,7 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
80
103
|
installs;
|
|
81
104
|
events;
|
|
82
105
|
log;
|
|
106
|
+
effective;
|
|
83
107
|
/** Test seam only: a deterministic interleaving point after the config rows are read, before the secrets. */
|
|
84
108
|
afterConfigRowRead;
|
|
85
109
|
constructor(kdb, txHost, keyring, host,
|
|
@@ -90,7 +114,9 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
90
114
|
/** `extension.org-disabled` after a disable commits (channel connections drop at once). */
|
|
91
115
|
events,
|
|
92
116
|
/** Secret values handled (written or decrypted) are masked in the logs after the commit. */
|
|
93
|
-
log
|
|
117
|
+
log,
|
|
118
|
+
/** The effective deployment config of each org (spec A §6): read for `needsConfig`. */
|
|
119
|
+
effective) {
|
|
94
120
|
this.kdb = kdb;
|
|
95
121
|
this.txHost = txHost;
|
|
96
122
|
this.keyring = keyring;
|
|
@@ -99,6 +125,7 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
99
125
|
this.installs = installs;
|
|
100
126
|
this.events = events;
|
|
101
127
|
this.log = log;
|
|
128
|
+
this.effective = effective;
|
|
102
129
|
}
|
|
103
130
|
/** The kernel-schema handle of the current transaction. */
|
|
104
131
|
get db() {
|
|
@@ -118,15 +145,38 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
118
145
|
await this.events.emit("extension.org-disabled", { orgId, plugin });
|
|
119
146
|
}
|
|
120
147
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
148
|
+
* The state of every loaded extension the org sees, in load order (no row: `enabled` false,
|
|
149
|
+
* `config` null), then the installed extensions not loaded right now (disabled on the deployment
|
|
150
|
+
* and the like) as `available: false`, sorted by name.
|
|
123
151
|
*/
|
|
124
152
|
async list(orgId) {
|
|
125
153
|
const installed = (await this.installs.list()).map((r) => ({
|
|
126
154
|
name: r.name,
|
|
127
155
|
version: r.version,
|
|
128
156
|
}));
|
|
129
|
-
return this.listSnapshot(orgId, installed);
|
|
157
|
+
return this.withLayers(orgId, await this.listSnapshot(orgId, installed));
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Fills `overrideState` and the platform half of `needsConfig` (spec A §6) for the views of
|
|
161
|
+
* extensions with overridable fields (the others always run with the platform's config, which
|
|
162
|
+
* loaded valid). Reads the org's copy rows once and the effective config of each such extension.
|
|
163
|
+
*/
|
|
164
|
+
async withLayers(orgId, views) {
|
|
165
|
+
const layered = views.filter((v) => v.overrideState !== "none");
|
|
166
|
+
if (layered.length === 0)
|
|
167
|
+
return views;
|
|
168
|
+
const copies = new Set((await this.db
|
|
169
|
+
.selectFrom("extension_org_overrides")
|
|
170
|
+
.select("plugin")
|
|
171
|
+
.where("org_id", "=", orgId)
|
|
172
|
+
.where("plugin", "in", layered.map((v) => v.plugin))
|
|
173
|
+
.execute()).map((r) => r.plugin));
|
|
174
|
+
for (const v of layered) {
|
|
175
|
+
v.overrideState = copies.has(v.plugin) ? "copy" : "following";
|
|
176
|
+
if (!(await this.effective.get(orgId, v.plugin)).ok)
|
|
177
|
+
v.needsConfig = true;
|
|
178
|
+
}
|
|
179
|
+
return views;
|
|
130
180
|
}
|
|
131
181
|
/** `REPEATABLE READ` read-only: the config rows and the secrets come from one snapshot. */
|
|
132
182
|
async listSnapshot(orgId, installed) {
|
|
@@ -141,10 +191,23 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
141
191
|
// Required bootstrap plugins are listed enabled (no org config row needed, spec §7)
|
|
142
192
|
const required = await requiredExtensions(t);
|
|
143
193
|
const loaded = this.host.manifests();
|
|
144
|
-
const
|
|
194
|
+
const items = await pluginItemsOf(t, [
|
|
195
|
+
...loaded.map((m) => m.name),
|
|
196
|
+
...installed.map((i) => i.name),
|
|
197
|
+
]);
|
|
198
|
+
// An extension whose plugin the org is not offered (a `named` plugin without it) is absent
|
|
199
|
+
const listed = new Set((await t
|
|
200
|
+
.selectFrom("catalog_item_scope_orgs")
|
|
201
|
+
.select("item_id")
|
|
202
|
+
.where("org_id", "=", orgId)
|
|
203
|
+
.execute()).map((r) => r.item_id));
|
|
204
|
+
const seen = (name) => required.has(name) || itemsVisible(items.get(name), listed);
|
|
205
|
+
const views = loaded
|
|
206
|
+
.filter((m) => seen(m.name))
|
|
207
|
+
.map((m) => this.view(m, rows.find((r) => r.plugin === m.name), setKeys, required.has(m.name), items.get(m.name)));
|
|
145
208
|
const names = new Set(loaded.map((m) => m.name));
|
|
146
209
|
const unavailable = installed
|
|
147
|
-
.filter((i) => !names.has(i.name))
|
|
210
|
+
.filter((i) => !names.has(i.name) && seen(i.name))
|
|
148
211
|
.sort((a, b) => a.name.localeCompare(b.name))
|
|
149
212
|
.map((i) => ({
|
|
150
213
|
plugin: i.name,
|
|
@@ -157,9 +220,31 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
157
220
|
orgConfigSchema: null,
|
|
158
221
|
available: false,
|
|
159
222
|
required: required.has(i.name),
|
|
223
|
+
...scopeFields(items.get(i.name), required.has(i.name)),
|
|
224
|
+
overrideState: "none",
|
|
225
|
+
needsConfig: false,
|
|
160
226
|
}));
|
|
161
227
|
return [...views, ...unavailable];
|
|
162
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* How an `enabled` write of this extension is handled: `direct` through {@link put} (a required
|
|
231
|
+
* bootstrap plugin keeps `extension.required`; an extension without a live item is config-declared;
|
|
232
|
+
* several live items keep the direct write, the strictest source rules applying), `locked` (a live
|
|
233
|
+
* item is builtin and the write switches off: `plugin.scope_locked`), or `item` (the single plugin
|
|
234
|
+
* whose org switch it is).
|
|
235
|
+
*/
|
|
236
|
+
async switchPlan(plugin, enabled) {
|
|
237
|
+
const t = this.db;
|
|
238
|
+
if ((await requiredExtensions(t)).has(plugin))
|
|
239
|
+
return { kind: "direct" };
|
|
240
|
+
const items = (await pluginItemsOf(t, [plugin])).get(plugin);
|
|
241
|
+
if (!items)
|
|
242
|
+
return { kind: "direct" };
|
|
243
|
+
if (!enabled && items.some(itemLocked))
|
|
244
|
+
return { kind: "locked" };
|
|
245
|
+
const [only] = items;
|
|
246
|
+
return items.length === 1 && only ? { kind: "item", itemId: only.id } : { kind: "direct" };
|
|
247
|
+
}
|
|
163
248
|
/**
|
|
164
249
|
* Writes enablement and / or config. The actor's role is re-read under the org row lock (needs
|
|
165
250
|
* `org.extensions.manage`).
|
|
@@ -171,19 +256,22 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
171
256
|
* - The merged full config (or, without `config`, the existing config when the result is enabled)
|
|
172
257
|
* does not satisfy the schema -> `extension.config_invalid`.
|
|
173
258
|
*/
|
|
174
|
-
async put(orgId, plugin, input,
|
|
259
|
+
async put(orgId, plugin, input,
|
|
260
|
+
/** null: the kernel itself (the plugin scope sync installing a plugin), no role check. */
|
|
261
|
+
actorAccountId, actorTokenId, opts = {}) {
|
|
175
262
|
const manifest = this.manifest(plugin);
|
|
176
263
|
const schema = manifest.config?.org;
|
|
177
264
|
if (input.config !== undefined && !schema) {
|
|
178
265
|
throw new ApiError("extension.no_org_config", `Extension ${plugin} has no organization config`);
|
|
179
266
|
}
|
|
180
|
-
|
|
267
|
+
const view = await this.write(orgId, plugin, manifest, input, actorAccountId, actorTokenId, opts);
|
|
268
|
+
return (await this.withLayers(orgId, [view]))[0];
|
|
181
269
|
}
|
|
182
270
|
async write(orgId, plugin, manifest, input, actorAccountId, actorTokenId, opts) {
|
|
183
271
|
const schema = manifest.config?.org;
|
|
184
272
|
let seen;
|
|
185
273
|
const t = this.db;
|
|
186
|
-
await this.orgLock.
|
|
274
|
+
await this.orgLock.lockFor(orgId, actorAccountId, "org.extensions.manage");
|
|
187
275
|
const row = await t
|
|
188
276
|
.selectFrom("extension_org_configs")
|
|
189
277
|
.select(["enabled", "config"])
|
|
@@ -191,31 +279,18 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
191
279
|
.where("org_id", "=", orgId)
|
|
192
280
|
.executeTakeFirst();
|
|
193
281
|
const required = (await requiredExtensions(t)).has(plugin);
|
|
282
|
+
const item = (await pluginItemsOf(t, [plugin])).get(plugin);
|
|
194
283
|
if (required && input.enabled === false)
|
|
195
284
|
throw requiredError(plugin);
|
|
196
285
|
if (opts.ifDisabled && (row?.enabled === true || required)) {
|
|
197
286
|
opts.ifDisabled.skipped = true;
|
|
198
|
-
return this.view(manifest, row, await this.setSecretKeys(t, orgId), required);
|
|
287
|
+
return this.view(manifest, row, await this.setSecretKeys(t, orgId), required, item);
|
|
199
288
|
}
|
|
200
289
|
// A required plugin is enabled whatever the row said (it may predate `required`)
|
|
201
290
|
const enabled = required || (input.enabled ?? row?.enabled ?? false);
|
|
202
|
-
//
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
const killed = await disabledPluginItems(t, [plugin]);
|
|
206
|
-
if (killed.length > 0)
|
|
207
|
-
throw pluginItemDisabled(killed);
|
|
208
|
-
// 经某个条目安装:只看该条目(应用里的插件按应用条目,C22);直接启用:全部来源里最严格的生效
|
|
209
|
-
if (opts.viaItem !== undefined) {
|
|
210
|
-
await assertItemInstallable(t, orgId, opts.viaItem, opts.approvedBy ?? opts.viaItem);
|
|
211
|
-
}
|
|
212
|
-
else
|
|
213
|
-
await assertPluginSourcesInstallable(t, orgId, plugin);
|
|
214
|
-
}
|
|
215
|
-
if (input.enabled === true)
|
|
216
|
-
await this.assertDependenciesEnabled(t, orgId, manifest);
|
|
217
|
-
else if (input.enabled === false && !input.force) {
|
|
218
|
-
await this.assertNoEnabledDependents(t, orgId, manifest);
|
|
291
|
+
// validateOnly: the rules for (newly) enabling and disabling belong to the write that follows
|
|
292
|
+
if (!opts.validateOnly) {
|
|
293
|
+
await this.assertSwitchRules(t, orgId, manifest, input, row, required, opts);
|
|
219
294
|
}
|
|
220
295
|
let plain = row?.config ?? null;
|
|
221
296
|
let changed = [];
|
|
@@ -253,7 +328,7 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
253
328
|
next = r.data;
|
|
254
329
|
}
|
|
255
330
|
seen = { schema, config: next };
|
|
256
|
-
if (input.config !== undefined) {
|
|
331
|
+
if (!opts.validateOnly && input.config !== undefined) {
|
|
257
332
|
changed = changedPaths(schema, before, next);
|
|
258
333
|
plain = structuredClone(next);
|
|
259
334
|
for (const p of paths) {
|
|
@@ -266,6 +341,10 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
266
341
|
}
|
|
267
342
|
}
|
|
268
343
|
}
|
|
344
|
+
// Also without an org config schema: nothing is written
|
|
345
|
+
if (opts.validateOnly) {
|
|
346
|
+
return this.view(manifest, row, await this.setSecretKeys(t, orgId), required, item);
|
|
347
|
+
}
|
|
269
348
|
// 当前 schema 中已不存在的密钥路径:同一事务内清掉遗留的密文行
|
|
270
349
|
const live = new Set((schema ? secretPaths(schema) : []).map((p) => secretKey(plugin, p)));
|
|
271
350
|
const prefix = secretKey(plugin, "");
|
|
@@ -309,7 +388,7 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
309
388
|
.where("plugin", "=", plugin)
|
|
310
389
|
.where("org_id", "=", orgId)
|
|
311
390
|
.executeTakeFirst();
|
|
312
|
-
const view = this.view(manifest, saved, await this.setSecretKeys(t, orgId), required);
|
|
391
|
+
const view = this.view(manifest, saved, await this.setSecretKeys(t, orgId), required, item);
|
|
313
392
|
// Only once the root transaction committed (an outer caller's too): a rolled-back write
|
|
314
393
|
// registers no secrets and disconnects nothing
|
|
315
394
|
afterCommit(async () => {
|
|
@@ -318,6 +397,31 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
318
397
|
});
|
|
319
398
|
return view;
|
|
320
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* The rules of a write that switches: newly enabling an extension from the platform catalog
|
|
402
|
+
* re-checks the item policy and grants (C22; one already enabled is unaffected), enabling needs
|
|
403
|
+
* the dependencies enabled, disabling (without `force`) no enabled dependents.
|
|
404
|
+
*/
|
|
405
|
+
async assertSwitchRules(t, orgId, manifest, input, row, required, opts) {
|
|
406
|
+
const plugin = manifest.name;
|
|
407
|
+
if (input.enabled === true && row?.enabled !== true && !required) {
|
|
408
|
+
// 插件自己的条目 disabled 是总开关,任何途径都不能新启用(裁决 M-5)
|
|
409
|
+
const killed = await disabledPluginItems(t, [plugin]);
|
|
410
|
+
if (killed.length > 0)
|
|
411
|
+
throw pluginItemDisabled(killed);
|
|
412
|
+
// 经某个条目安装:只看该条目(应用里的插件按应用条目,C22);直接启用:全部来源里最严格的生效
|
|
413
|
+
if (opts.viaItem !== undefined) {
|
|
414
|
+
await assertItemInstallable(t, orgId, opts.viaItem, opts.approvedBy ?? opts.viaItem);
|
|
415
|
+
}
|
|
416
|
+
else
|
|
417
|
+
await assertPluginSourcesInstallable(t, orgId, plugin);
|
|
418
|
+
}
|
|
419
|
+
if (input.enabled === true)
|
|
420
|
+
await this.assertDependenciesEnabled(t, orgId, manifest);
|
|
421
|
+
else if (input.enabled === false && !input.force) {
|
|
422
|
+
await this.assertNoEnabledDependents(t, orgId, manifest);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
321
425
|
/**
|
|
322
426
|
* 读取并解密某插件在该组织下的完整配置(供运行时按组织构造插件实例)。
|
|
323
427
|
* A required bootstrap plugin is enabled without a row (its stored config, or `{}`, is validated).
|
|
@@ -496,7 +600,7 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
496
600
|
throw new ApiError("extension.not_found", `Extension ${plugin} is not installed`);
|
|
497
601
|
return set;
|
|
498
602
|
}
|
|
499
|
-
view(m, row, setKeys, required) {
|
|
603
|
+
view(m, row, setKeys, required, items) {
|
|
500
604
|
const schema = m.config?.org;
|
|
501
605
|
const paths = schema ? secretPaths(schema) : [];
|
|
502
606
|
let config = null;
|
|
@@ -516,6 +620,12 @@ let OrgExtensionConfigs = class OrgExtensionConfigs {
|
|
|
516
620
|
orgConfigSchema: schema ? this.formSchema(m.name, m.version, schema) : null,
|
|
517
621
|
available: true,
|
|
518
622
|
required,
|
|
623
|
+
...scopeFields(items, required),
|
|
624
|
+
overrideState: [...fieldLevels(m.config?.deployment).values()].includes("override")
|
|
625
|
+
? "following"
|
|
626
|
+
: "none",
|
|
627
|
+
needsConfig: schema !== undefined &&
|
|
628
|
+
orgConfigIncomplete(schema, config, (p) => setKeys.has(secretKey(m.name, p))),
|
|
519
629
|
};
|
|
520
630
|
}
|
|
521
631
|
/**
|
|
@@ -571,7 +681,49 @@ OrgExtensionConfigs = __decorate([
|
|
|
571
681
|
__param(4, Inject(OrgLock)),
|
|
572
682
|
__param(5, Inject(ExtensionInstalls)),
|
|
573
683
|
__param(6, Inject(KernelEvents)),
|
|
574
|
-
__param(7, Inject(KERNEL_LOGGER))
|
|
684
|
+
__param(7, Inject(KERNEL_LOGGER)),
|
|
685
|
+
__param(8, Inject(EffectiveConfigs))
|
|
575
686
|
], OrgExtensionConfigs);
|
|
576
687
|
export { OrgExtensionConfigs };
|
|
688
|
+
/**
|
|
689
|
+
* Whether an org may see an extension with these live catalog items (`listed`: the items whose
|
|
690
|
+
* `named` list has the org): one visible item is enough; without an item (config-declared, or its
|
|
691
|
+
* items deleted) it is visible. A builtin item counts as `all`.
|
|
692
|
+
*/
|
|
693
|
+
function itemsVisible(items, listed) {
|
|
694
|
+
if (!items)
|
|
695
|
+
return true;
|
|
696
|
+
return items.some((i) => visibleTo({ scope: i.builtin ? "all" : i.scope }, listed.has(i.id)));
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Whether the org sees `plugin` in its extension list (a required bootstrap plugin always; else
|
|
700
|
+
* under its catalog items' scope, as {@link OrgExtensionConfigs.list} filters). `db` may be a
|
|
701
|
+
* transaction.
|
|
702
|
+
*/
|
|
703
|
+
export async function extensionVisibleTo(db, orgId, plugin) {
|
|
704
|
+
if ((await requiredExtensions(db)).has(plugin))
|
|
705
|
+
return true;
|
|
706
|
+
const items = (await pluginItemsOf(db, [plugin])).get(plugin);
|
|
707
|
+
if (!items)
|
|
708
|
+
return true;
|
|
709
|
+
const listed = new Set((await db
|
|
710
|
+
.selectFrom("catalog_item_scope_orgs")
|
|
711
|
+
.select("item_id")
|
|
712
|
+
.where("org_id", "=", orgId)
|
|
713
|
+
.where("item_id", "in", items.map((i) => i.id))
|
|
714
|
+
.execute()).map((r) => r.item_id));
|
|
715
|
+
return itemsVisible(items, listed);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* The stored org-only config does not satisfy the org schema (a required field missing): what the
|
|
719
|
+
* org form reports before any edit. A set secret is not decrypted here; issues on it or below it
|
|
720
|
+
* are ignored (it was validated when written).
|
|
721
|
+
*/
|
|
722
|
+
function orgConfigIncomplete(schema, plain, secretSet) {
|
|
723
|
+
const r = schema.safeParse(plain ?? {});
|
|
724
|
+
if (r.success)
|
|
725
|
+
return false;
|
|
726
|
+
const secrets = secretPaths(schema).filter(secretSet);
|
|
727
|
+
return toIssues(r.error).some((i) => !secrets.some((p) => i.path === p || i.path.startsWith(`${p}.`)));
|
|
728
|
+
}
|
|
577
729
|
const requiredError = (plugin) => new ApiError("extension.required", `Extension ${plugin} is required by this deployment (a bootstrap plugin): it is enabled in every organization and cannot be disabled`);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type JsonSchema } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* The org level of a deployment config field (spec A §5.1): `hidden` (platform only, orgs never
|
|
5
|
+
* see it; a field without `orgAccess`), `readonly` (orgs see it, cannot change it) or `override`
|
|
6
|
+
* (the platform sets the default, an org may bring its own value). Levels sit on top-level keys of
|
|
7
|
+
* the deployment schema only (§5.2); a nested field has its top-level key's level.
|
|
8
|
+
*/
|
|
9
|
+
export type FieldLevel = "hidden" | "readonly" | "override";
|
|
10
|
+
/** The top-level keys of a `ZodObject` deployment schema with their level; empty otherwise. */
|
|
11
|
+
export declare function fieldLevels(schema: z.ZodTypeAny | undefined): Map<string, FieldLevel>;
|
|
12
|
+
/**
|
|
13
|
+
* The same levels read from a package's static form schema (`x-org` on top-level properties), for
|
|
14
|
+
* an install record whose module this replica has not loaded.
|
|
15
|
+
*/
|
|
16
|
+
export declare function jsonSchemaFieldLevels(schema: JsonSchema | undefined): Map<string, FieldLevel>;
|
|
17
|
+
/**
|
|
18
|
+
* The platform's relaxed schema (§5.4a): a plain object rebuilt from the shape with every
|
|
19
|
+
* `override` key optional, so the platform may leave overridable fields empty (each org then
|
|
20
|
+
* brings its own); hidden and read-only fields stay as declared. Object-level refinements
|
|
21
|
+
* (`.refine` / `.superRefine`) are not carried over: they may read the absent fields, and zod
|
|
22
|
+
* refuses `.extend()` on a refined object. The identity when there is no `override` key. Parse
|
|
23
|
+
* through {@link parseLoadGate}, which uses this only when an overridable field is missing.
|
|
24
|
+
*/
|
|
25
|
+
export declare function relaxOverridable(schema: z.ZodTypeAny): z.ZodTypeAny;
|
|
26
|
+
/**
|
|
27
|
+
* The platform's load gate (§5.4a): the original schema, refinements included, whenever the
|
|
28
|
+
* platform config `raw` leaves no required overridable field empty; otherwise the relaxed plain
|
|
29
|
+
* object ({@link relaxOverridable}). Following orgs are then `needsConfig` and never called, and
|
|
30
|
+
* an org copy is parsed with the full schema.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseLoadGate(schema: z.ZodTypeAny, raw: unknown): z.ZodSafeParseResult<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* The required `override` keys the platform config `raw` leaves empty (absent and refused by the
|
|
35
|
+
* key's own schema), in schema order: orgs that follow the platform must configure them.
|
|
36
|
+
*/
|
|
37
|
+
export declare function missingOverridable(schema: z.ZodTypeAny, raw: unknown): string[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { orgAccessOf } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/** The top-level keys of a `ZodObject` deployment schema with their level; empty otherwise. */
|
|
4
|
+
export function fieldLevels(schema) {
|
|
5
|
+
const out = new Map();
|
|
6
|
+
if (!(schema instanceof z.ZodObject))
|
|
7
|
+
return out;
|
|
8
|
+
for (const [key, field] of Object.entries(schema.shape)) {
|
|
9
|
+
out.set(key, orgAccessOf(field) ?? "hidden");
|
|
10
|
+
}
|
|
11
|
+
return out;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The same levels read from a package's static form schema (`x-org` on top-level properties), for
|
|
15
|
+
* an install record whose module this replica has not loaded.
|
|
16
|
+
*/
|
|
17
|
+
export function jsonSchemaFieldLevels(schema) {
|
|
18
|
+
const out = new Map();
|
|
19
|
+
const props = schema?.properties;
|
|
20
|
+
if (typeof props !== "object" || props === null)
|
|
21
|
+
return out;
|
|
22
|
+
for (const [key, prop] of Object.entries(props)) {
|
|
23
|
+
const v = prop?.["x-org"];
|
|
24
|
+
out.set(key, v === "readonly" || v === "override" ? v : "hidden");
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
const overrideKeys = (schema) => [...fieldLevels(schema)].filter(([, l]) => l === "override").map(([k]) => k);
|
|
29
|
+
/**
|
|
30
|
+
* The platform's relaxed schema (§5.4a): a plain object rebuilt from the shape with every
|
|
31
|
+
* `override` key optional, so the platform may leave overridable fields empty (each org then
|
|
32
|
+
* brings its own); hidden and read-only fields stay as declared. Object-level refinements
|
|
33
|
+
* (`.refine` / `.superRefine`) are not carried over: they may read the absent fields, and zod
|
|
34
|
+
* refuses `.extend()` on a refined object. The identity when there is no `override` key. Parse
|
|
35
|
+
* through {@link parseLoadGate}, which uses this only when an overridable field is missing.
|
|
36
|
+
*/
|
|
37
|
+
export function relaxOverridable(schema) {
|
|
38
|
+
const keys = overrideKeys(schema);
|
|
39
|
+
if (keys.length === 0)
|
|
40
|
+
return schema;
|
|
41
|
+
const obj = schema;
|
|
42
|
+
const shape = { ...obj.shape };
|
|
43
|
+
for (const k of keys)
|
|
44
|
+
shape[k] = shape[k].optional();
|
|
45
|
+
const plain = z.object(shape);
|
|
46
|
+
const catchall = obj._zod.def.catchall;
|
|
47
|
+
return catchall ? plain.catchall(catchall) : plain;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The platform's load gate (§5.4a): the original schema, refinements included, whenever the
|
|
51
|
+
* platform config `raw` leaves no required overridable field empty; otherwise the relaxed plain
|
|
52
|
+
* object ({@link relaxOverridable}). Following orgs are then `needsConfig` and never called, and
|
|
53
|
+
* an org copy is parsed with the full schema.
|
|
54
|
+
*/
|
|
55
|
+
export function parseLoadGate(schema, raw) {
|
|
56
|
+
if (missingOverridable(schema, raw).length === 0)
|
|
57
|
+
return schema.safeParse(raw);
|
|
58
|
+
return relaxOverridable(schema).safeParse(raw);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The required `override` keys the platform config `raw` leaves empty (absent and refused by the
|
|
62
|
+
* key's own schema), in schema order: orgs that follow the platform must configure them.
|
|
63
|
+
*/
|
|
64
|
+
export function missingOverridable(schema, raw) {
|
|
65
|
+
const keys = overrideKeys(schema);
|
|
66
|
+
if (keys.length === 0)
|
|
67
|
+
return [];
|
|
68
|
+
const shape = schema.shape;
|
|
69
|
+
const value = typeof raw === "object" && raw !== null ? raw : {};
|
|
70
|
+
return keys.filter((k) => value[k] === undefined && !shape[k].safeParse(undefined).success);
|
|
71
|
+
}
|