@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,85 @@
|
|
|
1
|
+
import { configFields, describeSchema } from "./fields.js";
|
|
2
|
+
/** `db.poolMax` -> `CAPYBARA_DB__POOL_MAX` (the inverse of the envOverrides mapping)。 */
|
|
3
|
+
export function envName(path) {
|
|
4
|
+
const seg = path.split(".").map((s) => s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase());
|
|
5
|
+
return `CAPYBARA_${seg.join("__")}`;
|
|
6
|
+
}
|
|
7
|
+
const cell = (s) => s.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
8
|
+
const code = (s) => `\`${cell(s)}\``;
|
|
9
|
+
/** Default column: no default -> "required" ("optional" for optional fields); secret -> never printed (—). */
|
|
10
|
+
function defaultCell(secret, d) {
|
|
11
|
+
if (!d.hasDefault)
|
|
12
|
+
return d.optional ? "optional" : "required";
|
|
13
|
+
if (secret)
|
|
14
|
+
return "—";
|
|
15
|
+
const v = typeof d.defaultValue === "function" ? d.defaultValue() : d.defaultValue;
|
|
16
|
+
return code(JSON.stringify(v) ?? "undefined");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Renders the config schema as a deterministic Markdown table: dotted path, env var, type, default,
|
|
20
|
+
* hot-reloadable, secret, description. The default of a secret field is always printed as "—" and
|
|
21
|
+
* never reaches the document.
|
|
22
|
+
*/
|
|
23
|
+
export function renderConfigDocs(schema) {
|
|
24
|
+
const rows = configFields(schema).map((f) => {
|
|
25
|
+
const d = describeSchema(f.schema);
|
|
26
|
+
const secret = f.meta?.secret === true;
|
|
27
|
+
return `| ${[
|
|
28
|
+
code(f.path),
|
|
29
|
+
code(envName(f.path)),
|
|
30
|
+
code(d.type),
|
|
31
|
+
defaultCell(secret, d),
|
|
32
|
+
f.meta?.hot === true ? "yes" : "no",
|
|
33
|
+
secret ? "yes" : "no",
|
|
34
|
+
cell(f.meta?.description ?? ""),
|
|
35
|
+
].join(" | ")} |`;
|
|
36
|
+
});
|
|
37
|
+
return [
|
|
38
|
+
"# Configuration reference",
|
|
39
|
+
"",
|
|
40
|
+
"<!-- Generated by `pnpm gen:config-docs`; do not edit by hand. -->",
|
|
41
|
+
"",
|
|
42
|
+
"The config source is chosen by `CAPYBARA_CONFIG_SOURCE` (`file` or `nacos`); environment variables win.",
|
|
43
|
+
"Nested keys use double underscores, e.g. `CAPYBARA_DB__URL` maps to `db.url`.",
|
|
44
|
+
"The defaults of secret fields do not appear in this document.",
|
|
45
|
+
"",
|
|
46
|
+
"| Key | Env var | Type | Default | Hot | Secret | Description |",
|
|
47
|
+
"| --- | --- | --- | --- | --- | --- | --- |",
|
|
48
|
+
...rows,
|
|
49
|
+
"",
|
|
50
|
+
"## Nacos config source",
|
|
51
|
+
"",
|
|
52
|
+
"With `CAPYBARA_CONFIG_SOURCE=nacos`, Nacos is specified by the following environment variables (they are not config keys and cannot be written in the config file):",
|
|
53
|
+
"",
|
|
54
|
+
"| Env var | Description |",
|
|
55
|
+
"| --- | --- |",
|
|
56
|
+
"| `CAPYBARA_NACOS_SERVER` | Nacos address (e.g. `nacos:8848`; the protocol defaults to http). Required |",
|
|
57
|
+
"| `CAPYBARA_NACOS_NAMESPACE` | Namespace ID. Required |",
|
|
58
|
+
"| `CAPYBARA_NACOS_DATA_ID` | The config's dataId (YAML). Required; the group is fixed to `DEFAULT_GROUP` |",
|
|
59
|
+
"| `CAPYBARA_NACOS_USERNAME` / `CAPYBARA_NACOS_PASSWORD` | Username and password when Nacos has authentication on: the kernel logs in to obtain an accessToken and logs in again after 80% of `tokenTtl` or on a 403; set both or neither |",
|
|
60
|
+
"| `CAPYBARA_NACOS_ACCESS_TOKEN` | An accessToken used as is (the login endpoint is not called); cannot be set together with the username and password |",
|
|
61
|
+
"",
|
|
62
|
+
// The web tier's env vars and defaults are owned by apps/web/src/lib/kernel-proxy.ts (kernel address,
|
|
63
|
+
// body and package upload limits), apps/web/server.mjs (PORT / CAPYBARA_WEB_HOST) and
|
|
64
|
+
// apps/web/src/dev/catalog/routes.tsx (CAPYBARA_DEV_UI); change this text together with them.
|
|
65
|
+
// CAPYBARA_WEB_TRUST_PROXY: apps/web/src/lib/peer.ts; CAPYBARA_WEB_SHUTDOWN_GRACE_MS: apps/web/server.mjs.
|
|
66
|
+
// CAPYBARA_WEB_OBJECT_STORE_*: apps/web/src/lib/object-store-proxy.ts.
|
|
67
|
+
"## Web tier (apps/web) environment variables",
|
|
68
|
+
"",
|
|
69
|
+
"The web tier is a separate process (started through `apps/web/server.mjs`); it does not read the kernel config and only honors the following environment variables:",
|
|
70
|
+
"",
|
|
71
|
+
"| Env var | Description |",
|
|
72
|
+
"| --- | --- |",
|
|
73
|
+
"| `CAPYBARA_KERNEL_URL` | The kernel address that the `/api/*` proxy forwards to; default `http://localhost:8080` |",
|
|
74
|
+
"| `PORT` / `CAPYBARA_WEB_HOST` | The web tier's listen port (default 3000) and address |",
|
|
75
|
+
"| `CAPYBARA_WEB_TRUST_PROXY` | Proxies in front of the web tier (TLS proxy, load balancer) trusted to report the client address in `X-Forwarded-For`: a hop count (`1` = the nearest proxy) or a list of IPs / CIDRs, comma-separated or a JSON array, in the grammar of `http.trustProxy` (dotted netmasks, `loopback` / `linklocal` / `uniquelocal`; a range that trusts every address such as `/0` is refused; no `true` / `false`). Unset (default) trusts nothing: the socket peer is the client, so behind a proxy every user shares the proxy's address for login rate limiting. A hop count is only safe when the web tier is reachable solely through exactly that many proxies. Either way the kernel receives one sanitized client address; a malformed value stops the web tier at startup |",
|
|
76
|
+
"| `CAPYBARA_WEB_SHUTDOWN_GRACE_MS` | Production only: after SIGTERM / SIGINT, how long in-flight requests (including SSE streams) may run before the process exits; default 5000 |",
|
|
77
|
+
"| `CAPYBARA_WEB_MAX_BODY_BYTES` | Request body limit of the `/api/*` proxy, default 1 MiB (matches the kernel's bodyLimit) |",
|
|
78
|
+
"| `CAPYBARA_WEB_MAX_PACKAGE_BYTES` | Request body limit for extension package and plugin uploads (`/api/v1/admin/extensions/packages/file`, `/api/v1/admin/catalog/import/file`), default 50 MiB, forwarded while being read. This is the web tier's limit; the kernel additionally rejects by `packages.maxBytes`. Raise both together, otherwise a large package uploaded through the web is first rejected by the web tier with a 413 |",
|
|
79
|
+
"| `CAPYBARA_WEB_OBJECT_STORE_URL` | Object storage on the web origin: the object store's address as web reaches it (e.g. `http://seaweedfs-s3:8333`). When set, web proxies `/<bucket>/**` (and `/<bucket>` itself for POST only) there, so browsers upload attachments (presigned POST) and download attachments and artifacts (presigned GET) through web; set the object-store extension's `publicEndpoint` to the web origin with `forcePathStyle: true`. Only GET, HEAD and POST; the path is forwarded unchanged; cookies and authorization are not forwarded; responses carry `X-Content-Type-Options: nosniff` and `Content-Security-Policy: sandbox`; uploads are capped at `CAPYBARA_WEB_MAX_PACKAGE_BYTES`. Unset (default): off |",
|
|
80
|
+
"| `CAPYBARA_WEB_OBJECT_STORE_BUCKET` | With `CAPYBARA_WEB_OBJECT_STORE_URL`: the bucket, equal to the object-store extension's `bucket` (it is the first path segment web proxies) |",
|
|
81
|
+
"| `CAPYBARA_WEB_OBJECT_STORE_PUBLIC_HOST` | With `CAPYBARA_WEB_OBJECT_STORE_URL`: the host of the extension's `publicEndpoint` (a host such as `capybara.example.com`, or that URL). Sent upstream as `Host` instead of the incoming one, because presigned URLs sign the host they were issued for and front proxies rewrite it |",
|
|
82
|
+
"| `CAPYBARA_DEV_UI` | When set to `1`, production builds also serve the `/dev/ui` component catalog page (off by default) |",
|
|
83
|
+
"",
|
|
84
|
+
].join("\n");
|
|
85
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把 `CAPYBARA_A__B_C=x` 形式的环境变量转成嵌套对象 `{ a: { bC: x } }`。
|
|
3
|
+
* Under `extensionConfig` the second segment is the extension name, converted snake -> kebab.
|
|
4
|
+
* 同时存在 `CAPYBARA_X`(标量)与 `CAPYBARA_X__Y`(嵌套)时抛 ConfigError。
|
|
5
|
+
*/
|
|
6
|
+
export declare function envOverrides(env: NodeJS.ProcessEnv): Record<string, unknown>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ConfigError } from "./types.js";
|
|
2
|
+
const PREFIX = "CAPYBARA_";
|
|
3
|
+
const IGNORED = ["CAPYBARA_CONFIG_", "CAPYBARA_NACOS_"];
|
|
4
|
+
function snakeToCamel(segment) {
|
|
5
|
+
return segment.toLowerCase().replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
6
|
+
}
|
|
7
|
+
function parseValue(raw) {
|
|
8
|
+
let parsed;
|
|
9
|
+
try {
|
|
10
|
+
parsed = JSON.parse(raw);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return raw;
|
|
14
|
+
}
|
|
15
|
+
if (typeof parsed === "number")
|
|
16
|
+
return String(parsed) === raw ? parsed : raw;
|
|
17
|
+
if (typeof parsed === "string")
|
|
18
|
+
return raw;
|
|
19
|
+
return parsed;
|
|
20
|
+
}
|
|
21
|
+
/** Extension name segment: `EXAMPLE_COUNTER` -> `example-counter` (extension names contain no `_`, so the mapping is unambiguous). */
|
|
22
|
+
function snakeToKebab(segment) {
|
|
23
|
+
return segment.toLowerCase().replaceAll("_", "-");
|
|
24
|
+
}
|
|
25
|
+
function toPath(key) {
|
|
26
|
+
const segs = key.slice(PREFIX.length).split("__");
|
|
27
|
+
const path = segs.map(snakeToCamel);
|
|
28
|
+
if (path[0] === "extensionConfig" && segs.length > 1)
|
|
29
|
+
path[1] = snakeToKebab(segs[1]);
|
|
30
|
+
return path;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 把 `CAPYBARA_A__B_C=x` 形式的环境变量转成嵌套对象 `{ a: { bC: x } }`。
|
|
34
|
+
* Under `extensionConfig` the second segment is the extension name, converted snake -> kebab.
|
|
35
|
+
* 同时存在 `CAPYBARA_X`(标量)与 `CAPYBARA_X__Y`(嵌套)时抛 ConfigError。
|
|
36
|
+
*/
|
|
37
|
+
export function envOverrides(env) {
|
|
38
|
+
const entries = [];
|
|
39
|
+
for (const [key, raw] of Object.entries(env)) {
|
|
40
|
+
if (raw === undefined || !key.startsWith(PREFIX))
|
|
41
|
+
continue;
|
|
42
|
+
if (IGNORED.some((p) => key.startsWith(p)))
|
|
43
|
+
continue;
|
|
44
|
+
const path = toPath(key);
|
|
45
|
+
if (path.some((s) => s === ""))
|
|
46
|
+
continue;
|
|
47
|
+
entries.push({ key, path, raw });
|
|
48
|
+
}
|
|
49
|
+
for (const a of entries) {
|
|
50
|
+
for (const b of entries) {
|
|
51
|
+
if (a.path.length < b.path.length && a.path.every((s, i) => s === b.path[i])) {
|
|
52
|
+
throw new ConfigError(`conflicting environment variables: ${a.key} sets a scalar but ${b.key} sets a nested value under it`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const out = {};
|
|
57
|
+
for (const { path, raw } of entries) {
|
|
58
|
+
let node = out;
|
|
59
|
+
for (const seg of path.slice(0, -1)) {
|
|
60
|
+
const next = node[seg];
|
|
61
|
+
if (typeof next === "object" && next !== null && !Array.isArray(next)) {
|
|
62
|
+
node = next;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
const created = {};
|
|
66
|
+
node[seg] = created;
|
|
67
|
+
node = created;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
node[path[path.length - 1]] = parseValue(raw);
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type core } from "zod";
|
|
2
|
+
import type { FieldMeta } from "./schema.js";
|
|
3
|
+
/** 一个配置叶子字段:点路径与其元信息。 */
|
|
4
|
+
export interface ConfigField {
|
|
5
|
+
path: string;
|
|
6
|
+
meta: FieldMeta | undefined;
|
|
7
|
+
/** 该叶子的原始 schema(含 default / optional 等包装),供生成文档读取类型与默认值。 */
|
|
8
|
+
schema: core.$ZodType;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 剥掉包装后的内层 schema 类型与默认值(无 default 时 hasDefault 为 false);
|
|
12
|
+
* `optional` 表示包装链上有 optional(可以不填,且没有默认值时值为 undefined)。
|
|
13
|
+
*/
|
|
14
|
+
export declare function describeSchema(schema: core.$ZodType): {
|
|
15
|
+
type: string;
|
|
16
|
+
hasDefault: boolean;
|
|
17
|
+
defaultValue: unknown;
|
|
18
|
+
optional: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** 列出 schema 的所有叶子字段(对象递归展开;数组、record 等视作叶子)。 */
|
|
21
|
+
export declare function configFields(schema: core.$ZodType, prefix?: string, inheritedSecret?: boolean): ConfigField[];
|
|
22
|
+
/** 按点路径取值。 */
|
|
23
|
+
export declare function getPath(obj: unknown, path: string): unknown;
|
|
24
|
+
/** 按点路径设值(就地修改,中间对象必须已存在)。 */
|
|
25
|
+
export declare function setPath(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
26
|
+
/** 比较两份已校验配置,返回值发生变化的叶子点路径。 */
|
|
27
|
+
export declare function changedPaths(schema: core.$ZodType, a: unknown, b: unknown): string[];
|
|
28
|
+
/**
|
|
29
|
+
* 把一个密钥值展开成需要打码的字符串:字符串原样;数字、bigint 转成字符串;布尔不收集
|
|
30
|
+
* (`true` / `false` 不携带秘密,登记只会误伤普通文本);数组与对象(secret 叶子可能是 record / 数组 / 对象)
|
|
31
|
+
* 递归展开所有标量。最短长度由 logger 把关。
|
|
32
|
+
*/
|
|
33
|
+
export declare function secretScalars(value: unknown, out?: string[]): string[];
|
|
34
|
+
/** 收集标记为 secret 的字段的值(嵌套的数组 / 对象展开为其中所有标量,数字转成字符串,布尔跳过),供 logger 打码。 */
|
|
35
|
+
export declare function secretValues(schema: core.$ZodType, config: unknown): string[];
|
|
36
|
+
/**
|
|
37
|
+
* 找出 `configFields` 拆不出来的 secret 标记:secret 只能标在「从根经对象字段(及 default / optional 等包装)
|
|
38
|
+
* 可达」的节点上。标在 union / intersection / pipe(含 transform)/ lazy / array 元素 / record 值 /
|
|
39
|
+
* tuple / map / set 等内部的 secret,内核既无法单独加密存储也无法打码,返回其描述路径
|
|
40
|
+
* (如 `auth<union#1>.token`)。对象路径上的 secret 若未让对应叶子被视为 secret(被外层 meta 遮蔽)同样返回。
|
|
41
|
+
*/
|
|
42
|
+
export declare function unreachableSecrets(schema: core.$ZodType): string[];
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* 剥掉包装后的内层 schema 类型与默认值(无 default 时 hasDefault 为 false);
|
|
5
|
+
* `optional` 表示包装链上有 optional(可以不填,且没有默认值时值为 undefined)。
|
|
6
|
+
*/
|
|
7
|
+
export function describeSchema(schema) {
|
|
8
|
+
let node = schema;
|
|
9
|
+
let hasDefault = false;
|
|
10
|
+
let optional = false;
|
|
11
|
+
let defaultValue;
|
|
12
|
+
for (;;) {
|
|
13
|
+
const def = node._zod.def;
|
|
14
|
+
if (def.type === "default" || def.type === "prefault") {
|
|
15
|
+
if (!hasDefault) {
|
|
16
|
+
hasDefault = true;
|
|
17
|
+
defaultValue = def.defaultValue;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (def.type === "optional")
|
|
21
|
+
optional = true;
|
|
22
|
+
if (!WRAPPERS.has(def.type) || !def.innerType)
|
|
23
|
+
break;
|
|
24
|
+
node = def.innerType;
|
|
25
|
+
}
|
|
26
|
+
const def = node._zod.def;
|
|
27
|
+
// z.preprocess(fn, T) is a pipe from a transform into T: document T.
|
|
28
|
+
if (def.type === "pipe" && def.in?._zod.def.type === "transform" && def.out) {
|
|
29
|
+
return { ...describeSchema(def.out), hasDefault, defaultValue, optional };
|
|
30
|
+
}
|
|
31
|
+
// T.transform(fn) is a pipe from T into a transform: document T (what the config is written as).
|
|
32
|
+
if (def.type === "pipe" && def.out?._zod.def.type === "transform" && def.in) {
|
|
33
|
+
return { ...describeSchema(def.in), hasDefault, defaultValue, optional };
|
|
34
|
+
}
|
|
35
|
+
let type = def.type;
|
|
36
|
+
if (type === "array" && def.element)
|
|
37
|
+
type = `array<${describeSchema(def.element).type}>`;
|
|
38
|
+
else if (type === "union" && def.options) {
|
|
39
|
+
type = def.options.map((o) => describeSchema(o).type).join(" | ");
|
|
40
|
+
}
|
|
41
|
+
else if (type === "enum" && def.entries) {
|
|
42
|
+
type = Object.values(def.entries)
|
|
43
|
+
.map((v) => JSON.stringify(v))
|
|
44
|
+
.join(" | ");
|
|
45
|
+
}
|
|
46
|
+
return { type, hasDefault, defaultValue, optional };
|
|
47
|
+
}
|
|
48
|
+
const WRAPPERS = new Set(["default", "prefault", "optional", "nullable", "readonly", "catch"]);
|
|
49
|
+
/** 剥掉 default / optional 等包装,返回内层 schema 与沿途遇到的第一个(最外层)元信息。 */
|
|
50
|
+
function unwrap(schema) {
|
|
51
|
+
let node = schema;
|
|
52
|
+
let found = z.globalRegistry.get(node);
|
|
53
|
+
while (WRAPPERS.has(node._zod.def.type)) {
|
|
54
|
+
node = node._zod.def.innerType;
|
|
55
|
+
found ??= z.globalRegistry.get(node);
|
|
56
|
+
}
|
|
57
|
+
return { inner: node, meta: found };
|
|
58
|
+
}
|
|
59
|
+
/** 列出 schema 的所有叶子字段(对象递归展开;数组、record 等视作叶子)。 */
|
|
60
|
+
export function configFields(schema, prefix = "", inheritedSecret = false) {
|
|
61
|
+
const { inner, meta: own } = unwrap(schema);
|
|
62
|
+
const secret = inheritedSecret || own?.secret === true;
|
|
63
|
+
// 对象节点上标的 secret 对所有后代叶子生效,否则嵌套字段的默认值会被文档/日志漏出。
|
|
64
|
+
const meta = secret && own?.secret !== true
|
|
65
|
+
? { ...own, secret: true, description: own?.description ?? "" }
|
|
66
|
+
: own;
|
|
67
|
+
if (inner._zod.def.type === "object") {
|
|
68
|
+
const shape = inner._zod.def.shape;
|
|
69
|
+
return Object.entries(shape).flatMap(([k, v]) => configFields(v, prefix ? `${prefix}.${k}` : k, secret));
|
|
70
|
+
}
|
|
71
|
+
return [{ path: prefix, meta, schema }];
|
|
72
|
+
}
|
|
73
|
+
/** 按点路径取值。 */
|
|
74
|
+
export function getPath(obj, path) {
|
|
75
|
+
let node = obj;
|
|
76
|
+
for (const seg of path.split(".")) {
|
|
77
|
+
if (typeof node !== "object" || node === null)
|
|
78
|
+
return undefined;
|
|
79
|
+
node = node[seg];
|
|
80
|
+
}
|
|
81
|
+
return node;
|
|
82
|
+
}
|
|
83
|
+
/** 按点路径设值(就地修改,中间对象必须已存在)。 */
|
|
84
|
+
export function setPath(obj, path, value) {
|
|
85
|
+
const segs = path.split(".");
|
|
86
|
+
let node = obj;
|
|
87
|
+
for (const seg of segs.slice(0, -1))
|
|
88
|
+
node = node[seg];
|
|
89
|
+
node[segs[segs.length - 1]] = value;
|
|
90
|
+
}
|
|
91
|
+
/** 比较两份已校验配置,返回值发生变化的叶子点路径。 */
|
|
92
|
+
export function changedPaths(schema, a, b) {
|
|
93
|
+
return configFields(schema)
|
|
94
|
+
.map((f) => f.path)
|
|
95
|
+
.filter((p) => !isDeepStrictEqual(getPath(a, p), getPath(b, p)));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 把一个密钥值展开成需要打码的字符串:字符串原样;数字、bigint 转成字符串;布尔不收集
|
|
99
|
+
* (`true` / `false` 不携带秘密,登记只会误伤普通文本);数组与对象(secret 叶子可能是 record / 数组 / 对象)
|
|
100
|
+
* 递归展开所有标量。最短长度由 logger 把关。
|
|
101
|
+
*/
|
|
102
|
+
export function secretScalars(value, out = []) {
|
|
103
|
+
if (typeof value === "string")
|
|
104
|
+
out.push(value);
|
|
105
|
+
else if (typeof value === "number" || typeof value === "bigint") {
|
|
106
|
+
out.push(String(value));
|
|
107
|
+
}
|
|
108
|
+
else if (Array.isArray(value)) {
|
|
109
|
+
for (const v of value)
|
|
110
|
+
secretScalars(v, out);
|
|
111
|
+
}
|
|
112
|
+
else if (typeof value === "object" && value !== null) {
|
|
113
|
+
for (const v of Object.values(value))
|
|
114
|
+
secretScalars(v, out);
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
/** 收集标记为 secret 的字段的值(嵌套的数组 / 对象展开为其中所有标量,数字转成字符串,布尔跳过),供 logger 打码。 */
|
|
119
|
+
export function secretValues(schema, config) {
|
|
120
|
+
const out = [];
|
|
121
|
+
for (const f of configFields(schema)) {
|
|
122
|
+
if (f.meta?.secret)
|
|
123
|
+
secretScalars(getPath(config, f.path), out);
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
const isSecretNode = (node) => z.globalRegistry.get(node)?.secret === true;
|
|
128
|
+
/**
|
|
129
|
+
* 找出 `configFields` 拆不出来的 secret 标记:secret 只能标在「从根经对象字段(及 default / optional 等包装)
|
|
130
|
+
* 可达」的节点上。标在 union / intersection / pipe(含 transform)/ lazy / array 元素 / record 值 /
|
|
131
|
+
* tuple / map / set 等内部的 secret,内核既无法单独加密存储也无法打码,返回其描述路径
|
|
132
|
+
* (如 `auth<union#1>.token`)。对象路径上的 secret 若未让对应叶子被视为 secret(被外层 meta 遮蔽)同样返回。
|
|
133
|
+
*/
|
|
134
|
+
export function unreachableSecrets(schema) {
|
|
135
|
+
const covered = configFields(schema)
|
|
136
|
+
.filter((f) => f.meta?.secret)
|
|
137
|
+
.map((f) => f.path);
|
|
138
|
+
const isCovered = (p) => covered.some((c) => p === "" || c === p || c.startsWith(`${p}.`));
|
|
139
|
+
const out = [];
|
|
140
|
+
// 只防 lazy 自引用造成的环:同一 schema 实例可能复用在多个位置,每个位置都要检查
|
|
141
|
+
const stack = new Set();
|
|
142
|
+
const join = (prefix, seg) => (prefix ? `${prefix}.${seg}` : seg);
|
|
143
|
+
const t = (v) => v;
|
|
144
|
+
const walk = (node, label, onPath) => {
|
|
145
|
+
if (stack.has(node))
|
|
146
|
+
return;
|
|
147
|
+
stack.add(node);
|
|
148
|
+
try {
|
|
149
|
+
visit(node, label, onPath);
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
stack.delete(node);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const visit = (node, label, onPath) => {
|
|
156
|
+
if (isSecretNode(node)) {
|
|
157
|
+
if (onPath && isCovered(label))
|
|
158
|
+
return; // 整棵子树都按 secret 处理
|
|
159
|
+
out.push(label || "<root>");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const def = node._zod.def;
|
|
163
|
+
switch (def.type) {
|
|
164
|
+
case "object":
|
|
165
|
+
for (const [k, v] of Object.entries(def.shape)) {
|
|
166
|
+
walk(v, join(label, k), onPath);
|
|
167
|
+
}
|
|
168
|
+
if (def.catchall)
|
|
169
|
+
walk(t(def.catchall), `${label}<catchall>`, false);
|
|
170
|
+
return;
|
|
171
|
+
case "union":
|
|
172
|
+
def.options.forEach((o, i) => {
|
|
173
|
+
walk(o, `${label}<union#${i}>`, false);
|
|
174
|
+
});
|
|
175
|
+
return;
|
|
176
|
+
case "intersection":
|
|
177
|
+
walk(t(def.left), `${label}<intersection:left>`, false);
|
|
178
|
+
walk(t(def.right), `${label}<intersection:right>`, false);
|
|
179
|
+
return;
|
|
180
|
+
case "pipe":
|
|
181
|
+
walk(t(def.in), `${label}<pipe:in>`, false);
|
|
182
|
+
walk(t(def.out), `${label}<pipe:out>`, false);
|
|
183
|
+
return;
|
|
184
|
+
case "lazy":
|
|
185
|
+
walk(def.getter(), `${label}<lazy>`, false);
|
|
186
|
+
return;
|
|
187
|
+
case "array":
|
|
188
|
+
walk(t(def.element), `${label}[]`, false);
|
|
189
|
+
return;
|
|
190
|
+
case "set":
|
|
191
|
+
walk(t(def.valueType), `${label}<set>`, false);
|
|
192
|
+
return;
|
|
193
|
+
case "record":
|
|
194
|
+
case "map":
|
|
195
|
+
walk(t(def.keyType), `${label}<${def.type}:key>`, false);
|
|
196
|
+
walk(t(def.valueType), `${label}<${def.type}:value>`, false);
|
|
197
|
+
return;
|
|
198
|
+
case "tuple":
|
|
199
|
+
def.items.forEach((o, i) => {
|
|
200
|
+
walk(o, `${label}[${i}]`, false);
|
|
201
|
+
});
|
|
202
|
+
if (def.rest)
|
|
203
|
+
walk(t(def.rest), `${label}[...]`, false);
|
|
204
|
+
return;
|
|
205
|
+
default:
|
|
206
|
+
// default / optional 等包装沿用 configFields 的对象路径;其余带 innerType 的包装(nonoptional、
|
|
207
|
+
// promise 等)configFields 视作叶子,其内部的 secret 不可达。
|
|
208
|
+
if (def.innerType)
|
|
209
|
+
walk(t(def.innerType), label, onPath && WRAPPERS.has(def.type));
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
walk(schema, "", true);
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parse, YAMLParseError } from "yaml";
|
|
3
|
+
import { ConfigError } from "./types.js";
|
|
4
|
+
/** 从 YAML 文件读取配置;未指定路径时返回空对象(纯环境变量配置)。错误信息不含文件内容。 */
|
|
5
|
+
export function fileSource(path) {
|
|
6
|
+
return {
|
|
7
|
+
async load() {
|
|
8
|
+
if (!path)
|
|
9
|
+
return {};
|
|
10
|
+
let text;
|
|
11
|
+
try {
|
|
12
|
+
text = await readFile(path, "utf8");
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
const code = e.code ?? "unknown error";
|
|
16
|
+
throw new ConfigError(`cannot read config file '${path}': ${code}`);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
return parse(text) ?? {};
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
if (e instanceof YAMLParseError) {
|
|
23
|
+
const pos = e.linePos?.[0];
|
|
24
|
+
const at = pos ? ` at line ${pos.line}, column ${pos.col}` : "";
|
|
25
|
+
throw new ConfigError(`invalid YAML in config file '${path}'${at}`);
|
|
26
|
+
}
|
|
27
|
+
throw new ConfigError(`invalid YAML in config file '${path}'`);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type KernelConfig } from "./schema.js";
|
|
2
|
+
import { type ConfigSourceKind } from "./sources.js";
|
|
3
|
+
import { ConfigError, type ConfigSource } from "./types.js";
|
|
4
|
+
export { ConfigError, type ConfigSource };
|
|
5
|
+
/** 按 `CAPYBARA_CONFIG_SOURCE` 选择配置来源,默认 `file`。 */
|
|
6
|
+
export declare function selectConfigSource(env: NodeJS.ProcessEnv): ConfigSource;
|
|
7
|
+
/** 深合并:对象递归合并,其余(含数组)由 override 整体替换。 */
|
|
8
|
+
export declare function deepMerge(base: unknown, override: unknown): unknown;
|
|
9
|
+
/** 原始配置深合并环境变量覆盖(优先级最高)后校验;热更新与启动共用。错误只列路径不列值。 */
|
|
10
|
+
export declare function resolveConfig(raw: unknown, env: NodeJS.ProcessEnv): KernelConfig;
|
|
11
|
+
/** 选来源 → 深合并环境变量覆盖(优先级最高)→ 校验。 */
|
|
12
|
+
export declare function loadConfig(env: NodeJS.ProcessEnv): Promise<KernelConfig>;
|
|
13
|
+
/**
|
|
14
|
+
* 与 {@link loadConfig} 相同,另给出各插件部署配置字段的来源(文件 / Nacos / 环境变量,见
|
|
15
|
+
* {@link extensionConfigSources}):传给 `createKernel` 的 `extensionConfigSources`,后台据此把这些字段标为只读(D8)。
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadConfigWithSources(env: NodeJS.ProcessEnv): Promise<{
|
|
18
|
+
config: KernelConfig;
|
|
19
|
+
extensionConfigSources: Record<string, Record<string, ConfigSourceKind>>;
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { webhookBaseUrlProblem } from "../channels/webhook-url.js";
|
|
2
|
+
import { envOverrides } from "./env.js";
|
|
3
|
+
import { fileSource } from "./file-source.js";
|
|
4
|
+
import { createNacosSource } from "./nacos-source.js";
|
|
5
|
+
import { KernelConfigSchema } from "./schema.js";
|
|
6
|
+
import { configSourceKind, extensionConfigSources } from "./sources.js";
|
|
7
|
+
import { ConfigError } from "./types.js";
|
|
8
|
+
export { ConfigError };
|
|
9
|
+
/**
|
|
10
|
+
* Nacos 鉴权凭据:`CAPYBARA_NACOS_ACCESS_TOKEN`(静态令牌),或 `CAPYBARA_NACOS_USERNAME` +
|
|
11
|
+
* `CAPYBARA_NACOS_PASSWORD`(登录换取令牌);都不设则不鉴权。令牌与用户名不能同时设置,用户名与密码必须成对。
|
|
12
|
+
*/
|
|
13
|
+
function nacosAuth(env) {
|
|
14
|
+
const token = env.CAPYBARA_NACOS_ACCESS_TOKEN;
|
|
15
|
+
const username = env.CAPYBARA_NACOS_USERNAME;
|
|
16
|
+
const password = env.CAPYBARA_NACOS_PASSWORD;
|
|
17
|
+
if (token) {
|
|
18
|
+
if (username || password) {
|
|
19
|
+
throw new ConfigError("set either CAPYBARA_NACOS_ACCESS_TOKEN or CAPYBARA_NACOS_USERNAME / CAPYBARA_NACOS_PASSWORD, not both");
|
|
20
|
+
}
|
|
21
|
+
return { auth: { accessToken: token } };
|
|
22
|
+
}
|
|
23
|
+
if (!username && !password)
|
|
24
|
+
return {};
|
|
25
|
+
if (!username)
|
|
26
|
+
throw new ConfigError("CAPYBARA_NACOS_USERNAME is required when CAPYBARA_NACOS_PASSWORD is set");
|
|
27
|
+
if (!password)
|
|
28
|
+
throw new ConfigError("CAPYBARA_NACOS_PASSWORD is required when CAPYBARA_NACOS_USERNAME is set");
|
|
29
|
+
return { auth: { username, password } };
|
|
30
|
+
}
|
|
31
|
+
/** 按 `CAPYBARA_CONFIG_SOURCE` 选择配置来源,默认 `file`。 */
|
|
32
|
+
export function selectConfigSource(env) {
|
|
33
|
+
const kind = env.CAPYBARA_CONFIG_SOURCE || "file";
|
|
34
|
+
switch (kind) {
|
|
35
|
+
case "file":
|
|
36
|
+
return fileSource(env.CAPYBARA_CONFIG_FILE);
|
|
37
|
+
case "nacos": {
|
|
38
|
+
const need = (name) => {
|
|
39
|
+
const v = env[name];
|
|
40
|
+
if (!v)
|
|
41
|
+
throw new ConfigError(`${name} is required when CAPYBARA_CONFIG_SOURCE=nacos`);
|
|
42
|
+
return v;
|
|
43
|
+
};
|
|
44
|
+
const server = need("CAPYBARA_NACOS_SERVER");
|
|
45
|
+
const namespace = need("CAPYBARA_NACOS_NAMESPACE");
|
|
46
|
+
const dataId = need("CAPYBARA_NACOS_DATA_ID");
|
|
47
|
+
return createNacosSource({ server, namespace, dataId, ...nacosAuth(env) });
|
|
48
|
+
}
|
|
49
|
+
default:
|
|
50
|
+
throw new ConfigError(`unknown config source '${kind}' (expected 'file' or 'nacos')`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isPlainObject(v) {
|
|
54
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
55
|
+
}
|
|
56
|
+
/** 深合并:对象递归合并,其余(含数组)由 override 整体替换。 */
|
|
57
|
+
export function deepMerge(base, override) {
|
|
58
|
+
if (!isPlainObject(base) || !isPlainObject(override))
|
|
59
|
+
return override;
|
|
60
|
+
const out = { ...base };
|
|
61
|
+
for (const [k, v] of Object.entries(override)) {
|
|
62
|
+
out[k] = k in out ? deepMerge(out[k], v) : v;
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
/** 原始配置深合并环境变量覆盖(优先级最高)后校验;热更新与启动共用。错误只列路径不列值。 */
|
|
67
|
+
export function resolveConfig(raw, env) {
|
|
68
|
+
if (!isPlainObject(raw))
|
|
69
|
+
throw new ConfigError("config file root must be a mapping");
|
|
70
|
+
const merged = deepMerge(raw, envOverrides(env));
|
|
71
|
+
const result = KernelConfigSchema.safeParse(merged);
|
|
72
|
+
if (!result.success) {
|
|
73
|
+
const lines = result.error.issues.map((i) => ` - ${i.path.map(String).join(".") || "(root)"}: ${i.message}`);
|
|
74
|
+
throw new ConfigError(`invalid configuration:\n${lines.join("\n")}`);
|
|
75
|
+
}
|
|
76
|
+
// Cross-section rule (the loopback exception lives under `tools`)
|
|
77
|
+
const webhookProblem = webhookBaseUrlProblem(result.data);
|
|
78
|
+
if (webhookProblem !== null) {
|
|
79
|
+
throw new ConfigError(`invalid configuration:\n - channels.webhookBaseUrl: ${webhookProblem}`);
|
|
80
|
+
}
|
|
81
|
+
return result.data;
|
|
82
|
+
}
|
|
83
|
+
/** 选来源 → 深合并环境变量覆盖(优先级最高)→ 校验。 */
|
|
84
|
+
export async function loadConfig(env) {
|
|
85
|
+
return resolveConfig(await selectConfigSource(env).load(), env);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 与 {@link loadConfig} 相同,另给出各插件部署配置字段的来源(文件 / Nacos / 环境变量,见
|
|
89
|
+
* {@link extensionConfigSources}):传给 `createKernel` 的 `extensionConfigSources`,后台据此把这些字段标为只读(D8)。
|
|
90
|
+
*/
|
|
91
|
+
export async function loadConfigWithSources(env) {
|
|
92
|
+
const raw = await selectConfigSource(env).load();
|
|
93
|
+
const config = resolveConfig(raw, env);
|
|
94
|
+
return {
|
|
95
|
+
config,
|
|
96
|
+
extensionConfigSources: extensionConfigSources(raw, env, configSourceKind(env)),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ConfigSource } from "./types.js";
|
|
2
|
+
/** Nacos 配置来源的参数。 */
|
|
3
|
+
export interface NacosSourceOptions {
|
|
4
|
+
server: string;
|
|
5
|
+
namespace: string;
|
|
6
|
+
dataId: string;
|
|
7
|
+
/** 默认 `DEFAULT_GROUP`。 */
|
|
8
|
+
group?: string;
|
|
9
|
+
fetch?: typeof fetch;
|
|
10
|
+
/** 单次读取配置的超时,默认 10000ms;超时抛 ConfigError(启动快速失败)。 */
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
/** watch 出错后的退避间隔,默认 1000ms。 */
|
|
13
|
+
backoffMs?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Nacos 开启鉴权时的凭据:
|
|
16
|
+
* - 用户名密码:先 `POST /nacos/v1/auth/login` 换取 accessToken,用到 `tokenTtl` 的 80% 后(或请求收到 403 时)重新登录;
|
|
17
|
+
* - accessToken:直接使用,不调用登录接口(收到 403 即报错)。
|
|
18
|
+
* 令牌以 `accessToken` 查询参数随每个配置 / 监听请求发送。
|
|
19
|
+
*/
|
|
20
|
+
auth?: {
|
|
21
|
+
username: string;
|
|
22
|
+
password: string;
|
|
23
|
+
} | {
|
|
24
|
+
accessToken: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 从 Nacos 读取 YAML 配置并可长轮询监听变更。错误信息含 server 与 dataId,但不含响应体、YAML 内容或凭据。
|
|
29
|
+
* 鉴权见 `NacosSourceOptions.auth`:令牌按需续期(每次请求前检查是否到了续期时刻),不起定时器。
|
|
30
|
+
*/
|
|
31
|
+
export declare function createNacosSource(opts: NacosSourceOptions): ConfigSource;
|