@wascartech/devbot 0.0.0-stage → 2.1.0
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 +141 -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 +73 -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 +157 -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
package/dist/mention.js
ADDED
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import { config } from "./config.js";
|
|
2
|
+
// ponytail: /build is a global flag — strip wherever it appears (any line,
|
|
3
|
+
// any position). /agent <name> may appear anywhere on a line; the segment is
|
|
4
|
+
// whatever remains on that line after stripping the /agent <name> token.
|
|
5
|
+
// This preserves both old single-agent forms (`prompt /agent name` and
|
|
6
|
+
// `/agent name prompt` → segment is the non-agent text) AND enables the
|
|
7
|
+
// multi-line scattered form where /agent calls sit on their own lines anywhere
|
|
8
|
+
// in the message. Non-/agent prose (before, between, after /agent lines)
|
|
9
|
+
// becomes a shared preamble prepended once to the combined opencode prompt —
|
|
10
|
+
// the main plan/build agent reads it as background, then dispatches each
|
|
11
|
+
// @agent block.
|
|
12
|
+
// #48: a command token must stand as its own word. `(?<!\S)` requires start of
|
|
13
|
+
// line or whitespace before the leading slash (so a token embedded in a path,
|
|
14
|
+
// parentheses, or `**bold**` is not a command), and `(?![\w/])` rejects a
|
|
15
|
+
// trailing word char or `/` (so `/build/output` is a path, not `/build`).
|
|
16
|
+
// The right side stays lenient about punctuation so sentence-final `/build.`
|
|
17
|
+
// or `/build,` still fires; adjacency to parens/asterisks is handled by the
|
|
18
|
+
// span masking in protectDirectives.
|
|
19
|
+
const TOKEN_BUILD = /(?<!\S)\/build(?![\w/])/i;
|
|
20
|
+
const TOKEN_AGENT = /(?<!\S)\/agent\s+(\S+)/i;
|
|
21
|
+
const TOKEN_RESET = /(?<!\S)\/reset(?![\w/])/i;
|
|
22
|
+
// /stop short-circuits like /reset: it cancels this work item's in-flight and
|
|
23
|
+
// queued runs and never dispatches a run. /reset is checked first, so it wins
|
|
24
|
+
// if both appear.
|
|
25
|
+
const TOKEN_STOP = /(?<!\S)\/stop(?![\w/])/i;
|
|
26
|
+
// /help is a reply-only command (work item #95): it posts the command list and
|
|
27
|
+
// dispatches no run. It short-circuits like /stop but is checked after it, so
|
|
28
|
+
// /reset and /stop still win if they appear in the same mention.
|
|
29
|
+
const TOKEN_HELP = /(?<!\S)\/help(?![\w/])/i;
|
|
30
|
+
// /status is a reply-only command (work item #103): it posts a local snapshot and
|
|
31
|
+
// dispatches no run. Checked after /help, so /help wins if both appear; /reset
|
|
32
|
+
// and /stop still win over both.
|
|
33
|
+
const TOKEN_STATUS = /(?<!\S)\/status(?![\w/])/i;
|
|
34
|
+
// /force-push is a command (like /build, /base): a global token stripped
|
|
35
|
+
// wherever it appears. Standalone (without /build) it dispatches a push-only
|
|
36
|
+
// task — no opencode run, just a host-side --force-with-lease of the local
|
|
37
|
+
// wi-<iid> branch. Combined with /build it keeps its original meaning: run
|
|
38
|
+
// the agent first, then force-push its result.
|
|
39
|
+
const TOKEN_FORCE_PUSH = /(?<!\S)\/force-push(?![\w/])/i;
|
|
40
|
+
// /push and /mr are build-output commands (like /force-push). With /build they
|
|
41
|
+
// are per-run overrides that turn on the branch push / merge request even when
|
|
42
|
+
// the stored auto-push/auto-MR settings are off. Standalone (no /build) they
|
|
43
|
+
// dispatch a push-only / publish-and-open task. /mr implies a push. Global
|
|
44
|
+
// tokens stripped wherever they appear.
|
|
45
|
+
const TOKEN_PUSH = /(?<!\S)\/push(?![\w/])/i;
|
|
46
|
+
const TOKEN_MR = /(?<!\S)\/mr(?![\w/])/i;
|
|
47
|
+
// /fix-conflicts is a standalone command (work item #82): re-run the conflict
|
|
48
|
+
// resolver on the work item's existing branch against the target branch of
|
|
49
|
+
// its open MR (falling back to the resolved base target). It never publishes
|
|
50
|
+
// or creates/updates an MR — a successful resolve re-pushes the branch, which
|
|
51
|
+
// updates the existing MR on the forge. Global token stripped wherever it
|
|
52
|
+
// appears. With /build it forces the post-build conflict check for that run.
|
|
53
|
+
const TOKEN_FIX_CONFLICTS = /(?<!\S)\/fix-conflicts(?![\w/])/i;
|
|
54
|
+
// Contextual auto-* commands (#58). Each per-feature token optionally carries an
|
|
55
|
+
// `on`/`off` argument; a bare token is a query. `/auto` acts on all four (or
|
|
56
|
+
// queries all with no argument); `/ask` is an alias of `/auto off`. All are
|
|
57
|
+
// global, order-independent commands stripped from the prompt. The trailing
|
|
58
|
+
// `(?![\w-])` guard keeps `/auto` from swallowing `/auto-mr` and
|
|
59
|
+
// `/auto-push` from matching `/auto-pushback`; the argument's own guard keeps
|
|
60
|
+
// `/auto on` from firing on `/auto online`.
|
|
61
|
+
const AUTO_TOKEN_RE = /(?<!\S)\/(?<tok>auto-resolve-conflicts|auto-ci-report|auto-push|auto-mr|auto|ask)(?![\w-])(?:\s+(?<arg>on|off)(?![\w-]))?/gi;
|
|
62
|
+
const AUTO_TOKEN_FEATURE = {
|
|
63
|
+
"auto-push": "autoPush",
|
|
64
|
+
"auto-mr": "autoMr",
|
|
65
|
+
"auto-resolve-conflicts": "autoResolveConflicts",
|
|
66
|
+
"auto-ci-report": "ciFailAutoReport",
|
|
67
|
+
auto: "all",
|
|
68
|
+
ask: "all",
|
|
69
|
+
};
|
|
70
|
+
function toAutoAction(arg) {
|
|
71
|
+
if (!arg)
|
|
72
|
+
return "query";
|
|
73
|
+
return arg.toLowerCase() === "on" ? "on" : "off";
|
|
74
|
+
}
|
|
75
|
+
// Strip every auto-* command from one line, appending them to `commands` in
|
|
76
|
+
// textual order (so a later command for the same feature wins). `/ask` is
|
|
77
|
+
// normalized to `/auto off`; `/ask` takes no argument.
|
|
78
|
+
function stripAutoCommands(line, commands) {
|
|
79
|
+
AUTO_TOKEN_RE.lastIndex = 0;
|
|
80
|
+
for (const m of line.matchAll(AUTO_TOKEN_RE)) {
|
|
81
|
+
const feature = AUTO_TOKEN_FEATURE[m.groups?.tok?.toLowerCase() ?? ""];
|
|
82
|
+
if (!feature)
|
|
83
|
+
continue;
|
|
84
|
+
const action = m.groups?.tok?.toLowerCase() === "ask" ? "off" : toAutoAction(m.groups?.arg);
|
|
85
|
+
commands.push({ feature, action });
|
|
86
|
+
}
|
|
87
|
+
return line.replace(AUTO_TOKEN_RE, "");
|
|
88
|
+
}
|
|
89
|
+
// Safe charset for a /base branch name. The captured value is later
|
|
90
|
+
// interpolated into a shq()-quoted shell command in git.ts's clone chain, so
|
|
91
|
+
// this is a safety gate, not just UX: rejecting shell metacharacters here
|
|
92
|
+
// prevents injection at the source. Git ref names allow [A-Za-z0-9._/-].
|
|
93
|
+
const BASE_BRANCH_RE = /^[A-Za-z0-9._/-]+$/;
|
|
94
|
+
function normalizeAgentName(raw) {
|
|
95
|
+
return raw.toLowerCase().replace(/\.md$/i, "");
|
|
96
|
+
}
|
|
97
|
+
// #34/#48: token commands quoted, in code, in parentheses, or in bold are
|
|
98
|
+
// prose, not instructions. A note like "try `/build`", 'the flag is
|
|
99
|
+
// "/base main"', "(see /build docs)" should not switch mode or reroute an
|
|
100
|
+
// agent — the author is documenting the syntax, not using it.
|
|
101
|
+
// protectDirectives masks every region we want treated as literal text
|
|
102
|
+
// (fenced ``` blocks, inline `code`, "..." / '...' quotes, **bold**, and
|
|
103
|
+
// (parentheses)) behind private-use placeholders, then unmask() restores the
|
|
104
|
+
// originals so the text still reaches the OpenCode prompt verbatim. The
|
|
105
|
+
// delimiters themselves are kept, and newlines inside a masked region stay
|
|
106
|
+
// put so parseMention's line-based loop sees the same line structure.
|
|
107
|
+
//
|
|
108
|
+
// Delimiter precedence, left to right: ```` fence (multi-line) → inline backtick
|
|
109
|
+
// → double quote → single quote → bold `**...**` → parentheses `(...)`, all but
|
|
110
|
+
// the fence line-scoped. Single quotes are word-boundary gated so apostrophes
|
|
111
|
+
// ("it's", "'cause") are not read as delimiters; parentheses are nesting-aware
|
|
112
|
+
// and skip code/quoted spans so an inner `)` can't close early; an unmatched
|
|
113
|
+
// delimiter is left literal.
|
|
114
|
+
const PLACEHOLDER_OPEN = "\uE000";
|
|
115
|
+
const PLACEHOLDER_CLOSE = "\uE001";
|
|
116
|
+
function protectDirectives(raw) {
|
|
117
|
+
const originals = [];
|
|
118
|
+
// Mask one line's worth of content as a single placeholder; empty lines and
|
|
119
|
+
// newlines pass through untouched to preserve line structure.
|
|
120
|
+
const maskRuns = (text) => text
|
|
121
|
+
.split("\n")
|
|
122
|
+
.map((line) => {
|
|
123
|
+
if (line.length === 0)
|
|
124
|
+
return line;
|
|
125
|
+
const id = originals.push(line) - 1;
|
|
126
|
+
return `${PLACEHOLDER_OPEN}${id}${PLACEHOLDER_CLOSE}`;
|
|
127
|
+
})
|
|
128
|
+
.join("\n");
|
|
129
|
+
// Find a closing delimiter on the same line, returning -1 when none exists.
|
|
130
|
+
const lineClose = (start, delim) => {
|
|
131
|
+
const eol = raw.indexOf("\n", start);
|
|
132
|
+
const limit = eol === -1 ? raw.length : eol;
|
|
133
|
+
const close = raw.indexOf(delim, start);
|
|
134
|
+
return close !== -1 && close < limit ? close : -1;
|
|
135
|
+
};
|
|
136
|
+
// Index of the ')' matching the '(' at `open`, same line. Nested parens
|
|
137
|
+
// increment/decrement depth. Parens inside an inline code span or a quoted
|
|
138
|
+
// span on that line are skipped so their ')' can't close the span early.
|
|
139
|
+
const matchParen = (open) => {
|
|
140
|
+
const eol = raw.indexOf("\n", open);
|
|
141
|
+
const limit = eol === -1 ? raw.length : eol;
|
|
142
|
+
let depth = 1;
|
|
143
|
+
for (let j = open + 1; j < limit; j++) {
|
|
144
|
+
const c = raw[j];
|
|
145
|
+
if (c === "`") {
|
|
146
|
+
const cl = lineClose(j + 1, "`");
|
|
147
|
+
if (cl !== -1 && cl < limit) {
|
|
148
|
+
j = cl;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (c === '"') {
|
|
153
|
+
const cl = lineClose(j + 1, '"');
|
|
154
|
+
if (cl !== -1 && cl < limit) {
|
|
155
|
+
j = cl;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (c === "'") {
|
|
160
|
+
const prev = j > 0 ? raw[j - 1] : "";
|
|
161
|
+
if (!prev || !/[A-Za-z0-9_]/.test(prev)) {
|
|
162
|
+
for (let k = j + 1; k < limit; k++) {
|
|
163
|
+
if (raw[k] === "'") {
|
|
164
|
+
const next = k + 1 < raw.length ? raw[k + 1] : "";
|
|
165
|
+
if (!next || !/[A-Za-z0-9_]/.test(next)) {
|
|
166
|
+
j = k;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (c === "(")
|
|
174
|
+
depth++;
|
|
175
|
+
else if (c === ")") {
|
|
176
|
+
depth--;
|
|
177
|
+
if (depth === 0)
|
|
178
|
+
return j;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return -1;
|
|
182
|
+
};
|
|
183
|
+
let out = "";
|
|
184
|
+
let i = 0;
|
|
185
|
+
while (i < raw.length) {
|
|
186
|
+
const ch = raw[i];
|
|
187
|
+
// Fenced code block: ``` ... ``` (multi-line).
|
|
188
|
+
if (raw.startsWith("```", i)) {
|
|
189
|
+
const close = raw.indexOf("```", i + 3);
|
|
190
|
+
if (close !== -1) {
|
|
191
|
+
out += raw.slice(i, i + 3) + maskRuns(raw.slice(i + 3, close)) + raw.slice(close, close + 3);
|
|
192
|
+
i = close + 3;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
out += ch;
|
|
196
|
+
i++;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
// Inline code span: `...` to end of line.
|
|
200
|
+
if (ch === "`") {
|
|
201
|
+
const close = lineClose(i + 1, "`");
|
|
202
|
+
if (close !== -1) {
|
|
203
|
+
out += "`" + maskRuns(raw.slice(i + 1, close)) + "`";
|
|
204
|
+
i = close + 1;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
out += ch;
|
|
208
|
+
i++;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
// Double-quoted span: "..." to end of line.
|
|
212
|
+
if (ch === '"') {
|
|
213
|
+
const close = lineClose(i + 1, '"');
|
|
214
|
+
if (close !== -1) {
|
|
215
|
+
out += '"' + maskRuns(raw.slice(i + 1, close)) + '"';
|
|
216
|
+
i = close + 1;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
out += ch;
|
|
220
|
+
i++;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
// Single-quoted span, word-boundary gated: an opener must not follow a
|
|
224
|
+
// word char (so "it's" is prose) and a closer must not precede one.
|
|
225
|
+
if (ch === "'") {
|
|
226
|
+
const prev = i > 0 ? raw[i - 1] : "";
|
|
227
|
+
if (prev && /[A-Za-z0-9_]/.test(prev)) {
|
|
228
|
+
out += ch;
|
|
229
|
+
i++;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const eol = raw.indexOf("\n", i + 1);
|
|
233
|
+
const limit = eol === -1 ? raw.length : eol;
|
|
234
|
+
let close = -1;
|
|
235
|
+
for (let j = i + 1; j < limit; j++) {
|
|
236
|
+
if (raw[j] === "'") {
|
|
237
|
+
const next = j + 1 < raw.length ? raw[j + 1] : "";
|
|
238
|
+
if (!next || !/[A-Za-z0-9_]/.test(next)) {
|
|
239
|
+
close = j;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (close !== -1) {
|
|
245
|
+
out += "'" + maskRuns(raw.slice(i + 1, close)) + "'";
|
|
246
|
+
i = close + 1;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
out += ch;
|
|
250
|
+
i++;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
// Bold span: **...** to end of line.
|
|
254
|
+
if (raw.startsWith("**", i)) {
|
|
255
|
+
const close = lineClose(i + 2, "**");
|
|
256
|
+
if (close !== -1) {
|
|
257
|
+
out += "**" + maskRuns(raw.slice(i + 2, close)) + "**";
|
|
258
|
+
i = close + 2;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
out += ch;
|
|
262
|
+
i++;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
// Parenthesized span: (...) to end of line, nesting-aware.
|
|
266
|
+
if (ch === "(") {
|
|
267
|
+
const close = matchParen(i);
|
|
268
|
+
if (close !== -1) {
|
|
269
|
+
out += "(" + maskRuns(raw.slice(i + 1, close)) + ")";
|
|
270
|
+
i = close + 1;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
out += ch;
|
|
274
|
+
i++;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
out += ch;
|
|
278
|
+
i++;
|
|
279
|
+
}
|
|
280
|
+
const placeholderRe = new RegExp(`${PLACEHOLDER_OPEN}(\\d+)${PLACEHOLDER_CLOSE}`, "g");
|
|
281
|
+
return {
|
|
282
|
+
masked: out,
|
|
283
|
+
unmask: (s) => s.replace(placeholderRe, (_m, d) => originals[Number(d)] ?? ""),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
export function parseMention(raw) {
|
|
287
|
+
// #34: token commands inside code spans / quotes are literal prose. Mask those
|
|
288
|
+
// regions before scanning so /build, /agent, /reset, /base, and /force-push
|
|
289
|
+
// only act when they are real instructions; unmask on the way out so the
|
|
290
|
+
// protected text reaches the OpenCode prompt verbatim.
|
|
291
|
+
const { masked, unmask } = protectDirectives(raw);
|
|
292
|
+
// /reset short-circuits: wins over /build, /agent, and any prompt.
|
|
293
|
+
// /reset is a destructive op; never combine it with a run.
|
|
294
|
+
if (TOKEN_RESET.test(masked)) {
|
|
295
|
+
return { mode: "plan", prompt: "", agents: [], reset: true, stop: false, help: false, status: false, forcePush: false, push: false, mr: false, fixConflicts: false, autoCommands: [] };
|
|
296
|
+
}
|
|
297
|
+
// /stop short-circuits like /reset: it cancels in-flight work for this work
|
|
298
|
+
// item and never dispatches a run. /reset is checked first, so it wins if
|
|
299
|
+
// both appear. Quoted/code /stop was already masked away by protectDirectives.
|
|
300
|
+
if (TOKEN_STOP.test(masked)) {
|
|
301
|
+
return { mode: "plan", prompt: "", agents: [], reset: false, stop: true, help: false, status: false, forcePush: false, push: false, mr: false, fixConflicts: false, autoCommands: [] };
|
|
302
|
+
}
|
|
303
|
+
// /help short-circuits after /stop: reply with the command list and dispatch
|
|
304
|
+
// no run. Quoted/code /help was already masked away by protectDirectives.
|
|
305
|
+
if (TOKEN_HELP.test(masked)) {
|
|
306
|
+
return { mode: "plan", prompt: "", agents: [], reset: false, stop: false, help: true, status: false, forcePush: false, push: false, mr: false, fixConflicts: false, autoCommands: [] };
|
|
307
|
+
}
|
|
308
|
+
// /status short-circuits after /help: reply with the local status snapshot and
|
|
309
|
+
// dispatch no run. /help wins when both appear; /reset and /stop win over both.
|
|
310
|
+
if (TOKEN_STATUS.test(masked)) {
|
|
311
|
+
return { mode: "plan", prompt: "", agents: [], reset: false, stop: false, help: false, status: true, forcePush: false, push: false, mr: false, fixConflicts: false, autoCommands: [] };
|
|
312
|
+
}
|
|
313
|
+
let mode = "plan";
|
|
314
|
+
const agents = [];
|
|
315
|
+
const preambleParts = [];
|
|
316
|
+
// Contextual auto-* commands (#58), in textual order. Applied before any run
|
|
317
|
+
// in the same mention is dispatched; a bare command dispatches no run.
|
|
318
|
+
const autoCommands = [];
|
|
319
|
+
let forcePush = false;
|
|
320
|
+
// /push and /mr: global build-output commands, order-independent. They gate
|
|
321
|
+
// the run's host-side push / MR steps (standalone they dispatch a push-only /
|
|
322
|
+
// publish-and-open task; see webhook.ts).
|
|
323
|
+
let push = false;
|
|
324
|
+
let mr = false;
|
|
325
|
+
// /fix-conflicts: standalone manual conflict-fix command (see webhook.ts).
|
|
326
|
+
let fixConflicts = false;
|
|
327
|
+
// /base <branch>: global flag like /build, stripped wherever it appears.
|
|
328
|
+
// Last occurrence wins (duplicate /base in one mention). Validated against
|
|
329
|
+
// BASE_BRANCH_RE; an invalid name sets baseError so webhook.ts can reject
|
|
330
|
+
// the whole mention (Step-0 gate, before dispatch).
|
|
331
|
+
let baseBranch;
|
|
332
|
+
// /branch <name>: global command like /base, stripped wherever it appears.
|
|
333
|
+
// First-write-wins in the store; last occurrence in one mention wins.
|
|
334
|
+
// Validated against BASE_BRANCH_RE; an invalid name sets branchError so
|
|
335
|
+
// webhook.ts can reject the whole mention before dispatch.
|
|
336
|
+
let workBranch;
|
|
337
|
+
// Line-based: /agent <name> may appear anywhere on a line; the segment is
|
|
338
|
+
// whatever remains on that line after stripping the /agent <name> token.
|
|
339
|
+
// /build is a global flag stripped wherever it appears. /base <branch> is
|
|
340
|
+
// likewise a global flag. Any other text on a line (leftover after stripping
|
|
341
|
+
// the flags and the /agent token) is shared preamble prose.
|
|
342
|
+
for (const line of masked.split("\n")) {
|
|
343
|
+
let rest = line;
|
|
344
|
+
// Auto-* contextual commands (#58) are global: strip them wherever they
|
|
345
|
+
// appear and record them in textual order.
|
|
346
|
+
rest = stripAutoCommands(rest, autoCommands);
|
|
347
|
+
// /build is a global flag, order-independent.
|
|
348
|
+
if (TOKEN_BUILD.test(rest)) {
|
|
349
|
+
mode = "build";
|
|
350
|
+
rest = rest.replace(/(?<!\S)\/build(?![\w/])/gi, "");
|
|
351
|
+
}
|
|
352
|
+
// /force-push is a global command, order-independent. Stripped wherever it
|
|
353
|
+
// appears; standalone it dispatches a push-only task, with /build it
|
|
354
|
+
// forces the build's host-side push (see webhook.ts).
|
|
355
|
+
if (TOKEN_FORCE_PUSH.test(rest)) {
|
|
356
|
+
forcePush = true;
|
|
357
|
+
rest = rest.replace(/(?<!\S)\/force-push(?![\w/])/gi, "");
|
|
358
|
+
}
|
|
359
|
+
// /push and /mr are global build-output commands, order-independent. Stripped
|
|
360
|
+
// wherever they appear; /mr implies a push. TOKEN_PUSH cannot false-match
|
|
361
|
+
// /force-push (the word boundary after "push" fails before "-").
|
|
362
|
+
if (TOKEN_PUSH.test(rest)) {
|
|
363
|
+
push = true;
|
|
364
|
+
rest = rest.replace(/(?<!\S)\/push(?![\w/])/gi, "");
|
|
365
|
+
}
|
|
366
|
+
if (TOKEN_MR.test(rest)) {
|
|
367
|
+
mr = true;
|
|
368
|
+
rest = rest.replace(/(?<!\S)\/mr(?![\w/])/gi, "");
|
|
369
|
+
}
|
|
370
|
+
// /fix-conflicts is a global command, order-independent. Stripped wherever
|
|
371
|
+
// it appears; standalone it dispatches the conflict-fix-only task.
|
|
372
|
+
if (TOKEN_FIX_CONFLICTS.test(rest)) {
|
|
373
|
+
fixConflicts = true;
|
|
374
|
+
rest = rest.replace(/(?<!\S)\/fix-conflicts(?![\w/])/gi, "");
|
|
375
|
+
}
|
|
376
|
+
// /base <branch> is a global flag, order-independent. Last wins (a line
|
|
377
|
+
// may carry multiple /base tokens; the final one's branch is kept). The
|
|
378
|
+
// branch name is captured and validated; webhook.ts verifies it exists
|
|
379
|
+
// remotely before dispatch. All /base tokens are stripped from the line
|
|
380
|
+
// so they never reach the prompt. Use a global regex to find every
|
|
381
|
+
// occurrence, keep the last capture.
|
|
382
|
+
const baseMatches = [...rest.matchAll(/(?<!\S)\/base\s+(\S+)/gi)];
|
|
383
|
+
if (baseMatches.length > 0) {
|
|
384
|
+
baseBranch = baseMatches[baseMatches.length - 1][1];
|
|
385
|
+
rest = rest.replace(/(?<!\S)\/base\s+\S+/gi, "");
|
|
386
|
+
}
|
|
387
|
+
// /branch <name> is a global command, order-independent. Last wins. The
|
|
388
|
+
// name is captured and validated; webhook.ts verifies it does not already
|
|
389
|
+
// exist remotely before dispatch. All /branch tokens are stripped so they
|
|
390
|
+
// never reach the prompt.
|
|
391
|
+
const branchMatches = [...rest.matchAll(/(?<!\S)\/branch\s+(\S+)/gi)];
|
|
392
|
+
if (branchMatches.length > 0) {
|
|
393
|
+
workBranch = branchMatches[branchMatches.length - 1][1];
|
|
394
|
+
rest = rest.replace(/(?<!\S)\/branch\s+\S+/gi, "");
|
|
395
|
+
}
|
|
396
|
+
// /agent <name> captures the name; the segment is whatever text remains
|
|
397
|
+
// on the line after stripping the token. Matches both `/agent name prompt`
|
|
398
|
+
// and `prompt /agent name` (segment is the non-agent text either way).
|
|
399
|
+
const agentMatch = TOKEN_AGENT.exec(rest);
|
|
400
|
+
if (agentMatch && agentMatch[1]) {
|
|
401
|
+
const name = normalizeAgentName(agentMatch[1]);
|
|
402
|
+
const segment = unmask(rest
|
|
403
|
+
.replace(TOKEN_AGENT, "")
|
|
404
|
+
.replace(new RegExp(`@${config.BOT_USERNAME}\\b`, "g"), "")
|
|
405
|
+
.trim());
|
|
406
|
+
agents.push({ name, segment });
|
|
407
|
+
continue; // rest of this line is consumed by the /agent call
|
|
408
|
+
}
|
|
409
|
+
// Non-/agent line: whatever remains after stripping flags is preamble.
|
|
410
|
+
const trimmed = rest.trim();
|
|
411
|
+
if (trimmed)
|
|
412
|
+
preambleParts.push(trimmed);
|
|
413
|
+
}
|
|
414
|
+
// Strip any remaining @bot mentions from the preamble prose.
|
|
415
|
+
const preamble = unmask(preambleParts
|
|
416
|
+
.join("\n\n")
|
|
417
|
+
.replace(new RegExp(`@${config.BOT_USERNAME}\\b`, "g"), "")
|
|
418
|
+
.trim());
|
|
419
|
+
// Validate the captured base branch name (if any) against the safe charset.
|
|
420
|
+
// Invalid → set baseError + clear baseBranch so webhook.ts rejects the
|
|
421
|
+
// whole mention before dispatch (Step-0 gate). Empty capture (bare /base
|
|
422
|
+
// with no name) is also invalid — TOKEN_BASE requires \S+ so baseMatch[1]
|
|
423
|
+
// is always non-empty when matched; an undefined baseBranch with no match
|
|
424
|
+
// is the normal no-/base case.
|
|
425
|
+
let baseError;
|
|
426
|
+
if (baseBranch !== undefined && !BASE_BRANCH_RE.test(baseBranch)) {
|
|
427
|
+
baseError = `⚠️ Invalid branch name in /base: \`${baseBranch}\`.`;
|
|
428
|
+
baseBranch = undefined;
|
|
429
|
+
}
|
|
430
|
+
// Validate the captured work branch name against the same shell-safety
|
|
431
|
+
// charset as /base. Invalid → branchError + clear workBranch so webhook.ts
|
|
432
|
+
// rejects the whole mention (Step-0 gate).
|
|
433
|
+
let branchError;
|
|
434
|
+
if (workBranch !== undefined && !BASE_BRANCH_RE.test(workBranch)) {
|
|
435
|
+
branchError = `⚠️ Invalid branch name in /branch: \`${workBranch}\`.`;
|
|
436
|
+
workBranch = undefined;
|
|
437
|
+
}
|
|
438
|
+
// /force-push, /push, and /mr are commands, not modifiers: standalone (no
|
|
439
|
+
// /build) they are dispatched as their own task by webhook.ts. With /build
|
|
440
|
+
// they act as per-run overrides on the build run. No error/reject path here
|
|
441
|
+
// — both forms are valid.
|
|
442
|
+
return {
|
|
443
|
+
mode,
|
|
444
|
+
prompt: preamble,
|
|
445
|
+
agents,
|
|
446
|
+
reset: false,
|
|
447
|
+
stop: false,
|
|
448
|
+
help: false,
|
|
449
|
+
status: false,
|
|
450
|
+
forcePush,
|
|
451
|
+
push,
|
|
452
|
+
mr,
|
|
453
|
+
fixConflicts,
|
|
454
|
+
autoCommands,
|
|
455
|
+
...(baseBranch ? { baseBranch } : {}),
|
|
456
|
+
...(baseError ? { baseError } : {}),
|
|
457
|
+
...(workBranch ? { workBranch } : {}),
|
|
458
|
+
...(branchError ? { branchError } : {}),
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
// Returns the final prompt with one @<name> <segment> block per agent and the
|
|
462
|
+
// shared preamble prepended once, or an error string when the request is
|
|
463
|
+
// invalid and should not dispatch. Reject-whole-mention on first failure: empty
|
|
464
|
+
// segment (bare /agent <name> at EOL) or duplicate name. Unknown-agent
|
|
465
|
+
// validation is deferred to the runner, which knows the synced repo contents
|
|
466
|
+
// (work item #63) — see validateAgentNames.
|
|
467
|
+
export function resolveSubagent(parsed) {
|
|
468
|
+
if (parsed.agents.length === 0)
|
|
469
|
+
return { prompt: parsed.prompt };
|
|
470
|
+
for (const a of parsed.agents) {
|
|
471
|
+
if (a.segment.length === 0) {
|
|
472
|
+
return {
|
|
473
|
+
prompt: "",
|
|
474
|
+
error: `⚠️ No prompt given for \`/agent ${a.name}\`.`,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const seen = new Set();
|
|
479
|
+
for (const a of parsed.agents) {
|
|
480
|
+
if (seen.has(a.name)) {
|
|
481
|
+
return {
|
|
482
|
+
prompt: "",
|
|
483
|
+
error: `⚠️ Duplicate agent: \`${a.name}\`.`,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
seen.add(a.name);
|
|
487
|
+
}
|
|
488
|
+
const blocks = parsed.agents.map((a) => `@${a.name} ${a.segment}`);
|
|
489
|
+
const blocksJoined = blocks.join("\n\n");
|
|
490
|
+
// Empty preamble (e.g. bare /agent lines) → just the @agent blocks.
|
|
491
|
+
// One agent with a preamble → preamble + the single @agent block.
|
|
492
|
+
return {
|
|
493
|
+
prompt: parsed.prompt.length > 0
|
|
494
|
+
? `${parsed.prompt}\n\n${blocksJoined}`
|
|
495
|
+
: blocksJoined,
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
// opencode's built-in subagents, always available regardless of configured
|
|
499
|
+
// repos (work item #63). Used by the post-sync unknown-agent check.
|
|
500
|
+
export const BUILTIN_SUBAGENTS = ["general", "explore", "scout"];
|
|
501
|
+
// Validate every requested /agent name against the agents actually available at
|
|
502
|
+
// run time (built-ins + synced repo agents). Returns an error string naming the
|
|
503
|
+
// first unknown agent, or null when all are known.
|
|
504
|
+
export function validateAgentNames(requested, available) {
|
|
505
|
+
const set = new Set(available);
|
|
506
|
+
for (const name of requested) {
|
|
507
|
+
if (!set.has(name))
|
|
508
|
+
return `⚠️ Unknown agent: \`${name}\`.`;
|
|
509
|
+
}
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
//# sourceMappingURL=mention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention.js","sourceRoot":"","sources":["../src/mention.ts"],"names":[],"mappings":"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"}
|
package/dist/migrate.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { db } from "./db.js";
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
// Minimal versioned migration runner. No framework dependency — works with the
|
|
7
|
+
// shared sync DatabaseSync handle and matches the codebase's lean style. Each
|
|
8
|
+
// migration is a numbered .sql file in migrations/ applied in order inside a
|
|
9
|
+
// transaction; schema_migrations records the applied version. Fail-closed: a
|
|
10
|
+
// half-applied migration aborts boot so a never half-schema serves requests.
|
|
11
|
+
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const MIGRATIONS_DIR = join(MODULE_DIR, "..", "migrations");
|
|
13
|
+
function loadMigrations() {
|
|
14
|
+
let names;
|
|
15
|
+
try {
|
|
16
|
+
names = readdirSync(MIGRATIONS_DIR).filter((n) => n.endsWith(".sql"));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return names
|
|
22
|
+
.map((filename) => {
|
|
23
|
+
const m = /^(\d+)_.+\.sql$/.exec(filename);
|
|
24
|
+
if (!m)
|
|
25
|
+
return null;
|
|
26
|
+
const version = Number(m[1]);
|
|
27
|
+
const sql = readFileSync(join(MIGRATIONS_DIR, filename), "utf8");
|
|
28
|
+
return { version, filename, sql };
|
|
29
|
+
})
|
|
30
|
+
.filter((m) => m !== null)
|
|
31
|
+
.sort((a, b) => a.version - b.version);
|
|
32
|
+
}
|
|
33
|
+
function appliedVersion() {
|
|
34
|
+
db.exec(`
|
|
35
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
36
|
+
version INTEGER PRIMARY KEY,
|
|
37
|
+
applied_at INTEGER NOT NULL
|
|
38
|
+
)
|
|
39
|
+
`);
|
|
40
|
+
const row = db.prepare("SELECT MAX(version) AS v FROM schema_migrations").get();
|
|
41
|
+
return row?.v ?? 0;
|
|
42
|
+
}
|
|
43
|
+
export function migrate() {
|
|
44
|
+
const last = appliedVersion();
|
|
45
|
+
const all = loadMigrations();
|
|
46
|
+
const pending = all.filter((m) => m.version > last);
|
|
47
|
+
if (pending.length === 0) {
|
|
48
|
+
log.debug("migrations up to date", { applied: last });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
log.info("applying migrations", { from: last, to: pending[pending.length - 1].version, count: pending.length });
|
|
52
|
+
for (const m of pending) {
|
|
53
|
+
const t0 = Date.now();
|
|
54
|
+
try {
|
|
55
|
+
db.exec("BEGIN");
|
|
56
|
+
db.exec(m.sql);
|
|
57
|
+
db.prepare("INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)").run(m.version, Math.floor(Date.now() / 1000));
|
|
58
|
+
db.exec("COMMIT");
|
|
59
|
+
log.info("migration applied", { version: m.version, file: m.filename, ms: Date.now() - t0 });
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
db.exec("ROLLBACK");
|
|
63
|
+
log.error("migration failed, aborting boot", { version: m.version, file: m.filename, err: e instanceof Error ? e.message : String(e) });
|
|
64
|
+
throw new Error(`migration ${m.version} (${m.filename}) failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function migrationStatus() {
|
|
69
|
+
const last = appliedVersion();
|
|
70
|
+
const all = loadMigrations();
|
|
71
|
+
return { applied: last, pending: all.filter((m) => m.version > last).length };
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
|