@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.1
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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +20 -2
- package/bootstrap.json +26 -0
- package/dist/admin/admin.controller.d.ts +139 -0
- package/dist/admin/admin.controller.js +238 -0
- package/dist/admin/extensions.controller.d.ts +100 -0
- package/dist/admin/extensions.controller.js +226 -0
- package/dist/admin/setup.controller.d.ts +36 -0
- package/dist/admin/setup.controller.js +106 -0
- package/dist/admin/setup.service.d.ts +47 -0
- package/dist/admin/setup.service.js +90 -0
- package/dist/agents/agents.controller.d.ts +205 -0
- package/dist/agents/agents.controller.js +144 -0
- package/dist/agents/agents.service.d.ts +177 -0
- package/dist/agents/agents.service.js +677 -0
- package/dist/agents/definition.d.ts +198 -0
- package/dist/agents/definition.js +152 -0
- package/dist/agents/models.controller.d.ts +13 -0
- package/dist/agents/models.controller.js +31 -0
- package/dist/agents/templates.controller.d.ts +15 -0
- package/dist/agents/templates.controller.js +37 -0
- package/dist/agents/templates.d.ts +83 -0
- package/dist/agents/templates.js +173 -0
- package/dist/catalog/admin-catalog.controller.d.ts +143 -0
- package/dist/catalog/admin-catalog.controller.js +245 -0
- package/dist/catalog/catalog.service.d.ts +430 -0
- package/dist/catalog/catalog.service.js +882 -0
- package/dist/catalog/claude/agents.d.ts +27 -0
- package/dist/catalog/claude/agents.js +270 -0
- package/dist/catalog/claude/commands.d.ts +50 -0
- package/dist/catalog/claude/commands.js +179 -0
- package/dist/catalog/claude/manifest.d.ts +69 -0
- package/dist/catalog/claude/manifest.js +134 -0
- package/dist/catalog/claude/marketplace.d.ts +35 -0
- package/dist/catalog/claude/marketplace.js +194 -0
- package/dist/catalog/claude/mcp.d.ts +33 -0
- package/dist/catalog/claude/mcp.js +226 -0
- package/dist/catalog/claude/report.d.ts +86 -0
- package/dist/catalog/claude/report.js +121 -0
- package/dist/catalog/claude/translate.d.ts +56 -0
- package/dist/catalog/claude/translate.js +857 -0
- package/dist/catalog/cli.d.ts +46 -0
- package/dist/catalog/cli.js +211 -0
- package/dist/catalog/git-source.d.ts +127 -0
- package/dist/catalog/git-source.js +520 -0
- package/dist/catalog/marketplace-fetch.d.ts +99 -0
- package/dist/catalog/marketplace-fetch.js +203 -0
- package/dist/catalog/marketplaces.controller.d.ts +97 -0
- package/dist/catalog/marketplaces.controller.js +197 -0
- package/dist/catalog/marketplaces.service.d.ts +340 -0
- package/dist/catalog/marketplaces.service.js +1217 -0
- package/dist/catalog/org-catalog.controller.d.ts +128 -0
- package/dist/catalog/org-catalog.controller.js +277 -0
- package/dist/catalog/org-catalog.service.d.ts +246 -0
- package/dist/catalog/org-catalog.service.js +625 -0
- package/dist/catalog/plugin-import.d.ts +436 -0
- package/dist/catalog/plugin-import.js +1069 -0
- package/dist/catalog/plugin-install.d.ts +447 -0
- package/dist/catalog/plugin-install.js +1333 -0
- package/dist/catalog/plugin-package.d.ts +143 -0
- package/dist/catalog/plugin-package.js +382 -0
- package/dist/catalog/plugin-upgrade.d.ts +222 -0
- package/dist/catalog/plugin-upgrade.js +1219 -0
- package/dist/catalog/requests.service.d.ts +162 -0
- package/dist/catalog/requests.service.js +504 -0
- package/dist/catalog/schema-path.d.ts +7 -0
- package/dist/catalog/schema-path.js +63 -0
- package/dist/catalog/upgrade-targets.d.ts +59 -0
- package/dist/catalog/upgrade-targets.js +90 -0
- package/dist/catalog/versions.d.ts +31 -0
- package/dist/catalog/versions.js +44 -0
- package/dist/channels/actions.d.ts +37 -0
- package/dist/channels/actions.js +121 -0
- package/dist/channels/cards.d.ts +44 -0
- package/dist/channels/cards.js +156 -0
- package/dist/channels/connections.controller.d.ts +59 -0
- package/dist/channels/connections.controller.js +115 -0
- package/dist/channels/connections.service.d.ts +187 -0
- package/dist/channels/connections.service.js +534 -0
- package/dist/channels/features.d.ts +12 -0
- package/dist/channels/features.js +22 -0
- package/dist/channels/inbound.d.ts +120 -0
- package/dist/channels/inbound.js +332 -0
- package/dist/channels/outbound.d.ts +140 -0
- package/dist/channels/outbound.js +1126 -0
- package/dist/channels/phrases.d.ts +100 -0
- package/dist/channels/phrases.js +81 -0
- package/dist/channels/supervisor.d.ts +182 -0
- package/dist/channels/supervisor.js +625 -0
- package/dist/channels/threads.d.ts +29 -0
- package/dist/channels/threads.js +104 -0
- package/dist/channels/webhook-url.d.ts +16 -0
- package/dist/channels/webhook-url.js +34 -0
- package/dist/channels/webhook.controller.d.ts +19 -0
- package/dist/channels/webhook.controller.js +72 -0
- package/dist/channels/webhook.d.ts +73 -0
- package/dist/channels/webhook.js +274 -0
- package/dist/config/docs.d.ts +9 -0
- package/dist/config/docs.js +85 -0
- package/dist/config/env.d.ts +6 -0
- package/dist/config/env.js +73 -0
- package/dist/config/fields.d.ts +42 -0
- package/dist/config/fields.js +214 -0
- package/dist/config/file-source.d.ts +3 -0
- package/dist/config/file-source.js +31 -0
- package/dist/config/load.d.ts +20 -0
- package/dist/config/load.js +98 -0
- package/dist/config/nacos-source.d.ts +31 -0
- package/dist/config/nacos-source.js +229 -0
- package/dist/config/schema.d.ts +237 -0
- package/dist/config/schema.js +1192 -0
- package/dist/config/sources.d.ts +18 -0
- package/dist/config/sources.js +59 -0
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.js +7 -0
- package/dist/conversations/artifacts.d.ts +52 -0
- package/dist/conversations/artifacts.js +137 -0
- package/dist/conversations/attachments.controller.d.ts +28 -0
- package/dist/conversations/attachments.controller.js +96 -0
- package/dist/conversations/attachments.service.d.ts +180 -0
- package/dist/conversations/attachments.service.js +578 -0
- package/dist/conversations/conversations.controller.d.ts +288 -0
- package/dist/conversations/conversations.controller.js +607 -0
- package/dist/conversations/conversations.service.d.ts +321 -0
- package/dist/conversations/conversations.service.js +754 -0
- package/dist/conversations/event-log.d.ts +122 -0
- package/dist/conversations/event-log.js +259 -0
- package/dist/conversations/events.d.ts +856 -0
- package/dist/conversations/events.js +639 -0
- package/dist/conversations/files.d.ts +92 -0
- package/dist/conversations/files.js +213 -0
- package/dist/conversations/outputs-read.d.ts +34 -0
- package/dist/conversations/outputs-read.js +37 -0
- package/dist/conversations/queue.d.ts +169 -0
- package/dist/conversations/queue.js +527 -0
- package/dist/conversations/sandbox-status.d.ts +21 -0
- package/dist/conversations/sandbox-status.js +24 -0
- package/dist/conversations/selection.d.ts +46 -0
- package/dist/conversations/selection.js +75 -0
- package/dist/conversations/titles.d.ts +93 -0
- package/dist/conversations/titles.js +423 -0
- package/dist/ctx/bus.d.ts +16 -0
- package/dist/ctx/bus.js +101 -0
- package/dist/ctx/create-ctx.d.ts +109 -0
- package/dist/ctx/create-ctx.js +592 -0
- package/dist/ctx/kv.d.ts +4 -0
- package/dist/ctx/kv.js +31 -0
- package/dist/ctx/lock.d.ts +4 -0
- package/dist/ctx/lock.js +39 -0
- package/dist/ctx/namespace.d.ts +6 -0
- package/dist/ctx/namespace.js +12 -0
- package/dist/ctx/queue.d.ts +25 -0
- package/dist/ctx/queue.js +151 -0
- package/dist/ctx/secrets.d.ts +45 -0
- package/dist/ctx/secrets.js +175 -0
- package/dist/db/kernel-schema.d.ts +1122 -0
- package/dist/db/kernel-schema.js +5 -0
- package/dist/db/migrator.d.ts +28 -0
- package/dist/db/migrator.js +140 -0
- package/dist/db/pool.d.ts +21 -0
- package/dist/db/pool.js +28 -0
- package/dist/db/sql-statements.d.ts +34 -0
- package/dist/db/sql-statements.js +168 -0
- package/dist/errors.d.ts +211 -0
- package/dist/errors.js +213 -0
- package/dist/evals/budget.d.ts +61 -0
- package/dist/evals/budget.js +181 -0
- package/dist/evals/diff.d.ts +55 -0
- package/dist/evals/diff.js +133 -0
- package/dist/evals/judge.d.ts +53 -0
- package/dist/evals/judge.js +149 -0
- package/dist/evals/plan.d.ts +47 -0
- package/dist/evals/plan.js +77 -0
- package/dist/evals/reconstruct.d.ts +137 -0
- package/dist/evals/reconstruct.js +322 -0
- package/dist/evals/recorded-tools.d.ts +54 -0
- package/dist/evals/recorded-tools.js +167 -0
- package/dist/evals/run-replay.d.ts +86 -0
- package/dist/evals/run-replay.js +502 -0
- package/dist/evals/runs.controller.d.ts +100 -0
- package/dist/evals/runs.controller.js +199 -0
- package/dist/evals/runs.service.d.ts +275 -0
- package/dist/evals/runs.service.js +836 -0
- package/dist/evals/sets.controller.d.ts +61 -0
- package/dist/evals/sets.controller.js +183 -0
- package/dist/evals/sets.service.d.ts +128 -0
- package/dist/evals/sets.service.js +558 -0
- package/dist/evals/snapshot.d.ts +76 -0
- package/dist/evals/snapshot.js +207 -0
- package/dist/evals/step-replay.d.ts +113 -0
- package/dist/evals/step-replay.js +181 -0
- package/dist/evals/trajectory.controller.d.ts +41 -0
- package/dist/evals/trajectory.controller.js +88 -0
- package/dist/evals/trajectory.d.ts +144 -0
- package/dist/evals/trajectory.js +338 -0
- package/dist/evals/trajectory.service.d.ts +108 -0
- package/dist/evals/trajectory.service.js +323 -0
- package/dist/evals/worker.d.ts +101 -0
- package/dist/evals/worker.js +790 -0
- package/dist/extensions/admin-ops.d.ts +105 -0
- package/dist/extensions/admin-ops.js +353 -0
- package/dist/extensions/admin-view.d.ts +79 -0
- package/dist/extensions/admin-view.js +327 -0
- package/dist/extensions/approvals.d.ts +119 -0
- package/dist/extensions/approvals.js +205 -0
- package/dist/extensions/blobs.d.ts +45 -0
- package/dist/extensions/blobs.js +160 -0
- package/dist/extensions/bootstrap.d.ts +176 -0
- package/dist/extensions/bootstrap.js +535 -0
- package/dist/extensions/cli.d.ts +61 -0
- package/dist/extensions/cli.js +165 -0
- package/dist/extensions/config-json-schema.d.ts +9 -0
- package/dist/extensions/config-json-schema.js +73 -0
- package/dist/extensions/deployment-config.d.ts +138 -0
- package/dist/extensions/deployment-config.js +394 -0
- package/dist/extensions/enabled.d.ts +31 -0
- package/dist/extensions/enabled.js +55 -0
- package/dist/extensions/hooks.d.ts +161 -0
- package/dist/extensions/hooks.js +425 -0
- package/dist/extensions/host.d.ts +577 -0
- package/dist/extensions/host.js +2071 -0
- package/dist/extensions/inflight.d.ts +69 -0
- package/dist/extensions/inflight.js +277 -0
- package/dist/extensions/installs.d.ts +166 -0
- package/dist/extensions/installs.js +253 -0
- package/dist/extensions/instance.d.ts +167 -0
- package/dist/extensions/instance.js +329 -0
- package/dist/extensions/ledger.d.ts +30 -0
- package/dist/extensions/ledger.js +50 -0
- package/dist/extensions/lifecycle.d.ts +80 -0
- package/dist/extensions/lifecycle.js +152 -0
- package/dist/extensions/migrate-lock.d.ts +51 -0
- package/dist/extensions/migrate-lock.js +100 -0
- package/dist/extensions/org-config.controller.d.ts +24 -0
- package/dist/extensions/org-config.controller.js +59 -0
- package/dist/extensions/org-config.d.ts +169 -0
- package/dist/extensions/org-config.js +520 -0
- package/dist/extensions/package.d.ts +115 -0
- package/dist/extensions/package.js +246 -0
- package/dist/extensions/permission-set.d.ts +117 -0
- package/dist/extensions/permission-set.js +184 -0
- package/dist/extensions/permission-view.d.ts +194 -0
- package/dist/extensions/permission-view.js +284 -0
- package/dist/extensions/registry.d.ts +24 -0
- package/dist/extensions/registry.js +56 -0
- package/dist/extensions/resolve.d.ts +12 -0
- package/dist/extensions/resolve.js +71 -0
- package/dist/extensions/sources.d.ts +69 -0
- package/dist/extensions/sources.js +120 -0
- package/dist/extensions/sync.d.ts +40 -0
- package/dist/extensions/sync.js +242 -0
- package/dist/files/previewers.controller.d.ts +46 -0
- package/dist/files/previewers.controller.js +105 -0
- package/dist/files/previewers.d.ts +100 -0
- package/dist/files/previewers.js +250 -0
- package/dist/http/api.module.d.ts +114 -0
- package/dist/http/api.module.js +448 -0
- package/dist/http/app.d.ts +77 -0
- package/dist/http/app.js +220 -0
- package/dist/http/error.filter.d.ts +21 -0
- package/dist/http/error.filter.js +85 -0
- package/dist/http/gateway.module.d.ts +15 -0
- package/dist/http/gateway.module.js +13 -0
- package/dist/http/health.controller.d.ts +26 -0
- package/dist/http/health.controller.js +79 -0
- package/dist/http/nest-logger.d.ts +20 -0
- package/dist/http/nest-logger.js +28 -0
- package/dist/http/plugin-dispatch.d.ts +68 -0
- package/dist/http/plugin-dispatch.js +200 -0
- package/dist/http/tokens.d.ts +131 -0
- package/dist/http/tokens.js +131 -0
- package/dist/http/zod.pipe.d.ts +8 -0
- package/dist/http/zod.pipe.js +14 -0
- package/dist/identity/accounts.d.ts +93 -0
- package/dist/identity/accounts.js +367 -0
- package/dist/identity/api-tokens.d.ts +73 -0
- package/dist/identity/api-tokens.js +197 -0
- package/dist/identity/audit.d.ts +23 -0
- package/dist/identity/audit.js +41 -0
- package/dist/identity/auth.controller.d.ts +40 -0
- package/dist/identity/auth.controller.js +130 -0
- package/dist/identity/auth.guard.d.ts +41 -0
- package/dist/identity/auth.guard.js +162 -0
- package/dist/identity/binding.d.ts +47 -0
- package/dist/identity/binding.js +84 -0
- package/dist/identity/cookies.d.ts +16 -0
- package/dist/identity/cookies.js +32 -0
- package/dist/identity/credential-check.d.ts +17 -0
- package/dist/identity/credential-check.js +24 -0
- package/dist/identity/enterprise-admin.d.ts +14 -0
- package/dist/identity/enterprise-admin.js +27 -0
- package/dist/identity/external.d.ts +106 -0
- package/dist/identity/external.js +337 -0
- package/dist/identity/hash.d.ts +2 -0
- package/dist/identity/hash.js +3 -0
- package/dist/identity/login.d.ts +6 -0
- package/dist/identity/login.js +20 -0
- package/dist/identity/me.controller.d.ts +61 -0
- package/dist/identity/me.controller.js +159 -0
- package/dist/identity/passwords.d.ts +6 -0
- package/dist/identity/passwords.js +37 -0
- package/dist/identity/principal.d.ts +56 -0
- package/dist/identity/principal.js +38 -0
- package/dist/identity/rate-limit.d.ts +55 -0
- package/dist/identity/rate-limit.js +121 -0
- package/dist/identity/sessions.d.ts +84 -0
- package/dist/identity/sessions.js +306 -0
- package/dist/identity/settings.d.ts +121 -0
- package/dist/identity/settings.js +248 -0
- package/dist/identity/sso.controller.d.ts +59 -0
- package/dist/identity/sso.controller.js +192 -0
- package/dist/identity/sso.d.ts +83 -0
- package/dist/identity/sso.js +202 -0
- package/dist/inbox/inbox.service.d.ts +43 -0
- package/dist/inbox/inbox.service.js +57 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +67 -0
- package/dist/kernel.d.ts +259 -0
- package/dist/kernel.js +1326 -0
- package/dist/log-config.d.ts +9 -0
- package/dist/log-config.js +27 -0
- package/dist/log-context.d.ts +32 -0
- package/dist/log-context.js +40 -0
- package/dist/log-loki.d.ts +34 -0
- package/dist/log-loki.js +145 -0
- package/dist/log.d.ts +79 -0
- package/dist/log.js +303 -0
- package/dist/models/prices.d.ts +53 -0
- package/dist/models/prices.js +121 -0
- package/dist/models/purposes.controller.d.ts +19 -0
- package/dist/models/purposes.controller.js +56 -0
- package/dist/models/purposes.d.ts +140 -0
- package/dist/models/purposes.js +267 -0
- package/dist/net/proxy.d.ts +44 -0
- package/dist/net/proxy.js +162 -0
- package/dist/net/public-address.d.ts +60 -0
- package/dist/net/public-address.js +272 -0
- package/dist/net/safe-fetch.d.ts +38 -0
- package/dist/net/safe-fetch.js +140 -0
- package/dist/orgs/directory-sync.controller.d.ts +14 -0
- package/dist/orgs/directory-sync.controller.js +40 -0
- package/dist/orgs/directory-sync.d.ts +166 -0
- package/dist/orgs/directory-sync.js +558 -0
- package/dist/orgs/invitations.controller.d.ts +58 -0
- package/dist/orgs/invitations.controller.js +137 -0
- package/dist/orgs/invitations.service.d.ts +80 -0
- package/dist/orgs/invitations.service.js +217 -0
- package/dist/orgs/members.service.d.ts +63 -0
- package/dist/orgs/members.service.js +234 -0
- package/dist/orgs/offboarding.d.ts +141 -0
- package/dist/orgs/offboarding.js +398 -0
- package/dist/orgs/org-lock.d.ts +32 -0
- package/dist/orgs/org-lock.js +46 -0
- package/dist/orgs/org.guard.d.ts +35 -0
- package/dist/orgs/org.guard.js +95 -0
- package/dist/orgs/orgs.controller.d.ts +78 -0
- package/dist/orgs/orgs.controller.js +192 -0
- package/dist/orgs/orgs.service.d.ts +61 -0
- package/dist/orgs/orgs.service.js +209 -0
- package/dist/orgs/roles.d.ts +13 -0
- package/dist/orgs/roles.js +58 -0
- package/dist/orgs/settings.controller.d.ts +20 -0
- package/dist/orgs/settings.controller.js +53 -0
- package/dist/orgs/settings.service.d.ts +120 -0
- package/dist/orgs/settings.service.js +178 -0
- package/dist/packages/npm.d.ts +50 -0
- package/dist/packages/npm.js +218 -0
- package/dist/packages/provenance.d.ts +47 -0
- package/dist/packages/provenance.js +147 -0
- package/dist/packages/tgz.d.ts +76 -0
- package/dist/packages/tgz.js +225 -0
- package/dist/runtime/abort.d.ts +32 -0
- package/dist/runtime/abort.js +71 -0
- package/dist/runtime/checkpointer.d.ts +32 -0
- package/dist/runtime/checkpointer.js +243 -0
- package/dist/runtime/context/build.d.ts +254 -0
- package/dist/runtime/context/build.js +693 -0
- package/dist/runtime/context/claude-tools.d.ts +11 -0
- package/dist/runtime/context/claude-tools.js +24 -0
- package/dist/runtime/context/compaction.d.ts +26 -0
- package/dist/runtime/context/compaction.js +195 -0
- package/dist/runtime/context/pairing.d.ts +11 -0
- package/dist/runtime/context/pairing.js +82 -0
- package/dist/runtime/context/reminders.d.ts +5 -0
- package/dist/runtime/context/reminders.js +11 -0
- package/dist/runtime/context/skills.d.ts +105 -0
- package/dist/runtime/context/skills.js +283 -0
- package/dist/runtime/context/tokens.d.ts +19 -0
- package/dist/runtime/context/tokens.js +104 -0
- package/dist/runtime/conversation-lock.d.ts +40 -0
- package/dist/runtime/conversation-lock.js +97 -0
- package/dist/runtime/hook-calls.d.ts +84 -0
- package/dist/runtime/hook-calls.js +136 -0
- package/dist/runtime/langgraph-loop.d.ts +52 -0
- package/dist/runtime/langgraph-loop.js +247 -0
- package/dist/runtime/loop.d.ts +93 -0
- package/dist/runtime/loop.js +7 -0
- package/dist/runtime/maintenance.d.ts +80 -0
- package/dist/runtime/maintenance.js +148 -0
- package/dist/runtime/media-cache.d.ts +21 -0
- package/dist/runtime/media-cache.js +51 -0
- package/dist/runtime/model-call.d.ts +176 -0
- package/dist/runtime/model-call.js +1049 -0
- package/dist/runtime/providers.d.ts +86 -0
- package/dist/runtime/providers.js +224 -0
- package/dist/runtime/quota.d.ts +29 -0
- package/dist/runtime/quota.js +70 -0
- package/dist/runtime/run-finish.d.ts +45 -0
- package/dist/runtime/run-finish.js +69 -0
- package/dist/runtime/run-queue.d.ts +121 -0
- package/dist/runtime/run-queue.js +493 -0
- package/dist/runtime/run-worker.d.ts +138 -0
- package/dist/runtime/run-worker.js +806 -0
- package/dist/runtime/stream.controller.d.ts +34 -0
- package/dist/runtime/stream.controller.js +122 -0
- package/dist/runtime/stream.d.ts +63 -0
- package/dist/runtime/stream.js +262 -0
- package/dist/runtime/subagents/child.d.ts +80 -0
- package/dist/runtime/subagents/child.js +225 -0
- package/dist/runtime/subagents/definition.d.ts +103 -0
- package/dist/runtime/subagents/definition.js +392 -0
- package/dist/runtime/subagents/dispatch.d.ts +69 -0
- package/dist/runtime/subagents/dispatch.js +502 -0
- package/dist/runtime/subagents/limits.d.ts +23 -0
- package/dist/runtime/subagents/limits.js +34 -0
- package/dist/runtime/subagents/org-agents.d.ts +50 -0
- package/dist/runtime/subagents/org-agents.js +70 -0
- package/dist/runtime/subagents/preamble.d.ts +7 -0
- package/dist/runtime/subagents/preamble.js +11 -0
- package/dist/runtime/subagents/progress.d.ts +26 -0
- package/dist/runtime/subagents/progress.js +36 -0
- package/dist/runtime/subagents/roster.d.ts +55 -0
- package/dist/runtime/subagents/roster.js +111 -0
- package/dist/runtime/subagents/skill-fork.d.ts +123 -0
- package/dist/runtime/subagents/skill-fork.js +259 -0
- package/dist/runtime/usage-report.d.ts +163 -0
- package/dist/runtime/usage-report.js +551 -0
- package/dist/runtime/waits.d.ts +233 -0
- package/dist/runtime/waits.js +883 -0
- package/dist/sandbox/leases.d.ts +169 -0
- package/dist/sandbox/leases.js +515 -0
- package/dist/sandbox/lifecycle.d.ts +21 -0
- package/dist/sandbox/lifecycle.js +68 -0
- package/dist/sandbox/sandbox.service.d.ts +249 -0
- package/dist/sandbox/sandbox.service.js +908 -0
- package/dist/skills/catalog.d.ts +149 -0
- package/dist/skills/catalog.js +405 -0
- package/dist/skills/changes.controller.d.ts +56 -0
- package/dist/skills/changes.controller.js +136 -0
- package/dist/skills/changes.service.d.ts +175 -0
- package/dist/skills/changes.service.js +805 -0
- package/dist/skills/invocable.controller.d.ts +23 -0
- package/dist/skills/invocable.controller.js +50 -0
- package/dist/skills/invocation-keys.d.ts +23 -0
- package/dist/skills/invocation-keys.js +44 -0
- package/dist/skills/invoke.d.ts +135 -0
- package/dist/skills/invoke.js +286 -0
- package/dist/skills/package.d.ts +87 -0
- package/dist/skills/package.js +227 -0
- package/dist/skills/skills.controller.d.ts +40 -0
- package/dist/skills/skills.controller.js +110 -0
- package/dist/skills/skills.service.d.ts +192 -0
- package/dist/skills/skills.service.js +567 -0
- package/dist/storage/prefix.d.ts +36 -0
- package/dist/storage/prefix.js +104 -0
- package/dist/storage/purge.d.ts +27 -0
- package/dist/storage/purge.js +75 -0
- package/dist/storage/storage.service.d.ts +44 -0
- package/dist/storage/storage.service.js +145 -0
- package/dist/text.d.ts +13 -0
- package/dist/text.js +13 -0
- package/dist/tools/approvals.controller.d.ts +53 -0
- package/dist/tools/approvals.controller.js +128 -0
- package/dist/tools/approvals.service.d.ts +172 -0
- package/dist/tools/approvals.service.js +568 -0
- package/dist/tools/breaker.d.ts +28 -0
- package/dist/tools/breaker.js +72 -0
- package/dist/tools/builtins/agent.d.ts +81 -0
- package/dist/tools/builtins/agent.js +223 -0
- package/dist/tools/builtins/ask-user.d.ts +28 -0
- package/dist/tools/builtins/ask-user.js +139 -0
- package/dist/tools/builtins/read-tool-output.d.ts +18 -0
- package/dist/tools/builtins/read-tool-output.js +108 -0
- package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
- package/dist/tools/builtins/sandbox/bash.js +137 -0
- package/dist/tools/builtins/sandbox/common.d.ts +116 -0
- package/dist/tools/builtins/sandbox/common.js +306 -0
- package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
- package/dist/tools/builtins/sandbox/deliver.js +180 -0
- package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
- package/dist/tools/builtins/sandbox/edit.js +98 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
- package/dist/tools/builtins/sandbox/glob-match.js +240 -0
- package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
- package/dist/tools/builtins/sandbox/glob.js +104 -0
- package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
- package/dist/tools/builtins/sandbox/grep.js +133 -0
- package/dist/tools/builtins/sandbox/index.d.ts +12 -0
- package/dist/tools/builtins/sandbox/index.js +27 -0
- package/dist/tools/builtins/sandbox/names.d.ts +7 -0
- package/dist/tools/builtins/sandbox/names.js +20 -0
- package/dist/tools/builtins/sandbox/read.d.ts +8 -0
- package/dist/tools/builtins/sandbox/read.js +121 -0
- package/dist/tools/builtins/sandbox/write.d.ts +4 -0
- package/dist/tools/builtins/sandbox/write.js +88 -0
- package/dist/tools/builtins/skill-load.d.ts +53 -0
- package/dist/tools/builtins/skill-load.js +446 -0
- package/dist/tools/builtins/skill-write.d.ts +59 -0
- package/dist/tools/builtins/skill-write.js +244 -0
- package/dist/tools/builtins/tool-search.d.ts +31 -0
- package/dist/tools/builtins/tool-search.js +171 -0
- package/dist/tools/connector-content.controller.d.ts +34 -0
- package/dist/tools/connector-content.controller.js +78 -0
- package/dist/tools/connector-content.d.ts +104 -0
- package/dist/tools/connector-content.js +267 -0
- package/dist/tools/connectors.controller.d.ts +210 -0
- package/dist/tools/connectors.controller.js +234 -0
- package/dist/tools/connectors.service.d.ts +303 -0
- package/dist/tools/connectors.service.js +1102 -0
- package/dist/tools/credentials.d.ts +139 -0
- package/dist/tools/credentials.js +351 -0
- package/dist/tools/drift.d.ts +141 -0
- package/dist/tools/drift.js +539 -0
- package/dist/tools/elicitation.d.ts +81 -0
- package/dist/tools/elicitation.js +266 -0
- package/dist/tools/endpoint.d.ts +18 -0
- package/dist/tools/endpoint.js +115 -0
- package/dist/tools/info.d.ts +67 -0
- package/dist/tools/info.js +113 -0
- package/dist/tools/naming.d.ts +27 -0
- package/dist/tools/naming.js +47 -0
- package/dist/tools/oauth/discovery.d.ts +65 -0
- package/dist/tools/oauth/discovery.js +307 -0
- package/dist/tools/oauth/flow.d.ts +63 -0
- package/dist/tools/oauth/flow.js +237 -0
- package/dist/tools/oauth/oauth.controller.d.ts +31 -0
- package/dist/tools/oauth/oauth.controller.js +95 -0
- package/dist/tools/oauth/tokens.d.ts +111 -0
- package/dist/tools/oauth/tokens.js +258 -0
- package/dist/tools/outputs.d.ts +61 -0
- package/dist/tools/outputs.js +156 -0
- package/dist/tools/pipeline.d.ts +322 -0
- package/dist/tools/pipeline.js +1236 -0
- package/dist/tools/policy.d.ts +60 -0
- package/dist/tools/policy.js +236 -0
- package/dist/tools/questions.controller.d.ts +24 -0
- package/dist/tools/questions.controller.js +58 -0
- package/dist/tools/questions.service.d.ts +103 -0
- package/dist/tools/questions.service.js +295 -0
- package/dist/tools/redact.d.ts +20 -0
- package/dist/tools/redact.js +60 -0
- package/dist/tools/registry.d.ts +246 -0
- package/dist/tools/registry.js +481 -0
- package/dist/tools/resources.d.ts +16 -0
- package/dist/tools/resources.js +76 -0
- package/dist/tools/specs.d.ts +14 -0
- package/dist/tools/specs.js +31 -0
- package/dist/tools/validate.d.ts +20 -0
- package/dist/tools/validate.js +183 -0
- package/dist/tools/view.d.ts +43 -0
- package/dist/tools/view.js +225 -0
- package/dist/ui/embed-token.d.ts +31 -0
- package/dist/ui/embed-token.js +132 -0
- package/dist/ui/registry.d.ts +58 -0
- package/dist/ui/registry.js +90 -0
- package/dist/ui/ui-stream.d.ts +37 -0
- package/dist/ui/ui-stream.js +162 -0
- package/dist/ui/views.controller.d.ts +81 -0
- package/dist/ui/views.controller.js +261 -0
- package/dist/ui/views.d.ts +155 -0
- package/dist/ui/views.js +306 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +6 -0
- package/package.json +69 -3
- package/src/migrations/0001_init.sql +8 -0
- package/src/migrations/0002_secrets.sql +8 -0
- package/src/migrations/0003_identity.sql +117 -0
- package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
- package/src/migrations/0005_agents.sql +27 -0
- package/src/migrations/0006_conversations.sql +37 -0
- package/src/migrations/0007_checkpoints.sql +26 -0
- package/src/migrations/0008_runs_trigger_seq.sql +3 -0
- package/src/migrations/0009_runs_active_unique.sql +4 -0
- package/src/migrations/0010_tools.sql +125 -0
- package/src/migrations/0011_approvals_spec.sql +10 -0
- package/src/migrations/0012_run_waits.sql +24 -0
- package/src/migrations/0013_app_tools_source.sql +4 -0
- package/src/migrations/0014_tool_specs.sql +8 -0
- package/src/migrations/0015_tool_drift.sql +20 -0
- package/src/migrations/0016_plugin_permissions.sql +11 -0
- package/src/migrations/0017_identity_sources.sql +6 -0
- package/src/migrations/0018_channels.sql +74 -0
- package/src/migrations/0019_identity_trust.sql +17 -0
- package/src/migrations/0020_channel_card_lookup.sql +10 -0
- package/src/migrations/0021_org_storage_purge.sql +9 -0
- package/src/migrations/0022_attachments.sql +29 -0
- package/src/migrations/0023_sandboxes.sql +37 -0
- package/src/migrations/0024_skills.sql +46 -0
- package/src/migrations/0025_skills_catalog_idx.sql +6 -0
- package/src/migrations/0026_skill_changes.sql +34 -0
- package/src/migrations/0027_model_prices.sql +18 -0
- package/src/migrations/0028_evals.sql +105 -0
- package/src/migrations/0029_model_purposes.sql +18 -0
- package/src/migrations/0030_plugin_installs.sql +73 -0
- package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
- package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
- package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
- package/src/migrations/0034_directory.sql +49 -0
- package/src/migrations/0035_catalogs.sql +40 -0
- package/src/migrations/0036_app_import_staging.sql +17 -0
- package/src/migrations/0037_directory_installs.sql +92 -0
- package/src/migrations/0038_channel_inbound_mode.sql +6 -0
- package/src/migrations/0039_channel_card_pending.sql +8 -0
- package/src/migrations/0040_usage_report_sweep.sql +10 -0
- package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
- package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
- package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
- package/src/migrations/0044_catalog_one_kind.sql +90 -0
- package/src/migrations/0045_plugin_dependencies.sql +9 -0
- package/src/migrations/0046_git_sources.sql +25 -0
- package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
- package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
- package/src/migrations/0049_plugin_upgrades.sql +37 -0
- package/src/migrations/0050_bootstrap.sql +53 -0
- package/src/migrations/0051_claude_compat.sql +26 -0
- package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
- package/src/migrations/0053_subagents.sql +73 -0
- package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
- package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
- package/src/migrations/0056_approval_reason.sql +3 -0
- package/src/migrations/0057_conversation_titles.sql +11 -0
- package/src/migrations/0058_conversation_selection.sql +4 -0
- package/src/migrations/0059_conversation_queue.sql +22 -0
- package/src/migrations/0060_file_previewers.sql +10 -0
- package/src/migrations/0061_queue_selection.sql +5 -0
- package/src/migrations/0062_queued_skill.sql +8 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { KernelConfig } from "../config/schema.js";
|
|
2
|
+
import type { KernelDb } from "../db/kernel-schema.js";
|
|
3
|
+
import type { AdminExtensionView } from "./permission-view.js";
|
|
4
|
+
import type { ExtensionSource } from "./sources.js";
|
|
5
|
+
export interface ExtensionAdminOpsDeps {
|
|
6
|
+
db: KernelDb;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the admin view after the operation; when the package cannot be read it should return the
|
|
9
|
+
* degraded item (`ExtensionAdmin.get(name, { allowUnreadable: true })`). If it throws, the operation
|
|
10
|
+
* has already committed: ops logs an error and returns {@link fallbackView}, so an operation that
|
|
11
|
+
* took effect is not reported as failed.
|
|
12
|
+
*/
|
|
13
|
+
view(name: string): Promise<AdminExtensionView>;
|
|
14
|
+
/** 配置声明的插件名 → 来源(这些插件不能安装 / 停用 / 卸载,C15)。 */
|
|
15
|
+
declared(): ReadonlyMap<string, ExtensionSource>;
|
|
16
|
+
/** 读包(降级时核对目标版本的迁移文件)。 */
|
|
17
|
+
blobs: {
|
|
18
|
+
get(sha256: string): Promise<Uint8Array>;
|
|
19
|
+
};
|
|
20
|
+
config: () => KernelConfig;
|
|
21
|
+
/** 发布 `kernel.plugins.changed`。 */
|
|
22
|
+
bus: {
|
|
23
|
+
publish(topic: string, payload: unknown): Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
/** 发布失败时本副本自己 reconcile(不等待;其他副本靠周期任务兜底)。CLI 没有。 */
|
|
26
|
+
reconcile?: (reason: string) => Promise<void>;
|
|
27
|
+
log: {
|
|
28
|
+
warn(msg: string, fields?: Record<string, unknown>): void;
|
|
29
|
+
error(msg: string, fields?: Record<string, unknown>): void;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Deployment-level extension install / enable / disable / uninstall (C16 / D15): writes only the PG
|
|
34
|
+
* desired state (`extension_installs`) and the audit, then publishes `kernel.plugins.changed` after
|
|
35
|
+
* the commit (a failure only warns; the periodic reconcile catches up); replicas converge through
|
|
36
|
+
* reconcile, no restart. It does not wait for replicas: the returned view may say `converging`.
|
|
37
|
+
* Stateless, shared by every replica; the CLI uses it too (`actor` is null).
|
|
38
|
+
* Every write runs in a transaction: first `lockEnterpriseAdminsAndAuthorize` (skipped by the CLI),
|
|
39
|
+
* then an advisory lock by extension name and a lock on the install record row.
|
|
40
|
+
*/
|
|
41
|
+
export declare class ExtensionAdminOps {
|
|
42
|
+
private readonly d;
|
|
43
|
+
constructor(d: ExtensionAdminOpsDeps);
|
|
44
|
+
/**
|
|
45
|
+
* New install or version change (upgrade / downgrade): the install record points at package
|
|
46
|
+
* `sha256`; the desired state is unchanged (a new install is disabled). Audit `extension.installed`.
|
|
47
|
+
* - Config-declared -> `extension.config_declared`; a required bootstrap plugin may be
|
|
48
|
+
* installed at another version (an enterprise admin upgrades it; `required` is kept);
|
|
49
|
+
* - package not in the package store -> `extension.package_not_found`; the extension name in the
|
|
50
|
+
* package is not `name` -> `extension.name_mismatch`;
|
|
51
|
+
* - an install record of the same name exists but comes from another npm package ->
|
|
52
|
+
* `extension.name_conflict` (decided under a row lock in the transaction, no race);
|
|
53
|
+
* an extension name belongs to the npm package that first installed it (`extension_name_owners`,
|
|
54
|
+
* not deleted on uninstall): after an uninstall, another package installing an extension of the
|
|
55
|
+
* same name gets `extension.name_conflict` too (Ruling P3: uninstall keeps data, secrets, the
|
|
56
|
+
* snapshot and org enablement); the same npm package reinstalls as usual;
|
|
57
|
+
* config-declared extensions register ownership at startup too (I4); a name without an owner but
|
|
58
|
+
* with a snapshot / deployment config / org config left -> also `extension.name_conflict`;
|
|
59
|
+
* - downgrade (target version below the current one) whose target version has migration files not
|
|
60
|
+
* run yet -> `extension.downgrade_unsupported` (migrations are expand-only, a downgrade can only
|
|
61
|
+
* go back to a version whose migrations are a subset of those already run).
|
|
62
|
+
* Already pointing at the same package: nothing changes (no audit; for a changed source item only,
|
|
63
|
+
* see below).
|
|
64
|
+
* `opts.catalogItemId`: the source item when installing through the enterprise catalog, stored
|
|
65
|
+
* in `extension_installs.catalog_item_id` (F-AA) and registered in `extension_catalog_sources`;
|
|
66
|
+
* installing outside the catalog (upload / npm / CLI) **keeps** the existing source items (T26
|
|
67
|
+
* fix: clearing them would let org enablement bypass catalog policy, C22). The detail of the
|
|
68
|
+
* `extension.installed` audit carries `catalogItemId`; when it already points at the same package
|
|
69
|
+
* and only the source item changed, only that column changes, audit
|
|
70
|
+
* `extension.install_source_changed`.
|
|
71
|
+
*/
|
|
72
|
+
install(name: string, sha256: string, actor: string | null, actorTokenId?: string, opts?: {
|
|
73
|
+
catalogItemId?: string;
|
|
74
|
+
}): Promise<AdminExtensionView>;
|
|
75
|
+
/** Enable on the deployment (audit `extension.enabled`); no change when already enabled. Org enablement is unchanged. */
|
|
76
|
+
enable(name: string, actor: string | null, actorTokenId?: string): Promise<AdminExtensionView>;
|
|
77
|
+
/**
|
|
78
|
+
* Disables on the deployment (audit `extension.disabled`); no change when already disabled. Every
|
|
79
|
+
* replica unloads it (draining in-flight calls), and the extensions that `requires` it unload with
|
|
80
|
+
* it; the org enablement switch is unchanged and the org page shows it as unavailable. A required
|
|
81
|
+
* bootstrap plugin -> `extension.required`.
|
|
82
|
+
*/
|
|
83
|
+
disable(name: string, actor: string | null, actorTokenId?: string): Promise<AdminExtensionView>;
|
|
84
|
+
/**
|
|
85
|
+
* Uninstall: a required bootstrap plugin -> `extension.required`; must be disabled first
|
|
86
|
+
* (otherwise `extension.not_disabled`); deletes the install record
|
|
87
|
+
* and its catalog source items (`extension_catalog_sources`, same transaction; audit
|
|
88
|
+
* `extension.uninstalled`), and keeps the data: the extension schema, secrets, org configs,
|
|
89
|
+
* permission snapshot and the package in the package store are untouched (a reinstall picks them
|
|
90
|
+
* up).
|
|
91
|
+
*/
|
|
92
|
+
uninstall(name: string, actor: string | null, actorTokenId?: string): Promise<void>;
|
|
93
|
+
private setState;
|
|
94
|
+
/**
|
|
95
|
+
* 提交后的视图:拼视图失败(读包、查状态行出错)时操作已经生效,不能再报失败——记 error,返回降级视图。
|
|
96
|
+
*/
|
|
97
|
+
private viewAfterCommit;
|
|
98
|
+
/** 配置声明的插件不经安装记录管理。 */
|
|
99
|
+
private assertInstallable;
|
|
100
|
+
/** 按插件名串行(咨询锁,覆盖「还没有行」的新装),再锁住已有的安装记录行。 */
|
|
101
|
+
private lockRow;
|
|
102
|
+
private audit;
|
|
103
|
+
/** 提交后通知各副本;发布失败只告警(周期 reconcile 兜底),本副本自己先 reconcile。 */
|
|
104
|
+
private notify;
|
|
105
|
+
}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { SDK_VERSION } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
import semver from "semver";
|
|
4
|
+
import { pluginSchemaName } from "../ctx/create-ctx.js";
|
|
5
|
+
import { ApiError } from "../errors.js";
|
|
6
|
+
import { audit } from "../identity/audit.js";
|
|
7
|
+
import { lockEnterpriseAdminsAndAuthorize } from "../identity/enterprise-admin.js";
|
|
8
|
+
import { PLUGINS_CHANGED_TOPIC } from "./lifecycle.js";
|
|
9
|
+
import { unrunMigrations } from "./migrate-lock.js";
|
|
10
|
+
import { ExtensionPackageError, extensionPackageApiError, readExtensionPackage, } from "./package.js";
|
|
11
|
+
/**
|
|
12
|
+
* Deployment-level extension install / enable / disable / uninstall (C16 / D15): writes only the PG
|
|
13
|
+
* desired state (`extension_installs`) and the audit, then publishes `kernel.plugins.changed` after
|
|
14
|
+
* the commit (a failure only warns; the periodic reconcile catches up); replicas converge through
|
|
15
|
+
* reconcile, no restart. It does not wait for replicas: the returned view may say `converging`.
|
|
16
|
+
* Stateless, shared by every replica; the CLI uses it too (`actor` is null).
|
|
17
|
+
* Every write runs in a transaction: first `lockEnterpriseAdminsAndAuthorize` (skipped by the CLI),
|
|
18
|
+
* then an advisory lock by extension name and a lock on the install record row.
|
|
19
|
+
*/
|
|
20
|
+
export class ExtensionAdminOps {
|
|
21
|
+
d;
|
|
22
|
+
constructor(d) {
|
|
23
|
+
this.d = d;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* New install or version change (upgrade / downgrade): the install record points at package
|
|
27
|
+
* `sha256`; the desired state is unchanged (a new install is disabled). Audit `extension.installed`.
|
|
28
|
+
* - Config-declared -> `extension.config_declared`; a required bootstrap plugin may be
|
|
29
|
+
* installed at another version (an enterprise admin upgrades it; `required` is kept);
|
|
30
|
+
* - package not in the package store -> `extension.package_not_found`; the extension name in the
|
|
31
|
+
* package is not `name` -> `extension.name_mismatch`;
|
|
32
|
+
* - an install record of the same name exists but comes from another npm package ->
|
|
33
|
+
* `extension.name_conflict` (decided under a row lock in the transaction, no race);
|
|
34
|
+
* an extension name belongs to the npm package that first installed it (`extension_name_owners`,
|
|
35
|
+
* not deleted on uninstall): after an uninstall, another package installing an extension of the
|
|
36
|
+
* same name gets `extension.name_conflict` too (Ruling P3: uninstall keeps data, secrets, the
|
|
37
|
+
* snapshot and org enablement); the same npm package reinstalls as usual;
|
|
38
|
+
* config-declared extensions register ownership at startup too (I4); a name without an owner but
|
|
39
|
+
* with a snapshot / deployment config / org config left -> also `extension.name_conflict`;
|
|
40
|
+
* - downgrade (target version below the current one) whose target version has migration files not
|
|
41
|
+
* run yet -> `extension.downgrade_unsupported` (migrations are expand-only, a downgrade can only
|
|
42
|
+
* go back to a version whose migrations are a subset of those already run).
|
|
43
|
+
* Already pointing at the same package: nothing changes (no audit; for a changed source item only,
|
|
44
|
+
* see below).
|
|
45
|
+
* `opts.catalogItemId`: the source item when installing through the enterprise catalog, stored
|
|
46
|
+
* in `extension_installs.catalog_item_id` (F-AA) and registered in `extension_catalog_sources`;
|
|
47
|
+
* installing outside the catalog (upload / npm / CLI) **keeps** the existing source items (T26
|
|
48
|
+
* fix: clearing them would let org enablement bypass catalog policy, C22). The detail of the
|
|
49
|
+
* `extension.installed` audit carries `catalogItemId`; when it already points at the same package
|
|
50
|
+
* and only the source item changed, only that column changes, audit
|
|
51
|
+
* `extension.install_source_changed`.
|
|
52
|
+
*/
|
|
53
|
+
async install(name, sha256, actor, actorTokenId, opts = {}) {
|
|
54
|
+
this.assertInstallable(name);
|
|
55
|
+
const pkg = await this.d.db
|
|
56
|
+
.selectFrom("extension_packages")
|
|
57
|
+
.select(["sha256", "name", "package_name", "version", "source"])
|
|
58
|
+
.where("sha256", "=", sha256)
|
|
59
|
+
.executeTakeFirst();
|
|
60
|
+
if (!pkg) {
|
|
61
|
+
throw new ApiError("extension.package_not_found", `Extension package ${sha256} is not in the package store; upload it first`);
|
|
62
|
+
}
|
|
63
|
+
if (pkg.name !== name) {
|
|
64
|
+
throw new ApiError("extension.name_mismatch", `Package ${sha256} contains extension ${pkg.name}, not ${name}`);
|
|
65
|
+
}
|
|
66
|
+
// The downgrade check needs the target package's migration files: read and parse the package
|
|
67
|
+
// outside the transaction (inside it only _migrations is compared). A stored package in the
|
|
68
|
+
// pre-0.1.0 format -> extension.legacy_format.
|
|
69
|
+
const target = await readExtensionPackage(await this.d.blobs.get(sha256), {
|
|
70
|
+
maxBytes: this.d.config().packages.maxBytes,
|
|
71
|
+
hostSdkVersion: SDK_VERSION,
|
|
72
|
+
}).catch((e) => {
|
|
73
|
+
throw e instanceof ExtensionPackageError ? extensionPackageApiError(e) : e;
|
|
74
|
+
});
|
|
75
|
+
const changed = await this.d.db.transaction().execute(async (trx) => {
|
|
76
|
+
if (actor !== null)
|
|
77
|
+
await lockEnterpriseAdminsAndAuthorize(trx, actor);
|
|
78
|
+
const row = await this.lockRow(trx, name);
|
|
79
|
+
// 不经目录重装时保留原来的来源条目(不清空,C22)
|
|
80
|
+
const catalogItemId = opts.catalogItemId ?? row?.catalog_item_id ?? null;
|
|
81
|
+
if (opts.catalogItemId !== undefined) {
|
|
82
|
+
await trx
|
|
83
|
+
.insertInto("extension_catalog_sources")
|
|
84
|
+
.values({ plugin: name, item_id: opts.catalogItemId })
|
|
85
|
+
.onConflict((oc) => oc.columns(["plugin", "item_id"]).doNothing())
|
|
86
|
+
.execute();
|
|
87
|
+
}
|
|
88
|
+
if (row && row.package_name !== pkg.package_name) {
|
|
89
|
+
throw new ApiError("extension.name_conflict", `Extension ${name} is already installed from package ${row.package_name}; package ${pkg.package_name} uses the same extension name`);
|
|
90
|
+
}
|
|
91
|
+
// Ruling P3:插件名归第一次安装它的 npm 包(卸载不删),别的包不能接手(数据、密钥与批准都还在)。
|
|
92
|
+
// 还没有归属、却已有这个名字留下的快照 / 部署配置 / 组织配置(I4:如归属表之前就有的配置声明插件):
|
|
93
|
+
// 不知道它们属于哪个包,同样拒绝
|
|
94
|
+
const owned = await trx
|
|
95
|
+
.selectFrom("extension_name_owners")
|
|
96
|
+
.select("package_name")
|
|
97
|
+
.where("name", "=", name)
|
|
98
|
+
.executeTakeFirst();
|
|
99
|
+
if (!owned && (await hasRetainedData(trx, name))) {
|
|
100
|
+
throw new ApiError("extension.name_conflict", `Extension name ${name} already has retained data (permission approval, deployment config or organization settings) from an extension that is not installed here, and no package owns the name; package ${pkg.package_name} cannot take it over. Remove that data or use a different extension name`);
|
|
101
|
+
}
|
|
102
|
+
await trx
|
|
103
|
+
.insertInto("extension_name_owners")
|
|
104
|
+
.values({ name, package_name: pkg.package_name })
|
|
105
|
+
.onConflict((oc) => oc.column("name").doNothing())
|
|
106
|
+
.execute();
|
|
107
|
+
const owner = await trx
|
|
108
|
+
.selectFrom("extension_name_owners")
|
|
109
|
+
.select("package_name")
|
|
110
|
+
.where("name", "=", name)
|
|
111
|
+
.executeTakeFirstOrThrow();
|
|
112
|
+
if (owner.package_name !== pkg.package_name) {
|
|
113
|
+
throw new ApiError("extension.name_conflict", `Extension name ${name} was previously used by package ${owner.package_name}; its data, secrets and permission approval are retained for that package, so package ${pkg.package_name} cannot take over the name`);
|
|
114
|
+
}
|
|
115
|
+
// 已指向同一个包:什么都不改,降级视图仍给出真实的期望状态
|
|
116
|
+
if (row?.sha256 === sha256) {
|
|
117
|
+
if (row.catalog_item_id !== catalogItemId) {
|
|
118
|
+
// 包没变、只有来源条目变了:照样留审计(来源变化影响 T26 的目录策略约束)
|
|
119
|
+
await trx
|
|
120
|
+
.updateTable("extension_installs")
|
|
121
|
+
.set({ catalog_item_id: catalogItemId })
|
|
122
|
+
.where("name", "=", name)
|
|
123
|
+
.execute();
|
|
124
|
+
await this.audit(trx, actor, actorTokenId, "extension.install_source_changed", name, pkg.version, sha256, { catalogItemId, previousCatalogItemId: row.catalog_item_id });
|
|
125
|
+
}
|
|
126
|
+
return { changed: false, state: row.desired_state };
|
|
127
|
+
}
|
|
128
|
+
if (row && isDowngrade(pkg.version, row.version)) {
|
|
129
|
+
const unrun = await unrunMigrations(trx, name, target.migrationSql);
|
|
130
|
+
if (unrun.length > 0) {
|
|
131
|
+
throw new ApiError("extension.downgrade_unsupported", `Extension ${name} ${pkg.version} has migrations that were never run here (${unrun.join(", ")}); extension migrations only expand, so downgrade only to a version whose migrations have all been applied`, unrun.map((file) => ({ file })));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
await trx
|
|
135
|
+
.insertInto("extension_installs")
|
|
136
|
+
.values({
|
|
137
|
+
name,
|
|
138
|
+
sha256,
|
|
139
|
+
version: pkg.version,
|
|
140
|
+
source: pkg.source,
|
|
141
|
+
desired_state: "disabled",
|
|
142
|
+
installed_by: actor,
|
|
143
|
+
updated_by: actor,
|
|
144
|
+
catalog_item_id: catalogItemId,
|
|
145
|
+
})
|
|
146
|
+
.onConflict((oc) => oc.column("name").doUpdateSet({
|
|
147
|
+
sha256,
|
|
148
|
+
version: pkg.version,
|
|
149
|
+
source: pkg.source,
|
|
150
|
+
updated_by: actor,
|
|
151
|
+
catalog_item_id: catalogItemId,
|
|
152
|
+
updated_at: sql `now()`,
|
|
153
|
+
}))
|
|
154
|
+
.execute();
|
|
155
|
+
await this.audit(trx, actor, actorTokenId, "extension.installed", name, pkg.version, sha256, {
|
|
156
|
+
catalogItemId,
|
|
157
|
+
});
|
|
158
|
+
return { changed: true, state: row?.desired_state ?? "disabled" };
|
|
159
|
+
});
|
|
160
|
+
if (changed.changed)
|
|
161
|
+
await this.notify(name);
|
|
162
|
+
return this.viewAfterCommit(name, { version: pkg.version, sha256, state: changed.state });
|
|
163
|
+
}
|
|
164
|
+
/** Enable on the deployment (audit `extension.enabled`); no change when already enabled. Org enablement is unchanged. */
|
|
165
|
+
enable(name, actor, actorTokenId) {
|
|
166
|
+
return this.setState(name, "enabled", actor, actorTokenId);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Disables on the deployment (audit `extension.disabled`); no change when already disabled. Every
|
|
170
|
+
* replica unloads it (draining in-flight calls), and the extensions that `requires` it unload with
|
|
171
|
+
* it; the org enablement switch is unchanged and the org page shows it as unavailable. A required
|
|
172
|
+
* bootstrap plugin -> `extension.required`.
|
|
173
|
+
*/
|
|
174
|
+
disable(name, actor, actorTokenId) {
|
|
175
|
+
return this.setState(name, "disabled", actor, actorTokenId);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Uninstall: a required bootstrap plugin -> `extension.required`; must be disabled first
|
|
179
|
+
* (otherwise `extension.not_disabled`); deletes the install record
|
|
180
|
+
* and its catalog source items (`extension_catalog_sources`, same transaction; audit
|
|
181
|
+
* `extension.uninstalled`), and keeps the data: the extension schema, secrets, org configs,
|
|
182
|
+
* permission snapshot and the package in the package store are untouched (a reinstall picks them
|
|
183
|
+
* up).
|
|
184
|
+
*/
|
|
185
|
+
async uninstall(name, actor, actorTokenId) {
|
|
186
|
+
this.assertInstallable(name);
|
|
187
|
+
await this.d.db.transaction().execute(async (trx) => {
|
|
188
|
+
if (actor !== null)
|
|
189
|
+
await lockEnterpriseAdminsAndAuthorize(trx, actor);
|
|
190
|
+
const row = await this.lockRow(trx, name);
|
|
191
|
+
if (!row)
|
|
192
|
+
throw notFound(name);
|
|
193
|
+
if (row.required)
|
|
194
|
+
throw required(name);
|
|
195
|
+
if (row.desired_state !== "disabled") {
|
|
196
|
+
throw new ApiError("extension.not_disabled", `Extension ${name} is enabled; disable it before uninstalling`);
|
|
197
|
+
}
|
|
198
|
+
await trx.deleteFrom("extension_installs").where("name", "=", name).execute();
|
|
199
|
+
// 来源条目随安装记录一起删:之后不经目录重新安装时不再受旧条目的策略约束(T26 裁决)
|
|
200
|
+
await trx.deleteFrom("extension_catalog_sources").where("plugin", "=", name).execute();
|
|
201
|
+
await this.audit(trx, actor, actorTokenId, "extension.uninstalled", name, row.version, row.sha256);
|
|
202
|
+
});
|
|
203
|
+
await this.notify(name);
|
|
204
|
+
}
|
|
205
|
+
async setState(name, state, actor, actorTokenId) {
|
|
206
|
+
this.assertInstallable(name);
|
|
207
|
+
const result = await this.d.db.transaction().execute(async (trx) => {
|
|
208
|
+
if (actor !== null)
|
|
209
|
+
await lockEnterpriseAdminsAndAuthorize(trx, actor);
|
|
210
|
+
const row = await this.lockRow(trx, name);
|
|
211
|
+
if (!row)
|
|
212
|
+
throw notFound(name);
|
|
213
|
+
if (state === "disabled" && row.required)
|
|
214
|
+
throw required(name);
|
|
215
|
+
if (row.desired_state === state)
|
|
216
|
+
return { row, changed: false };
|
|
217
|
+
await trx
|
|
218
|
+
.updateTable("extension_installs")
|
|
219
|
+
.set({
|
|
220
|
+
desired_state: state,
|
|
221
|
+
updated_by: actor,
|
|
222
|
+
updated_at: sql `now()`,
|
|
223
|
+
})
|
|
224
|
+
.where("name", "=", name)
|
|
225
|
+
.execute();
|
|
226
|
+
await this.audit(trx, actor, actorTokenId, state === "enabled" ? "extension.enabled" : "extension.disabled", name, row.version, row.sha256);
|
|
227
|
+
return { row, changed: true };
|
|
228
|
+
});
|
|
229
|
+
if (result.changed)
|
|
230
|
+
await this.notify(name);
|
|
231
|
+
return this.viewAfterCommit(name, {
|
|
232
|
+
version: result.row.version,
|
|
233
|
+
sha256: result.row.sha256,
|
|
234
|
+
state,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* 提交后的视图:拼视图失败(读包、查状态行出错)时操作已经生效,不能再报失败——记 error,返回降级视图。
|
|
239
|
+
*/
|
|
240
|
+
async viewAfterCommit(name, known) {
|
|
241
|
+
try {
|
|
242
|
+
return await this.d.view(name);
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
this.d.log.error("plugin change committed, but its admin view cannot be built", {
|
|
246
|
+
plugin: name,
|
|
247
|
+
err,
|
|
248
|
+
});
|
|
249
|
+
return fallbackView(name, known, err);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/** 配置声明的插件不经安装记录管理。 */
|
|
253
|
+
assertInstallable(name) {
|
|
254
|
+
const declared = this.d.declared().get(name);
|
|
255
|
+
if (declared === "config") {
|
|
256
|
+
throw new ApiError("extension.config_declared", `Extension ${name} is declared in the startup config (extensions); change that list and restart instead`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/** 按插件名串行(咨询锁,覆盖「还没有行」的新装),再锁住已有的安装记录行。 */
|
|
260
|
+
async lockRow(trx, name) {
|
|
261
|
+
await sql `SELECT pg_advisory_xact_lock(hashtext(${`capybara.plugin-install:${name}`}))`.execute(trx);
|
|
262
|
+
return trx
|
|
263
|
+
.selectFrom("extension_installs")
|
|
264
|
+
.innerJoin("extension_packages", "extension_packages.sha256", "extension_installs.sha256")
|
|
265
|
+
.select([
|
|
266
|
+
"extension_installs.sha256",
|
|
267
|
+
"extension_installs.version",
|
|
268
|
+
"extension_installs.desired_state",
|
|
269
|
+
"extension_installs.catalog_item_id",
|
|
270
|
+
"extension_installs.required",
|
|
271
|
+
"extension_packages.package_name",
|
|
272
|
+
])
|
|
273
|
+
.where("extension_installs.name", "=", name)
|
|
274
|
+
.forUpdate("extension_installs")
|
|
275
|
+
.executeTakeFirst();
|
|
276
|
+
}
|
|
277
|
+
async audit(trx, actor, actorTokenId, action, name, version, sha256, extra = {}) {
|
|
278
|
+
await audit(trx, {
|
|
279
|
+
...(actor !== null && { actorAccountId: actor }),
|
|
280
|
+
...(actorTokenId !== undefined && { actorTokenId }),
|
|
281
|
+
action,
|
|
282
|
+
target: name,
|
|
283
|
+
detail: { name, version, sha256, ...extra },
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/** 提交后通知各副本;发布失败只告警(周期 reconcile 兜底),本副本自己先 reconcile。 */
|
|
287
|
+
async notify(name) {
|
|
288
|
+
try {
|
|
289
|
+
await this.d.bus.publish(PLUGINS_CHANGED_TOPIC, { plugin: name });
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
this.d.log.warn("cannot publish plugins.changed; replicas converge on the next periodic reconcile", { plugin: name, err });
|
|
293
|
+
this.d
|
|
294
|
+
.reconcile?.(`changed:${name}`)
|
|
295
|
+
.catch((e) => this.d.log.error("plugin reconcile failed", { plugin: name, err: e }));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* 拼不出视图时的降级项(与后台列表里包读不到的项同形:status failed、权限为空、带 `error`)。
|
|
301
|
+
*/
|
|
302
|
+
function fallbackView(name, known, err) {
|
|
303
|
+
return {
|
|
304
|
+
name,
|
|
305
|
+
version: known.version,
|
|
306
|
+
source: "install",
|
|
307
|
+
sha256: known.sha256,
|
|
308
|
+
status: "failed",
|
|
309
|
+
desired: known.state === undefined
|
|
310
|
+
? null
|
|
311
|
+
: { version: known.version, sha256: known.sha256, state: known.state },
|
|
312
|
+
replicas: [],
|
|
313
|
+
permissions: [],
|
|
314
|
+
added: [],
|
|
315
|
+
addedItems: [],
|
|
316
|
+
removed: [],
|
|
317
|
+
reviewHash: "",
|
|
318
|
+
sensitive: false,
|
|
319
|
+
warnings: [],
|
|
320
|
+
snapshot: null,
|
|
321
|
+
configurable: false,
|
|
322
|
+
configValid: true,
|
|
323
|
+
removable: true,
|
|
324
|
+
required: false,
|
|
325
|
+
installSource: null,
|
|
326
|
+
error: `the change was saved, but its current status cannot be read: ${err instanceof Error ? err.message : String(err)}`,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
/** 插件名已留下的数据:权限快照、部署配置、任一组织的配置,或插件 schema(`plugin_<name>`)。 */
|
|
330
|
+
async function hasRetainedData(trx, name) {
|
|
331
|
+
const schema = await sql `SELECT 1 AS x FROM pg_namespace WHERE nspname = ${pluginSchemaName(name)}`.execute(trx);
|
|
332
|
+
if (schema.rows.length > 0)
|
|
333
|
+
return true;
|
|
334
|
+
const hit = await trx
|
|
335
|
+
.selectFrom("extension_permission_snapshots")
|
|
336
|
+
.select(sql `1`.as("x"))
|
|
337
|
+
.where("plugin", "=", name)
|
|
338
|
+
.union(trx
|
|
339
|
+
.selectFrom("extension_deployment_configs")
|
|
340
|
+
.select(sql `1`.as("x"))
|
|
341
|
+
.where("plugin", "=", name))
|
|
342
|
+
.union(trx
|
|
343
|
+
.selectFrom("extension_org_configs")
|
|
344
|
+
.select(sql `1`.as("x"))
|
|
345
|
+
.where("plugin", "=", name))
|
|
346
|
+
.limit(1)
|
|
347
|
+
.executeTakeFirst();
|
|
348
|
+
return hit !== undefined;
|
|
349
|
+
}
|
|
350
|
+
const required = (name) => new ApiError("extension.required", `Extension ${name} is required by this deployment (a bootstrap plugin): it is enabled in every organization and cannot be disabled or uninstalled; an enterprise admin can upgrade it`);
|
|
351
|
+
const notFound = (name) => new ApiError("extension.not_found", `Extension ${name} is not installed in this deployment`);
|
|
352
|
+
/** `to` 比 `from` 旧(任一方不是合法 semver 时不算降级)。 */
|
|
353
|
+
const isDowngrade = (to, from) => semver.valid(to) !== null && semver.valid(from) !== null && semver.lt(to, from);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { KernelConfig } from "../config/schema.js";
|
|
2
|
+
import type { KernelDb } from "../db/kernel-schema.js";
|
|
3
|
+
import type { ExtensionBlobs } from "./blobs.js";
|
|
4
|
+
import type { DeclaredExtensionInfo } from "./host.js";
|
|
5
|
+
import type { ExtensionInstalls } from "./installs.js";
|
|
6
|
+
import { PLUGINS_CHANGED_TOPIC } from "./lifecycle.js";
|
|
7
|
+
import { type AdminExtensionView } from "./permission-view.js";
|
|
8
|
+
export { PLUGINS_CHANGED_TOPIC };
|
|
9
|
+
/** The web approval request body (`POST /api/v1/admin/extensions/:name/approve`). */
|
|
10
|
+
export interface ApproveBody {
|
|
11
|
+
/** 安装记录的包;配置声明的插件为 null。 */
|
|
12
|
+
sha256: string | null;
|
|
13
|
+
reviewHash: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ExtensionAdminDeps {
|
|
16
|
+
db: KernelDb;
|
|
17
|
+
blobs: Pick<ExtensionBlobs, "get">;
|
|
18
|
+
installs: ExtensionInstalls;
|
|
19
|
+
config: () => KernelConfig;
|
|
20
|
+
host: {
|
|
21
|
+
declaredPlugins(): DeclaredExtensionInfo[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* 本副本 reconcile(批准后等它完成再返回视图;其他副本经 `kernel.plugins.changed` 收敛)。CLI 没有(只发布)。
|
|
25
|
+
*/
|
|
26
|
+
reconcile?: (reason: string) => Promise<void>;
|
|
27
|
+
bus: {
|
|
28
|
+
publish(topic: string, payload: unknown): Promise<void>;
|
|
29
|
+
};
|
|
30
|
+
log: {
|
|
31
|
+
warn(msg: string, fields?: Record<string, unknown>): void;
|
|
32
|
+
error(msg: string, fields?: Record<string, unknown>): void;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 部署级插件后台(企业管理员):列表 / 详情与网页批准权限(D8)。无状态,多副本共用;
|
|
37
|
+
* 状态由 PG(安装记录、快照、各副本状态行)与本副本宿主(配置声明插件的清单)推出。
|
|
38
|
+
*/
|
|
39
|
+
export declare class ExtensionAdmin {
|
|
40
|
+
private readonly d;
|
|
41
|
+
private readonly packageSets;
|
|
42
|
+
constructor(d: ExtensionAdminDeps);
|
|
43
|
+
/** 全部插件(配置声明 → 安装记录,各自按名字)。 */
|
|
44
|
+
list(): Promise<AdminExtensionView[]>;
|
|
45
|
+
/**
|
|
46
|
+
* A single extension; unknown -> `extension.not_found`; package unreadable ->
|
|
47
|
+
* `extension.package_unavailable`. With `allowUnreadable` an unreadable package returns the same
|
|
48
|
+
* degraded item as {@link list} (status failed, with `error`): used after a write has committed, so
|
|
49
|
+
* an operation that took effect is not reported as failed. A package in the pre-0.1.0 format is
|
|
50
|
+
* a state, not an error: it always returns the item with status `legacy_format` (so the admin can
|
|
51
|
+
* see it and uninstall it).
|
|
52
|
+
*/
|
|
53
|
+
get(name: string, opts?: {
|
|
54
|
+
allowUnreadable?: boolean;
|
|
55
|
+
}): Promise<AdminExtensionView>;
|
|
56
|
+
/**
|
|
57
|
+
* Web approval: re-checks the enterprise admin under the lock, compares the reviewed package
|
|
58
|
+
* (`sha256`) and permission digest (`reviewHash`), writes the snapshot (source web) and the
|
|
59
|
+
* `extension.permissions_approved` audit; after the commit publishes `kernel.plugins.changed` (a
|
|
60
|
+
* failure only warns) and waits for one reconcile on this replica (other replicas converge through
|
|
61
|
+
* the bus, the periodic job catches lost messages). Returns the view after approval.
|
|
62
|
+
* - Unknown -> `extension.not_found`;
|
|
63
|
+
* - the install record's `sha256` differs from the current one, or `reviewHash` differs from the one
|
|
64
|
+
* recomputed now -> `extension.approval_stale`; a config-declared extension's `sha256` must be
|
|
65
|
+
* null (otherwise `validation_failed`);
|
|
66
|
+
* - the snapshot already covers the current permission set (nothing to approve, F-N) ->
|
|
67
|
+
* `extension.not_pending`.
|
|
68
|
+
*/
|
|
69
|
+
approve(actor: string, name: string, body: ApproveBody, opts?: {
|
|
70
|
+
actorTokenId?: string;
|
|
71
|
+
}): Promise<AdminExtensionView>;
|
|
72
|
+
/** 配置声明 → 安装记录(与配置声明重名的安装记录不生效,不单列)。`only` 给出时只取这一个。 */
|
|
73
|
+
private subjects;
|
|
74
|
+
/**
|
|
75
|
+
* 包的权限集合(静态清单 + 迁移 SQL,与上传时的审阅相同)、迁移审阅警告与是否有部署级配置字段;按 sha256 缓存。
|
|
76
|
+
*/
|
|
77
|
+
private packageInfo;
|
|
78
|
+
private views;
|
|
79
|
+
}
|