@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,183 @@
|
|
|
1
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
2
|
+
import { canonicalJson } from "./registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* 编译结果缓存的上限:超过后整体丢弃(工具定义每步从库里重新读出,缓存不能无限增长)。
|
|
5
|
+
* 缓存的是由定义推导出的只读数据,不是跨进程状态。
|
|
6
|
+
*/
|
|
7
|
+
const CACHE_MAX = 500;
|
|
8
|
+
/** 不受信任的 schema(连接器工具,来自连接器)JSON 序列化后的字节上限:超过不编译、不校验。 */
|
|
9
|
+
export const UNTRUSTED_SCHEMA_MAX_BYTES = 64 * 1024;
|
|
10
|
+
/** 不受信任的 schema 的嵌套层数上限(对象 / 数组层数):超过不编译、不校验。 */
|
|
11
|
+
export const UNTRUSTED_SCHEMA_MAX_DEPTH = 32;
|
|
12
|
+
/** 缓存键 → 编译结果(null = 不校验:无法编译或超限)。 */
|
|
13
|
+
const compiled = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* 每个 schema 用自己的 Ajv 实例:不同工具的 schema 声明同一个 `$id` 时不会在共享实例里冲突
|
|
16
|
+
* (共享实例会报「schema with key or id already exists」,后者就校验不了)。
|
|
17
|
+
*/
|
|
18
|
+
const newAjv = () => new Ajv2020({ strict: false, allErrors: true });
|
|
19
|
+
/** 值是「名字 → 子 schema」映射的关键字(键是属性名 / 定义名,不是关键字,不能按关键字剥)。 */
|
|
20
|
+
const SCHEMA_MAPS = new Set(["properties", "$defs", "definitions", "dependentSchemas"]);
|
|
21
|
+
/** 值是数据而不是 schema 的关键字:原样保留。 */
|
|
22
|
+
const LITERALS = new Set(["enum", "const", "default", "examples", "required"]);
|
|
23
|
+
/** 子 schema 处于否定 / 条件位置的关键字:在其中剥离约束不一定放宽,可能反而收紧(拒掉合法调用)。 */
|
|
24
|
+
const NON_POSITIVE = new Set(["not", "oneOf", "if", "then", "else"]);
|
|
25
|
+
/**
|
|
26
|
+
* 不受信任的 schema 去掉 Ajv 中有风险或不可控的部分:
|
|
27
|
+
* - `pattern`(正则可能灾难性回溯,拖住事件循环)、`format`(未知格式 / 昂贵校验)直接去掉;
|
|
28
|
+
* - `patternProperties` 去掉,并按 additionalProperties 语义放宽:原本 `additionalProperties: false` 时
|
|
29
|
+
* 额外属性须符合其中某个模式的 schema,原本是 schema 时与之取 anyOf,原本缺省 / true 时不变。
|
|
30
|
+
* 只在正向位置去掉约束才是放宽;在 `not` / `oneOf` / `if` / `then` / `else` 之下,或 schema 用了
|
|
31
|
+
* `unevaluatedProperties` / `unevaluatedItems`(剥 patternProperties 会改变「已评估」集合)时,
|
|
32
|
+
* 剥离可能收紧,调用方据 {@link SanitizeState} 放弃校验。
|
|
33
|
+
*/
|
|
34
|
+
function sanitize(node, state, nonPositive = false) {
|
|
35
|
+
if (Array.isArray(node))
|
|
36
|
+
return node.map((x) => sanitize(x, state, nonPositive));
|
|
37
|
+
if (node === null || typeof node !== "object")
|
|
38
|
+
return node;
|
|
39
|
+
const src = node;
|
|
40
|
+
const out = {};
|
|
41
|
+
for (const [k, v] of Object.entries(src)) {
|
|
42
|
+
if (k === "pattern" || k === "format" || k === "patternProperties") {
|
|
43
|
+
state.stripped = true;
|
|
44
|
+
if (nonPositive)
|
|
45
|
+
state.strippedNonPositive = true;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (k === "unevaluatedProperties" || k === "unevaluatedItems")
|
|
49
|
+
state.unevaluated = true;
|
|
50
|
+
const childNeg = nonPositive || NON_POSITIVE.has(k);
|
|
51
|
+
if (LITERALS.has(k))
|
|
52
|
+
out[k] = v;
|
|
53
|
+
else if (SCHEMA_MAPS.has(k) && v !== null && typeof v === "object" && !Array.isArray(v)) {
|
|
54
|
+
out[k] = Object.fromEntries(Object.entries(v).map(([name, sub]) => [name, sanitize(sub, state, childNeg)]));
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
out[k] = sanitize(v, state, childNeg);
|
|
58
|
+
}
|
|
59
|
+
const pp = src.patternProperties;
|
|
60
|
+
if (pp !== null && typeof pp === "object" && !Array.isArray(pp)) {
|
|
61
|
+
const subs = Object.values(pp).map((x) => sanitize(x, state, nonPositive));
|
|
62
|
+
const ap = src.additionalProperties;
|
|
63
|
+
if (subs.length > 0 && ap === false)
|
|
64
|
+
out.additionalProperties = { anyOf: subs };
|
|
65
|
+
else if (subs.length > 0 && ap !== undefined && ap !== true) {
|
|
66
|
+
out.additionalProperties = { anyOf: [out.additionalProperties, ...subs] };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
/** 剥离后的 schema;剥离不能保证只放宽时返回跳过原因。 */
|
|
72
|
+
function sanitizeOrSkip(schema) {
|
|
73
|
+
const state = { stripped: false, strippedNonPositive: false, unevaluated: false };
|
|
74
|
+
const out = sanitize(schema, state);
|
|
75
|
+
if (state.strippedNonPositive) {
|
|
76
|
+
return { skip: "constraints stripped under not/oneOf/if/then/else" };
|
|
77
|
+
}
|
|
78
|
+
if (state.stripped && state.unevaluated) {
|
|
79
|
+
return {
|
|
80
|
+
skip: "constraints stripped in a schema using unevaluatedProperties/unevaluatedItems",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return { schema: out };
|
|
84
|
+
}
|
|
85
|
+
/** 嵌套层数(对象 / 数组),超过 `limit` 即停止计算并返回 `limit + 1`。 */
|
|
86
|
+
function depthOf(v, limit, d = 0) {
|
|
87
|
+
if (d > limit || v === null || typeof v !== "object")
|
|
88
|
+
return d;
|
|
89
|
+
let max = d + 1;
|
|
90
|
+
for (const x of Array.isArray(v) ? v : Object.values(v)) {
|
|
91
|
+
max = Math.max(max, depthOf(x, limit, d + 1));
|
|
92
|
+
if (max > limit)
|
|
93
|
+
return max;
|
|
94
|
+
}
|
|
95
|
+
return max;
|
|
96
|
+
}
|
|
97
|
+
/** 不受信任的 schema 超限的原因;不超限为 null。 */
|
|
98
|
+
function limitIssue(schema) {
|
|
99
|
+
let bytes;
|
|
100
|
+
try {
|
|
101
|
+
bytes = Buffer.byteLength(JSON.stringify(schema), "utf8");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return "schema is not serializable";
|
|
105
|
+
}
|
|
106
|
+
if (bytes > UNTRUSTED_SCHEMA_MAX_BYTES) {
|
|
107
|
+
return `schema larger than ${UNTRUSTED_SCHEMA_MAX_BYTES} bytes`;
|
|
108
|
+
}
|
|
109
|
+
if (depthOf(schema, UNTRUSTED_SCHEMA_MAX_DEPTH) > UNTRUSTED_SCHEMA_MAX_DEPTH) {
|
|
110
|
+
return `schema nested deeper than ${UNTRUSTED_SCHEMA_MAX_DEPTH} levels`;
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
function remember(key, fn) {
|
|
115
|
+
if (compiled.size >= CACHE_MAX)
|
|
116
|
+
compiled.clear();
|
|
117
|
+
compiled.set(key, fn);
|
|
118
|
+
return fn;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 编译工具的 inputSchema;去掉 `$schema`(MCP 服务常声明 draft-07,Ajv 2020 实例不认它的元 schema)。
|
|
122
|
+
* 不受信任的先查大小 / 层数(超限 → null,记一次 warn),再 {@link sanitize}
|
|
123
|
+
* (剥离不能保证只放宽 → null,记一次 warn)。
|
|
124
|
+
* 定义本身无法编译 → null(不拦截调用,交给工具自己校验),按缓存键只 warn 一次(缓存命中不再记)。
|
|
125
|
+
*/
|
|
126
|
+
function compile(toolKey, schema, untrusted, log) {
|
|
127
|
+
const { $schema: _ignored, ...rest } = schema;
|
|
128
|
+
const raw = `${untrusted ? "u" : "t"}:${canonicalJson(rest)}`;
|
|
129
|
+
if (compiled.has(raw))
|
|
130
|
+
return compiled.get(raw) ?? null;
|
|
131
|
+
if (untrusted) {
|
|
132
|
+
const issue = limitIssue(rest);
|
|
133
|
+
if (issue !== null) {
|
|
134
|
+
log?.warn("tool input schema not validated", { toolKey, reason: issue });
|
|
135
|
+
return remember(raw, null);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let target = rest;
|
|
139
|
+
if (untrusted) {
|
|
140
|
+
const r = sanitizeOrSkip(rest);
|
|
141
|
+
if ("skip" in r) {
|
|
142
|
+
log?.warn("tool input schema not validated", { toolKey, reason: r.skip });
|
|
143
|
+
return remember(raw, null);
|
|
144
|
+
}
|
|
145
|
+
target = r.schema;
|
|
146
|
+
}
|
|
147
|
+
let fn;
|
|
148
|
+
try {
|
|
149
|
+
fn = newAjv().compile(target);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
log?.warn("tool input schema failed to compile; validation skipped", {
|
|
153
|
+
toolKey,
|
|
154
|
+
reason: err instanceof Error ? err.message.slice(0, 200) : String(err),
|
|
155
|
+
});
|
|
156
|
+
fn = null;
|
|
157
|
+
}
|
|
158
|
+
return remember(raw, fn);
|
|
159
|
+
}
|
|
160
|
+
function describe(e) {
|
|
161
|
+
const at = e.instancePath === "" ? "/" : e.instancePath;
|
|
162
|
+
let msg = `${at} ${e.message ?? "is invalid"}`;
|
|
163
|
+
const p = e.params;
|
|
164
|
+
if (e.keyword === "additionalProperties" && typeof p.additionalProperty === "string") {
|
|
165
|
+
msg += ` (${p.additionalProperty})`;
|
|
166
|
+
}
|
|
167
|
+
else if (e.keyword === "enum" && Array.isArray(p.allowedValues)) {
|
|
168
|
+
msg += ` ${JSON.stringify(p.allowedValues)}`;
|
|
169
|
+
}
|
|
170
|
+
return msg;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 管线第 2 阶段:按工具的 inputSchema 校验参数(ajv,JSON Schema 2020-12,`strict: false`,`allErrors: true`)。
|
|
174
|
+
* 合法 → null;不合法 → 给模型的英文说明:全部错误路径 + 完整 inputSchema(spec 6.3「给事实,不猜」)。
|
|
175
|
+
* schema 自身无法编译或超限时不拦截(返回 null)。
|
|
176
|
+
*/
|
|
177
|
+
export function validateInput(key, spec, input, opts = {}) {
|
|
178
|
+
const fn = compile(key, spec.inputSchema, opts.untrusted === true, opts.log);
|
|
179
|
+
if (!fn || fn(input))
|
|
180
|
+
return null;
|
|
181
|
+
const errors = (fn.errors ?? []).map(describe);
|
|
182
|
+
return `Invalid arguments for ${key}: ${errors.join("; ")}\nInput schema: ${JSON.stringify(spec.inputSchema)}`;
|
|
183
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured tool views (UI refresh B, spec §5.5 / §5.9): the line diff behind the `edit` view of
|
|
3
|
+
* `tool_result.view`. Display only: the view is never sent to the model.
|
|
4
|
+
*/
|
|
5
|
+
/** At most this many diff lines (context + added + removed) go into one view. */
|
|
6
|
+
export declare const TOOL_VIEW_DIFF_MAX_LINES = 2000;
|
|
7
|
+
/** A diff line longer than this is cut (the `tool_result.view` schema limit). */
|
|
8
|
+
export declare const TOOL_VIEW_LINE_MAX_CHARS = 2000;
|
|
9
|
+
/** Above this size (bytes, either side) no hunks are computed, only counts. */
|
|
10
|
+
export declare const TOOL_VIEW_DIFF_MAX_BYTES: number;
|
|
11
|
+
/**
|
|
12
|
+
* The most diff text (UTF-8 bytes, all lines together) one view carries; beyond it the rest is left
|
|
13
|
+
* out with `truncated: true`. The view sits in an event row that every events fetch re-reads.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TOOL_VIEW_DIFF_MAX_TEXT_BYTES: number;
|
|
16
|
+
export interface DiffLine {
|
|
17
|
+
kind: "ctx" | "add" | "del";
|
|
18
|
+
text: string;
|
|
19
|
+
}
|
|
20
|
+
export interface Hunk {
|
|
21
|
+
/** First old line of the hunk (1-based; 0 when the hunk has no old lines, as in unified diffs). */
|
|
22
|
+
oldStart: number;
|
|
23
|
+
/** First new line of the hunk (1-based; 0 when the hunk has no new lines). */
|
|
24
|
+
newStart: number;
|
|
25
|
+
lines: DiffLine[];
|
|
26
|
+
}
|
|
27
|
+
export interface LineDiff {
|
|
28
|
+
hunks: Hunk[];
|
|
29
|
+
added: number;
|
|
30
|
+
removed: number;
|
|
31
|
+
/** Hunks were left out (the line cap) or not computed (a side over 1 MB). */
|
|
32
|
+
truncated: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The line diff from `before` to `after` as unified-diff hunks with `context` lines around each
|
|
36
|
+
* change. Output is capped at {@link TOOL_VIEW_DIFF_MAX_LINES} lines (`truncated: true` beyond);
|
|
37
|
+
* when either side is over 1 MB no hunks are computed and the counts come from comparing line sets.
|
|
38
|
+
*/
|
|
39
|
+
export declare function lineDiff(before: string, after: string, context?: number): LineDiff;
|
|
40
|
+
/** The longest path in a view (the `tool_result.view` schema limit, UTF-16 units). */
|
|
41
|
+
export declare const TOOL_VIEW_PATH_MAX_CHARS = 1024;
|
|
42
|
+
/** A path cut to fit a view (kept whole when it fits; the row shows it as given). */
|
|
43
|
+
export declare function viewPath(path: string): string;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured tool views (UI refresh B, spec §5.5 / §5.9): the line diff behind the `edit` view of
|
|
3
|
+
* `tool_result.view`. Display only: the view is never sent to the model.
|
|
4
|
+
*/
|
|
5
|
+
/** At most this many diff lines (context + added + removed) go into one view. */
|
|
6
|
+
export const TOOL_VIEW_DIFF_MAX_LINES = 2000;
|
|
7
|
+
/** A diff line longer than this is cut (the `tool_result.view` schema limit). */
|
|
8
|
+
export const TOOL_VIEW_LINE_MAX_CHARS = 2000;
|
|
9
|
+
/** Above this size (bytes, either side) no hunks are computed, only counts. */
|
|
10
|
+
export const TOOL_VIEW_DIFF_MAX_BYTES = 1024 * 1024;
|
|
11
|
+
/**
|
|
12
|
+
* The most diff text (UTF-8 bytes, all lines together) one view carries; beyond it the rest is left
|
|
13
|
+
* out with `truncated: true`. The view sits in an event row that every events fetch re-reads.
|
|
14
|
+
*/
|
|
15
|
+
export const TOOL_VIEW_DIFF_MAX_TEXT_BYTES = 256 * 1024;
|
|
16
|
+
/**
|
|
17
|
+
* The most edits the Myers search looks for in the part that differs; beyond it the part is shown as
|
|
18
|
+
* removed then added (still a correct diff, just not minimal), so time and memory stay bounded.
|
|
19
|
+
*/
|
|
20
|
+
const MAX_EDITS = 1000;
|
|
21
|
+
/** Lines of a text; a final newline does not start another line. */
|
|
22
|
+
function splitLines(text) {
|
|
23
|
+
if (text === "")
|
|
24
|
+
return [];
|
|
25
|
+
const lines = text.split("\n");
|
|
26
|
+
if (lines.at(-1) === "")
|
|
27
|
+
lines.pop();
|
|
28
|
+
return lines;
|
|
29
|
+
}
|
|
30
|
+
const byteLength = (s) => Buffer.byteLength(s, "utf8");
|
|
31
|
+
/** Added / removed counts by comparing the line multisets (no alignment). */
|
|
32
|
+
function countOnly(a, b) {
|
|
33
|
+
const left = new Map();
|
|
34
|
+
for (const l of a)
|
|
35
|
+
left.set(l, (left.get(l) ?? 0) + 1);
|
|
36
|
+
let added = 0;
|
|
37
|
+
for (const l of b) {
|
|
38
|
+
const n = left.get(l) ?? 0;
|
|
39
|
+
if (n > 0)
|
|
40
|
+
left.set(l, n - 1);
|
|
41
|
+
else
|
|
42
|
+
added++;
|
|
43
|
+
}
|
|
44
|
+
let removed = 0;
|
|
45
|
+
for (const n of left.values())
|
|
46
|
+
removed += n;
|
|
47
|
+
return { added, removed };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Myers' O(ND) edit script between `a` and `b` (both already stripped of their common prefix and
|
|
51
|
+
* suffix): the list of operations in order. Null when more than {@link MAX_EDITS} edits are needed.
|
|
52
|
+
*/
|
|
53
|
+
function myers(a, b) {
|
|
54
|
+
const n = a.length;
|
|
55
|
+
const m = b.length;
|
|
56
|
+
const max = Math.min(n + m, MAX_EDITS);
|
|
57
|
+
const offset = max + 1;
|
|
58
|
+
let v = new Int32Array(2 * max + 3);
|
|
59
|
+
const trace = [];
|
|
60
|
+
for (let d = 0; d <= max; d++) {
|
|
61
|
+
trace.push(v);
|
|
62
|
+
const next = v.slice();
|
|
63
|
+
for (let k = -d; k <= d; k += 2) {
|
|
64
|
+
let x;
|
|
65
|
+
if (k === -d || (k !== d && v[offset + k - 1] < v[offset + k + 1])) {
|
|
66
|
+
x = v[offset + k + 1];
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
x = v[offset + k - 1] + 1;
|
|
70
|
+
}
|
|
71
|
+
let y = x - k;
|
|
72
|
+
while (x < n && y < m && a[x] === b[y]) {
|
|
73
|
+
x++;
|
|
74
|
+
y++;
|
|
75
|
+
}
|
|
76
|
+
next[offset + k] = x;
|
|
77
|
+
if (x >= n && y >= m)
|
|
78
|
+
return backtrack(trace, d, n, m, offset);
|
|
79
|
+
}
|
|
80
|
+
v = next;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
function backtrack(trace, dEnd, n, m, offset) {
|
|
85
|
+
const ops = [];
|
|
86
|
+
let x = n;
|
|
87
|
+
let y = m;
|
|
88
|
+
for (let d = dEnd; d > 0; d--) {
|
|
89
|
+
const v = trace[d];
|
|
90
|
+
const k = x - y;
|
|
91
|
+
const down = k === -d || (k !== d && v[offset + k - 1] < v[offset + k + 1]);
|
|
92
|
+
const prevK = down ? k + 1 : k - 1;
|
|
93
|
+
const prevX = v[offset + prevK];
|
|
94
|
+
const prevY = prevX - prevK;
|
|
95
|
+
while (x > prevX && y > prevY) {
|
|
96
|
+
ops.push("ctx");
|
|
97
|
+
x--;
|
|
98
|
+
y--;
|
|
99
|
+
}
|
|
100
|
+
ops.push(down ? "add" : "del");
|
|
101
|
+
x = prevX;
|
|
102
|
+
y = prevY;
|
|
103
|
+
}
|
|
104
|
+
while (x > 0 && y > 0) {
|
|
105
|
+
ops.push("ctx");
|
|
106
|
+
x--;
|
|
107
|
+
y--;
|
|
108
|
+
}
|
|
109
|
+
return ops.reverse();
|
|
110
|
+
}
|
|
111
|
+
/** A diff line as the view keeps it: cut to the schema limit, NUL as U+FFFD (jsonb rejects it). */
|
|
112
|
+
const cut = (s) => (s.length > TOOL_VIEW_LINE_MAX_CHARS ? s.slice(0, TOOL_VIEW_LINE_MAX_CHARS) : s).replaceAll("\0", "\uFFFD");
|
|
113
|
+
/**
|
|
114
|
+
* The line diff from `before` to `after` as unified-diff hunks with `context` lines around each
|
|
115
|
+
* change. Output is capped at {@link TOOL_VIEW_DIFF_MAX_LINES} lines (`truncated: true` beyond);
|
|
116
|
+
* when either side is over 1 MB no hunks are computed and the counts come from comparing line sets.
|
|
117
|
+
*/
|
|
118
|
+
export function lineDiff(before, after, context = 3) {
|
|
119
|
+
const a = splitLines(before);
|
|
120
|
+
const b = splitLines(after);
|
|
121
|
+
if (byteLength(before) > TOOL_VIEW_DIFF_MAX_BYTES ||
|
|
122
|
+
byteLength(after) > TOOL_VIEW_DIFF_MAX_BYTES) {
|
|
123
|
+
return { hunks: [], ...countOnly(a, b), truncated: true };
|
|
124
|
+
}
|
|
125
|
+
// common prefix and suffix first: most edits change one small region
|
|
126
|
+
let pre = 0;
|
|
127
|
+
while (pre < a.length && pre < b.length && a[pre] === b[pre])
|
|
128
|
+
pre++;
|
|
129
|
+
let suf = 0;
|
|
130
|
+
while (suf < a.length - pre &&
|
|
131
|
+
suf < b.length - pre &&
|
|
132
|
+
a[a.length - 1 - suf] === b[b.length - 1 - suf]) {
|
|
133
|
+
suf++;
|
|
134
|
+
}
|
|
135
|
+
const midA = a.slice(pre, a.length - suf);
|
|
136
|
+
const midB = b.slice(pre, b.length - suf);
|
|
137
|
+
const mid = myers(midA, midB) ?? [
|
|
138
|
+
...midA.map(() => "del"),
|
|
139
|
+
...midB.map(() => "add"),
|
|
140
|
+
];
|
|
141
|
+
const ops = [
|
|
142
|
+
...Array(pre).fill("ctx"),
|
|
143
|
+
...mid,
|
|
144
|
+
...Array(suf).fill("ctx"),
|
|
145
|
+
];
|
|
146
|
+
const all = [];
|
|
147
|
+
let ai = 0;
|
|
148
|
+
let bi = 0;
|
|
149
|
+
let added = 0;
|
|
150
|
+
let removed = 0;
|
|
151
|
+
for (const kind of ops) {
|
|
152
|
+
all.push({ kind, ai, bi });
|
|
153
|
+
if (kind === "ctx") {
|
|
154
|
+
ai++;
|
|
155
|
+
bi++;
|
|
156
|
+
}
|
|
157
|
+
else if (kind === "del") {
|
|
158
|
+
ai++;
|
|
159
|
+
removed++;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
bi++;
|
|
163
|
+
added++;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// group changes into hunks: a change starts or extends a hunk when within 2 * context of the last
|
|
167
|
+
const ranges = [];
|
|
168
|
+
for (let i = 0; i < all.length; i++) {
|
|
169
|
+
if (all[i].kind === "ctx")
|
|
170
|
+
continue;
|
|
171
|
+
const start = Math.max(0, i - context);
|
|
172
|
+
const end = Math.min(all.length, i + context + 1);
|
|
173
|
+
const lastRange = ranges.at(-1);
|
|
174
|
+
if (lastRange && start <= lastRange[1])
|
|
175
|
+
lastRange[1] = end;
|
|
176
|
+
else
|
|
177
|
+
ranges.push([start, end]);
|
|
178
|
+
}
|
|
179
|
+
const hunks = [];
|
|
180
|
+
let emitted = 0;
|
|
181
|
+
let textBytes = 0;
|
|
182
|
+
let truncated = false;
|
|
183
|
+
for (const [start, end] of ranges) {
|
|
184
|
+
if (emitted >= TOOL_VIEW_DIFF_MAX_LINES || textBytes >= TOOL_VIEW_DIFF_MAX_TEXT_BYTES) {
|
|
185
|
+
truncated = true;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
const slice = all.slice(start, end);
|
|
189
|
+
const room = TOOL_VIEW_DIFF_MAX_LINES - emitted;
|
|
190
|
+
const lines = [];
|
|
191
|
+
let first;
|
|
192
|
+
for (const o of slice.length > room ? slice.slice(0, room) : slice) {
|
|
193
|
+
const text = cut((o.kind === "add" ? b[o.bi] : a[o.ai]));
|
|
194
|
+
const size = byteLength(text);
|
|
195
|
+
if (textBytes + size > TOOL_VIEW_DIFF_MAX_TEXT_BYTES)
|
|
196
|
+
break;
|
|
197
|
+
textBytes += size;
|
|
198
|
+
first ??= o;
|
|
199
|
+
lines.push({ kind: o.kind, text });
|
|
200
|
+
}
|
|
201
|
+
if (lines.length < slice.length)
|
|
202
|
+
truncated = true;
|
|
203
|
+
if (first === undefined)
|
|
204
|
+
break;
|
|
205
|
+
const hasOld = lines.some((l) => l.kind !== "add");
|
|
206
|
+
const hasNew = lines.some((l) => l.kind !== "del");
|
|
207
|
+
hunks.push({
|
|
208
|
+
oldStart: hasOld ? first.ai + 1 : first.ai,
|
|
209
|
+
newStart: hasNew ? first.bi + 1 : first.bi,
|
|
210
|
+
lines,
|
|
211
|
+
});
|
|
212
|
+
emitted += lines.length;
|
|
213
|
+
}
|
|
214
|
+
return { hunks, added, removed, truncated };
|
|
215
|
+
}
|
|
216
|
+
/** The longest path in a view (the `tool_result.view` schema limit, UTF-16 units). */
|
|
217
|
+
export const TOOL_VIEW_PATH_MAX_CHARS = 1024;
|
|
218
|
+
/** A path cut to fit a view (kept whole when it fits; the row shows it as given). */
|
|
219
|
+
export function viewPath(path) {
|
|
220
|
+
if (path.length <= TOOL_VIEW_PATH_MAX_CHARS)
|
|
221
|
+
return path;
|
|
222
|
+
const head = path.slice(0, TOOL_VIEW_PATH_MAX_CHARS - 1);
|
|
223
|
+
// never end on half a surrogate pair
|
|
224
|
+
return `${/[\uD800-\uDBFF]$/.test(head) ? head.slice(0, -1) : head}…`;
|
|
225
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { EmbedClaims } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import type { Keyring } from "../ctx/secrets.js";
|
|
3
|
+
/** 嵌入令牌的有效期(秒)。网页在过期前 60 秒续期。 */
|
|
4
|
+
export declare const EMBED_TOKEN_TTL_SECONDS = 300;
|
|
5
|
+
/** 校验 `exp` 时容许的副本间时钟偏差(秒)。 */
|
|
6
|
+
export declare const EMBED_TOKEN_SKEW_SECONDS = 30;
|
|
7
|
+
/** HKDF 用途(keyring 派生时 info 为 `capybara:capybara-embed/1`),也是签名输入的域前缀。 */
|
|
8
|
+
export declare const EMBED_KEY_INFO = "capybara-embed/1";
|
|
9
|
+
/**
|
|
10
|
+
* 嵌入令牌:`base64url(JSON 声明).base64url(HMAC-SHA256(key, "capybara-embed/1." + 第一段))`。
|
|
11
|
+
* - 格式固定、没有头(没有 alg 可混淆);密钥由主密钥环经 HKDF 派生,轮换后上一把主密钥签的令牌仍可校验到过期;
|
|
12
|
+
* - 校验:严格 base64url、常量时间比较签名、逐字段核对声明、`exp` 容许 {@link EMBED_TOKEN_SKEW_SECONDS} 秒偏差、
|
|
13
|
+
* `exp` 不得超过「现在 + 有效期 + 偏差」、`plugin` 必须是调用方插件;任何一项不过都返回 null(不说明原因)。
|
|
14
|
+
* 无状态(不落库、不进 Redis):各副本用同一主密钥即可校验,不需要共享状态。
|
|
15
|
+
*/
|
|
16
|
+
export declare class EmbedTokens {
|
|
17
|
+
private readonly current;
|
|
18
|
+
private readonly keys;
|
|
19
|
+
private readonly now;
|
|
20
|
+
constructor(keyring: Keyring, opts?: {
|
|
21
|
+
now?: () => number;
|
|
22
|
+
});
|
|
23
|
+
/** 签发:`exp` = 现在 + {@link EMBED_TOKEN_TTL_SECONDS}。 */
|
|
24
|
+
issue(c: Omit<EmbedClaims, "exp">): {
|
|
25
|
+
token: string;
|
|
26
|
+
claims: EmbedClaims;
|
|
27
|
+
expiresAt: Date;
|
|
28
|
+
};
|
|
29
|
+
/** 校验令牌并要求它签给 `plugin`;不通过返回 null。 */
|
|
30
|
+
verify(token: unknown, plugin: string): EmbedClaims | null;
|
|
31
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { ORG_ROLES } from "../orgs/roles.js";
|
|
3
|
+
/** 嵌入令牌的有效期(秒)。网页在过期前 60 秒续期。 */
|
|
4
|
+
export const EMBED_TOKEN_TTL_SECONDS = 300;
|
|
5
|
+
/** 校验 `exp` 时容许的副本间时钟偏差(秒)。 */
|
|
6
|
+
export const EMBED_TOKEN_SKEW_SECONDS = 30;
|
|
7
|
+
/** HKDF 用途(keyring 派生时 info 为 `capybara:capybara-embed/1`),也是签名输入的域前缀。 */
|
|
8
|
+
export const EMBED_KEY_INFO = "capybara-embed/1";
|
|
9
|
+
/** 令牌总长上限:声明有界(id ≤ 100 字符),远小于此。 */
|
|
10
|
+
const TOKEN_MAX = 2048;
|
|
11
|
+
const MAC_LEN = 32;
|
|
12
|
+
const B64URL = /^[A-Za-z0-9_-]+$/;
|
|
13
|
+
const PLUGIN_RE = /^[a-z][a-z0-9-]{1,40}$/;
|
|
14
|
+
const CLAIM_KEYS = new Set([
|
|
15
|
+
"plugin",
|
|
16
|
+
"orgId",
|
|
17
|
+
"accountId",
|
|
18
|
+
"role",
|
|
19
|
+
"conversationId",
|
|
20
|
+
"fileId",
|
|
21
|
+
"contribution",
|
|
22
|
+
"exp",
|
|
23
|
+
]);
|
|
24
|
+
const ROLES = new Set(ORG_ROLES);
|
|
25
|
+
const isId = (v) => typeof v === "string" && v !== "" && v.length <= 100;
|
|
26
|
+
/**
|
|
27
|
+
* 严格解码 base64url:只允许字母表内字符、不带填充,且必须是规范编码(解码后再编码与原文相同),
|
|
28
|
+
* 同一份字节只有一种写法。
|
|
29
|
+
*/
|
|
30
|
+
function decodeStrict(s) {
|
|
31
|
+
if (!B64URL.test(s))
|
|
32
|
+
return null;
|
|
33
|
+
const buf = Buffer.from(s, "base64url");
|
|
34
|
+
return buf.toString("base64url") === s ? buf : null;
|
|
35
|
+
}
|
|
36
|
+
/** 逐字段核对声明:只认已知字段、类型正确,返回只含已知字段的新对象。 */
|
|
37
|
+
function parseClaims(v) {
|
|
38
|
+
if (typeof v !== "object" || v === null || Array.isArray(v))
|
|
39
|
+
return null;
|
|
40
|
+
const c = v;
|
|
41
|
+
if (Object.keys(c).some((k) => !CLAIM_KEYS.has(k)))
|
|
42
|
+
return null;
|
|
43
|
+
if (typeof c.plugin !== "string" || !PLUGIN_RE.test(c.plugin))
|
|
44
|
+
return null;
|
|
45
|
+
if (!isId(c.orgId) || !isId(c.accountId) || !isId(c.contribution))
|
|
46
|
+
return null;
|
|
47
|
+
if (!ROLES.has(c.role))
|
|
48
|
+
return null;
|
|
49
|
+
if (c.conversationId !== undefined && !isId(c.conversationId))
|
|
50
|
+
return null;
|
|
51
|
+
if (c.fileId !== undefined && (!isId(c.fileId) || c.conversationId === undefined))
|
|
52
|
+
return null;
|
|
53
|
+
if (typeof c.exp !== "number" || !Number.isSafeInteger(c.exp))
|
|
54
|
+
return null;
|
|
55
|
+
return {
|
|
56
|
+
plugin: c.plugin,
|
|
57
|
+
orgId: c.orgId,
|
|
58
|
+
accountId: c.accountId,
|
|
59
|
+
role: c.role,
|
|
60
|
+
...(c.conversationId !== undefined && { conversationId: c.conversationId }),
|
|
61
|
+
...(c.fileId !== undefined && { fileId: c.fileId }),
|
|
62
|
+
contribution: c.contribution,
|
|
63
|
+
exp: c.exp,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 嵌入令牌:`base64url(JSON 声明).base64url(HMAC-SHA256(key, "capybara-embed/1." + 第一段))`。
|
|
68
|
+
* - 格式固定、没有头(没有 alg 可混淆);密钥由主密钥环经 HKDF 派生,轮换后上一把主密钥签的令牌仍可校验到过期;
|
|
69
|
+
* - 校验:严格 base64url、常量时间比较签名、逐字段核对声明、`exp` 容许 {@link EMBED_TOKEN_SKEW_SECONDS} 秒偏差、
|
|
70
|
+
* `exp` 不得超过「现在 + 有效期 + 偏差」、`plugin` 必须是调用方插件;任何一项不过都返回 null(不说明原因)。
|
|
71
|
+
* 无状态(不落库、不进 Redis):各副本用同一主密钥即可校验,不需要共享状态。
|
|
72
|
+
*/
|
|
73
|
+
export class EmbedTokens {
|
|
74
|
+
current;
|
|
75
|
+
keys;
|
|
76
|
+
now;
|
|
77
|
+
constructor(keyring, opts = {}) {
|
|
78
|
+
const derived = keyring.deriveKey(EMBED_KEY_INFO);
|
|
79
|
+
const ids = [derived.currentId, ...keyring.toJSON().previousIds];
|
|
80
|
+
this.current = derived.current;
|
|
81
|
+
this.keys = ids.map((id) => derived.byId(id)).filter((k) => k !== undefined);
|
|
82
|
+
this.now = opts.now ?? Date.now;
|
|
83
|
+
}
|
|
84
|
+
/** 签发:`exp` = 现在 + {@link EMBED_TOKEN_TTL_SECONDS}。 */
|
|
85
|
+
issue(c) {
|
|
86
|
+
const exp = Math.floor(this.now() / 1000) + EMBED_TOKEN_TTL_SECONDS;
|
|
87
|
+
const claims = parseClaims({ ...c, exp });
|
|
88
|
+
if (claims === null)
|
|
89
|
+
throw new Error("embed token claims are invalid");
|
|
90
|
+
const payload = Buffer.from(JSON.stringify(claims), "utf8").toString("base64url");
|
|
91
|
+
const token = `${payload}.${mac(this.current, payload).toString("base64url")}`;
|
|
92
|
+
return { token, claims, expiresAt: new Date(exp * 1000) };
|
|
93
|
+
}
|
|
94
|
+
/** 校验令牌并要求它签给 `plugin`;不通过返回 null。 */
|
|
95
|
+
verify(token, plugin) {
|
|
96
|
+
if (typeof token !== "string" || token.length > TOKEN_MAX)
|
|
97
|
+
return null;
|
|
98
|
+
const dot = token.indexOf(".");
|
|
99
|
+
if (dot <= 0 || dot !== token.lastIndexOf("."))
|
|
100
|
+
return null;
|
|
101
|
+
const payload = token.slice(0, dot);
|
|
102
|
+
const sig = decodeStrict(token.slice(dot + 1));
|
|
103
|
+
const body = decodeStrict(payload);
|
|
104
|
+
if (sig === null || body === null || sig.length !== MAC_LEN)
|
|
105
|
+
return null;
|
|
106
|
+
// 每把候选密钥都算一遍、常量时间比较(不因第一把匹配就提前返回)
|
|
107
|
+
let ok = false;
|
|
108
|
+
for (const key of this.keys)
|
|
109
|
+
ok = timingSafeEqual(mac(key, payload), sig) || ok;
|
|
110
|
+
if (!ok)
|
|
111
|
+
return null;
|
|
112
|
+
let parsed;
|
|
113
|
+
try {
|
|
114
|
+
parsed = JSON.parse(body.toString("utf8"));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const claims = parseClaims(parsed);
|
|
120
|
+
if (claims === null || claims.plugin !== plugin)
|
|
121
|
+
return null;
|
|
122
|
+
const nowSec = this.now() / 1000;
|
|
123
|
+
if (claims.exp + EMBED_TOKEN_SKEW_SECONDS <= nowSec)
|
|
124
|
+
return null;
|
|
125
|
+
if (claims.exp > nowSec + EMBED_TOKEN_TTL_SECONDS + EMBED_TOKEN_SKEW_SECONDS)
|
|
126
|
+
return null;
|
|
127
|
+
return claims;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function mac(key, payload) {
|
|
131
|
+
return createHmac("sha256", key).update(`${EMBED_KEY_INFO}.${payload}`).digest();
|
|
132
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ExtensionManifest, UiActionArgs, UiActionResult, UiContribution, UiRenderArgs, UiView } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { type OrgRole } from "../orgs/roles.js";
|
|
3
|
+
/** 会话 id 的格式(UUID)。 */
|
|
4
|
+
export declare const UUID_RE: RegExp;
|
|
5
|
+
/** 组织页面(`place: "page"`)所需的最低角色(A38):guest 只用对话位置的贡献。 */
|
|
6
|
+
export declare const PAGE_MIN_ROLE: OrgRole;
|
|
7
|
+
/** Places on the conversation page (everything but an org page): they need a `conversationId`. */
|
|
8
|
+
export declare const isConversationPlace: (place: UiContribution["place"]) => boolean;
|
|
9
|
+
/** 该角色能否使用这个位置的贡献。 */
|
|
10
|
+
export declare const canUsePlace: (place: UiContribution["place"], role: OrgRole) => boolean;
|
|
11
|
+
/** 插件视图的 render 函数(`ctx.ui.view` 注册)。 */
|
|
12
|
+
export type UiRender = (args: UiRenderArgs) => Promise<UiView>;
|
|
13
|
+
/** 插件视图的动作处理函数(`ctx.ui.action` 注册)。 */
|
|
14
|
+
export type UiActionHandler = (args: UiActionArgs) => Promise<UiActionResult>;
|
|
15
|
+
/**
|
|
16
|
+
* 组织级界面刷新的内核 bus 主题(命名空间 `kernel`):`org-ui.<orgId>`。
|
|
17
|
+
* 对话视图的刷新走会话主题 `conv.<id>`(与事件、增量共用),见 `conversationTopic`。
|
|
18
|
+
*/
|
|
19
|
+
export declare const orgUiTopic: (orgId: string) => string;
|
|
20
|
+
/** 界面刷新消息:`conv.<id>` 与 `org-ui.<orgId>` 上的 `{ kind: "ui", plugin, contribution }`。 */
|
|
21
|
+
export interface UiBusMessage {
|
|
22
|
+
kind: "ui";
|
|
23
|
+
plugin: string;
|
|
24
|
+
contribution: string;
|
|
25
|
+
}
|
|
26
|
+
/** 是否为界面刷新消息(bus 上的消息来自其他副本,按形状核对)。 */
|
|
27
|
+
export declare function isUiBusMessage(m: unknown): m is UiBusMessage;
|
|
28
|
+
/** SSE 帧 `event: ui`,数据 `{ plugin, contribution }`。 */
|
|
29
|
+
export declare const uiFrame: (m: UiBusMessage) => string;
|
|
30
|
+
/**
|
|
31
|
+
* 单个插件在 setup 期间注册的视图与动作:进程内的静态登记(同 `ctx.tools.register`),
|
|
32
|
+
* 不是跨请求的共享状态——各副本加载同一插件得到同样的登记。
|
|
33
|
+
* id 必须是 `permissions.ui.views` 里的(与清单 `ui` 里 kind view 的贡献一一对应,`defineExtension` 已交叉核对)。
|
|
34
|
+
*/
|
|
35
|
+
export declare class PluginUiRegistration {
|
|
36
|
+
private readonly manifest;
|
|
37
|
+
/** 越权(id 未在 `permissions.ui.views` 声明):抛 ExtensionPermissionError 并写审计。 */
|
|
38
|
+
private readonly deny;
|
|
39
|
+
readonly views: Map<string, UiRender>;
|
|
40
|
+
readonly actions: Map<string, UiActionHandler>;
|
|
41
|
+
private readonly declaredViews;
|
|
42
|
+
private readonly contributions;
|
|
43
|
+
private sealed;
|
|
44
|
+
constructor(manifest: ExtensionManifest,
|
|
45
|
+
/** 越权(id 未在 `permissions.ui.views` 声明):抛 ExtensionPermissionError 并写审计。 */
|
|
46
|
+
deny: (item: string) => never);
|
|
47
|
+
/** setup 结束后调用:此后 view / action 抛错。 */
|
|
48
|
+
seal(): void;
|
|
49
|
+
view(id: string, render: UiRender): void;
|
|
50
|
+
action(id: string, handler: UiActionHandler): void;
|
|
51
|
+
/** 校验 invalidate 的目标,返回规范化后的 `{ orgId, conversationId?, contribution }`。 */
|
|
52
|
+
target(t: unknown): {
|
|
53
|
+
orgId: string;
|
|
54
|
+
conversationId?: string;
|
|
55
|
+
contribution: string;
|
|
56
|
+
};
|
|
57
|
+
private register;
|
|
58
|
+
}
|