@wascartech/devbot 0.0.0-stage → 2.1.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/README.md +638 -2
- package/dist/access-grant-store.js +99 -0
- package/dist/access-grant-store.js.map +1 -0
- package/dist/access-resolve.js +11 -0
- package/dist/access-resolve.js.map +1 -0
- package/dist/access-rule-store.js +99 -0
- package/dist/access-rule-store.js.map +1 -0
- package/dist/admin/access-routes.js +73 -0
- package/dist/admin/access-routes.js.map +1 -0
- package/dist/admin/access-rule-routes.js +107 -0
- package/dist/admin/access-rule-routes.js.map +1 -0
- package/dist/admin/custom-repos-routes.js +93 -0
- package/dist/admin/custom-repos-routes.js.map +1 -0
- package/dist/admin/env-routes.js +74 -0
- package/dist/admin/env-routes.js.map +1 -0
- package/dist/admin/global-settings-routes.js +254 -0
- package/dist/admin/global-settings-routes.js.map +1 -0
- package/dist/admin/mcp-cleanup.js +12 -0
- package/dist/admin/mcp-cleanup.js.map +1 -0
- package/dist/admin/mcp-routes.js +169 -0
- package/dist/admin/mcp-routes.js.map +1 -0
- package/dist/admin/query-params.js +80 -0
- package/dist/admin/query-params.js.map +1 -0
- package/dist/admin/routes.js +150 -0
- package/dist/admin/routes.js.map +1 -0
- package/dist/admin/run-history-routes.js +44 -0
- package/dist/admin/run-history-routes.js.map +1 -0
- package/dist/admin/run-routes.js +99 -0
- package/dist/admin/run-routes.js.map +1 -0
- package/dist/admin/settings-routes.js +119 -0
- package/dist/admin/settings-routes.js.map +1 -0
- package/dist/admin/stats-routes.js +51 -0
- package/dist/admin/stats-routes.js.map +1 -0
- package/dist/admin/task-routes.js +213 -0
- package/dist/admin/task-routes.js.map +1 -0
- package/dist/admin/test-routes.js +38 -0
- package/dist/admin/test-routes.js.map +1 -0
- package/dist/admin/volume-routes.js +82 -0
- package/dist/admin/volume-routes.js.map +1 -0
- package/dist/admin/webhook-routes.js +174 -0
- package/dist/admin/webhook-routes.js.map +1 -0
- package/dist/agents.js +48 -0
- package/dist/agents.js.map +1 -0
- package/dist/assignee-value.js +6 -0
- package/dist/assignee-value.js.map +1 -0
- package/dist/attachments.js +76 -0
- package/dist/attachments.js.map +1 -0
- package/dist/auto-commands.js +88 -0
- package/dist/auto-commands.js.map +1 -0
- package/dist/auto-features.js +32 -0
- package/dist/auto-features.js.map +1 -0
- package/dist/base-branch-store.js +40 -0
- package/dist/base-branch-store.js.map +1 -0
- package/dist/base-branches.js +9 -0
- package/dist/base-branches.js.map +1 -0
- package/dist/build-workflow.js +116 -0
- package/dist/build-workflow.js.map +1 -0
- package/dist/change-request-lifecycle.js +16 -0
- package/dist/change-request-lifecycle.js.map +1 -0
- package/dist/change-request-store.js +72 -0
- package/dist/change-request-store.js.map +1 -0
- package/dist/ci-failure.js +80 -0
- package/dist/ci-failure.js.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/conflict-fix.js +178 -0
- package/dist/conflict-fix.js.map +1 -0
- package/dist/cookie.js +70 -0
- package/dist/cookie.js.map +1 -0
- package/dist/crypto-util.js +40 -0
- package/dist/crypto-util.js.map +1 -0
- package/dist/custom-repos-store.js +90 -0
- package/dist/custom-repos-store.js.map +1 -0
- package/dist/custom-repos-sync.js +118 -0
- package/dist/custom-repos-sync.js.map +1 -0
- package/dist/db.js +12 -0
- package/dist/db.js.map +1 -0
- package/dist/devbot-scripts.js +18 -0
- package/dist/devbot-scripts.js.map +1 -0
- package/dist/devcontainer.js +150 -0
- package/dist/devcontainer.js.map +1 -0
- package/dist/env-config-store.js +132 -0
- package/dist/env-config-store.js.map +1 -0
- package/dist/error-log-store.js +193 -0
- package/dist/error-log-store.js.map +1 -0
- package/dist/git.js +605 -0
- package/dist/git.js.map +1 -0
- package/dist/global-queue.js +127 -0
- package/dist/global-queue.js.map +1 -0
- package/dist/global-settings-store.js +307 -0
- package/dist/global-settings-store.js.map +1 -0
- package/dist/help.js +41 -0
- package/dist/help.js.map +1 -0
- package/dist/http-csp.js +15 -0
- package/dist/http-csp.js.map +1 -0
- package/dist/http-util.js +40 -0
- package/dist/http-util.js.map +1 -0
- package/dist/idempotency.js +50 -0
- package/dist/idempotency.js.map +1 -0
- package/dist/lifecycle.js +234 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/logger.js +33 -0
- package/dist/logger.js.map +1 -0
- package/dist/lsp-servers.js +81 -0
- package/dist/lsp-servers.js.map +1 -0
- package/dist/mcp/auth.js +62 -0
- package/dist/mcp/auth.js.map +1 -0
- package/dist/mcp/effective-mcp.js +42 -0
- package/dist/mcp/effective-mcp.js.map +1 -0
- package/dist/mcp/oauth-refresh.js +138 -0
- package/dist/mcp/oauth-refresh.js.map +1 -0
- package/dist/mcp/peer-sync.js +109 -0
- package/dist/mcp/peer-sync.js.map +1 -0
- package/dist/mcp/registry.js +54 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/runner-bridge.js +93 -0
- package/dist/mcp/runner-bridge.js.map +1 -0
- package/dist/mcp/server.js +173 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/_helpers.js +88 -0
- package/dist/mcp/tools/_helpers.js.map +1 -0
- package/dist/mcp/tools/attachments.js +117 -0
- package/dist/mcp/tools/attachments.js.map +1 -0
- package/dist/mcp/tools/cicd.js +105 -0
- package/dist/mcp/tools/cicd.js.map +1 -0
- package/dist/mcp/tools/discovery.js +34 -0
- package/dist/mcp/tools/discovery.js.map +1 -0
- package/dist/mcp/tools/issues.js +56 -0
- package/dist/mcp/tools/issues.js.map +1 -0
- package/dist/mcp/tools/merge_requests.js +67 -0
- package/dist/mcp/tools/merge_requests.js.map +1 -0
- package/dist/mcp/tools/metadata.js +127 -0
- package/dist/mcp/tools/metadata.js.map +1 -0
- package/dist/mcp/tools/peer_sync.js +43 -0
- package/dist/mcp/tools/peer_sync.js.map +1 -0
- package/dist/mcp/tools/repository.js +178 -0
- package/dist/mcp/tools/repository.js.map +1 -0
- package/dist/mcp/tools/work_tracking.js +125 -0
- package/dist/mcp/tools/work_tracking.js.map +1 -0
- package/dist/mcp/tools/workitems.js +30 -0
- package/dist/mcp/tools/workitems.js.map +1 -0
- package/dist/mcp/volume-files.js +187 -0
- package/dist/mcp/volume-files.js.map +1 -0
- package/dist/mcp-auth-store.js +134 -0
- package/dist/mcp-auth-store.js.map +1 -0
- package/dist/mcp-config-store.js +83 -0
- package/dist/mcp-config-store.js.map +1 -0
- package/dist/mention.js +512 -0
- package/dist/mention.js.map +1 -0
- package/dist/migrate.js +438 -0
- package/dist/migrate.js.map +1 -0
- package/dist/mr-assignee.js +71 -0
- package/dist/mr-assignee.js.map +1 -0
- package/dist/mr-content.js +90 -0
- package/dist/mr-content.js.map +1 -0
- package/dist/oauth-routes.js +54 -0
- package/dist/oauth-routes.js.map +1 -0
- package/dist/onboarding-allowlist.js +32 -0
- package/dist/onboarding-allowlist.js.map +1 -0
- package/dist/opencode.js +291 -0
- package/dist/opencode.js.map +1 -0
- package/dist/outbound-webhook-store.js +229 -0
- package/dist/outbound-webhook-store.js.map +1 -0
- package/dist/outbound-webhook.js +314 -0
- package/dist/outbound-webhook.js.map +1 -0
- package/dist/path-sandbox.js +200 -0
- package/dist/path-sandbox.js.map +1 -0
- package/dist/platform/git-auth.js +34 -0
- package/dist/platform/git-auth.js.map +1 -0
- package/dist/platform/gitealike/attachments.js +62 -0
- package/dist/platform/gitealike/attachments.js.map +1 -0
- package/dist/platform/gitealike/base.js +935 -0
- package/dist/platform/gitealike/base.js.map +1 -0
- package/dist/platform/gitealike/forgejo.js +16 -0
- package/dist/platform/gitealike/forgejo.js.map +1 -0
- package/dist/platform/gitealike/gitea.js +16 -0
- package/dist/platform/gitealike/gitea.js.map +1 -0
- package/dist/platform/gitealike/http.js +152 -0
- package/dist/platform/gitealike/http.js.map +1 -0
- package/dist/platform/gitealike/schemas.js +284 -0
- package/dist/platform/gitealike/schemas.js.map +1 -0
- package/dist/platform/github/attachments.js +52 -0
- package/dist/platform/github/attachments.js.map +1 -0
- package/dist/platform/github/http.js +153 -0
- package/dist/platform/github/http.js.map +1 -0
- package/dist/platform/github/index.js +936 -0
- package/dist/platform/github/index.js.map +1 -0
- package/dist/platform/github/schemas.js +308 -0
- package/dist/platform/github/schemas.js.map +1 -0
- package/dist/platform/github/zip.js +85 -0
- package/dist/platform/github/zip.js.map +1 -0
- package/dist/platform/gitlab/admin.js +105 -0
- package/dist/platform/gitlab/admin.js.map +1 -0
- package/dist/platform/gitlab/api.js +229 -0
- package/dist/platform/gitlab/api.js.map +1 -0
- package/dist/platform/gitlab/attachments.js +79 -0
- package/dist/platform/gitlab/attachments.js.map +1 -0
- package/dist/platform/gitlab/http.js +165 -0
- package/dist/platform/gitlab/http.js.map +1 -0
- package/dist/platform/gitlab/index.js +630 -0
- package/dist/platform/gitlab/index.js.map +1 -0
- package/dist/platform/gitlab/oauth.js +58 -0
- package/dist/platform/gitlab/oauth.js.map +1 -0
- package/dist/platform/gitlab/read.js +182 -0
- package/dist/platform/gitlab/read.js.map +1 -0
- package/dist/platform/gitlab/schemas-read.js +274 -0
- package/dist/platform/gitlab/schemas-read.js.map +1 -0
- package/dist/platform/gitlab/schemas.js +251 -0
- package/dist/platform/gitlab/schemas.js.map +1 -0
- package/dist/platform/gitlab/signature.js +52 -0
- package/dist/platform/gitlab/signature.js.map +1 -0
- package/dist/platform/index.js +38 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/port.js +26 -0
- package/dist/platform/port.js.map +1 -0
- package/dist/platform/types.js +80 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/podman.js +119 -0
- package/dist/podman.js.map +1 -0
- package/dist/project-sync.js +69 -0
- package/dist/project-sync.js.map +1 -0
- package/dist/prompt.js +47 -0
- package/dist/prompt.js.map +1 -0
- package/dist/queue-store.js +236 -0
- package/dist/queue-store.js.map +1 -0
- package/dist/queue.js +129 -0
- package/dist/queue.js.map +1 -0
- package/dist/redact.js +23 -0
- package/dist/redact.js.map +1 -0
- package/dist/run-files.js +297 -0
- package/dist/run-files.js.map +1 -0
- package/dist/run-filters.js +54 -0
- package/dist/run-filters.js.map +1 -0
- package/dist/run-history-store.js +229 -0
- package/dist/run-history-store.js.map +1 -0
- package/dist/run-log-sink.js +270 -0
- package/dist/run-log-sink.js.map +1 -0
- package/dist/run-log.js +97 -0
- package/dist/run-log.js.map +1 -0
- package/dist/run-usage.js +29 -0
- package/dist/run-usage.js.map +1 -0
- package/dist/run-view.js +112 -0
- package/dist/run-view.js.map +1 -0
- package/dist/runner.js +1094 -0
- package/dist/runner.js.map +1 -0
- package/dist/runtime-apply.js +26 -0
- package/dist/runtime-apply.js.map +1 -0
- package/dist/runtime-settings.js +71 -0
- package/dist/runtime-settings.js.map +1 -0
- package/dist/runtime-state.js +19 -0
- package/dist/runtime-state.js.map +1 -0
- package/dist/server.js +119 -0
- package/dist/server.js.map +1 -0
- package/dist/settings-store.js +320 -0
- package/dist/settings-store.js.map +1 -0
- package/dist/status.js +121 -0
- package/dist/status.js.map +1 -0
- package/dist/stop.js +56 -0
- package/dist/stop.js.map +1 -0
- package/dist/sweeps.js +87 -0
- package/dist/sweeps.js.map +1 -0
- package/dist/task-log.js +279 -0
- package/dist/task-log.js.map +1 -0
- package/dist/task-view.js +62 -0
- package/dist/task-view.js.map +1 -0
- package/dist/token-store.js +68 -0
- package/dist/token-store.js.map +1 -0
- package/dist/types/access.js +74 -0
- package/dist/types/access.js.map +1 -0
- package/dist/types/custom-repos.js +28 -0
- package/dist/types/custom-repos.js.map +1 -0
- package/dist/types/env-config.js +25 -0
- package/dist/types/env-config.js.map +1 -0
- package/dist/types/env.js +190 -0
- package/dist/types/env.js.map +1 -0
- package/dist/types/global-settings.js +178 -0
- package/dist/types/global-settings.js.map +1 -0
- package/dist/types/lsp-servers.js +145 -0
- package/dist/types/lsp-servers.js.map +1 -0
- package/dist/types/mcp-config.js +77 -0
- package/dist/types/mcp-config.js.map +1 -0
- package/dist/types/opencode.js +59 -0
- package/dist/types/opencode.js.map +1 -0
- package/dist/types/outbound-webhook.js +56 -0
- package/dist/types/outbound-webhook.js.map +1 -0
- package/dist/types/project-settings.js +114 -0
- package/dist/types/project-settings.js.map +1 -0
- package/dist/types/provider-registry.js +37 -0
- package/dist/types/provider-registry.js.map +1 -0
- package/dist/types/runtime-settings.js +78 -0
- package/dist/types/runtime-settings.js.map +1 -0
- package/dist/usage-stats.js +159 -0
- package/dist/usage-stats.js.map +1 -0
- package/dist/version.js +19 -0
- package/dist/version.js.map +1 -0
- package/dist/volume-gc.js +193 -0
- package/dist/volume-gc.js.map +1 -0
- package/dist/volume-manage.js +191 -0
- package/dist/volume-manage.js.map +1 -0
- package/dist/volume-store.js +122 -0
- package/dist/volume-store.js.map +1 -0
- package/dist/webhook.js +1106 -0
- package/dist/webhook.js.map +1 -0
- package/dist/work-item-auto-store.js +75 -0
- package/dist/work-item-auto-store.js.map +1 -0
- package/dist/work-item-branch-store.js +37 -0
- package/dist/work-item-branch-store.js.map +1 -0
- package/migrations/0001_initial.sql +59 -0
- package/migrations/0002_queue_status.sql +15 -0
- package/migrations/0003_work_item_base_branch.sql +14 -0
- package/migrations/0004_project_settings.sql +15 -0
- package/migrations/0005_global_settings.sql +34 -0
- package/migrations/0006_model_variants.sql +8 -0
- package/migrations/0007_container_error_logs.sql +21 -0
- package/migrations/0008_project_access_grants.sql +16 -0
- package/migrations/0009_drop_imported_legacy.sql +4 -0
- package/migrations/0010_container_error_log_model.sql +6 -0
- package/migrations/0011_container_error_log_title.sql +5 -0
- package/migrations/0012_pending_task_cancel.sql +6 -0
- package/migrations/0013_builder_image.sql +6 -0
- package/migrations/0014_build_workflow.sql +7 -0
- package/migrations/0015_access_rules.sql +24 -0
- package/migrations/0016_trigger_policy.sql +17 -0
- package/migrations/0017_attachment_upload.sql +8 -0
- package/migrations/0018_work_item_branch.sql +11 -0
- package/migrations/0019_auto_push_mr.sql +18 -0
- package/migrations/0020_outbound_webhooks.sql +47 -0
- package/migrations/0021_runtime_settings.sql +12 -0
- package/migrations/0022_auto_resolve_conflicts.sql +17 -0
- package/migrations/0023_ci_fail_auto_report.sql +27 -0
- package/migrations/0024_work_item_auto_override.sql +22 -0
- package/migrations/0025_run_history.sql +37 -0
- package/migrations/0026_run_history_task_seq.sql +6 -0
- package/migrations/0027_custom_repos.sql +11 -0
- package/migrations/0028_run_usage.sql +14 -0
- package/migrations/0029_drop_ocr_langs.sql +6 -0
- package/migrations/0030_mr_assignee.sql +9 -0
- package/migrations/0031_lsp_servers.sql +14 -0
- package/opencode-config/managed/devbot-agent-policy.md +61 -0
- package/opencode-config/managed/opencode.json +77 -0
- package/opencode-config/opencode.json +211 -0
- package/opencode-config/plugins/devbot-path-guard.js +224 -0
- package/package.json +158 -4
- package/public/assets/DashboardSidebarCollapse-rIuzCmVm.js +1 -0
- package/public/assets/DashboardToolbar-DFCUqZ4Z.js +1 -0
- package/public/assets/ErrorLogModal.vue_vue_type_script_setup_true_lang-BCyNIf1E.js +1 -0
- package/public/assets/ErrorLogsPage-DyYK2Rop.js +1 -0
- package/public/assets/LogSlideover.vue_vue_type_script_setup_true_lang-33xie7TE.js +1 -0
- package/public/assets/OverviewPage-CFfa0uwg.js +1 -0
- package/public/assets/PageGrid-CBROIU87.js +1 -0
- package/public/assets/PeriodRangePicker.vue_vue_type_script_setup_true_lang-DiFUNem7.js +1 -0
- package/public/assets/ProjectDetailPage-CreyvUit.js +1 -0
- package/public/assets/ProjectsPage-CFx8-elJ.js +1 -0
- package/public/assets/RunDetailSlideover.vue_vue_type_script_setup_true_lang-DopYYmCT.js +1 -0
- package/public/assets/RunsPage-CRnnXU4P.js +1 -0
- package/public/assets/Select-Bvx32Diz.js +1 -0
- package/public/assets/SelectMenu-BjMxc4VB.js +1 -0
- package/public/assets/SettingsPage-Bb6LM3wO.js +60 -0
- package/public/assets/TimeCell.vue_vue_type_script_setup_true_lang-DW_UB0Fu.js +1 -0
- package/public/assets/UsagePage-BLMDEsv-.js +332 -0
- package/public/assets/UsagePage-DodEeAjB.css +1 -0
- package/public/assets/VolumesPage-CxcLc3L2.js +1 -0
- package/public/assets/WebhookConfigPanel.vue_vue_type_script_setup_true_lang-B2V2GF6b.js +1 -0
- package/public/assets/WorkItemCell.vue_vue_type_script_setup_true_lang-BQn6vTjd.js +1 -0
- package/public/assets/index-BMbMibyb.js +4 -0
- package/public/assets/index-C5RBBrPj.js +30 -0
- package/public/assets/index-CgX29UgC.css +1 -0
- package/public/assets/usage-format-jsb31_O8.js +1 -0
- package/public/assets/useManagedProjects-8rtjRqVJ.js +1 -0
- package/public/assets/useRouteTab-DfwrcMic.js +1 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.png +0 -0
- package/public/index.html +15 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { logReq } from "./http-util.js";
|
|
3
|
+
import { config } from "./config.js";
|
|
4
|
+
import { getPlatform } from "./platform/index.js";
|
|
5
|
+
import { isOnboardingAllowed } from "./onboarding-allowlist.js";
|
|
6
|
+
import { signCookie, cookieOptions, SESSION_COOKIE, STATE_COOKIE, } from "./cookie.js";
|
|
7
|
+
export function mountOauthRoutes(app) {
|
|
8
|
+
const platform = getPlatform();
|
|
9
|
+
app.get("/oauth/start", (_req, res) => {
|
|
10
|
+
const state = randomBytes(16).toString("hex");
|
|
11
|
+
res.cookie(STATE_COOKIE, state, cookieOptions(600));
|
|
12
|
+
return res.redirect(302, platform.onboarding.authorizeUrl(state));
|
|
13
|
+
});
|
|
14
|
+
app.get("/oauth/callback", async (req, res) => {
|
|
15
|
+
const code = req.query.code;
|
|
16
|
+
const state = req.query.state;
|
|
17
|
+
const cookies = req.cookies;
|
|
18
|
+
const expectedState = cookies?.[STATE_COOKIE];
|
|
19
|
+
if (!code || !state || state !== expectedState) {
|
|
20
|
+
logReq(req, "warn", "oauth invalid state", {
|
|
21
|
+
hasCode: !!code,
|
|
22
|
+
stateType: typeof state,
|
|
23
|
+
hasExpectedState: !!expectedState,
|
|
24
|
+
match: typeof state === "string" && state === expectedState,
|
|
25
|
+
cookieHeaderPresent: !!req.headers.cookie,
|
|
26
|
+
cookieKeys: Object.keys(req.cookies ?? {}),
|
|
27
|
+
});
|
|
28
|
+
return res.status(403).send("invalid state");
|
|
29
|
+
}
|
|
30
|
+
// ponytail: clear state cookie immediately after validation — single-use
|
|
31
|
+
// CSRF token, consumed whether the callback succeeds or fails.
|
|
32
|
+
res.clearCookie(STATE_COOKIE, { path: "/" });
|
|
33
|
+
try {
|
|
34
|
+
const { accessToken } = await platform.onboarding.exchangeCode(String(code));
|
|
35
|
+
const user = await platform.onboarding.currentUser(accessToken);
|
|
36
|
+
// The allowlist is the single authorization gate for all drivers —
|
|
37
|
+
// per-forge admin status is no longer checked. Fails closed when
|
|
38
|
+
// ONBOARDING_USERS is empty.
|
|
39
|
+
if (!isOnboardingAllowed(user.username, config.ONBOARDING_USERS)) {
|
|
40
|
+
logReq(req, "warn", "oauth user not allowlisted", { userId: user.id, username: user.username });
|
|
41
|
+
return res.status(403).send("user not authorized to onboard");
|
|
42
|
+
}
|
|
43
|
+
const exp = Math.floor(Date.now() / 1000) + 3600;
|
|
44
|
+
const cookie = signCookie({ accessToken, userId: user.id, username: user.username, exp });
|
|
45
|
+
res.cookie(SESSION_COOKIE, cookie, cookieOptions(3600));
|
|
46
|
+
return res.redirect(302, "/");
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
logReq(req, "error", "oauth callback failed", { err: e });
|
|
50
|
+
return res.status(500).send("oauth failed");
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=oauth-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-routes.js","sourceRoot":"","sources":["../src/oauth-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// WebUI onboarding authorization gate.
|
|
2
|
+
//
|
|
3
|
+
// A single, platform-neutral allowlist replaces the per-forge instance-admin
|
|
4
|
+
// check: the operator lists the forge usernames allowed to complete onboarding
|
|
5
|
+
// in ONBOARDING_USERS (comma-separated). This is required because github.com
|
|
6
|
+
// has no instance-admin concept, and keeping one gate for every driver makes
|
|
7
|
+
// GitLab/ForgeJo/Gitea behave exactly like GitHub. The gate FAILS CLOSED: an
|
|
8
|
+
// unset/empty allowlist denies everyone, so a misconfigured deploy cannot be
|
|
9
|
+
// onboarded by an arbitrary user.
|
|
10
|
+
/** Parse the raw env value into a normalized, de-duplicated username set. */
|
|
11
|
+
export function parseOnboardingUsers(raw) {
|
|
12
|
+
const set = new Set();
|
|
13
|
+
if (!raw)
|
|
14
|
+
return set;
|
|
15
|
+
for (const part of raw.split(",")) {
|
|
16
|
+
const username = part.trim().toLowerCase();
|
|
17
|
+
if (username)
|
|
18
|
+
set.add(username);
|
|
19
|
+
}
|
|
20
|
+
return set;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* True when `username` is permitted to onboard. Forge usernames are treated
|
|
24
|
+
* case-insensitively, so both sides are lowercased. An empty allowlist denies
|
|
25
|
+
* everyone (fail closed).
|
|
26
|
+
*/
|
|
27
|
+
export function isOnboardingAllowed(username, raw) {
|
|
28
|
+
if (!username)
|
|
29
|
+
return false;
|
|
30
|
+
return parseOnboardingUsers(raw).has(username.trim().toLowerCase());
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=onboarding-allowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding-allowlist.js","sourceRoot":"","sources":["../src/onboarding-allowlist.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,kCAAkC;AAElC,6EAA6E;AAC7E,MAAM,UAAU,oBAAoB,CAAC,GAA8B;IACjE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,QAAQ;YAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAmC,EAAE,GAA8B;IACrG,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/opencode.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
2
|
+
import { log } from "./logger.js";
|
|
3
|
+
import { redact } from "./redact.js";
|
|
4
|
+
import { OpencodeEventSchema, EventWithPartSchema, TextPartSchema, ErrorEventSchema, StepFinishPartSchema, } from "./types/opencode.js";
|
|
5
|
+
export function zeroUsage() {
|
|
6
|
+
return { input: 0, output: 0, reasoning: 0, cacheRead: 0, cacheWrite: 0, costUsd: 0 };
|
|
7
|
+
}
|
|
8
|
+
// Sum the step-finish parts of a run's NDJSON events. Pure; a malformed part is
|
|
9
|
+
// skipped so a bad upstream shape can never inject NaN into the totals.
|
|
10
|
+
export function extractUsage(events) {
|
|
11
|
+
const total = zeroUsage();
|
|
12
|
+
for (const raw of events) {
|
|
13
|
+
const ev = OpencodeEventSchema.safeParse(raw);
|
|
14
|
+
if (!ev.success)
|
|
15
|
+
continue;
|
|
16
|
+
const withPart = EventWithPartSchema.safeParse(ev.data);
|
|
17
|
+
if (!withPart.success)
|
|
18
|
+
continue;
|
|
19
|
+
const part = StepFinishPartSchema.safeParse(withPart.data.part);
|
|
20
|
+
if (!part.success)
|
|
21
|
+
continue;
|
|
22
|
+
const t = part.data.tokens;
|
|
23
|
+
total.input += t?.input ?? 0;
|
|
24
|
+
total.output += t?.output ?? 0;
|
|
25
|
+
total.reasoning += t?.reasoning ?? 0;
|
|
26
|
+
total.cacheRead += t?.cache?.read ?? 0;
|
|
27
|
+
total.cacheWrite += t?.cache?.write ?? 0;
|
|
28
|
+
total.costUsd += part.data.cost ?? 0;
|
|
29
|
+
}
|
|
30
|
+
return total;
|
|
31
|
+
}
|
|
32
|
+
function isTextPart(p) {
|
|
33
|
+
return TextPartSchema.safeParse(p).success;
|
|
34
|
+
}
|
|
35
|
+
function truncate(s, max = 2000) {
|
|
36
|
+
return s.length > max ? s.slice(0, max) + "…[truncated]" : s;
|
|
37
|
+
}
|
|
38
|
+
export function extractText(events) {
|
|
39
|
+
const texts = [];
|
|
40
|
+
for (const raw of events) {
|
|
41
|
+
const parsed = OpencodeEventSchema.safeParse(raw);
|
|
42
|
+
if (!parsed.success)
|
|
43
|
+
continue;
|
|
44
|
+
const errorEvent = ErrorEventSchema.safeParse(parsed.data);
|
|
45
|
+
if (errorEvent.success) {
|
|
46
|
+
const msg = errorEvent.data.error.data?.message ?? errorEvent.data.error.message;
|
|
47
|
+
if (msg)
|
|
48
|
+
texts.push(`⚠️ ${msg}`);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const withPart = EventWithPartSchema.safeParse(parsed.data);
|
|
52
|
+
if (!withPart.success)
|
|
53
|
+
continue;
|
|
54
|
+
if (isTextPart(withPart.data.part))
|
|
55
|
+
texts.push(withPart.data.part.text);
|
|
56
|
+
}
|
|
57
|
+
// ponytail: post only the last text/error entry to the forge (one note per run,
|
|
58
|
+
// not the whole transcript). Upgrade to a richer formatter if summaries
|
|
59
|
+
// ever need multi-part composition.
|
|
60
|
+
return texts.at(-1) ?? "";
|
|
61
|
+
}
|
|
62
|
+
// ponytail: spawnSync blocks the loop briefly on timeout (error path only).
|
|
63
|
+
// If many concurrent timeouts fire, switch to async spawn fire-and-forget.
|
|
64
|
+
export function killContainerByName(name) {
|
|
65
|
+
try {
|
|
66
|
+
spawnSync("podman", ["rm", "-f", name], { stdio: "ignore" });
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* best-effort; container may already be gone */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function containerNameFromArgs(args) {
|
|
73
|
+
const i = args.indexOf("--name");
|
|
74
|
+
return i >= 0 && i + 1 < args.length ? args[i + 1] : undefined;
|
|
75
|
+
}
|
|
76
|
+
export function runPodmanCapture(opts) {
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
const child = spawn("podman", opts.args, {
|
|
79
|
+
cwd: opts.cwd,
|
|
80
|
+
env: { ...process.env, ...opts.env },
|
|
81
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
82
|
+
});
|
|
83
|
+
const stderrChunks = [];
|
|
84
|
+
const stdoutChunks = [];
|
|
85
|
+
const events = [];
|
|
86
|
+
const rawStdout = () => redact(Buffer.concat(stdoutChunks).toString("utf8"));
|
|
87
|
+
let lineBuf = "";
|
|
88
|
+
let timedOut = false;
|
|
89
|
+
let stalled = false;
|
|
90
|
+
let settled = false;
|
|
91
|
+
let lastOutputAt = Date.now();
|
|
92
|
+
const timer = setTimeout(() => {
|
|
93
|
+
timedOut = true;
|
|
94
|
+
try {
|
|
95
|
+
child.kill("SIGKILL");
|
|
96
|
+
}
|
|
97
|
+
catch { /* already dead */ }
|
|
98
|
+
const cname = containerNameFromArgs(opts.args);
|
|
99
|
+
if (cname)
|
|
100
|
+
killContainerByName(cname);
|
|
101
|
+
}, opts.timeoutMs);
|
|
102
|
+
// Inactivity watchdog (work item #96): a fully silent run is killed early
|
|
103
|
+
// instead of sitting "running" until timeoutMs. Checked a few times per
|
|
104
|
+
// stall window (bounded) so the kill lands promptly without busy-polling.
|
|
105
|
+
const stallMs = opts.stallMs ?? 0;
|
|
106
|
+
const stallTimer = stallMs > 0
|
|
107
|
+
? setInterval(() => {
|
|
108
|
+
if (settled || stalled)
|
|
109
|
+
return;
|
|
110
|
+
if (Date.now() - lastOutputAt < stallMs)
|
|
111
|
+
return;
|
|
112
|
+
stalled = true;
|
|
113
|
+
try {
|
|
114
|
+
child.kill("SIGKILL");
|
|
115
|
+
}
|
|
116
|
+
catch { /* already dead */ }
|
|
117
|
+
const cname = containerNameFromArgs(opts.args);
|
|
118
|
+
if (cname)
|
|
119
|
+
killContainerByName(cname);
|
|
120
|
+
}, Math.max(1_000, Math.min(30_000, Math.floor(stallMs / 4))))
|
|
121
|
+
: undefined;
|
|
122
|
+
const clearTimers = () => {
|
|
123
|
+
clearTimeout(timer);
|
|
124
|
+
if (stallTimer)
|
|
125
|
+
clearInterval(stallTimer);
|
|
126
|
+
};
|
|
127
|
+
// ponytail: log each event as it arrives so a long run is observable in
|
|
128
|
+
// realtime. One log line per event across all part types — upgrade to
|
|
129
|
+
// debounce/batch or a LOG_OPENCODE_* flag if a chatty model floods.
|
|
130
|
+
function handleLine(raw) {
|
|
131
|
+
const trimmed = raw.trim();
|
|
132
|
+
if (!trimmed)
|
|
133
|
+
return;
|
|
134
|
+
let parsed;
|
|
135
|
+
try {
|
|
136
|
+
parsed = JSON.parse(trimmed);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
events.push(parsed);
|
|
142
|
+
const ev = OpencodeEventSchema.safeParse(parsed);
|
|
143
|
+
if (!ev.success)
|
|
144
|
+
return;
|
|
145
|
+
const errEv = ErrorEventSchema.safeParse(ev.data);
|
|
146
|
+
if (errEv.success) {
|
|
147
|
+
const msg = errEv.data.error.data?.message ?? errEv.data.error.message;
|
|
148
|
+
if (msg)
|
|
149
|
+
log.warn("opencode error event", { ...opts.context, msg });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const withPart = EventWithPartSchema.safeParse(ev.data);
|
|
153
|
+
if (!withPart.success)
|
|
154
|
+
return;
|
|
155
|
+
const p = withPart.data.part;
|
|
156
|
+
// ponytail: log every part type as it arrives — previously only text/error
|
|
157
|
+
// were logged and every other part (tools, steps, reasoning, files, …)
|
|
158
|
+
// was silently dropped in realtime (the raw stdout dump at run end was
|
|
159
|
+
// the only record, at debug level, post-exit). One log line per event;
|
|
160
|
+
// add a LOG_OPENCODE_* flag if a chatty model floods.
|
|
161
|
+
switch (p.type) {
|
|
162
|
+
case "text":
|
|
163
|
+
log.debug("opencode text", { ...opts.context, text: p.text });
|
|
164
|
+
break;
|
|
165
|
+
case "tool": {
|
|
166
|
+
const st = p.state;
|
|
167
|
+
log.debug("opencode tool", {
|
|
168
|
+
...opts.context,
|
|
169
|
+
tool: p.tool,
|
|
170
|
+
status: st?.status,
|
|
171
|
+
input: st?.input,
|
|
172
|
+
output: st?.output ? truncate(st.output) : undefined,
|
|
173
|
+
error: st?.error,
|
|
174
|
+
});
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "step-start":
|
|
178
|
+
log.debug("opencode step-start", { ...opts.context });
|
|
179
|
+
break;
|
|
180
|
+
case "step-finish": {
|
|
181
|
+
const sf = StepFinishPartSchema.safeParse(p);
|
|
182
|
+
log.debug("opencode step-finish", {
|
|
183
|
+
...opts.context,
|
|
184
|
+
reason: p.reason,
|
|
185
|
+
tokens: sf.success ? sf.data.tokens : undefined,
|
|
186
|
+
cost: sf.success ? sf.data.cost : undefined,
|
|
187
|
+
});
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
case "reasoning":
|
|
191
|
+
log.debug("opencode reasoning", { ...opts.context, text: p.text });
|
|
192
|
+
break;
|
|
193
|
+
case "file":
|
|
194
|
+
log.debug("opencode file", { ...opts.context, mime: p.mime, filename: p.filename, url: p.url });
|
|
195
|
+
break;
|
|
196
|
+
case "subtask":
|
|
197
|
+
log.debug("opencode subtask", { ...opts.context, agent: p.agent, description: p.description });
|
|
198
|
+
break;
|
|
199
|
+
case "agent":
|
|
200
|
+
log.debug("opencode agent", { ...opts.context, name: p.name });
|
|
201
|
+
break;
|
|
202
|
+
case "retry":
|
|
203
|
+
log.warn("opencode retry", { ...opts.context, attempt: p.attempt, error: p.error });
|
|
204
|
+
break;
|
|
205
|
+
case "compaction":
|
|
206
|
+
log.debug("opencode compaction", { ...opts.context, auto: p.auto });
|
|
207
|
+
break;
|
|
208
|
+
case "snapshot":
|
|
209
|
+
log.debug("opencode snapshot", { ...opts.context });
|
|
210
|
+
break;
|
|
211
|
+
case "patch":
|
|
212
|
+
log.debug("opencode patch", { ...opts.context, files: p.files });
|
|
213
|
+
break;
|
|
214
|
+
default:
|
|
215
|
+
// ponytail: unknown part type — log the FULL body (not truncated) so
|
|
216
|
+
// no part is ever silently dropped again. Large if a future version
|
|
217
|
+
// emits a big-blob unknown type; that's the cost of completeness.
|
|
218
|
+
log.debug("opencode part", { ...opts.context, type: p.type, part: p });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
child.stdout.on("data", (b) => {
|
|
222
|
+
lastOutputAt = Date.now();
|
|
223
|
+
stdoutChunks.push(b);
|
|
224
|
+
opts.onChunk?.("stdout", b.toString("utf8"));
|
|
225
|
+
lineBuf += b.toString("utf8");
|
|
226
|
+
let nl;
|
|
227
|
+
while ((nl = lineBuf.indexOf("\n")) >= 0) {
|
|
228
|
+
handleLine(lineBuf.slice(0, nl));
|
|
229
|
+
lineBuf = lineBuf.slice(nl + 1);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
child.stderr.on("data", (b) => {
|
|
233
|
+
lastOutputAt = Date.now();
|
|
234
|
+
stderrChunks.push(b);
|
|
235
|
+
opts.onChunk?.("stderr", b.toString("utf8"));
|
|
236
|
+
});
|
|
237
|
+
child.on("error", (err) => {
|
|
238
|
+
if (settled)
|
|
239
|
+
return;
|
|
240
|
+
settled = true;
|
|
241
|
+
clearTimers();
|
|
242
|
+
log.error("podman spawn error", { ...opts.context, err: err.message });
|
|
243
|
+
resolve({ text: `⚠️ Failed to start container: ${err.message}`, error: true, exitCode: -1, kind: "spawn", rawOutput: rawStdout(), stderrTail: "", usage: zeroUsage() });
|
|
244
|
+
});
|
|
245
|
+
child.on("close", (code) => {
|
|
246
|
+
if (settled)
|
|
247
|
+
return;
|
|
248
|
+
settled = true;
|
|
249
|
+
clearTimers();
|
|
250
|
+
const exitCode = code ?? -1;
|
|
251
|
+
if (timedOut || stalled) {
|
|
252
|
+
const text = stalled
|
|
253
|
+
? `⚠️ Run stalled — no output for ${Math.floor(stallMs / 60_000)}min, killed`
|
|
254
|
+
: `⚠️ Run timed out after ${Math.floor(opts.timeoutMs / 60_000)}min`;
|
|
255
|
+
log.warn(stalled ? "opencode stalled" : "opencode timed out", { ...opts.context, stallMs, timeoutMs: opts.timeoutMs });
|
|
256
|
+
resolve({
|
|
257
|
+
text,
|
|
258
|
+
error: true,
|
|
259
|
+
exitCode,
|
|
260
|
+
kind: "timeout",
|
|
261
|
+
rawOutput: rawStdout(),
|
|
262
|
+
stderrTail: redact(Buffer.concat(stderrChunks).toString("utf8")),
|
|
263
|
+
usage: extractUsage(events),
|
|
264
|
+
});
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
268
|
+
// Flush any trailing partial line (opencode may exit without a final \n).
|
|
269
|
+
if (lineBuf.length > 0)
|
|
270
|
+
handleLine(lineBuf);
|
|
271
|
+
const stderrTail = redact(stderr.length > 1024 ? stderr.slice(-1024) : stderr);
|
|
272
|
+
const text = extractText(events);
|
|
273
|
+
if (exitCode !== 0 || (text.length === 0 && events.length === 0)) {
|
|
274
|
+
log.warn("opencode run failed", { ...opts.context, exitCode, eventCount: events.length, stderrTail });
|
|
275
|
+
resolve({
|
|
276
|
+
text: text.length > 0 ? text : `⚠️ opencode exited (${exitCode})\n\`\`\`\n${stderrTail}\n\`\`\``,
|
|
277
|
+
error: true,
|
|
278
|
+
exitCode,
|
|
279
|
+
kind: "exit",
|
|
280
|
+
rawOutput: redact(Buffer.concat(stdoutChunks).toString("utf8")),
|
|
281
|
+
stderrTail,
|
|
282
|
+
usage: extractUsage(events),
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
log.debug("opencode ok", { ...opts.context, exitCode, eventCount: events.length });
|
|
287
|
+
resolve({ text: text || "✅ Done (no text output)", error: false, exitCode, kind: "ok", rawOutput: "", stderrTail: "", usage: extractUsage(events) });
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { db } from "./db.js";
|
|
2
|
+
import { log } from "./logger.js";
|
|
3
|
+
import { encrypt, decryptOrPlaintext } from "./crypto-util.js";
|
|
4
|
+
import { randomBytes } from "node:crypto";
|
|
5
|
+
import { WebhookEndpointSchema, } from "./types/outbound-webhook.js";
|
|
6
|
+
// Outbound webhook endpoints + their delivery queue. Same DB file as the other
|
|
7
|
+
// stores (devbot.db, 0600). Endpoints are keyed by (project_id, name); global
|
|
8
|
+
// endpoints reuse the sentinel scope id 0 (GLOBAL_SCOPE_ID), exactly like
|
|
9
|
+
// global MCP servers. The signing secret is encrypted at rest with SESSION_KEY.
|
|
10
|
+
//
|
|
11
|
+
// Deliveries are durable rows: emit() inserts one per matching endpoint, a
|
|
12
|
+
// worker claims due rows (atomic pending→delivering CAS), and settles them.
|
|
13
|
+
// A failed delivery is re-queued with a backoff until retries are exhausted.
|
|
14
|
+
const SEC = () => Math.floor(Date.now() / 1000);
|
|
15
|
+
export function initOutboundWebhookTables() {
|
|
16
|
+
// Belt-and-braces: migration 0020 is authoritative; keep the idempotent
|
|
17
|
+
// CREATE so a test DB opened without migrate() still works.
|
|
18
|
+
db.exec(`
|
|
19
|
+
CREATE TABLE IF NOT EXISTS outbound_webhooks (
|
|
20
|
+
project_id INTEGER NOT NULL,
|
|
21
|
+
name TEXT NOT NULL,
|
|
22
|
+
url TEXT NOT NULL,
|
|
23
|
+
events TEXT NOT NULL,
|
|
24
|
+
headers TEXT NOT NULL DEFAULT '{}',
|
|
25
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
26
|
+
secret TEXT NOT NULL,
|
|
27
|
+
created_at INTEGER NOT NULL,
|
|
28
|
+
updated_at INTEGER NOT NULL,
|
|
29
|
+
PRIMARY KEY (project_id, name)
|
|
30
|
+
)
|
|
31
|
+
`);
|
|
32
|
+
db.exec(`
|
|
33
|
+
CREATE TABLE IF NOT EXISTS outbound_webhook_deliveries (
|
|
34
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
|
+
project_id INTEGER NOT NULL,
|
|
36
|
+
webhook_name TEXT NOT NULL,
|
|
37
|
+
event TEXT NOT NULL,
|
|
38
|
+
payload TEXT NOT NULL,
|
|
39
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
40
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
41
|
+
next_attempt_at INTEGER NOT NULL,
|
|
42
|
+
response_status INTEGER,
|
|
43
|
+
response_body TEXT NOT NULL DEFAULT '',
|
|
44
|
+
last_error TEXT NOT NULL DEFAULT '',
|
|
45
|
+
created_at INTEGER NOT NULL,
|
|
46
|
+
updated_at INTEGER NOT NULL
|
|
47
|
+
)
|
|
48
|
+
`);
|
|
49
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_outbound_deliveries_due ON outbound_webhook_deliveries(status, next_attempt_at)");
|
|
50
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_outbound_deliveries_webhook ON outbound_webhook_deliveries(project_id, webhook_name)");
|
|
51
|
+
}
|
|
52
|
+
export function newWebhookSecret() {
|
|
53
|
+
return `whsec_${randomBytes(32).toString("base64url")}`;
|
|
54
|
+
}
|
|
55
|
+
function parseEvents(raw) {
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(raw);
|
|
58
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function parseHeaders(raw) {
|
|
65
|
+
try {
|
|
66
|
+
const parsed = JSON.parse(raw);
|
|
67
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
68
|
+
? parsed
|
|
69
|
+
: {};
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function toStored(r) {
|
|
76
|
+
return {
|
|
77
|
+
projectId: r.project_id,
|
|
78
|
+
name: r.name,
|
|
79
|
+
url: r.url,
|
|
80
|
+
events: parseEvents(r.events),
|
|
81
|
+
headers: parseHeaders(r.headers),
|
|
82
|
+
enabled: r.enabled === 1,
|
|
83
|
+
secret: decryptOrPlaintext(r.secret),
|
|
84
|
+
createdAt: r.created_at,
|
|
85
|
+
updatedAt: r.updated_at,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export function upsertWebhook(projectId, name, endpoint, secret) {
|
|
89
|
+
// Re-validate at the store boundary — the API layer validates too, but this
|
|
90
|
+
// is the trust boundary for the delivery worker.
|
|
91
|
+
const v = WebhookEndpointSchema.safeParse(endpoint);
|
|
92
|
+
if (!v.success)
|
|
93
|
+
throw new Error("invalid webhook endpoint");
|
|
94
|
+
const now = SEC();
|
|
95
|
+
db.prepare(`INSERT OR REPLACE INTO outbound_webhooks
|
|
96
|
+
(project_id, name, url, events, headers, enabled, secret, created_at, updated_at)
|
|
97
|
+
VALUES (?, ?, ?, ?, ?, ?, ?,
|
|
98
|
+
COALESCE((SELECT created_at FROM outbound_webhooks WHERE project_id = ? AND name = ?), ?),
|
|
99
|
+
?)`).run(projectId, name, v.data.url, JSON.stringify(v.data.events), JSON.stringify(v.data.headers), v.data.enabled ? 1 : 0, encrypt(secret), projectId, name, now, now);
|
|
100
|
+
}
|
|
101
|
+
export function getWebhook(projectId, name) {
|
|
102
|
+
const row = db
|
|
103
|
+
.prepare("SELECT * FROM outbound_webhooks WHERE project_id = ? AND name = ?")
|
|
104
|
+
.get(projectId, name);
|
|
105
|
+
return row ? toStored(row) : null;
|
|
106
|
+
}
|
|
107
|
+
export function listWebhooks(projectId) {
|
|
108
|
+
const rows = db
|
|
109
|
+
.prepare("SELECT * FROM outbound_webhooks WHERE project_id = ? ORDER BY name")
|
|
110
|
+
.all(projectId);
|
|
111
|
+
return rows.map(toStored);
|
|
112
|
+
}
|
|
113
|
+
export function deleteWebhook(projectId, name) {
|
|
114
|
+
const r = db
|
|
115
|
+
.prepare("DELETE FROM outbound_webhooks WHERE project_id = ? AND name = ?")
|
|
116
|
+
.run(projectId, name);
|
|
117
|
+
return r.changes > 0;
|
|
118
|
+
}
|
|
119
|
+
export function deleteAllOutboundWebhooksForProject(projectId) {
|
|
120
|
+
db.prepare("DELETE FROM outbound_webhooks WHERE project_id = ?").run(projectId);
|
|
121
|
+
db.prepare("DELETE FROM outbound_webhook_deliveries WHERE project_id = ?").run(projectId);
|
|
122
|
+
}
|
|
123
|
+
// Enabled endpoints in this project's scope (project + global) subscribed to
|
|
124
|
+
// `event`. Global endpoints use scope id 0, which is never a real project id.
|
|
125
|
+
export function matchingWebhooks(projectId, event) {
|
|
126
|
+
const rows = db
|
|
127
|
+
.prepare("SELECT * FROM outbound_webhooks WHERE enabled = 1 AND project_id IN (?, 0) ORDER BY project_id, name")
|
|
128
|
+
.all(projectId);
|
|
129
|
+
return rows.map(toStored).filter((w) => w.events.includes(event));
|
|
130
|
+
}
|
|
131
|
+
// ---- Delivery queue --------------------------------------------------------
|
|
132
|
+
export function enqueueDelivery(projectId, webhookName, event, payload) {
|
|
133
|
+
const now = SEC();
|
|
134
|
+
const r = db
|
|
135
|
+
.prepare(`INSERT INTO outbound_webhook_deliveries
|
|
136
|
+
(project_id, webhook_name, event, payload, status, attempts, next_attempt_at, created_at, updated_at)
|
|
137
|
+
VALUES (?, ?, ?, ?, 'pending', 0, ?, ?, ?)`)
|
|
138
|
+
.run(projectId, webhookName, event, payload, Date.now(), now, now);
|
|
139
|
+
return Number(r.lastInsertRowid);
|
|
140
|
+
}
|
|
141
|
+
function toDeliverySummary(r) {
|
|
142
|
+
return {
|
|
143
|
+
id: r.id,
|
|
144
|
+
projectId: r.project_id,
|
|
145
|
+
webhookName: r.webhook_name,
|
|
146
|
+
event: r.event,
|
|
147
|
+
status: r.status,
|
|
148
|
+
attempts: r.attempts,
|
|
149
|
+
nextAttemptAt: r.next_attempt_at,
|
|
150
|
+
responseStatus: r.response_status,
|
|
151
|
+
lastError: r.last_error,
|
|
152
|
+
createdAt: r.created_at,
|
|
153
|
+
updatedAt: r.updated_at,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function toDeliveryRow(r) {
|
|
157
|
+
return { ...toDeliverySummary(r), payload: r.payload, responseBody: r.response_body };
|
|
158
|
+
}
|
|
159
|
+
// Claim due pending rows (atomic pending→delivering CAS). Returns the claimed
|
|
160
|
+
// rows so the worker can deliver them. `nowMs` is explicit for testability.
|
|
161
|
+
export function claimDueDeliveries(limit, nowMs) {
|
|
162
|
+
const rows = db
|
|
163
|
+
.prepare(`SELECT * FROM outbound_webhook_deliveries
|
|
164
|
+
WHERE status = 'pending' AND next_attempt_at <= ?
|
|
165
|
+
ORDER BY id ASC LIMIT ?`)
|
|
166
|
+
.all(nowMs, limit);
|
|
167
|
+
const claimed = [];
|
|
168
|
+
const upd = db.prepare("UPDATE outbound_webhook_deliveries SET status = 'delivering', updated_at = ? WHERE id = ? AND status = 'pending'");
|
|
169
|
+
for (const r of rows) {
|
|
170
|
+
if (upd.run(SEC(), r.id).changes === 0)
|
|
171
|
+
continue; // CAS lost
|
|
172
|
+
claimed.push(toDeliveryRow({ ...r, status: "delivering" }));
|
|
173
|
+
}
|
|
174
|
+
return claimed;
|
|
175
|
+
}
|
|
176
|
+
export function settleDeliverySucceeded(id, responseStatus, responseBody) {
|
|
177
|
+
db.prepare(`UPDATE outbound_webhook_deliveries
|
|
178
|
+
SET status = 'succeeded', attempts = attempts + 1, response_status = ?, response_body = ?,
|
|
179
|
+
last_error = '', updated_at = ?
|
|
180
|
+
WHERE id = ?`).run(responseStatus, responseBody.slice(0, 2000), SEC(), id);
|
|
181
|
+
}
|
|
182
|
+
// Settle a failed attempt. `retryAt` non-null re-queues as pending for that
|
|
183
|
+
// time; null marks the delivery terminally failed (retries exhausted).
|
|
184
|
+
export function settleDeliveryFailed(id, input) {
|
|
185
|
+
db.prepare(`UPDATE outbound_webhook_deliveries
|
|
186
|
+
SET status = ?, attempts = attempts + 1, response_status = ?, response_body = ?,
|
|
187
|
+
last_error = ?, next_attempt_at = ?, updated_at = ?
|
|
188
|
+
WHERE id = ?`).run(input.retryAt === null ? "failed" : "pending", input.responseStatus, input.responseBody.slice(0, 2000), input.error.slice(0, 2000), input.retryAt ?? Date.now(), SEC(), id);
|
|
189
|
+
}
|
|
190
|
+
// Crash recovery: a delivery claimed but never settled goes back to pending.
|
|
191
|
+
export function resetStuckDeliveries() {
|
|
192
|
+
const r = db
|
|
193
|
+
.prepare("UPDATE outbound_webhook_deliveries SET status = 'pending', updated_at = ? WHERE status = 'delivering'")
|
|
194
|
+
.run(SEC());
|
|
195
|
+
return Number(r.changes);
|
|
196
|
+
}
|
|
197
|
+
export function listDeliveries(projectId, webhookName, limit, offset) {
|
|
198
|
+
const rows = db
|
|
199
|
+
.prepare(`SELECT * FROM outbound_webhook_deliveries
|
|
200
|
+
WHERE project_id = ? AND webhook_name = ?
|
|
201
|
+
ORDER BY id DESC LIMIT ? OFFSET ?`)
|
|
202
|
+
.all(projectId, webhookName, limit, offset);
|
|
203
|
+
return rows.map(toDeliverySummary);
|
|
204
|
+
}
|
|
205
|
+
export function countDeliveries(projectId, webhookName) {
|
|
206
|
+
const row = db
|
|
207
|
+
.prepare("SELECT COUNT(*) AS c FROM outbound_webhook_deliveries WHERE project_id = ? AND webhook_name = ?")
|
|
208
|
+
.get(projectId, webhookName);
|
|
209
|
+
return row.c;
|
|
210
|
+
}
|
|
211
|
+
export function getDelivery(id) {
|
|
212
|
+
const row = db.prepare("SELECT * FROM outbound_webhook_deliveries WHERE id = ?").get(id);
|
|
213
|
+
return row ? toDeliveryRow(row) : null;
|
|
214
|
+
}
|
|
215
|
+
// Re-queue a terminal delivery for another attempt (manual replay from the UI).
|
|
216
|
+
export function replayDelivery(id) {
|
|
217
|
+
const r = db
|
|
218
|
+
.prepare("UPDATE outbound_webhook_deliveries SET status = 'pending', next_attempt_at = ?, updated_at = ? WHERE id = ?")
|
|
219
|
+
.run(Date.now(), SEC(), id);
|
|
220
|
+
return r.changes > 0;
|
|
221
|
+
}
|
|
222
|
+
export function purgeDeliveriesOlderThan(days) {
|
|
223
|
+
const cutoff = SEC() - days * 24 * 3600;
|
|
224
|
+
const r = db.prepare("DELETE FROM outbound_webhook_deliveries WHERE created_at < ?").run(cutoff);
|
|
225
|
+
if (r.changes > 0)
|
|
226
|
+
log.debug("outbound delivery purge", { purged: r.changes, days });
|
|
227
|
+
return Number(r.changes);
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=outbound-webhook-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbound-webhook-store.js","sourceRoot":"","sources":["../src/outbound-webhook-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,qBAAqB,GAKtB,MAAM,6BAA6B,CAAC;AAErC,+EAA+E;AAC/E,8EAA8E;AAC9E,0EAA0E;AAC1E,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAE7E,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAEhD,MAAM,UAAU,yBAAyB;IACvC,wEAAwE;IACxE,4DAA4D;IAC5D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;GAaP,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;GAgBP,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC,gHAAgH,CAAC,CAAC;IAC1H,EAAE,CAAC,IAAI,CAAC,qHAAqH,CAAC,CAAC;AACjI,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,SAAS,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAC1D,CAAC;AA0BD,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAA0B,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACnE,CAAC,CAAE,MAAiC;YACpC,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,CAAe;IAC/B,OAAO;QACL,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QAChC,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC;QACxB,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC;QACpC,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,SAAS,EAAE,CAAC,CAAC,UAAU;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,IAAY,EAAE,QAAyB,EAAE,MAAc;IACtG,4EAA4E;IAC5E,iDAAiD;IACjD,MAAM,CAAC,GAAG,qBAAqB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC;IAClB,EAAE,CAAC,OAAO,CACR;;;;UAIM,CACP,CAAC,GAAG,CACH,SAAS,EACT,IAAI,EACJ,CAAC,CAAC,IAAI,CAAC,GAAG,EACV,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAC7B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAC9B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACtB,OAAO,CAAC,MAAM,CAAC,EACf,SAAS,EACT,IAAI,EACJ,GAAG,EACH,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,IAAY;IACxD,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CAAC,mEAAmE,CAAC;SAC5E,GAAG,CAAC,SAAS,EAAE,IAAI,CAA6B,CAAC;IACpD,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,oEAAoE,CAAC;SAC7E,GAAG,CAAC,SAAS,CAA8B,CAAC;IAC/C,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,IAAY;IAC3D,MAAM,CAAC,GAAG,EAAE;SACT,OAAO,CAAC,iEAAiE,CAAC;SAC1E,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,mCAAmC,CAAC,SAAiB;IACnE,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAChF,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC5F,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,KAAoB;IACtE,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN,sGAAsG,CACvG;SACA,GAAG,CAAC,SAAS,CAA8B,CAAC;IAC/C,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,WAAmB,EAAE,KAAa,EAAE,OAAe;IACpG,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC;IAClB,MAAM,CAAC,GAAG,EAAE;SACT,OAAO,CACN;;kDAE4C,CAC7C;SACA,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;AACnC,CAAC;AAkBD,SAAS,iBAAiB,CAAC,CAAgB;IACzC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,WAAW,EAAE,CAAC,CAAC,YAAY;QAC3B,KAAK,EAAE,CAAC,CAAC,KAAsB;QAC/B,MAAM,EAAE,CAAC,CAAC,MAA0C;QACpD,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,aAAa,EAAE,CAAC,CAAC,eAAe;QAChC,cAAc,EAAE,CAAC,CAAC,eAAe;QACjC,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,SAAS,EAAE,CAAC,CAAC,UAAU;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,CAAgB;IACrC,OAAO,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC;AACxF,CAAC;AAED,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,KAAa;IAC7D,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;gCAE0B,CAC3B;SACA,GAAG,CAAC,KAAK,EAAE,KAAK,CAA+B,CAAC;IACnD,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,kHAAkH,CACnH,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC;YAAE,SAAS,CAAC,WAAW;QAC7D,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EAAU,EAAE,cAA6B,EAAE,YAAoB;IACrG,EAAE,CAAC,OAAO,CACR;;;mBAGe,CAChB,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAClC,EAAU,EACV,KAAqG;IAErG,EAAE,CAAC,OAAO,CACR;;;mBAGe,CAChB,CAAC,GAAG,CACH,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAC7C,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EACjC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAC1B,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,EAC3B,GAAG,EAAE,EACL,EAAE,CACH,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,oBAAoB;IAClC,MAAM,CAAC,GAAG,EAAE;SACT,OAAO,CAAC,uGAAuG,CAAC;SAChH,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IACd,OAAO,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,WAAmB,EAAE,KAAa,EAAE,MAAc;IAClG,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;0CAEoC,CACrC;SACA,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAA+B,CAAC;IAC5E,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,WAAmB;IACpE,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CAAC,iGAAiG,CAAC;SAC1G,GAAG,CAAC,SAAS,EAAE,WAAW,CAAkB,CAAC;IAChD,OAAO,GAAG,CAAC,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC,GAAG,CAAC,EAAE,CAE1E,CAAC;IACd,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,MAAM,CAAC,GAAG,EAAE;SACT,OAAO,CACN,6GAA6G,CAC9G;SACA,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,MAAM,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,8DAA8D,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjG,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC;QAAE,GAAG,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACrF,OAAO,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC"}
|