@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,297 @@
|
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { config } from "./config.js";
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
import { shq, redact } from "./redact.js";
|
|
7
|
+
import { podman } from "./podman.js";
|
|
8
|
+
import { volumeName, envArgs, podmanVolumeName, xdgVolumeName, XDG_HOME_DIR, logDriverArgs } from "./git.js";
|
|
9
|
+
import { storageConf, PODMAN_STORE_DIR } from "./devcontainer.js";
|
|
10
|
+
import { permissionGlobRule } from "./path-sandbox.js";
|
|
11
|
+
import { DEFAULT_LSP_SERVERS, normalizeLspServers } from "./lsp-servers.js";
|
|
12
|
+
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
// Base opencode config, loaded once at startup (per user choice — restart to
|
|
14
|
+
// pick up edits, same as today's read-only bind mount). The per-run config
|
|
15
|
+
// written into the volume is this base + an injected mcp.servers block
|
|
16
|
+
// carrying the per-thread bearer token + a provider block per configured
|
|
17
|
+
// provider.
|
|
18
|
+
const OPENCODE_CONFIG_PATH = join(MODULE_DIR, "..", "opencode-config", "opencode.json");
|
|
19
|
+
let baseOpencodeConfig = {};
|
|
20
|
+
try {
|
|
21
|
+
baseOpencodeConfig = JSON.parse(readFileSync(OPENCODE_CONFIG_PATH, "utf8"));
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
log.error("failed to load base opencode config", { path: OPENCODE_CONFIG_PATH, err: e instanceof Error ? e.message : String(e) });
|
|
25
|
+
}
|
|
26
|
+
// In-container path guard plugin (work item #46). Loaded by opencode from
|
|
27
|
+
// $XDG_CONFIG_HOME/opencode/plugins/ (Global.Path.config derives from
|
|
28
|
+
// XDG_CONFIG_HOME, which the runner points at the xdg volume). Read here and
|
|
29
|
+
// written into the volume per run so the agent's container always has the
|
|
30
|
+
// current policy without a bind mount.
|
|
31
|
+
const PATH_GUARD_PLUGIN_PATH = join(MODULE_DIR, "..", "opencode-config", "plugins", "devbot-path-guard.js");
|
|
32
|
+
let pathGuardPlugin = "";
|
|
33
|
+
try {
|
|
34
|
+
pathGuardPlugin = readFileSync(PATH_GUARD_PLUGIN_PATH, "utf8");
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
log.error("failed to load path guard plugin", { path: PATH_GUARD_PLUGIN_PATH, err: e instanceof Error ? e.message : String(e) });
|
|
38
|
+
}
|
|
39
|
+
// Build the opencode `provider` map from configured providers: npm package,
|
|
40
|
+
// display name, optional baseURL, and the model catalog. `api_url` from the
|
|
41
|
+
// registry is the provider's default endpoint; `base_url` is an explicit
|
|
42
|
+
// override. Providers without either (e.g. anthropic, openai) rely on
|
|
43
|
+
// opencode's bundled defaults.
|
|
44
|
+
export function buildProviderBlock(providers) {
|
|
45
|
+
const out = {};
|
|
46
|
+
for (const p of providers) {
|
|
47
|
+
if (!p.enabled)
|
|
48
|
+
continue;
|
|
49
|
+
const entry = { npm: p.npm, name: p.name };
|
|
50
|
+
const baseURL = p.baseUrl || p.apiUrl;
|
|
51
|
+
if (baseURL)
|
|
52
|
+
entry.options = { baseURL };
|
|
53
|
+
const models = {};
|
|
54
|
+
for (const m of p.models) {
|
|
55
|
+
const c = p.modelCosts?.[m];
|
|
56
|
+
const priced = c && (c.input || c.output || c.cacheRead || c.cacheWrite);
|
|
57
|
+
models[m] = priced
|
|
58
|
+
? { name: m, cost: { input: c.input, output: c.output, cache_read: c.cacheRead, cache_write: c.cacheWrite } }
|
|
59
|
+
: { name: m };
|
|
60
|
+
}
|
|
61
|
+
entry.models = models;
|
|
62
|
+
out[p.id] = entry;
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
export function buildOpencodeConfig(mcpToken, servers, plugins = "", providers = [], skillsPaths = [], lspServers = DEFAULT_LSP_SERVERS) {
|
|
67
|
+
const base = { ...baseOpencodeConfig };
|
|
68
|
+
// Per-run LSP allowlist (work item #102). Start from the shipped object and
|
|
69
|
+
// disable every id outside the resolved list. An empty resolved list is the
|
|
70
|
+
// off switch and emits `lsp: false`.
|
|
71
|
+
const selected = new Set(normalizeLspServers(lspServers));
|
|
72
|
+
const shippedLsp = base.lsp;
|
|
73
|
+
if (selected.size === 0) {
|
|
74
|
+
base.lsp = false;
|
|
75
|
+
}
|
|
76
|
+
else if (shippedLsp && typeof shippedLsp === "object" && !Array.isArray(shippedLsp)) {
|
|
77
|
+
const next = {};
|
|
78
|
+
for (const [id, entry] of Object.entries(shippedLsp)) {
|
|
79
|
+
if (!selected.has(id)) {
|
|
80
|
+
next[id] = { disabled: true };
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
84
|
+
const enabledEntry = { ...entry };
|
|
85
|
+
delete enabledEntry.disabled;
|
|
86
|
+
next[id] = enabledEntry;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
next[id] = entry;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
base.lsp = next;
|
|
93
|
+
}
|
|
94
|
+
// Fold the resolved plugin string into the base config's `plugin` array
|
|
95
|
+
// (merge, not replace): union of base + resolved, dedup by exact name, base
|
|
96
|
+
// entries first. Absent/empty = no-op; the base `plugin` array (if any) is
|
|
97
|
+
// untouched. OpenCode reads this array as npm packages to bun-install at
|
|
98
|
+
// startup; see https://opencode.ai/docs/plugins#use-a-plugin — local plugins
|
|
99
|
+
// in .opencode/plugins/ are directory-loaded and out of scope.
|
|
100
|
+
const envPlugins = plugins
|
|
101
|
+
.split(",")
|
|
102
|
+
.map((s) => s.trim())
|
|
103
|
+
.filter(Boolean);
|
|
104
|
+
if (envPlugins.length) {
|
|
105
|
+
const basePlugins = Array.isArray(base.plugin) ? base.plugin : [];
|
|
106
|
+
base.plugin = Array.from(new Set([...basePlugins, ...envPlugins]));
|
|
107
|
+
}
|
|
108
|
+
// Provider block: configured providers replace any base `provider` entries.
|
|
109
|
+
// The shipped opencode.json no longer hardcodes openai-compatible; every
|
|
110
|
+
// provider (registry or custom) is injected per run.
|
|
111
|
+
const providerBlock = buildProviderBlock(providers);
|
|
112
|
+
const baseProvider = (base.provider && typeof base.provider === "object" && !Array.isArray(base.provider))
|
|
113
|
+
? base.provider
|
|
114
|
+
: {};
|
|
115
|
+
const mergedProvider = { ...baseProvider, ...providerBlock };
|
|
116
|
+
if (Object.keys(mergedProvider).length > 0)
|
|
117
|
+
base.provider = mergedProvider;
|
|
118
|
+
const mcpBaseUrl = (config.MCP_BASE_URL ?? `http://host.containers.internal:${config.MCP_PORT}`).replace(/\/$/, "");
|
|
119
|
+
// ponytail: shallow merge — the caller passes the project's external servers;
|
|
120
|
+
// we inject two bundled internal servers: chrome-devtools (local, headless
|
|
121
|
+
// Chromium) then devbot-forge (remote, the bot's own forge tools).
|
|
122
|
+
// devbot-forge is assigned LAST so it always wins on name collision.
|
|
123
|
+
const mergedServers = { ...servers };
|
|
124
|
+
// Bundled chrome-devtools-mcp — always active, headless, no telemetry.
|
|
125
|
+
// The browser only launches when an agent invokes a browser tool; idle
|
|
126
|
+
// cost is just a Node stdio process. --executable-path points at Fedora's
|
|
127
|
+
// chromium-browser (installed in Dockerfile.builder); the MCP defaults to
|
|
128
|
+
// searching for Google Chrome which isn't in the image. --no-sandbox is
|
|
129
|
+
// required for non-root container execution; --disable-dev-shm-usage
|
|
130
|
+
// avoids crashes on the small container /dev/shm.
|
|
131
|
+
mergedServers["chrome-devtools"] = {
|
|
132
|
+
type: "local",
|
|
133
|
+
command: [
|
|
134
|
+
"chrome-devtools-mcp",
|
|
135
|
+
"--headless",
|
|
136
|
+
"--isolated",
|
|
137
|
+
"--no-usage-statistics",
|
|
138
|
+
"--no-performance-crux",
|
|
139
|
+
"--executable-path", "/usr/bin/chromium-browser",
|
|
140
|
+
"--chromeArg=--no-sandbox",
|
|
141
|
+
"--chromeArg=--disable-dev-shm-usage",
|
|
142
|
+
"--chromeArg=--disable-gpu",
|
|
143
|
+
],
|
|
144
|
+
enabled: true,
|
|
145
|
+
environment: {
|
|
146
|
+
CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: "1",
|
|
147
|
+
CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS: "1",
|
|
148
|
+
},
|
|
149
|
+
timeout: 10_000,
|
|
150
|
+
};
|
|
151
|
+
// Bot's own server — always present, always wins on name collision (assigned
|
|
152
|
+
// last). URL points at the internal MCP port (127.0.0.1 only), reached by
|
|
153
|
+
// the container via host.containers.internal (see --add-host in runner.ts).
|
|
154
|
+
mergedServers["devbot-forge"] = {
|
|
155
|
+
type: "remote",
|
|
156
|
+
url: `${mcpBaseUrl}/mcp`,
|
|
157
|
+
headers: { Authorization: `Bearer ${mcpToken}` },
|
|
158
|
+
oauth: false,
|
|
159
|
+
enabled: true,
|
|
160
|
+
};
|
|
161
|
+
// Every LOCAL MCP server (the bundled Chrome and any project-configured local
|
|
162
|
+
// server) runs as the unprivileged `agent` UID, so it cannot read
|
|
163
|
+
// /home/devbot/.xdg. Remote servers are HTTP and are left untouched.
|
|
164
|
+
for (const entry of Object.values(mergedServers)) {
|
|
165
|
+
if (entry && entry.type === "local" && Array.isArray(entry.command)) {
|
|
166
|
+
entry.command = ["/usr/local/bin/devbot-exec-agent", ...entry.command];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const merged = { ...base, mcp: mergedServers };
|
|
170
|
+
// Custom skills (work item #63): extra folders opencode scans for
|
|
171
|
+
// {skill,skills}/**/SKILL.md. Unioned with any base-config paths (same
|
|
172
|
+
// pattern as plugin) so an operator's base config is never clobbered.
|
|
173
|
+
if (skillsPaths.length > 0) {
|
|
174
|
+
const baseSkills = base.skills && typeof base.skills === "object" && !Array.isArray(base.skills)
|
|
175
|
+
? base.skills
|
|
176
|
+
: {};
|
|
177
|
+
const basePaths = Array.isArray(baseSkills.paths) ? baseSkills.paths : [];
|
|
178
|
+
base.skills = { ...baseSkills, paths: Array.from(new Set([...basePaths, ...skillsPaths])) };
|
|
179
|
+
merged.skills = base.skills;
|
|
180
|
+
}
|
|
181
|
+
// Path-scope permission denies (work item #46). Merged LAST so a base config
|
|
182
|
+
// or a hand-edited DB row cannot weaken them. These are the fallback tier
|
|
183
|
+
// for custom builder images that predate the managed /etc/opencode config;
|
|
184
|
+
// the guard plugin remains the guaranteed in-process layer.
|
|
185
|
+
const basePermission = base.permission && typeof base.permission === "object" && !Array.isArray(base.permission)
|
|
186
|
+
? base.permission
|
|
187
|
+
: {};
|
|
188
|
+
const denyRule = permissionGlobRule();
|
|
189
|
+
merged.permission = {
|
|
190
|
+
...basePermission,
|
|
191
|
+
read: denyRule,
|
|
192
|
+
edit: denyRule,
|
|
193
|
+
glob: denyRule,
|
|
194
|
+
grep: denyRule,
|
|
195
|
+
list: denyRule,
|
|
196
|
+
};
|
|
197
|
+
return JSON.stringify(merged, null, 2);
|
|
198
|
+
}
|
|
199
|
+
// auth.json maps provider id -> { type, key }. One entry per enabled provider.
|
|
200
|
+
export function buildAuthJson(providers) {
|
|
201
|
+
const auth = {};
|
|
202
|
+
for (const p of providers) {
|
|
203
|
+
if (p.enabled && p.apiKey)
|
|
204
|
+
auth[p.id] = { type: "api", key: p.apiKey };
|
|
205
|
+
}
|
|
206
|
+
return JSON.stringify(auth, null, 2);
|
|
207
|
+
}
|
|
208
|
+
// Write auth.json, the per-run opencode.json, AND the per-run mcp-auth.json
|
|
209
|
+
// onto the per-work-item xdg volume (mounted at XDG_HOME_DIR — OUTSIDE
|
|
210
|
+
// /workspace, the cloned repo's working tree). auth.json lands at
|
|
211
|
+
// <XDG_HOME_DIR>/data/opencode/auth.json (where opencode reads it via
|
|
212
|
+
// $XDG_DATA_HOME). opencode.json lands at
|
|
213
|
+
// <XDG_HOME_DIR>/config/opencode/opencode.json (read via $XDG_CONFIG_HOME,
|
|
214
|
+
// which we pass to the run container). mcp-auth.json lands at
|
|
215
|
+
// <XDG_HOME_DIR>/data/opencode/mcp-auth.json (read via $XDG_DATA_HOME) and
|
|
216
|
+
// carries the project's pasted OAuth tokens for remote MCP servers. Keeping
|
|
217
|
+
// them off /workspace means the agent's `git add -A` cannot commit the MCP
|
|
218
|
+
// bearer token or the provider API keys into the target repository.
|
|
219
|
+
//
|
|
220
|
+
// We write INTO the volume rather than bind-mounting because podman rootless
|
|
221
|
+
// bind mounts land as root:root in the container namespace, which devbot can't
|
|
222
|
+
// read (SELinux blocks it even at 644). The container runs as devbot (uid
|
|
223
|
+
// 1000), which owns the volume, so the files end up devbot:devbot 600 —
|
|
224
|
+
// readable by opencode.
|
|
225
|
+
//
|
|
226
|
+
// The opencode.json carries a per-thread MCP bearer token scoped to this work
|
|
227
|
+
// item's project. The mcp-auth.json carries pasted OAuth entries; serverUrl is
|
|
228
|
+
// force-overwritten to match each stored config's url (see buildMcpAuthJson).
|
|
229
|
+
// Folding all three writes into one `podman run` keeps the spawn cost at one.
|
|
230
|
+
export async function writeRunFilesToVolume(workItemId, mcpToken, mcpServers, mcpAuthJson, envVars = [], plugins = "", providers = [], builderImage = config.BUILDER_IMAGE, skillsPaths = [], lspServers = DEFAULT_LSP_SERVERS) {
|
|
231
|
+
const vol = volumeName(workItemId);
|
|
232
|
+
const xdgVol = xdgVolumeName(workItemId);
|
|
233
|
+
const authJson = buildAuthJson(providers);
|
|
234
|
+
const opencodeJson = buildOpencodeConfig(mcpToken, mcpServers, plugins, providers, skillsPaths, lspServers);
|
|
235
|
+
const r = await podman([
|
|
236
|
+
"run", "--rm", ...logDriverArgs(), "--name", `devbot-wi-${workItemId}-auth`,
|
|
237
|
+
"-v", `${vol}:/workspace:Z`,
|
|
238
|
+
"-v", `${xdgVol}:${XDG_HOME_DIR}:Z`,
|
|
239
|
+
...envArgs(envVars),
|
|
240
|
+
builderImage,
|
|
241
|
+
"sh", "-c",
|
|
242
|
+
// Stage in a devbot-owned directory on the xdg volume, NOT /workspace/.tmp
|
|
243
|
+
// or /workspace/.xdg-*: /workspace is the cloned target repo's working tree,
|
|
244
|
+
// so anything written there could be staged by the agent's `git add -A`. The
|
|
245
|
+
// staging dir lives on the same (xdg) volume for atomic renames and is safe
|
|
246
|
+
// to `rm -rf` because devbot owns the whole volume.
|
|
247
|
+
`mkdir -p ${XDG_HOME_DIR}/data/opencode ${XDG_HOME_DIR}/config/opencode ${XDG_HOME_DIR}/config/opencode/plugins ${XDG_HOME_DIR}/data/.tmp-write ` +
|
|
248
|
+
`&& printf %s ${shq(authJson)} > ${XDG_HOME_DIR}/data/.tmp-write/auth.json ` +
|
|
249
|
+
`&& chmod 600 ${XDG_HOME_DIR}/data/.tmp-write/auth.json ` +
|
|
250
|
+
`&& printf %s ${shq(opencodeJson)} > ${XDG_HOME_DIR}/data/.tmp-write/opencode.json ` +
|
|
251
|
+
`&& chmod 600 ${XDG_HOME_DIR}/data/.tmp-write/opencode.json ` +
|
|
252
|
+
`&& printf %s ${shq(mcpAuthJson)} > ${XDG_HOME_DIR}/data/.tmp-write/mcp-auth.json ` +
|
|
253
|
+
`&& chmod 600 ${XDG_HOME_DIR}/data/.tmp-write/mcp-auth.json ` +
|
|
254
|
+
`&& printf %s ${shq(pathGuardPlugin)} > ${XDG_HOME_DIR}/config/opencode/plugins/devbot-path-guard.js ` +
|
|
255
|
+
`&& chmod 600 ${XDG_HOME_DIR}/config/opencode/plugins/devbot-path-guard.js ` +
|
|
256
|
+
`&& mv ${XDG_HOME_DIR}/data/.tmp-write/auth.json ${XDG_HOME_DIR}/data/opencode/auth.json ` +
|
|
257
|
+
`&& mv ${XDG_HOME_DIR}/data/.tmp-write/opencode.json ${XDG_HOME_DIR}/config/opencode/opencode.json ` +
|
|
258
|
+
`&& mv ${XDG_HOME_DIR}/data/.tmp-write/mcp-auth.json ${XDG_HOME_DIR}/data/opencode/mcp-auth.json ` +
|
|
259
|
+
`&& rm -rf ${XDG_HOME_DIR}/data/.tmp-write ` +
|
|
260
|
+
// The credential volume is readable ONLY by opencode (uid devbot). The
|
|
261
|
+
// `agent` UID runs bash/MCP/podman and must be locked out by DAC.
|
|
262
|
+
`&& chmod 700 ${XDG_HOME_DIR} && chmod 700 ${XDG_HOME_DIR}/config ${XDG_HOME_DIR}/data`,
|
|
263
|
+
]);
|
|
264
|
+
if (r.code !== 0) {
|
|
265
|
+
throw new Error(`writeRunFilesToVolume failed: ${redact(r.stderr.slice(-256))}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Create the private nested-Podman store volume (if absent) and write the inner
|
|
269
|
+
// containers/storage.conf pinning the resolved driver and graphroot/runroot.
|
|
270
|
+
// One `podman run` folds volume auto-creation (named `-v` volumes are created on
|
|
271
|
+
// demand) and the config write. Only called for build-mode runs with
|
|
272
|
+
// DEVCONTAINER_ENABLED; throws on failure so the run aborts with a real error.
|
|
273
|
+
//
|
|
274
|
+
// --userns=keep-id is REQUIRED: the builder image's user is uid 1000 but the
|
|
275
|
+
// container's rootless subuid map differs from the host's, so a store volume
|
|
276
|
+
// populated WITHOUT keep-id is owned by an unmapped subuid and the actual run
|
|
277
|
+
// (launched with keep-id, see nestedPodmanArgs) cannot write its storage/
|
|
278
|
+
// subdir — nested podman then fails with "mkdir ... permission denied". Writing
|
|
279
|
+
// under the same userns mapping the run uses keeps the volume writable.
|
|
280
|
+
export async function ensurePodmanStore(workItemId, driver, builderImage = config.BUILDER_IMAGE) {
|
|
281
|
+
const vol = podmanVolumeName(workItemId);
|
|
282
|
+
const r = await podman([
|
|
283
|
+
"run", "--rm", ...logDriverArgs(), "--name", `devbot-wi-${workItemId}-podman-init`,
|
|
284
|
+
"--userns=keep-id",
|
|
285
|
+
"-v", `${vol}:${PODMAN_STORE_DIR}:Z`,
|
|
286
|
+
builderImage,
|
|
287
|
+
"sh", "-c",
|
|
288
|
+
// The nested podman runs as the unprivileged `agent` UID (gid devbot); make
|
|
289
|
+
// the store root group-writable so it can create storage/ + runroot/.
|
|
290
|
+
`printf %s ${shq(storageConf(driver))} > ${PODMAN_STORE_DIR}/storage.conf ` +
|
|
291
|
+
`&& chmod 0775 ${PODMAN_STORE_DIR}`,
|
|
292
|
+
]);
|
|
293
|
+
if (r.code !== 0) {
|
|
294
|
+
throw new Error(`ensurePodmanStore failed: ${redact(r.stderr.slice(-256))}`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=run-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-files.js","sourceRoot":"","sources":["../src/run-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function matchesActiveRun(v, f) {
|
|
2
|
+
if (f.projectId !== undefined && v.projectId !== f.projectId)
|
|
3
|
+
return false;
|
|
4
|
+
if (f.model !== undefined && v.model !== f.model)
|
|
5
|
+
return false;
|
|
6
|
+
if (f.mode !== undefined && v.mode !== f.mode)
|
|
7
|
+
return false;
|
|
8
|
+
if (f.title !== undefined && !v.workItemTitle.toLowerCase().includes(f.title.toLowerCase()))
|
|
9
|
+
return false;
|
|
10
|
+
if (f.window !== undefined && !(v.enqueuedAt >= f.window.start && v.enqueuedAt < f.window.end))
|
|
11
|
+
return false;
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
// The settled-history filter for a given status: `errored` pins the row state
|
|
15
|
+
// to `failed`, `cancelled` to `cancelled`; `all`/`settled` leave it open. The
|
|
16
|
+
// date window maps to `finished_at` bounds.
|
|
17
|
+
export function historyFilter(f, status) {
|
|
18
|
+
const out = {};
|
|
19
|
+
if (status === "errored")
|
|
20
|
+
out.status = "failed";
|
|
21
|
+
else if (status === "cancelled")
|
|
22
|
+
out.status = "cancelled";
|
|
23
|
+
if (f.projectId !== undefined)
|
|
24
|
+
out.projectId = f.projectId;
|
|
25
|
+
if (f.model !== undefined)
|
|
26
|
+
out.model = f.model;
|
|
27
|
+
if (f.mode !== undefined)
|
|
28
|
+
out.mode = f.mode;
|
|
29
|
+
if (f.title !== undefined)
|
|
30
|
+
out.title = f.title;
|
|
31
|
+
if (f.window !== undefined) {
|
|
32
|
+
out.sinceMs = f.window.start;
|
|
33
|
+
out.untilMs = f.window.end;
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
// Union of the settled-history options and the in-flight rows' values, so a
|
|
38
|
+
// filter can select a project/model/mode that only exists in-flight.
|
|
39
|
+
export function mergeFilterOptions(history, active) {
|
|
40
|
+
const projects = new Set(history.projects);
|
|
41
|
+
const models = new Set(history.models);
|
|
42
|
+
const modes = new Set(history.modes);
|
|
43
|
+
for (const v of active) {
|
|
44
|
+
projects.add(v.projectId);
|
|
45
|
+
models.add(v.model);
|
|
46
|
+
modes.add(v.mode);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
projects: [...projects].sort((a, b) => a - b),
|
|
50
|
+
models: [...models].sort(),
|
|
51
|
+
modes: [...modes].sort(),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=run-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-filters.js","sourceRoot":"","sources":["../src/run-filters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { db } from "./db.js";
|
|
2
|
+
function escLike(term) {
|
|
3
|
+
return term.replace(/[\\%_]/g, (ch) => `\\${ch}`);
|
|
4
|
+
}
|
|
5
|
+
function buildHistoryWhere(filter) {
|
|
6
|
+
if (!filter)
|
|
7
|
+
return { sql: "", params: [] };
|
|
8
|
+
const clauses = [];
|
|
9
|
+
const params = [];
|
|
10
|
+
if (filter.status !== undefined) {
|
|
11
|
+
clauses.push("status = ?");
|
|
12
|
+
params.push(filter.status);
|
|
13
|
+
}
|
|
14
|
+
if (filter.projectId !== undefined) {
|
|
15
|
+
clauses.push("project_id = ?");
|
|
16
|
+
params.push(filter.projectId);
|
|
17
|
+
}
|
|
18
|
+
if (filter.model !== undefined) {
|
|
19
|
+
clauses.push("model = ?");
|
|
20
|
+
params.push(filter.model);
|
|
21
|
+
}
|
|
22
|
+
if (filter.mode !== undefined) {
|
|
23
|
+
clauses.push("mode = ?");
|
|
24
|
+
params.push(filter.mode);
|
|
25
|
+
}
|
|
26
|
+
if (filter.title !== undefined) {
|
|
27
|
+
clauses.push("work_item_title LIKE ? ESCAPE '\\'");
|
|
28
|
+
params.push(`%${escLike(filter.title)}%`);
|
|
29
|
+
}
|
|
30
|
+
if (filter.sinceMs !== undefined) {
|
|
31
|
+
clauses.push("finished_at >= ?");
|
|
32
|
+
params.push(filter.sinceMs);
|
|
33
|
+
}
|
|
34
|
+
if (filter.untilMs !== undefined) {
|
|
35
|
+
clauses.push("finished_at < ?");
|
|
36
|
+
params.push(filter.untilMs);
|
|
37
|
+
}
|
|
38
|
+
return { sql: clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "", params };
|
|
39
|
+
}
|
|
40
|
+
export function initRunHistoryTables() {
|
|
41
|
+
// Belt-and-braces: migration 0025 is authoritative; keep the idempotent
|
|
42
|
+
// CREATE so a test DB opened without migrate() still works.
|
|
43
|
+
db.exec(`
|
|
44
|
+
CREATE TABLE IF NOT EXISTS run_history (
|
|
45
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
46
|
+
task_seq INTEGER,
|
|
47
|
+
project_id INTEGER NOT NULL,
|
|
48
|
+
work_item_id INTEGER NOT NULL,
|
|
49
|
+
work_item_iid INTEGER NOT NULL,
|
|
50
|
+
work_item_title TEXT NOT NULL DEFAULT '',
|
|
51
|
+
mode TEXT NOT NULL,
|
|
52
|
+
model TEXT NOT NULL DEFAULT '',
|
|
53
|
+
variant TEXT NOT NULL DEFAULT '',
|
|
54
|
+
status TEXT NOT NULL,
|
|
55
|
+
phase TEXT NOT NULL DEFAULT '',
|
|
56
|
+
kind TEXT NOT NULL DEFAULT '',
|
|
57
|
+
exit_code INTEGER,
|
|
58
|
+
message TEXT NOT NULL DEFAULT '',
|
|
59
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
60
|
+
enqueued_at INTEGER NOT NULL DEFAULT 0,
|
|
61
|
+
started_at INTEGER NOT NULL DEFAULT 0,
|
|
62
|
+
finished_at INTEGER NOT NULL,
|
|
63
|
+
log_file TEXT NOT NULL DEFAULT '',
|
|
64
|
+
log_truncated INTEGER NOT NULL DEFAULT 0
|
|
65
|
+
)
|
|
66
|
+
`);
|
|
67
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_run_history_finished ON run_history(finished_at)");
|
|
68
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_run_history_project ON run_history(project_id)");
|
|
69
|
+
// A pre-0026 DB lacks the task_seq index. CREATE errors if it exists.
|
|
70
|
+
try {
|
|
71
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_run_history_task_seq ON run_history(task_seq)");
|
|
72
|
+
}
|
|
73
|
+
catch { /* exists */ }
|
|
74
|
+
// Pre-0028 DBs lack the token-usage columns (work item #66).
|
|
75
|
+
for (const col of [
|
|
76
|
+
"input_tokens INTEGER NOT NULL DEFAULT 0",
|
|
77
|
+
"output_tokens INTEGER NOT NULL DEFAULT 0",
|
|
78
|
+
"reasoning_tokens INTEGER NOT NULL DEFAULT 0",
|
|
79
|
+
"cache_read_tokens INTEGER NOT NULL DEFAULT 0",
|
|
80
|
+
"cache_write_tokens INTEGER NOT NULL DEFAULT 0",
|
|
81
|
+
"cost_usd REAL NOT NULL DEFAULT 0",
|
|
82
|
+
]) {
|
|
83
|
+
try {
|
|
84
|
+
db.exec(`ALTER TABLE run_history ADD COLUMN ${col}`);
|
|
85
|
+
}
|
|
86
|
+
catch { /* exists */ }
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function toSummary(r) {
|
|
90
|
+
return {
|
|
91
|
+
id: r.id,
|
|
92
|
+
taskSeq: r.task_seq,
|
|
93
|
+
projectId: r.project_id,
|
|
94
|
+
workItemId: r.work_item_id,
|
|
95
|
+
workItemIid: r.work_item_iid,
|
|
96
|
+
workItemTitle: r.work_item_title,
|
|
97
|
+
mode: r.mode,
|
|
98
|
+
model: r.model,
|
|
99
|
+
variant: r.variant,
|
|
100
|
+
status: r.status,
|
|
101
|
+
phase: r.phase,
|
|
102
|
+
kind: r.kind,
|
|
103
|
+
exitCode: r.exit_code,
|
|
104
|
+
message: r.message,
|
|
105
|
+
attempts: r.attempts,
|
|
106
|
+
enqueuedAt: r.enqueued_at,
|
|
107
|
+
startedAt: r.started_at,
|
|
108
|
+
finishedAt: r.finished_at,
|
|
109
|
+
logFile: r.log_file,
|
|
110
|
+
logTruncated: r.log_truncated === 1,
|
|
111
|
+
inputTokens: r.input_tokens,
|
|
112
|
+
outputTokens: r.output_tokens,
|
|
113
|
+
reasoningTokens: r.reasoning_tokens,
|
|
114
|
+
cacheReadTokens: r.cache_read_tokens,
|
|
115
|
+
cacheWriteTokens: r.cache_write_tokens,
|
|
116
|
+
costUsd: r.cost_usd,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function recordRunHistory(input) {
|
|
120
|
+
const r = db
|
|
121
|
+
.prepare(`INSERT INTO run_history
|
|
122
|
+
(task_seq, project_id, work_item_id, work_item_iid, work_item_title, mode, model, variant,
|
|
123
|
+
status, phase, kind, exit_code, message, attempts, enqueued_at, started_at, finished_at,
|
|
124
|
+
log_file, log_truncated, input_tokens, output_tokens, reasoning_tokens, cache_read_tokens,
|
|
125
|
+
cache_write_tokens, cost_usd)
|
|
126
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
127
|
+
.run(input.taskSeq, input.projectId, input.workItemId, input.workItemNumber, input.workItemTitle ?? "", input.mode, input.model ?? "", input.variant ?? "", input.status, input.phase ?? "", input.kind ?? "", input.exitCode, input.message ?? "", input.attempts ?? 0, input.enqueuedAt ?? 0, input.startedAt ?? 0, Date.now(), input.logFile, input.logTruncated ? 1 : 0, input.inputTokens ?? 0, input.outputTokens ?? 0, input.reasoningTokens ?? 0, input.cacheReadTokens ?? 0, input.cacheWriteTokens ?? 0, input.costUsd ?? 0);
|
|
128
|
+
return Number(r.lastInsertRowid);
|
|
129
|
+
}
|
|
130
|
+
const SUMMARY_COLS = `id, task_seq, project_id, work_item_id, work_item_iid, work_item_title, mode, model, variant,
|
|
131
|
+
status, phase, kind, exit_code, message, attempts, enqueued_at, started_at, finished_at,
|
|
132
|
+
log_file, log_truncated, input_tokens, output_tokens, reasoning_tokens, cache_read_tokens,
|
|
133
|
+
cache_write_tokens, cost_usd`;
|
|
134
|
+
// Newest-first by task seq (work item #61). The unified Runs page merges these
|
|
135
|
+
// with in-flight queue rows on the shared seq, so both sources order by seq
|
|
136
|
+
// DESC. Rows with no task_seq (null) sort last. `id DESC` is a deterministic
|
|
137
|
+
// tiebreaker: without it, LIMIT/OFFSET paging over many null-seq rows could
|
|
138
|
+
// return ties in a different order per request and skip/repeat rows.
|
|
139
|
+
export function listRunHistoryBySeq(limit, offset, filter) {
|
|
140
|
+
const { sql: where, params } = buildHistoryWhere(filter);
|
|
141
|
+
const sql = `SELECT ${SUMMARY_COLS} FROM run_history${where} ORDER BY task_seq IS NULL, task_seq DESC, id DESC` +
|
|
142
|
+
(limit === undefined ? "" : " LIMIT ? OFFSET ?");
|
|
143
|
+
const args = limit === undefined ? params : [...params, limit, offset ?? 0];
|
|
144
|
+
const rows = db.prepare(sql).all(...args);
|
|
145
|
+
return rows.map(toSummary);
|
|
146
|
+
}
|
|
147
|
+
export function countRunHistory(filter) {
|
|
148
|
+
const { sql: where, params } = buildHistoryWhere(filter);
|
|
149
|
+
const row = db.prepare(`SELECT COUNT(*) AS c FROM run_history${where}`).get(...params);
|
|
150
|
+
return row.c;
|
|
151
|
+
}
|
|
152
|
+
// Distinct filter values across all settled history, ignoring any active
|
|
153
|
+
// filter, so a selected value can always be cleared again. Mirrors
|
|
154
|
+
// `computeUsageStats().filterOptions`.
|
|
155
|
+
export function listRunHistoryFilterOptions() {
|
|
156
|
+
const rows = db
|
|
157
|
+
.prepare("SELECT DISTINCT project_id, model, mode FROM run_history")
|
|
158
|
+
.all();
|
|
159
|
+
const projects = new Set();
|
|
160
|
+
const models = new Set();
|
|
161
|
+
const modes = new Set();
|
|
162
|
+
for (const r of rows) {
|
|
163
|
+
projects.add(r.project_id);
|
|
164
|
+
models.add(r.model);
|
|
165
|
+
modes.add(r.mode);
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
projects: [...projects].sort((a, b) => a - b),
|
|
169
|
+
models: [...models].sort(),
|
|
170
|
+
modes: [...modes].sort(),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export function getRunHistory(id) {
|
|
174
|
+
const row = db.prepare(`SELECT ${SUMMARY_COLS} FROM run_history WHERE id = ?`).get(id);
|
|
175
|
+
return row ? toSummary(row) : null;
|
|
176
|
+
}
|
|
177
|
+
// Newest history row for a task seq. Backs the live-log route's settle fallback:
|
|
178
|
+
// a task that just finished has no pending_tasks row, but its history row
|
|
179
|
+
// points at the archived log file. Null when the task never settled.
|
|
180
|
+
export function getRunHistoryByTaskSeq(taskSeq) {
|
|
181
|
+
const row = db
|
|
182
|
+
.prepare(`SELECT ${SUMMARY_COLS} FROM run_history WHERE task_seq = ? ORDER BY id DESC LIMIT 1`)
|
|
183
|
+
.get(taskSeq);
|
|
184
|
+
return row ? toSummary(row) : null;
|
|
185
|
+
}
|
|
186
|
+
// Blank the log-file reference on the given rows (the TTL purger deleted the
|
|
187
|
+
// files). The row itself is kept. Returns the number of rows updated.
|
|
188
|
+
export function clearLogFile(ids) {
|
|
189
|
+
if (ids.length === 0)
|
|
190
|
+
return 0;
|
|
191
|
+
const stmt = db.prepare("UPDATE run_history SET log_file = '' WHERE id = ?");
|
|
192
|
+
let n = 0;
|
|
193
|
+
for (const id of ids)
|
|
194
|
+
n += Number(stmt.run(id).changes);
|
|
195
|
+
return n;
|
|
196
|
+
}
|
|
197
|
+
// Rows whose log file is older than `cutoffMs` and still carry a reference —
|
|
198
|
+
// the candidates the TTL purge must unlink and clear. `finished_at` is epoch
|
|
199
|
+
// MILLISECONDS (matching enqueued_at/started_at), so the cutoff is ms too.
|
|
200
|
+
export function listExpiredLogRows(cutoffMs) {
|
|
201
|
+
const rows = db
|
|
202
|
+
.prepare("SELECT id, log_file FROM run_history WHERE log_file != '' AND finished_at < ?")
|
|
203
|
+
.all(cutoffMs);
|
|
204
|
+
return rows.map((r) => ({ id: r.id, logFile: r.log_file }));
|
|
205
|
+
}
|
|
206
|
+
export function listUsageRows(sinceMs) {
|
|
207
|
+
const rows = db
|
|
208
|
+
.prepare(`SELECT id, finished_at, project_id, work_item_iid, work_item_title, model, mode,
|
|
209
|
+
input_tokens, output_tokens, reasoning_tokens, cache_read_tokens,
|
|
210
|
+
cache_write_tokens, cost_usd
|
|
211
|
+
FROM run_history WHERE finished_at >= ? ORDER BY finished_at DESC`)
|
|
212
|
+
.all(sinceMs);
|
|
213
|
+
return rows.map((r) => ({
|
|
214
|
+
id: r.id,
|
|
215
|
+
finishedAt: r.finished_at,
|
|
216
|
+
projectId: r.project_id,
|
|
217
|
+
workItemIid: r.work_item_iid,
|
|
218
|
+
workItemTitle: r.work_item_title,
|
|
219
|
+
model: r.model,
|
|
220
|
+
mode: r.mode,
|
|
221
|
+
inputTokens: r.input_tokens,
|
|
222
|
+
outputTokens: r.output_tokens,
|
|
223
|
+
reasoningTokens: r.reasoning_tokens,
|
|
224
|
+
cacheReadTokens: r.cache_read_tokens,
|
|
225
|
+
cacheWriteTokens: r.cache_write_tokens,
|
|
226
|
+
costUsd: r.cost_usd,
|
|
227
|
+
}));
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=run-history-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-history-store.js","sourceRoot":"","sources":["../src/run-history-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAyF7B,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAyB;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IAC5F,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IACtG,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IACzF,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IACtF,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAClI,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IACpG,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IACnG,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,wEAAwE;IACxE,4DAA4D;IAC5D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;GAuBP,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;IAC3F,EAAE,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;IACzF,sEAAsE;IACtE,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACvH,6DAA6D;IAC7D,KAAK,MAAM,GAAG,IAAI;QAChB,yCAAyC;QACzC,0CAA0C;QAC1C,6CAA6C;QAC7C,8CAA8C;QAC9C,+CAA+C;QAC/C,kCAAkC;KACnC,EAAE,CAAC;QACF,IAAI,CAAC;YAAC,EAAE,CAAC,IAAI,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACtF,CAAC;AACH,CAAC;AA+BD,SAAS,SAAS,CAAC,CAAQ;IACzB,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,OAAO,EAAE,CAAC,CAAC,QAAQ;QACnB,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,UAAU,EAAE,CAAC,CAAC,YAAY;QAC1B,WAAW,EAAE,CAAC,CAAC,aAAa;QAC5B,aAAa,EAAE,CAAC,CAAC,eAAe;QAChC,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,SAAS;QACrB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,UAAU,EAAE,CAAC,CAAC,WAAW;QACzB,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,UAAU,EAAE,CAAC,CAAC,WAAW;QACzB,OAAO,EAAE,CAAC,CAAC,QAAQ;QACnB,YAAY,EAAE,CAAC,CAAC,aAAa,KAAK,CAAC;QACnC,WAAW,EAAE,CAAC,CAAC,YAAY;QAC3B,YAAY,EAAE,CAAC,CAAC,aAAa;QAC7B,eAAe,EAAE,CAAC,CAAC,gBAAgB;QACnC,eAAe,EAAE,CAAC,CAAC,iBAAiB;QACpC,gBAAgB,EAAE,CAAC,CAAC,kBAAkB;QACtC,OAAO,EAAE,CAAC,CAAC,QAAQ;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,MAAM,CAAC,GAAG,EAAE;SACT,OAAO,CACN;;;;;0FAKoF,CACrF;SACA,GAAG,CACF,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,aAAa,IAAI,EAAE,EACzB,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,KAAK,IAAI,EAAE,EACjB,KAAK,CAAC,OAAO,IAAI,EAAE,EACnB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,KAAK,IAAI,EAAE,EACjB,KAAK,CAAC,IAAI,IAAI,EAAE,EAChB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,OAAO,IAAI,EAAE,EACnB,KAAK,CAAC,QAAQ,IAAI,CAAC,EACnB,KAAK,CAAC,UAAU,IAAI,CAAC,EACrB,KAAK,CAAC,SAAS,IAAI,CAAC,EACpB,IAAI,CAAC,GAAG,EAAE,EACV,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC1B,KAAK,CAAC,WAAW,IAAI,CAAC,EACtB,KAAK,CAAC,YAAY,IAAI,CAAC,EACvB,KAAK,CAAC,eAAe,IAAI,CAAC,EAC1B,KAAK,CAAC,eAAe,IAAI,CAAC,EAC1B,KAAK,CAAC,gBAAgB,IAAI,CAAC,EAC3B,KAAK,CAAC,OAAO,IAAI,CAAC,CACnB,CAAC;IACJ,OAAO,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,YAAY,GAChB;;;gCAG8B,CAAC;AAEjC,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,qEAAqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,KAAc,EAAE,MAAe,EAAE,MAAyB;IAC5F,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,GAAG,GACP,UAAU,YAAY,oBAAoB,KAAK,oDAAoD;QACnG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAuB,CAAC;IAChE,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAyB;IACvD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,wCAAwC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAkB,CAAC;IACxG,OAAO,GAAG,CAAC,CAAC,CAAC;AACf,CAAC;AAED,yEAAyE;AACzE,mEAAmE;AACnE,uCAAuC;AACvC,MAAM,UAAU,2BAA2B;IACzC,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,0DAA0D,CAAC;SACnE,GAAG,EAAgE,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACpB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE;QAC1B,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,YAAY,gCAAgC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAiC,CAAC;IACvH,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,iFAAiF;AACjF,0EAA0E;AAC1E,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CAAC,UAAU,YAAY,+DAA+D,CAAC;SAC9F,GAAG,CAAC,OAAO,CAAiC,CAAC;IAChD,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,6EAA6E;AAC7E,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAAC,GAAa;IACxC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,EAAE,IAAI,GAAG;QAAE,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACxD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6EAA6E;AAC7E,6EAA6E;AAC7E,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,+EAA+E,CAAC;SACxF,GAAG,CAAC,QAAQ,CAA4C,CAAC;IAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC;AAoBD,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;2EAGqE,CACtE;SACA,GAAG,CAAC,OAAO,CAcZ,CAAC;IACH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtB,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,UAAU,EAAE,CAAC,CAAC,WAAW;QACzB,SAAS,EAAE,CAAC,CAAC,UAAU;QACvB,WAAW,EAAE,CAAC,CAAC,aAAa;QAC5B,aAAa,EAAE,CAAC,CAAC,eAAe;QAChC,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,WAAW,EAAE,CAAC,CAAC,YAAY;QAC3B,YAAY,EAAE,CAAC,CAAC,aAAa;QAC7B,eAAe,EAAE,CAAC,CAAC,gBAAgB;QACnC,eAAe,EAAE,CAAC,CAAC,iBAAiB;QACpC,gBAAgB,EAAE,CAAC,CAAC,kBAAkB;QACtC,OAAO,EAAE,CAAC,CAAC,QAAQ;KACpB,CAAC,CAAC,CAAC;AACN,CAAC"}
|