@capybara-hq/kernel 0.1.0-rc.1 → 0.1.0-rc.3
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/dist/admin/admin.controller.d.ts +17 -17
- package/dist/admin/admin.controller.js +43 -26
- package/dist/admin/admin.module.d.ts +3 -0
- package/dist/admin/admin.module.js +22 -0
- package/dist/admin/extensions.controller.d.ts +14 -14
- package/dist/admin/extensions.controller.js +30 -17
- package/dist/admin/setup-lock.d.ts +16 -0
- package/dist/admin/setup-lock.js +47 -0
- package/dist/admin/setup.controller.d.ts +8 -8
- package/dist/admin/setup.controller.js +27 -25
- package/dist/admin/setup.service.d.ts +19 -27
- package/dist/admin/setup.service.js +61 -61
- package/dist/agents/agent-lookup.d.ts +53 -0
- package/dist/agents/agent-lookup.js +187 -0
- package/dist/agents/agents.controller.d.ts +1 -1
- package/dist/agents/agents.controller.js +14 -8
- package/dist/agents/agents.module.d.ts +7 -0
- package/dist/agents/agents.module.js +41 -0
- package/dist/agents/agents.service.d.ts +39 -58
- package/dist/agents/agents.service.js +280 -335
- package/dist/agents/definition.d.ts +39 -8
- package/dist/agents/definition.js +201 -17
- package/dist/agents/models.controller.d.ts +1 -1
- package/dist/agents/models.controller.js +2 -2
- package/dist/agents/templates.controller.d.ts +1 -1
- package/dist/agents/templates.controller.js +2 -2
- package/dist/agents/templates.d.ts +6 -8
- package/dist/agents/templates.js +39 -8
- package/dist/app.d.ts +93 -0
- package/dist/app.js +150 -0
- package/dist/catalog/admin-catalog.controller.d.ts +3 -3
- package/dist/catalog/admin-catalog.controller.js +27 -13
- package/dist/catalog/catalog-content.d.ts +185 -0
- package/dist/catalog/catalog-content.js +326 -0
- package/dist/catalog/catalog-items.d.ts +186 -0
- package/dist/catalog/catalog-items.js +410 -0
- package/dist/catalog/catalog.module.d.ts +14 -0
- package/dist/catalog/catalog.module.js +71 -0
- package/dist/catalog/catalog.service.d.ts +34 -188
- package/dist/catalog/catalog.service.js +155 -489
- package/dist/catalog/claude/agents.js +13 -10
- package/dist/catalog/cli.d.ts +3 -2
- package/dist/catalog/cli.js +13 -31
- package/dist/catalog/job-ids.d.ts +15 -0
- package/dist/catalog/job-ids.js +15 -0
- package/dist/catalog/jobs.d.ts +27 -0
- package/dist/catalog/jobs.js +70 -0
- package/dist/catalog/locks.d.ts +24 -0
- package/dist/catalog/locks.js +63 -0
- package/dist/catalog/marketplaces.controller.d.ts +4 -4
- package/dist/catalog/marketplaces.controller.js +22 -11
- package/dist/catalog/marketplaces.service.d.ts +31 -14
- package/dist/catalog/marketplaces.service.js +330 -256
- package/dist/catalog/org-catalog.controller.d.ts +4 -3
- package/dist/catalog/org-catalog.controller.js +29 -14
- package/dist/catalog/org-catalog.service.d.ts +32 -198
- package/dist/catalog/org-catalog.service.js +159 -400
- package/dist/catalog/plugin-import.d.ts +73 -34
- package/dist/catalog/plugin-import.js +356 -217
- package/dist/catalog/plugin-install.d.ts +83 -41
- package/dist/catalog/plugin-install.js +421 -269
- package/dist/catalog/plugin-upgrade.d.ts +59 -4
- package/dist/catalog/plugin-upgrade.js +407 -282
- package/dist/catalog/requests.service.d.ts +27 -15
- package/dist/catalog/requests.service.js +201 -145
- package/dist/catalog/upgrade-targets.d.ts +4 -7
- package/dist/channels/actions.d.ts +6 -4
- package/dist/channels/actions.js +1 -1
- package/dist/channels/cards.d.ts +10 -4
- package/dist/channels/cards.js +16 -8
- package/dist/channels/channels.module.d.ts +40 -0
- package/dist/channels/channels.module.js +128 -0
- package/dist/channels/connections.controller.d.ts +1 -1
- package/dist/channels/connections.controller.js +11 -6
- package/dist/channels/connections.service.d.ts +43 -21
- package/dist/channels/connections.service.js +236 -131
- package/dist/channels/inbound.d.ts +34 -38
- package/dist/channels/inbound.js +107 -41
- package/dist/channels/job-ids.d.ts +10 -0
- package/dist/channels/job-ids.js +10 -0
- package/dist/channels/jobs.d.ts +85 -0
- package/dist/channels/jobs.js +157 -0
- package/dist/channels/outbound.d.ts +60 -82
- package/dist/channels/outbound.js +165 -194
- package/dist/channels/supervisor.d.ts +88 -46
- package/dist/channels/supervisor.js +230 -132
- package/dist/channels/threads.d.ts +29 -8
- package/dist/channels/threads.js +71 -13
- package/dist/channels/webhook.d.ts +20 -14
- package/dist/channels/webhook.js +51 -20
- package/dist/config/load.d.ts +3 -2
- package/dist/config/load.js +3 -2
- package/dist/config/nacos-source.js +11 -2
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.js +12 -6
- package/dist/conversations/access.d.ts +29 -0
- package/dist/conversations/access.js +86 -0
- package/dist/conversations/artifacts.d.ts +11 -11
- package/dist/conversations/artifacts.js +36 -10
- package/dist/conversations/attachments.controller.d.ts +1 -1
- package/dist/conversations/attachments.controller.js +8 -6
- package/dist/conversations/attachments.module.d.ts +7 -0
- package/dist/conversations/attachments.module.js +25 -0
- package/dist/conversations/attachments.service.d.ts +30 -22
- package/dist/conversations/attachments.service.js +119 -46
- package/dist/conversations/conversations.controller.d.ts +8 -7
- package/dist/conversations/conversations.controller.js +59 -29
- package/dist/conversations/conversations.module.d.ts +8 -0
- package/dist/conversations/conversations.module.js +69 -0
- package/dist/conversations/conversations.service.d.ts +40 -38
- package/dist/conversations/conversations.service.js +130 -140
- package/dist/conversations/event-log.d.ts +39 -18
- package/dist/conversations/event-log.js +93 -27
- package/dist/conversations/events.d.ts +23 -3
- package/dist/conversations/events.js +26 -14
- package/dist/conversations/files.d.ts +10 -10
- package/dist/conversations/files.js +37 -11
- package/dist/conversations/idem-keys.d.ts +5 -0
- package/dist/conversations/idem-keys.js +5 -0
- package/dist/conversations/job-ids.d.ts +6 -0
- package/dist/conversations/job-ids.js +6 -0
- package/dist/conversations/outputs-read.d.ts +11 -11
- package/dist/conversations/outputs-read.js +31 -7
- package/dist/conversations/queue.d.ts +48 -56
- package/dist/conversations/queue.js +13 -289
- package/dist/conversations/queue.service.d.ts +60 -0
- package/dist/conversations/queue.service.js +343 -0
- package/dist/conversations/sandbox-status.d.ts +13 -10
- package/dist/conversations/sandbox-status.js +36 -8
- package/dist/conversations/titles.d.ts +71 -24
- package/dist/conversations/titles.js +159 -63
- package/dist/ctx/bus.js +9 -3
- package/dist/ctx/create-ctx.d.ts +6 -0
- package/dist/ctx/create-ctx.js +7 -9
- package/dist/ctx/lock.d.ts +7 -3
- package/dist/ctx/lock.js +9 -20
- package/dist/ctx/secrets.d.ts +10 -2
- package/dist/ctx/secrets.js +7 -3
- package/dist/db/kernel-schema.d.ts +4 -4
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +1 -0
- package/dist/evals/budget.d.ts +42 -21
- package/dist/evals/budget.js +114 -62
- package/dist/evals/evals.module.d.ts +31 -0
- package/dist/evals/evals.module.js +114 -0
- package/dist/evals/jobs.d.ts +20 -0
- package/dist/evals/jobs.js +45 -0
- package/dist/evals/recorded-tools.d.ts +27 -1
- package/dist/evals/recorded-tools.js +85 -10
- package/dist/evals/run-replay.d.ts +61 -8
- package/dist/evals/run-replay.js +159 -85
- package/dist/evals/runs.controller.d.ts +1 -1
- package/dist/evals/runs.controller.js +17 -8
- package/dist/evals/runs.service.d.ts +23 -45
- package/dist/evals/runs.service.js +245 -234
- package/dist/evals/sets.controller.d.ts +1 -1
- package/dist/evals/sets.controller.js +17 -8
- package/dist/evals/sets.service.d.ts +22 -6
- package/dist/evals/sets.service.js +248 -194
- package/dist/evals/snapshot.d.ts +2 -2
- package/dist/evals/step-replay.d.ts +2 -2
- package/dist/evals/step-replay.js +1 -1
- package/dist/evals/trajectory.controller.d.ts +1 -1
- package/dist/evals/trajectory.controller.js +11 -7
- package/dist/evals/trajectory.d.ts +2 -2
- package/dist/evals/trajectory.service.d.ts +5 -4
- package/dist/evals/trajectory.service.js +30 -7
- package/dist/evals/worker.d.ts +44 -27
- package/dist/evals/worker.js +220 -121
- package/dist/extensions/admin-ops.d.ts +61 -33
- package/dist/extensions/admin-ops.js +248 -154
- package/dist/extensions/admin-view.d.ts +38 -27
- package/dist/extensions/admin-view.js +126 -55
- package/dist/extensions/approvals.d.ts +12 -8
- package/dist/extensions/approvals.js +73 -46
- package/dist/extensions/blobs.d.ts +27 -10
- package/dist/extensions/blobs.js +111 -45
- package/dist/extensions/bootstrap.d.ts +58 -31
- package/dist/extensions/bootstrap.js +175 -121
- package/dist/extensions/cli.d.ts +20 -10
- package/dist/extensions/cli.js +41 -96
- package/dist/extensions/config-issues.d.ts +7 -0
- package/dist/extensions/config-issues.js +31 -0
- package/dist/extensions/deployment-config-store.d.ts +49 -0
- package/dist/extensions/deployment-config-store.js +133 -0
- package/dist/extensions/deployment-config.d.ts +58 -67
- package/dist/extensions/deployment-config.js +202 -230
- package/dist/extensions/enabled.d.ts +5 -5
- package/dist/extensions/extensions.module.d.ts +8 -0
- package/dist/extensions/extensions.module.js +77 -0
- package/dist/extensions/hooks.d.ts +3 -2
- package/dist/extensions/hooks.js +1 -1
- package/dist/extensions/host.d.ts +72 -68
- package/dist/extensions/host.js +191 -152
- package/dist/extensions/installs.d.ts +49 -16
- package/dist/extensions/installs.js +128 -32
- package/dist/extensions/job-ids.d.ts +6 -0
- package/dist/extensions/job-ids.js +6 -0
- package/dist/extensions/lifecycle-topics.d.ts +18 -0
- package/dist/extensions/lifecycle-topics.js +18 -0
- package/dist/extensions/lifecycle.d.ts +35 -47
- package/dist/extensions/lifecycle.js +103 -39
- package/dist/extensions/locks.d.ts +33 -0
- package/dist/extensions/locks.js +86 -0
- package/dist/extensions/migrate-lock.d.ts +3 -4
- package/dist/extensions/org-config.controller.d.ts +1 -1
- package/dist/extensions/org-config.controller.js +8 -5
- package/dist/extensions/org-config.d.ts +48 -46
- package/dist/extensions/org-config.js +284 -226
- package/dist/extensions/registry.d.ts +50 -2
- package/dist/extensions/registry.js +89 -4
- package/dist/extensions/sources.d.ts +12 -8
- package/dist/extensions/sources.js +34 -13
- package/dist/files/files.module.d.ts +3 -0
- package/dist/files/files.module.js +22 -0
- package/dist/files/previewers.controller.d.ts +7 -2
- package/dist/files/previewers.controller.js +17 -9
- package/dist/files/previewers.d.ts +13 -18
- package/dist/files/previewers.js +83 -36
- package/dist/http/adapter.d.ts +3 -0
- package/dist/http/adapter.js +25 -0
- package/dist/http/api.module.d.ts +3 -110
- package/dist/http/api.module.js +47 -355
- package/dist/http/app.d.ts +11 -15
- package/dist/http/app.js +17 -62
- package/dist/http/error-filter.module.d.ts +5 -0
- package/dist/http/error-filter.module.js +18 -0
- package/dist/http/error.filter.js +2 -2
- package/dist/identity/accounts.d.ts +82 -29
- package/dist/identity/accounts.js +294 -175
- package/dist/identity/api-tokens.d.ts +11 -7
- package/dist/identity/api-tokens.js +71 -44
- package/dist/identity/audit.d.ts +7 -4
- package/dist/identity/audit.js +5 -1
- package/dist/identity/auth.controller.d.ts +11 -10
- package/dist/identity/auth.controller.js +31 -25
- package/dist/identity/auth.guard.d.ts +3 -3
- package/dist/identity/auth.guard.js +6 -4
- package/dist/identity/binding.d.ts +9 -11
- package/dist/identity/binding.js +41 -13
- package/dist/identity/enterprise-admin.d.ts +18 -12
- package/dist/identity/enterprise-admin.js +67 -13
- package/dist/identity/external-identity-lock.d.ts +17 -0
- package/dist/identity/external-identity-lock.js +39 -0
- package/dist/identity/external.d.ts +19 -15
- package/dist/identity/external.js +163 -125
- package/dist/identity/identity.module.d.ts +6 -0
- package/dist/identity/identity.module.js +56 -0
- package/dist/identity/me.controller.d.ts +16 -15
- package/dist/identity/me.controller.js +37 -31
- package/dist/identity/sessions.d.ts +12 -10
- package/dist/identity/sessions.js +74 -42
- package/dist/identity/settings.d.ts +20 -14
- package/dist/identity/settings.js +86 -58
- package/dist/identity/sso.controller.d.ts +7 -7
- package/dist/identity/sso.controller.js +13 -9
- package/dist/identity/sso.d.ts +9 -12
- package/dist/identity/sso.js +54 -24
- package/dist/inbox/inbox.module.d.ts +3 -0
- package/dist/inbox/inbox.module.js +22 -0
- package/dist/inbox/inbox.service.d.ts +7 -9
- package/dist/inbox/inbox.service.js +32 -11
- package/dist/index.d.ts +16 -11
- package/dist/index.js +9 -6
- package/dist/infra/cache/cache.module.d.ts +3 -0
- package/dist/infra/cache/cache.module.js +16 -0
- package/dist/infra/cache/cache.service.d.ts +21 -0
- package/dist/infra/cache/cache.service.js +80 -0
- package/dist/infra/cache/cacheable.decorator.d.ts +32 -0
- package/dist/infra/cache/cacheable.decorator.js +83 -0
- package/dist/infra/cli/kernel-cli.module.d.ts +66 -0
- package/dist/infra/cli/kernel-cli.module.js +165 -0
- package/dist/infra/close-within.d.ts +15 -0
- package/dist/infra/close-within.js +36 -0
- package/dist/infra/config/config.module.d.ts +13 -0
- package/dist/infra/config/config.module.js +39 -0
- package/dist/infra/config/kernel-config.service.d.ts +25 -0
- package/dist/infra/config/kernel-config.service.js +126 -0
- package/dist/infra/database/after-commit.d.ts +6 -0
- package/dist/infra/database/after-commit.js +9 -0
- package/dist/infra/database/database.module.d.ts +25 -0
- package/dist/infra/database/database.module.js +90 -0
- package/dist/infra/database/kernel-db.d.ts +22 -0
- package/dist/infra/database/kernel-db.js +65 -0
- package/dist/infra/database/transaction-host.d.ts +50 -0
- package/dist/infra/database/transaction-host.js +125 -0
- package/dist/infra/database/transactional.decorator.d.ts +15 -0
- package/dist/infra/database/transactional.decorator.js +27 -0
- package/dist/infra/database/xact-lock.d.ts +17 -0
- package/dist/infra/database/xact-lock.js +43 -0
- package/dist/infra/events/kernel-events.d.ts +96 -0
- package/dist/infra/events/kernel-events.js +65 -0
- package/dist/infra/health/health.controller.d.ts +26 -0
- package/dist/infra/health/health.controller.js +104 -0
- package/dist/infra/health/health.module.d.ts +9 -0
- package/dist/infra/health/health.module.js +24 -0
- package/dist/infra/health/health.options.d.ts +10 -0
- package/dist/infra/health/health.options.js +15 -0
- package/dist/infra/health/shutdown-state.d.ts +6 -0
- package/dist/infra/health/shutdown-state.js +2 -0
- package/dist/infra/lifecycle/graceful-shutdown.module.d.ts +6 -0
- package/dist/infra/lifecycle/graceful-shutdown.module.js +23 -0
- package/dist/infra/lifecycle/graceful-shutdown.service.d.ts +70 -0
- package/dist/infra/lifecycle/graceful-shutdown.service.js +135 -0
- package/dist/infra/lifecycle/process-guards.d.ts +52 -0
- package/dist/infra/lifecycle/process-guards.js +86 -0
- package/dist/infra/lifecycle/shutdown-signals.d.ts +30 -0
- package/dist/infra/lifecycle/shutdown-signals.js +48 -0
- package/dist/infra/lock/key-template.d.ts +13 -0
- package/dist/infra/lock/key-template.js +46 -0
- package/dist/infra/lock/lock.module.d.ts +3 -0
- package/dist/infra/lock/lock.module.js +16 -0
- package/dist/infra/lock/lock.service.d.ts +120 -0
- package/dist/infra/lock/lock.service.js +343 -0
- package/dist/infra/lock/shared-lease.d.ts +44 -0
- package/dist/infra/lock/shared-lease.js +121 -0
- package/dist/infra/lock/with-lock.decorator.d.ts +28 -0
- package/dist/infra/lock/with-lock.decorator.js +49 -0
- package/dist/infra/logging/logging.module.d.ts +16 -0
- package/dist/infra/logging/logging.module.js +34 -0
- package/dist/infra/queue/configured-processor.d.ts +18 -0
- package/dist/infra/queue/configured-processor.js +23 -0
- package/dist/infra/queue/job-failure.d.ts +18 -0
- package/dist/infra/queue/job-failure.js +26 -0
- package/dist/infra/queue/queue-shutdown.d.ts +27 -0
- package/dist/infra/queue/queue-shutdown.js +81 -0
- package/dist/infra/queue/queue.module.d.ts +16 -0
- package/dist/infra/queue/queue.module.js +61 -0
- package/dist/infra/queue/redis-connection.d.ts +7 -0
- package/dist/infra/queue/redis-connection.js +18 -0
- package/dist/infra/queue/retired-schedulers.d.ts +7 -0
- package/dist/infra/queue/retired-schedulers.js +9 -0
- package/dist/infra/queue/run-job.d.ts +16 -0
- package/dist/infra/queue/run-job.js +19 -0
- package/dist/infra/redis/redis.module.d.ts +24 -0
- package/dist/infra/redis/redis.module.js +87 -0
- package/dist/infra/schedule/cron-tick.d.ts +12 -0
- package/dist/infra/schedule/cron-tick.js +25 -0
- package/dist/infra/schedule/locked-cron.decorator.d.ts +27 -0
- package/dist/infra/schedule/locked-cron.decorator.js +53 -0
- package/dist/infra/schedule/locked-interval.d.ts +69 -0
- package/dist/infra/schedule/locked-interval.js +190 -0
- package/dist/infra/schedule/locked-tick.d.ts +90 -0
- package/dist/infra/schedule/locked-tick.js +137 -0
- package/dist/infra/schedule/schedule.module.d.ts +8 -0
- package/dist/infra/schedule/schedule.module.js +27 -0
- package/dist/infra/schedule/scheduled-runs.d.ts +69 -0
- package/dist/infra/schedule/scheduled-runs.js +163 -0
- package/dist/infra/swagger/swagger.d.ts +16 -0
- package/dist/infra/swagger/swagger.js +31 -0
- package/dist/infra/throttler/credential-throttler.d.ts +35 -0
- package/dist/infra/throttler/credential-throttler.js +77 -0
- package/dist/infra/throttler/named-throttlers.d.ts +31 -0
- package/dist/infra/throttler/named-throttlers.js +119 -0
- package/dist/infra/throttler/redis-throttler-storage.d.ts +38 -0
- package/dist/infra/throttler/redis-throttler-storage.js +130 -0
- package/dist/infra/throttler/throttler.guard.d.ts +23 -0
- package/dist/infra/throttler/throttler.guard.js +68 -0
- package/dist/infra/throttler/throttler.module.d.ts +15 -0
- package/dist/infra/throttler/throttler.module.js +53 -0
- package/dist/infra/tokens.d.ts +15 -0
- package/dist/infra/tokens.js +15 -0
- package/dist/infra/validation/create-zod-dto.d.ts +23 -0
- package/dist/infra/validation/create-zod-dto.js +35 -0
- package/dist/infra/validation/parse-with-zod.d.ts +7 -0
- package/dist/infra/validation/parse-with-zod.js +12 -0
- package/dist/infra/validation/validation.module.d.ts +3 -0
- package/dist/infra/validation/validation.module.js +16 -0
- package/dist/infra/validation/zod-params.d.ts +7 -0
- package/dist/infra/validation/zod-params.js +42 -0
- package/dist/infra/validation/zod-validation.pipe.d.ts +11 -0
- package/dist/infra/validation/zod-validation.pipe.js +31 -0
- package/dist/kernel.d.ts +9 -244
- package/dist/kernel.js +8 -1305
- package/dist/kernel.module.d.ts +17 -0
- package/dist/kernel.module.js +136 -0
- package/dist/lifecycle/kernel-lifecycle.d.ts +140 -0
- package/dist/lifecycle/kernel-lifecycle.js +456 -0
- package/dist/lifecycle/tokens.d.ts +3 -0
- package/dist/lifecycle/tokens.js +3 -0
- package/dist/log-context.d.ts +2 -0
- package/dist/log-context.js +4 -0
- package/dist/models/models.module.d.ts +3 -0
- package/dist/models/models.module.js +24 -0
- package/dist/models/prices.d.ts +8 -2
- package/dist/models/prices.js +65 -37
- package/dist/models/purposes.controller.d.ts +1 -1
- package/dist/models/purposes.controller.js +5 -6
- package/dist/models/purposes.d.ts +35 -13
- package/dist/models/purposes.js +101 -51
- package/dist/orgs/directory-sync.controller.d.ts +1 -1
- package/dist/orgs/directory-sync.controller.js +2 -2
- package/dist/orgs/directory-sync.d.ts +61 -31
- package/dist/orgs/directory-sync.js +212 -125
- package/dist/orgs/invitations.controller.d.ts +8 -8
- package/dist/orgs/invitations.controller.js +27 -26
- package/dist/orgs/invitations.service.d.ts +12 -9
- package/dist/orgs/invitations.service.js +130 -92
- package/dist/orgs/job-ids.d.ts +8 -0
- package/dist/orgs/job-ids.js +8 -0
- package/dist/orgs/members.service.d.ts +19 -12
- package/dist/orgs/members.service.js +161 -117
- package/dist/orgs/offboarding.d.ts +54 -57
- package/dist/orgs/offboarding.js +161 -71
- package/dist/orgs/org-lock.d.ts +28 -19
- package/dist/orgs/org-lock.js +81 -35
- package/dist/orgs/org.guard.d.ts +1 -1
- package/dist/orgs/org.guard.js +2 -2
- package/dist/orgs/orgs.controller.d.ts +13 -13
- package/dist/orgs/orgs.controller.js +29 -17
- package/dist/orgs/orgs.module.d.ts +6 -0
- package/dist/orgs/orgs.module.js +68 -0
- package/dist/orgs/orgs.service.d.ts +30 -19
- package/dist/orgs/orgs.service.js +139 -86
- package/dist/orgs/settings.controller.d.ts +1 -1
- package/dist/orgs/settings.controller.js +8 -6
- package/dist/orgs/settings.service.d.ts +16 -10
- package/dist/orgs/settings.service.js +77 -48
- package/dist/overrides.d.ts +56 -0
- package/dist/overrides.js +30 -0
- package/dist/roles/gateway-role.d.ts +43 -0
- package/dist/roles/gateway-role.js +98 -0
- package/dist/roles/gateway.module.d.ts +8 -0
- package/dist/roles/gateway.module.js +28 -0
- package/dist/roles/worker-role.d.ts +63 -0
- package/dist/roles/worker-role.js +144 -0
- package/dist/roles/worker.module.d.ts +14 -0
- package/dist/roles/worker.module.js +90 -0
- package/dist/runtime/abort.js +19 -2
- package/dist/runtime/checkpointer.d.ts +8 -3
- package/dist/runtime/checkpointer.js +87 -55
- package/dist/runtime/context/build.d.ts +6 -6
- package/dist/runtime/context/build.js +18 -8
- package/dist/runtime/context/claude-tools.d.ts +2 -1
- package/dist/runtime/context/claude-tools.js +9 -10
- package/dist/runtime/context/legacy-text.d.ts +22 -0
- package/dist/runtime/context/legacy-text.js +37 -0
- package/dist/runtime/context/skills.d.ts +29 -11
- package/dist/runtime/context/skills.js +37 -30
- package/dist/runtime/conversation-lock.d.ts +20 -11
- package/dist/runtime/conversation-lock.js +62 -72
- package/dist/runtime/hook-calls.d.ts +3 -3
- package/dist/runtime/hook-calls.js +1 -6
- package/dist/runtime/job-ids.d.ts +10 -0
- package/dist/runtime/job-ids.js +10 -0
- package/dist/runtime/langgraph-loop.js +1 -1
- package/dist/runtime/loop.d.ts +8 -1
- package/dist/runtime/loop.js +14 -0
- package/dist/runtime/maintenance-queue.d.ts +10 -0
- package/dist/runtime/maintenance-queue.js +10 -0
- package/dist/runtime/maintenance.d.ts +45 -74
- package/dist/runtime/maintenance.js +139 -137
- package/dist/runtime/model-call.d.ts +7 -4
- package/dist/runtime/model-call.js +25 -58
- package/dist/runtime/providers.d.ts +17 -6
- package/dist/runtime/providers.js +66 -25
- package/dist/runtime/quota.d.ts +17 -3
- package/dist/runtime/quota.js +27 -2
- package/dist/runtime/retired-schedulers.d.ts +7 -0
- package/dist/runtime/retired-schedulers.js +31 -0
- package/dist/runtime/run-control.d.ts +33 -0
- package/dist/runtime/run-control.js +77 -0
- package/dist/runtime/run-finish.d.ts +27 -18
- package/dist/runtime/run-finish.js +98 -51
- package/dist/runtime/run-jobs.d.ts +48 -0
- package/dist/runtime/run-jobs.js +95 -0
- package/dist/runtime/run-processors.d.ts +60 -0
- package/dist/runtime/run-processors.js +185 -0
- package/dist/runtime/run-queue.d.ts +32 -57
- package/dist/runtime/run-queue.js +291 -295
- package/dist/runtime/run-steps.d.ts +39 -0
- package/dist/runtime/run-steps.js +96 -0
- package/dist/runtime/run-worker.d.ts +122 -76
- package/dist/runtime/run-worker.js +343 -229
- package/dist/runtime/runtime.module.d.ts +10 -0
- package/dist/runtime/runtime.module.js +112 -0
- package/dist/runtime/step-log.d.ts +40 -0
- package/dist/runtime/step-log.js +94 -0
- package/dist/runtime/stream.controller.d.ts +5 -8
- package/dist/runtime/stream.controller.js +14 -12
- package/dist/runtime/stream.d.ts +24 -6
- package/dist/runtime/stream.js +78 -7
- package/dist/runtime/subagents/child.d.ts +3 -44
- package/dist/runtime/subagents/child.js +0 -79
- package/dist/runtime/subagents/definition.d.ts +5 -10
- package/dist/runtime/subagents/definition.js +13 -14
- package/dist/runtime/subagents/dispatch.d.ts +89 -8
- package/dist/runtime/subagents/dispatch.js +137 -142
- package/dist/runtime/subagents/limits.d.ts +9 -4
- package/dist/runtime/subagents/limits.js +4 -2
- package/dist/runtime/subagents/org-agents.d.ts +4 -4
- package/dist/runtime/subagents/org-agents.js +3 -2
- package/dist/runtime/subagents/progress.d.ts +2 -2
- package/dist/runtime/subagents/roster.d.ts +4 -4
- package/dist/runtime/subagents/roster.js +2 -2
- package/dist/runtime/subagents/skill-fork.d.ts +8 -9
- package/dist/runtime/subagents/skill-fork.js +17 -6
- package/dist/runtime/subagents/subagents.service.d.ts +40 -0
- package/dist/runtime/subagents/subagents.service.js +101 -0
- package/dist/runtime/usage-report.d.ts +94 -52
- package/dist/runtime/usage-report.js +200 -100
- package/dist/runtime/waits.d.ts +127 -59
- package/dist/runtime/waits.js +433 -210
- package/dist/sandbox/job-ids.d.ts +10 -0
- package/dist/sandbox/job-ids.js +10 -0
- package/dist/sandbox/jobs.d.ts +41 -0
- package/dist/sandbox/jobs.js +113 -0
- package/dist/sandbox/leases.d.ts +39 -31
- package/dist/sandbox/leases.js +117 -257
- package/dist/sandbox/providers.d.ts +19 -0
- package/dist/sandbox/providers.js +38 -0
- package/dist/sandbox/sandbox.module.d.ts +8 -0
- package/dist/sandbox/sandbox.module.js +30 -0
- package/dist/sandbox/sandbox.service.d.ts +24 -29
- package/dist/sandbox/sandbox.service.js +106 -75
- package/dist/skills/catalog.d.ts +37 -24
- package/dist/skills/catalog.js +100 -57
- package/dist/skills/changes.controller.d.ts +4 -4
- package/dist/skills/changes.controller.js +15 -9
- package/dist/skills/changes.service.d.ts +30 -20
- package/dist/skills/changes.service.js +425 -367
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +8 -5
- package/dist/skills/invocation-keys.d.ts +1 -1
- package/dist/skills/invocation-keys.js +1 -1
- package/dist/skills/invoke.d.ts +17 -16
- package/dist/skills/invoke.js +53 -21
- package/dist/skills/skills.controller.d.ts +1 -1
- package/dist/skills/skills.controller.js +11 -6
- package/dist/skills/skills.module.d.ts +6 -0
- package/dist/skills/skills.module.js +30 -0
- package/dist/skills/skills.service.d.ts +47 -30
- package/dist/skills/skills.service.js +221 -158
- package/dist/storage/job-ids.d.ts +6 -0
- package/dist/storage/job-ids.js +6 -0
- package/dist/storage/purge.d.ts +22 -7
- package/dist/storage/purge.js +55 -3
- package/dist/storage/storage.module.d.ts +6 -0
- package/dist/storage/storage.module.js +23 -0
- package/dist/storage/storage.service.d.ts +18 -4
- package/dist/storage/storage.service.js +44 -3
- package/dist/tools/approvals.controller.d.ts +1 -1
- package/dist/tools/approvals.controller.js +12 -8
- package/dist/tools/approvals.service.d.ts +33 -25
- package/dist/tools/approvals.service.js +343 -259
- package/dist/tools/breaker.d.ts +2 -2
- package/dist/tools/breaker.js +21 -3
- package/dist/tools/builtin-names.d.ts +73 -0
- package/dist/tools/builtin-names.js +116 -0
- package/dist/tools/builtins/agent.d.ts +7 -7
- package/dist/tools/builtins/agent.js +7 -11
- package/dist/tools/builtins/ask-user.d.ts +3 -3
- package/dist/tools/builtins/ask-user.js +3 -3
- package/dist/tools/builtins/builtin-tools.d.ts +21 -0
- package/dist/tools/builtins/builtin-tools.js +80 -0
- package/dist/tools/builtins/read-tool-output.d.ts +3 -3
- package/dist/tools/builtins/read-tool-output.js +3 -3
- package/dist/tools/builtins/sandbox/bash.d.ts +5 -5
- package/dist/tools/builtins/sandbox/bash.js +33 -30
- package/dist/tools/builtins/sandbox/common.d.ts +5 -4
- package/dist/tools/builtins/sandbox/common.js +2 -2
- package/dist/tools/builtins/sandbox/deliver.d.ts +1 -1
- package/dist/tools/builtins/sandbox/deliver.js +13 -13
- package/dist/tools/builtins/sandbox/edit.d.ts +1 -1
- package/dist/tools/builtins/sandbox/edit.js +42 -31
- package/dist/tools/builtins/sandbox/file-state.d.ts +34 -0
- package/dist/tools/builtins/sandbox/file-state.js +34 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +1 -1
- package/dist/tools/builtins/sandbox/glob-match.js +1 -1
- package/dist/tools/builtins/sandbox/glob.d.ts +1 -1
- package/dist/tools/builtins/sandbox/glob.js +6 -6
- package/dist/tools/builtins/sandbox/grep.d.ts +7 -4
- package/dist/tools/builtins/sandbox/grep.js +149 -32
- 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.d.ts +2 -2
- package/dist/tools/builtins/sandbox/read.js +22 -15
- package/dist/tools/builtins/sandbox/write.d.ts +1 -1
- package/dist/tools/builtins/sandbox/write.js +38 -34
- package/dist/tools/builtins/skill-load.d.ts +6 -6
- package/dist/tools/builtins/skill-load.js +33 -17
- package/dist/tools/builtins/skill-write.d.ts +4 -4
- package/dist/tools/builtins/skill-write.js +10 -10
- package/dist/tools/builtins/tool-search.d.ts +13 -9
- package/dist/tools/builtins/tool-search.js +25 -14
- package/dist/tools/canonical-json.d.ts +6 -0
- package/dist/tools/canonical-json.js +16 -0
- package/dist/tools/connector-content.controller.d.ts +1 -1
- package/dist/tools/connector-content.controller.js +11 -6
- package/dist/tools/connector-content.d.ts +12 -15
- package/dist/tools/connector-content.js +53 -18
- package/dist/tools/connectors.controller.d.ts +1 -1
- package/dist/tools/connectors.controller.js +21 -10
- package/dist/tools/connectors.service.d.ts +31 -13
- package/dist/tools/connectors.service.js +438 -348
- package/dist/tools/credentials.d.ts +17 -20
- package/dist/tools/credentials.js +55 -34
- package/dist/tools/display-names.d.ts +9 -0
- package/dist/tools/display-names.js +24 -0
- package/dist/tools/drift.d.ts +29 -41
- package/dist/tools/drift.js +116 -84
- package/dist/tools/elicitation.js +1 -1
- package/dist/tools/info.d.ts +32 -13
- package/dist/tools/info.js +88 -39
- package/dist/tools/job-ids.d.ts +13 -0
- package/dist/tools/job-ids.js +15 -0
- package/dist/tools/jobs.d.ts +24 -0
- package/dist/tools/jobs.js +69 -0
- package/dist/tools/legacy-data.d.ts +34 -0
- package/dist/tools/legacy-data.js +76 -0
- package/dist/tools/legacy-keys.d.ts +51 -0
- package/dist/tools/legacy-keys.js +115 -0
- package/dist/tools/naming.d.ts +1 -5
- package/dist/tools/naming.js +1 -7
- package/dist/tools/oauth/flow-paths.d.ts +16 -0
- package/dist/tools/oauth/flow-paths.js +38 -0
- package/dist/tools/oauth/flow.d.ts +30 -30
- package/dist/tools/oauth/flow.js +109 -81
- package/dist/tools/oauth/oauth.controller.d.ts +3 -3
- package/dist/tools/oauth/oauth.controller.js +12 -9
- package/dist/tools/oauth/tokens.d.ts +11 -3
- package/dist/tools/oauth/tokens.js +15 -14
- package/dist/tools/outputs.d.ts +13 -4
- package/dist/tools/outputs.js +48 -4
- package/dist/tools/pipeline.d.ts +72 -50
- package/dist/tools/pipeline.js +239 -100
- package/dist/tools/policy.d.ts +3 -16
- package/dist/tools/policy.js +13 -19
- package/dist/tools/questions.controller.d.ts +2 -2
- package/dist/tools/questions.controller.js +9 -6
- package/dist/tools/questions.service.d.ts +26 -25
- package/dist/tools/questions.service.js +201 -142
- package/dist/tools/registry.d.ts +43 -38
- package/dist/tools/registry.js +100 -72
- package/dist/tools/resources.d.ts +1 -1
- package/dist/tools/resources.js +1 -1
- package/dist/tools/specs.d.ts +5 -4
- package/dist/tools/specs.js +3 -1
- package/dist/tools/tools.module.d.ts +10 -0
- package/dist/tools/tools.module.js +91 -0
- package/dist/ui/call-extension.d.ts +16 -0
- package/dist/ui/call-extension.js +38 -0
- package/dist/ui/embed-token.d.ts +9 -5
- package/dist/ui/embed-token.js +34 -6
- package/dist/ui/ui-stream.d.ts +22 -17
- package/dist/ui/ui-stream.js +72 -12
- package/dist/ui/ui.module.d.ts +7 -0
- package/dist/ui/ui.module.js +28 -0
- package/dist/ui/views.controller.d.ts +14 -12
- package/dist/ui/views.controller.js +32 -25
- package/dist/ui/views.d.ts +9 -57
- package/dist/ui/views.js +43 -45
- package/package.json +10 -3
- package/src/migrations/0063_tool_keys_claude_code.sql +220 -0
- package/dist/http/health.controller.d.ts +0 -26
- package/dist/http/health.controller.js +0 -79
- package/dist/http/tokens.d.ts +0 -131
- package/dist/http/tokens.js +0 -131
- package/dist/http/zod.pipe.d.ts +0 -8
- package/dist/http/zod.pipe.js +0 -14
- package/dist/identity/rate-limit.d.ts +0 -55
- package/dist/identity/rate-limit.js +0 -121
- package/dist/sandbox/lifecycle.d.ts +0 -21
- package/dist/sandbox/lifecycle.js +0 -68
- package/dist/tools/builtins/sandbox/names.d.ts +0 -7
- package/dist/tools/builtins/sandbox/names.js +0 -20
- /package/dist/http/{gateway.module.d.ts → gateway-routes.d.ts} +0 -0
- /package/dist/http/{gateway.module.js → gateway-routes.js} +0 -0
|
@@ -1,13 +1,33 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
1
10
|
import { SDK_VERSION } from "@capybara-hq/plugin-sdk";
|
|
11
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
2
12
|
import { sql } from "kysely";
|
|
3
13
|
import semver from "semver";
|
|
4
14
|
import { pluginSchemaName } from "../ctx/create-ctx.js";
|
|
5
15
|
import { ApiError } from "../errors.js";
|
|
6
16
|
import { audit } from "../identity/audit.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
17
|
+
import { EnterpriseAdminLock } from "../identity/enterprise-admin.js";
|
|
18
|
+
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
19
|
+
import { afterCommit } from "../infra/database/after-commit.js";
|
|
20
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
21
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
22
|
+
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
23
|
+
import { KERNEL_BUS, KERNEL_LOGGER } from "../infra/tokens.js";
|
|
24
|
+
import { ExtensionAdmin } from "./admin-view.js";
|
|
25
|
+
import { ExtensionBlobs } from "./blobs.js";
|
|
26
|
+
import { ExtensionLifecycle, PLUGINS_CHANGED_TOPIC } from "./lifecycle.js";
|
|
27
|
+
import { PluginInstallLock } from "./locks.js";
|
|
9
28
|
import { unrunMigrations } from "./migrate-lock.js";
|
|
10
29
|
import { ExtensionPackageError, extensionPackageApiError, readExtensionPackage, } from "./package.js";
|
|
30
|
+
import { ExtensionRegistry } from "./registry.js";
|
|
11
31
|
/**
|
|
12
32
|
* Deployment-level extension install / enable / disable / uninstall (C16 / D15): writes only the PG
|
|
13
33
|
* desired state (`extension_installs`) and the audit, then publishes `kernel.plugins.changed` after
|
|
@@ -17,10 +37,53 @@ import { ExtensionPackageError, extensionPackageApiError, readExtensionPackage,
|
|
|
17
37
|
* Every write runs in a transaction: first `lockEnterpriseAdminsAndAuthorize` (skipped by the CLI),
|
|
18
38
|
* then an advisory lock by extension name and a lock on the install record row.
|
|
19
39
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
let ExtensionAdminOps = class ExtensionAdminOps {
|
|
41
|
+
kdb;
|
|
42
|
+
txHost;
|
|
43
|
+
adminLock;
|
|
44
|
+
installLock;
|
|
45
|
+
admin;
|
|
46
|
+
registry;
|
|
47
|
+
blobs;
|
|
48
|
+
config;
|
|
49
|
+
bus;
|
|
50
|
+
lifecycle;
|
|
51
|
+
log;
|
|
52
|
+
constructor(kdb, txHost,
|
|
53
|
+
/** The enterprise admin lock (identity/enterprise-admin.ts): joins the transaction. */
|
|
54
|
+
adminLock, installLock,
|
|
55
|
+
/**
|
|
56
|
+
* The admin view after the operation, degraded when the package cannot be read
|
|
57
|
+
* (`get(name, { allowUnreadable: true })`). If it throws, the operation has already committed:
|
|
58
|
+
* ops logs an error and returns {@link fallbackView}, so an operation that took effect is not
|
|
59
|
+
* reported as failed.
|
|
60
|
+
*/
|
|
61
|
+
admin,
|
|
62
|
+
/** The config-declared extension names (they cannot be installed / disabled / uninstalled, C15). */
|
|
63
|
+
registry,
|
|
64
|
+
/** Reads packages (a downgrade checks the target version's migration files). */
|
|
65
|
+
blobs, config,
|
|
66
|
+
/** Publishes `kernel.plugins.changed`. */
|
|
67
|
+
bus,
|
|
68
|
+
/**
|
|
69
|
+
* When the publish fails this replica reconciles itself (not awaited; other replicas catch up
|
|
70
|
+
* periodically). A no-op where the lifecycle never started (the CLI).
|
|
71
|
+
*/
|
|
72
|
+
lifecycle, log) {
|
|
73
|
+
this.kdb = kdb;
|
|
74
|
+
this.txHost = txHost;
|
|
75
|
+
this.adminLock = adminLock;
|
|
76
|
+
this.installLock = installLock;
|
|
77
|
+
this.admin = admin;
|
|
78
|
+
this.registry = registry;
|
|
79
|
+
this.blobs = blobs;
|
|
80
|
+
this.config = config;
|
|
81
|
+
this.bus = bus;
|
|
82
|
+
this.lifecycle = lifecycle;
|
|
83
|
+
this.log = log;
|
|
84
|
+
}
|
|
85
|
+
get db() {
|
|
86
|
+
return this.kdb.db;
|
|
24
87
|
}
|
|
25
88
|
/**
|
|
26
89
|
* New install or version change (upgrade / downgrade): the install record points at package
|
|
@@ -52,7 +115,7 @@ export class ExtensionAdminOps {
|
|
|
52
115
|
*/
|
|
53
116
|
async install(name, sha256, actor, actorTokenId, opts = {}) {
|
|
54
117
|
this.assertInstallable(name);
|
|
55
|
-
const pkg = await this.
|
|
118
|
+
const pkg = await this.db
|
|
56
119
|
.selectFrom("extension_packages")
|
|
57
120
|
.select(["sha256", "name", "package_name", "version", "source"])
|
|
58
121
|
.where("sha256", "=", sha256)
|
|
@@ -66,100 +129,101 @@ export class ExtensionAdminOps {
|
|
|
66
129
|
// The downgrade check needs the target package's migration files: read and parse the package
|
|
67
130
|
// outside the transaction (inside it only _migrations is compared). A stored package in the
|
|
68
131
|
// pre-0.1.0 format -> extension.legacy_format.
|
|
69
|
-
const target = await readExtensionPackage(await this.
|
|
70
|
-
maxBytes: this.
|
|
132
|
+
const target = await readExtensionPackage(await this.blobs.get(sha256), {
|
|
133
|
+
maxBytes: this.config.get().packages.maxBytes,
|
|
71
134
|
hostSdkVersion: SDK_VERSION,
|
|
72
135
|
}).catch((e) => {
|
|
73
136
|
throw e instanceof ExtensionPackageError ? extensionPackageApiError(e) : e;
|
|
74
137
|
});
|
|
75
|
-
const changed = await this.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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())
|
|
138
|
+
const changed = await this.writeInstall(name, sha256, pkg, target, actor, actorTokenId, opts);
|
|
139
|
+
return this.viewAfterCommit(name, { version: pkg.version, sha256, state: changed.state });
|
|
140
|
+
}
|
|
141
|
+
async writeInstall(name, sha256, pkg, target, actor, actorTokenId, opts) {
|
|
142
|
+
const db = this.db;
|
|
143
|
+
if (actor !== null)
|
|
144
|
+
await this.adminLock.lockAndAuthorize(actor);
|
|
145
|
+
const row = await this.lockRow(name);
|
|
146
|
+
// 不经目录重装时保留原来的来源条目(不清空,C22)
|
|
147
|
+
const catalogItemId = opts.catalogItemId ?? row?.catalog_item_id ?? null;
|
|
148
|
+
if (opts.catalogItemId !== undefined) {
|
|
149
|
+
await db
|
|
150
|
+
.insertInto("extension_catalog_sources")
|
|
151
|
+
.values({ plugin: name, item_id: opts.catalogItemId })
|
|
152
|
+
.onConflict((oc) => oc.columns(["plugin", "item_id"]).doNothing())
|
|
106
153
|
.execute();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
154
|
+
}
|
|
155
|
+
if (row && row.package_name !== pkg.package_name) {
|
|
156
|
+
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`);
|
|
157
|
+
}
|
|
158
|
+
// Ruling P3:插件名归第一次安装它的 npm 包(卸载不删),别的包不能接手(数据、密钥与批准都还在)。
|
|
159
|
+
// 还没有归属、却已有这个名字留下的快照 / 部署配置 / 组织配置(I4:如归属表之前就有的配置声明插件):
|
|
160
|
+
// 不知道它们属于哪个包,同样拒绝
|
|
161
|
+
const owned = await db
|
|
162
|
+
.selectFrom("extension_name_owners")
|
|
163
|
+
.select("package_name")
|
|
164
|
+
.where("name", "=", name)
|
|
165
|
+
.executeTakeFirst();
|
|
166
|
+
if (!owned && (await hasRetainedData(db, name))) {
|
|
167
|
+
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`);
|
|
168
|
+
}
|
|
169
|
+
await db
|
|
170
|
+
.insertInto("extension_name_owners")
|
|
171
|
+
.values({ name, package_name: pkg.package_name })
|
|
172
|
+
.onConflict((oc) => oc.column("name").doNothing())
|
|
173
|
+
.execute();
|
|
174
|
+
const owner = await db
|
|
175
|
+
.selectFrom("extension_name_owners")
|
|
176
|
+
.select("package_name")
|
|
177
|
+
.where("name", "=", name)
|
|
178
|
+
.executeTakeFirstOrThrow();
|
|
179
|
+
if (owner.package_name !== pkg.package_name) {
|
|
180
|
+
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`);
|
|
181
|
+
}
|
|
182
|
+
// 已指向同一个包:什么都不改,降级视图仍给出真实的期望状态
|
|
183
|
+
if (row?.sha256 === sha256) {
|
|
184
|
+
if (row.catalog_item_id !== catalogItemId) {
|
|
185
|
+
// 包没变、只有来源条目变了:照样留审计(来源变化影响 T26 的目录策略约束)
|
|
186
|
+
await db
|
|
187
|
+
.updateTable("extension_installs")
|
|
188
|
+
.set({ catalog_item_id: catalogItemId })
|
|
189
|
+
.where("name", "=", name)
|
|
190
|
+
.execute();
|
|
191
|
+
await this.audit(actor, actorTokenId, "extension.install_source_changed", name, pkg.version, sha256, { catalogItemId, previousCatalogItemId: row.catalog_item_id });
|
|
127
192
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
193
|
+
return { changed: false, state: row.desired_state };
|
|
194
|
+
}
|
|
195
|
+
if (row && isDowngrade(pkg.version, row.version)) {
|
|
196
|
+
const unrun = await unrunMigrations(db, name, target.migrationSql);
|
|
197
|
+
if (unrun.length > 0) {
|
|
198
|
+
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 })));
|
|
133
199
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return { changed: true, state: row?.desired_state ?? "disabled" };
|
|
200
|
+
}
|
|
201
|
+
await db
|
|
202
|
+
.insertInto("extension_installs")
|
|
203
|
+
.values({
|
|
204
|
+
name,
|
|
205
|
+
sha256,
|
|
206
|
+
version: pkg.version,
|
|
207
|
+
source: pkg.source,
|
|
208
|
+
desired_state: "disabled",
|
|
209
|
+
installed_by: actor,
|
|
210
|
+
updated_by: actor,
|
|
211
|
+
catalog_item_id: catalogItemId,
|
|
212
|
+
})
|
|
213
|
+
.onConflict((oc) => oc.column("name").doUpdateSet({
|
|
214
|
+
sha256,
|
|
215
|
+
version: pkg.version,
|
|
216
|
+
source: pkg.source,
|
|
217
|
+
updated_by: actor,
|
|
218
|
+
catalog_item_id: catalogItemId,
|
|
219
|
+
updated_at: sql `now()`,
|
|
220
|
+
}))
|
|
221
|
+
.execute();
|
|
222
|
+
await this.audit(actor, actorTokenId, "extension.installed", name, pkg.version, sha256, {
|
|
223
|
+
catalogItemId,
|
|
159
224
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return this.viewAfterCommit(name, { version: pkg.version, sha256, state: changed.state });
|
|
225
|
+
afterCommit(() => this.notify(name));
|
|
226
|
+
return { changed: true, state: row?.desired_state ?? "disabled" };
|
|
163
227
|
}
|
|
164
228
|
/** Enable on the deployment (audit `extension.enabled`); no change when already enabled. Org enablement is unchanged. */
|
|
165
229
|
enable(name, actor, actorTokenId) {
|
|
@@ -184,65 +248,68 @@ export class ExtensionAdminOps {
|
|
|
184
248
|
*/
|
|
185
249
|
async uninstall(name, actor, actorTokenId) {
|
|
186
250
|
this.assertInstallable(name);
|
|
187
|
-
await this.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
await
|
|
251
|
+
await this.writeUninstall(name, actor, actorTokenId);
|
|
252
|
+
}
|
|
253
|
+
async writeUninstall(name, actor, actorTokenId) {
|
|
254
|
+
const db = this.db;
|
|
255
|
+
if (actor !== null)
|
|
256
|
+
await this.adminLock.lockAndAuthorize(actor);
|
|
257
|
+
const row = await this.lockRow(name);
|
|
258
|
+
if (!row)
|
|
259
|
+
throw notFound(name);
|
|
260
|
+
if (row.required)
|
|
261
|
+
throw required(name);
|
|
262
|
+
if (row.desired_state !== "disabled") {
|
|
263
|
+
throw new ApiError("extension.not_disabled", `Extension ${name} is enabled; disable it before uninstalling`);
|
|
264
|
+
}
|
|
265
|
+
await db.deleteFrom("extension_installs").where("name", "=", name).execute();
|
|
266
|
+
// 来源条目随安装记录一起删:之后不经目录重新安装时不再受旧条目的策略约束(T26 裁决)
|
|
267
|
+
await db.deleteFrom("extension_catalog_sources").where("plugin", "=", name).execute();
|
|
268
|
+
await this.audit(actor, actorTokenId, "extension.uninstalled", name, row.version, row.sha256);
|
|
269
|
+
afterCommit(() => this.notify(name));
|
|
204
270
|
}
|
|
205
271
|
async setState(name, state, actor, actorTokenId) {
|
|
206
272
|
this.assertInstallable(name);
|
|
207
|
-
const result = await this.
|
|
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);
|
|
273
|
+
const result = await this.writeState(name, state, actor, actorTokenId);
|
|
231
274
|
return this.viewAfterCommit(name, {
|
|
232
275
|
version: result.row.version,
|
|
233
276
|
sha256: result.row.sha256,
|
|
234
277
|
state,
|
|
235
278
|
});
|
|
236
279
|
}
|
|
280
|
+
async writeState(name, state, actor, actorTokenId) {
|
|
281
|
+
const db = this.db;
|
|
282
|
+
if (actor !== null)
|
|
283
|
+
await this.adminLock.lockAndAuthorize(actor);
|
|
284
|
+
const row = await this.lockRow(name);
|
|
285
|
+
if (!row)
|
|
286
|
+
throw notFound(name);
|
|
287
|
+
if (state === "disabled" && row.required)
|
|
288
|
+
throw required(name);
|
|
289
|
+
if (row.desired_state === state)
|
|
290
|
+
return { row, changed: false };
|
|
291
|
+
await db
|
|
292
|
+
.updateTable("extension_installs")
|
|
293
|
+
.set({
|
|
294
|
+
desired_state: state,
|
|
295
|
+
updated_by: actor,
|
|
296
|
+
updated_at: sql `now()`,
|
|
297
|
+
})
|
|
298
|
+
.where("name", "=", name)
|
|
299
|
+
.execute();
|
|
300
|
+
await this.audit(actor, actorTokenId, state === "enabled" ? "extension.enabled" : "extension.disabled", name, row.version, row.sha256);
|
|
301
|
+
afterCommit(() => this.notify(name));
|
|
302
|
+
return { row, changed: true };
|
|
303
|
+
}
|
|
237
304
|
/**
|
|
238
305
|
* 提交后的视图:拼视图失败(读包、查状态行出错)时操作已经生效,不能再报失败——记 error,返回降级视图。
|
|
239
306
|
*/
|
|
240
307
|
async viewAfterCommit(name, known) {
|
|
241
308
|
try {
|
|
242
|
-
return await this.
|
|
309
|
+
return await this.admin.get(name, { allowUnreadable: true });
|
|
243
310
|
}
|
|
244
311
|
catch (err) {
|
|
245
|
-
this.
|
|
312
|
+
this.log.error("plugin change committed, but its admin view cannot be built", {
|
|
246
313
|
plugin: name,
|
|
247
314
|
err,
|
|
248
315
|
});
|
|
@@ -251,15 +318,15 @@ export class ExtensionAdminOps {
|
|
|
251
318
|
}
|
|
252
319
|
/** 配置声明的插件不经安装记录管理。 */
|
|
253
320
|
assertInstallable(name) {
|
|
254
|
-
const declared = this.
|
|
321
|
+
const declared = this.registry.declared().get(name);
|
|
255
322
|
if (declared === "config") {
|
|
256
323
|
throw new ApiError("extension.config_declared", `Extension ${name} is declared in the startup config (extensions); change that list and restart instead`);
|
|
257
324
|
}
|
|
258
325
|
}
|
|
259
|
-
/**
|
|
260
|
-
async lockRow(
|
|
261
|
-
await
|
|
262
|
-
return
|
|
326
|
+
/** 按插件名串行(`PluginInstallLock`,覆盖「还没有行」的新装),再锁住已有的安装记录行。 */
|
|
327
|
+
async lockRow(name) {
|
|
328
|
+
await this.installLock.lock(name);
|
|
329
|
+
return this.db
|
|
263
330
|
.selectFrom("extension_installs")
|
|
264
331
|
.innerJoin("extension_packages", "extension_packages.sha256", "extension_installs.sha256")
|
|
265
332
|
.select([
|
|
@@ -274,8 +341,8 @@ export class ExtensionAdminOps {
|
|
|
274
341
|
.forUpdate("extension_installs")
|
|
275
342
|
.executeTakeFirst();
|
|
276
343
|
}
|
|
277
|
-
async audit(
|
|
278
|
-
await audit(
|
|
344
|
+
async audit(actor, actorTokenId, action, name, version, sha256, extra = {}) {
|
|
345
|
+
await audit(this.db, {
|
|
279
346
|
...(actor !== null && { actorAccountId: actor }),
|
|
280
347
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
281
348
|
action,
|
|
@@ -286,16 +353,43 @@ export class ExtensionAdminOps {
|
|
|
286
353
|
/** 提交后通知各副本;发布失败只告警(周期 reconcile 兜底),本副本自己先 reconcile。 */
|
|
287
354
|
async notify(name) {
|
|
288
355
|
try {
|
|
289
|
-
await this.
|
|
356
|
+
await this.bus.publish(PLUGINS_CHANGED_TOPIC, { plugin: name });
|
|
290
357
|
}
|
|
291
358
|
catch (err) {
|
|
292
|
-
this.
|
|
293
|
-
this.
|
|
294
|
-
.reconcile
|
|
295
|
-
.catch((e) => this.
|
|
359
|
+
this.log.warn("cannot publish plugins.changed; replicas converge on the next periodic reconcile", { plugin: name, err });
|
|
360
|
+
this.lifecycle
|
|
361
|
+
.reconcile(`changed:${name}`)
|
|
362
|
+
.catch((e) => this.log.error("plugin reconcile failed", { plugin: name, err: e }));
|
|
296
363
|
}
|
|
297
364
|
}
|
|
298
|
-
}
|
|
365
|
+
};
|
|
366
|
+
__decorate([
|
|
367
|
+
Transactional()
|
|
368
|
+
], ExtensionAdminOps.prototype, "writeInstall", null);
|
|
369
|
+
__decorate([
|
|
370
|
+
Transactional()
|
|
371
|
+
], ExtensionAdminOps.prototype, "writeUninstall", null);
|
|
372
|
+
__decorate([
|
|
373
|
+
Transactional()
|
|
374
|
+
], ExtensionAdminOps.prototype, "writeState", null);
|
|
375
|
+
__decorate([
|
|
376
|
+
Transactional({ propagation: "mandatory" })
|
|
377
|
+
], ExtensionAdminOps.prototype, "lockRow", null);
|
|
378
|
+
ExtensionAdminOps = __decorate([
|
|
379
|
+
Injectable(),
|
|
380
|
+
__param(0, Inject(KernelDb)),
|
|
381
|
+
__param(1, Inject(TransactionHost)),
|
|
382
|
+
__param(2, Inject(EnterpriseAdminLock)),
|
|
383
|
+
__param(3, Inject(PluginInstallLock)),
|
|
384
|
+
__param(4, Inject(ExtensionAdmin)),
|
|
385
|
+
__param(5, Inject(ExtensionRegistry)),
|
|
386
|
+
__param(6, Inject(ExtensionBlobs)),
|
|
387
|
+
__param(7, Inject(KernelConfigService)),
|
|
388
|
+
__param(8, Inject(KERNEL_BUS)),
|
|
389
|
+
__param(9, Inject(ExtensionLifecycle)),
|
|
390
|
+
__param(10, Inject(KERNEL_LOGGER))
|
|
391
|
+
], ExtensionAdminOps);
|
|
392
|
+
export { ExtensionAdminOps };
|
|
299
393
|
/**
|
|
300
394
|
* 拼不出视图时的降级项(与后台列表里包读不到的项同形:status failed、权限为空、带 `error`)。
|
|
301
395
|
*/
|
|
@@ -327,19 +421,19 @@ function fallbackView(name, known, err) {
|
|
|
327
421
|
};
|
|
328
422
|
}
|
|
329
423
|
/** 插件名已留下的数据:权限快照、部署配置、任一组织的配置,或插件 schema(`plugin_<name>`)。 */
|
|
330
|
-
async function hasRetainedData(
|
|
331
|
-
const schema = await sql `SELECT 1 AS x FROM pg_namespace WHERE nspname = ${pluginSchemaName(name)}`.execute(
|
|
424
|
+
async function hasRetainedData(db, name) {
|
|
425
|
+
const schema = await sql `SELECT 1 AS x FROM pg_namespace WHERE nspname = ${pluginSchemaName(name)}`.execute(db);
|
|
332
426
|
if (schema.rows.length > 0)
|
|
333
427
|
return true;
|
|
334
|
-
const hit = await
|
|
428
|
+
const hit = await db
|
|
335
429
|
.selectFrom("extension_permission_snapshots")
|
|
336
430
|
.select(sql `1`.as("x"))
|
|
337
431
|
.where("plugin", "=", name)
|
|
338
|
-
.union(
|
|
432
|
+
.union(db
|
|
339
433
|
.selectFrom("extension_deployment_configs")
|
|
340
434
|
.select(sql `1`.as("x"))
|
|
341
435
|
.where("plugin", "=", name))
|
|
342
|
-
.union(
|
|
436
|
+
.union(db
|
|
343
437
|
.selectFrom("extension_org_configs")
|
|
344
438
|
.select(sql `1`.as("x"))
|
|
345
439
|
.where("plugin", "=", name))
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
1
|
+
import { EnterpriseAdminLock } from "../identity/enterprise-admin.js";
|
|
2
|
+
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
3
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
4
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
5
|
+
import type { KernelLogger } from "../log.js";
|
|
6
|
+
import { ExtensionApprovals } from "./approvals.js";
|
|
7
|
+
import { ExtensionBlobs } from "./blobs.js";
|
|
8
|
+
import { ExtensionHost } from "./host.js";
|
|
9
|
+
import { ExtensionInstalls } from "./installs.js";
|
|
10
|
+
import { ExtensionLifecycle, PLUGINS_CHANGED_TOPIC } from "./lifecycle.js";
|
|
11
|
+
import { PluginApproveLock } from "./locks.js";
|
|
7
12
|
import { type AdminExtensionView } from "./permission-view.js";
|
|
8
13
|
export { PLUGINS_CHANGED_TOPIC };
|
|
9
14
|
/** The web approval request body (`POST /api/v1/admin/extensions/:name/approve`). */
|
|
@@ -12,34 +17,39 @@ export interface ApproveBody {
|
|
|
12
17
|
sha256: string | null;
|
|
13
18
|
reviewHash: string;
|
|
14
19
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
};
|
|
20
|
+
/** The kernel bus as the admin operations use it (publish only). */
|
|
21
|
+
export interface PublishBus {
|
|
22
|
+
publish(topic: string, payload: unknown): Promise<void>;
|
|
34
23
|
}
|
|
35
24
|
/**
|
|
36
25
|
* 部署级插件后台(企业管理员):列表 / 详情与网页批准权限(D8)。无状态,多副本共用;
|
|
37
26
|
* 状态由 PG(安装记录、快照、各副本状态行)与本副本宿主(配置声明插件的清单)推出。
|
|
38
27
|
*/
|
|
39
28
|
export declare class ExtensionAdmin {
|
|
40
|
-
private readonly
|
|
29
|
+
private readonly kdb;
|
|
30
|
+
readonly txHost: TransactionHost;
|
|
31
|
+
/** The enterprise admin lock (identity/enterprise-admin.ts): joins the transaction. */
|
|
32
|
+
private readonly adminLock;
|
|
33
|
+
private readonly approveLock;
|
|
34
|
+
private readonly blobs;
|
|
35
|
+
private readonly installs;
|
|
36
|
+
private readonly approvals;
|
|
37
|
+
/** The config-declared extensions (this replica's host; the CLI fills it from its inspection). */
|
|
38
|
+
private readonly host;
|
|
39
|
+
/** This replica's reconcile after an approval (a no-op where the lifecycle never started: the CLI). */
|
|
40
|
+
private readonly lifecycle;
|
|
41
|
+
private readonly config;
|
|
42
|
+
private readonly bus;
|
|
43
|
+
private readonly log;
|
|
41
44
|
private readonly packageSets;
|
|
42
|
-
constructor(
|
|
45
|
+
constructor(kdb: KernelDb, txHost: TransactionHost,
|
|
46
|
+
/** The enterprise admin lock (identity/enterprise-admin.ts): joins the transaction. */
|
|
47
|
+
adminLock: EnterpriseAdminLock, approveLock: PluginApproveLock, blobs: ExtensionBlobs, installs: ExtensionInstalls, approvals: ExtensionApprovals,
|
|
48
|
+
/** The config-declared extensions (this replica's host; the CLI fills it from its inspection). */
|
|
49
|
+
host: ExtensionHost,
|
|
50
|
+
/** This replica's reconcile after an approval (a no-op where the lifecycle never started: the CLI). */
|
|
51
|
+
lifecycle: ExtensionLifecycle, config: KernelConfigService, bus: PublishBus, log: KernelLogger);
|
|
52
|
+
private get db();
|
|
43
53
|
/** 全部插件(配置声明 → 安装记录,各自按名字)。 */
|
|
44
54
|
list(): Promise<AdminExtensionView[]>;
|
|
45
55
|
/**
|
|
@@ -69,6 +79,7 @@ export declare class ExtensionAdmin {
|
|
|
69
79
|
approve(actor: string, name: string, body: ApproveBody, opts?: {
|
|
70
80
|
actorTokenId?: string;
|
|
71
81
|
}): Promise<AdminExtensionView>;
|
|
82
|
+
private writeApproval;
|
|
72
83
|
/** 配置声明 → 安装记录(与配置声明重名的安装记录不生效,不单列)。`only` 给出时只取这一个。 */
|
|
73
84
|
private subjects;
|
|
74
85
|
/**
|