relay-dsh-plugin-events 0.2.1 → 0.2.2

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/lib/client.js CHANGED
@@ -7,8 +7,8 @@ window.__ModuleLoader__.load({
7
7
  let react = require("react");
8
8
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
- //#region \0relay-css-module:/home/runner/work/relay-dsh-plugin-events/relay-dsh-plugin-events/src/client/WaitingEventsSection.module.css.mjs
11
- const css = ".bDRFYa_section{width:100%;max-width:780px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.bDRFYa_toolbar{justify-content:flex-end;align-items:center;gap:8px;min-height:32px;display:flex}.bDRFYa_total,.bDRFYa_counts,.bDRFYa_rowState,.bDRFYa_monitorTimes small,.bDRFYa_message,.bDRFYa_empty{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.bDRFYa_iconButton{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.bDRFYa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.bDRFYa_iconButton:focus-visible,.bDRFYa_sessionButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.bDRFYa_iconButton:disabled{cursor:default;opacity:.4}.bDRFYa_message,.bDRFYa_empty,.bDRFYa_failure p,.bDRFYa_error,.bDRFYa_summary{margin:0}.bDRFYa_empty{text-align:center;padding:48px 8px}.bDRFYa_failure{color:var(--dsw-alias-state-error-primary);align-items:center;gap:10px;font-size:13px;display:flex}.bDRFYa_error{color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}.bDRFYa_registrations,.bDRFYa_waits,.bDRFYa_monitors{margin:0;padding:0;list-style:none}.bDRFYa_registrations{flex-direction:column;gap:10px;display:flex}.bDRFYa_registration{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;overflow:hidden}.bDRFYa_registrationHeader{align-items:center;gap:8px;min-height:48px;padding:8px 10px 8px 14px;display:flex}.bDRFYa_sessionButton{min-width:0;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:4px;padding:3px 0;display:flex}.bDRFYa_title{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:600;line-height:20px;overflow:hidden}.bDRFYa_statusBadge{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, transparent);color:var(--dsw-alias-state-business-primary);border-radius:5px;flex:none;padding:2px 7px;font-size:11px;line-height:16px}.bDRFYa_actions{flex:none;align-items:center;gap:6px;display:flex}.bDRFYa_summary{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);padding:0 14px 6px;font-size:13px;line-height:19px}.bDRFYa_counts{gap:12px;padding:0 14px 10px;display:flex}.bDRFYa_waits,.bDRFYa_monitors{border-top:1px solid var(--dsw-alias-border-l2)}.bDRFYa_waits li,.bDRFYa_monitors li{align-items:center;gap:9px;min-height:40px;padding:8px 10px 8px 14px;display:flex}.bDRFYa_waits li+li,.bDRFYa_monitors li+li{border-top:1px solid var(--dsw-alias-border-l2)}.bDRFYa_waitText{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;line-height:18px}.bDRFYa_stateDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:7px;height:7px}.bDRFYa_stateDot[data-state=active]{background:var(--dsw-alias-state-success-primary)}.bDRFYa_stateDot[data-state=claimed],.bDRFYa_stateDot[data-state=triggered]{background:var(--dsw-alias-state-business-primary)}.bDRFYa_stateDot[data-state=degraded],.bDRFYa_stateDot[data-state=failed]{background:var(--dsw-alias-state-error-primary)}.bDRFYa_monitorMain{flex:1;align-items:center;gap:9px;min-width:0;display:flex}.bDRFYa_monitorTimes{flex-direction:column;min-width:0;font-size:12px;line-height:18px;display:flex}.bDRFYa_monitorTimes small{overflow-wrap:anywhere}@media (width<=620px){.bDRFYa_registrationHeader{flex-wrap:wrap}.bDRFYa_actions{margin-left:auto}.bDRFYa_statusBadge{order:3}}";
10
+ //#region \0relay-css-module:./src/client/WaitingEventsSection.module.css.mjs
11
+ const css = ".bDRFYa_section{width:100%;max-width:780px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.bDRFYa_toolbar{justify-content:flex-end;align-items:center;gap:8px;min-height:32px;display:flex}.bDRFYa_total,.bDRFYa_counts,.bDRFYa_rowState,.bDRFYa_monitorTimes small,.bDRFYa_message,.bDRFYa_empty{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.bDRFYa_iconButton{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.bDRFYa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.bDRFYa_iconButton:focus-visible,.bDRFYa_sessionButton:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.bDRFYa_iconButton:disabled{cursor:default;opacity:.4}.bDRFYa_message,.bDRFYa_empty,.bDRFYa_failure p,.bDRFYa_error,.bDRFYa_summary{margin:0}.bDRFYa_empty{text-align:center;padding:48px 8px}.bDRFYa_failure{color:var(--dsw-alias-state-error-primary);align-items:center;gap:10px;font-size:13px;display:flex}.bDRFYa_error{color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}.bDRFYa_registrations,.bDRFYa_waits,.bDRFYa_monitors,.bDRFYa_events{margin:0;padding:0;list-style:none}.bDRFYa_eventDetails{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);flex-direction:column;gap:4px;margin:8px 0 0;padding:8px 0 0;font-size:12px;list-style:none;display:flex}.bDRFYa_eventDetails li,.bDRFYa_activation{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px;min-width:0;display:flex}.bDRFYa_eventDetails small,.bDRFYa_activation small{overflow-wrap:anywhere;width:100%}.bDRFYa_activation{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);margin-top:8px;padding-top:8px;font-size:12px}.bDRFYa_history{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:8px;padding-top:12px;display:flex}.bDRFYa_historyHeader,.bDRFYa_pagination,.bDRFYa_filters{align-items:center;gap:8px;min-width:0;display:flex}.bDRFYa_historyHeader{justify-content:space-between}.bDRFYa_historyHeader span,.bDRFYa_pagination span,.bDRFYa_filters label{color:var(--dsw-alias-label-secondary);font-size:12px}.bDRFYa_filters{flex-wrap:wrap}.bDRFYa_filters label{flex-direction:column;flex:1;gap:3px;min-width:150px;display:flex}.bDRFYa_filters select,.bDRFYa_filters input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;padding:5px 7px}.bDRFYa_filters select:focus-visible,.bDRFYa_filters input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.bDRFYa_pagination{justify-content:flex-end}.bDRFYa_connectors,.bDRFYa_bundleCatalog{flex-direction:column;gap:8px;display:flex}.bDRFYa_catalogHeader,.bDRFYa_bundleHeader{justify-content:space-between;align-items:center;gap:8px;min-width:0;display:flex}.bDRFYa_catalogHeader h3,.bDRFYa_bundleTypes p{margin:0}.bDRFYa_catalogHeader span,.bDRFYa_emptyCatalog,.bDRFYa_bundleTypes p{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.bDRFYa_bundleTypes{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0;padding:0;list-style:none;display:grid}.bDRFYa_bundleTypes>li{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;min-width:0;padding:10px 12px;overflow:hidden}.bDRFYa_bundlePermissions,.bDRFYa_bundleRemediation{overflow-wrap:anywhere}.bDRFYa_bundleRemediation{color:var(--dsw-alias-label-primary)!important}@media (width<=620px){.bDRFYa_bundleTypes{grid-template-columns:minmax(0,1fr)}}.bDRFYa_connectors h3,.bDRFYa_connectorNote{margin:0}.bDRFYa_connector{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;overflow:hidden}.bDRFYa_connectorHeader,.bDRFYa_secretAction,.bDRFYa_accounts li{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;display:flex}.bDRFYa_connectorHeader{justify-content:space-between}.bDRFYa_details{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 16px;margin:10px 0;display:grid}.bDRFYa_details div{min-width:0}.bDRFYa_details dt,.bDRFYa_details dd,.bDRFYa_connectorNote,.bDRFYa_accounts small{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);margin:0;font-size:11px;line-height:16px}.bDRFYa_details dd{color:var(--dsw-alias-label-secondary)}.bDRFYa_secretAction label{width:100%;color:var(--dsw-alias-label-secondary);font-size:12px}.bDRFYa_secretAction input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:180px;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:6px 8px}.bDRFYa_secretAction input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.bDRFYa_accounts{flex-direction:column;gap:8px;margin:8px 0 0;padding:0;list-style:none;display:flex}.bDRFYa_accounts li>div:first-child{flex-direction:column;flex:1;min-width:180px;display:flex}.bDRFYa_history h3,.bDRFYa_events p,.bDRFYa_emptyHistory{margin:0}.bDRFYa_events{flex-direction:column;gap:8px;display:flex}.bDRFYa_events li{overflow-wrap:anywhere;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px}.bDRFYa_eventHeader{justify-content:space-between;gap:8px;display:flex}.bDRFYa_events p,.bDRFYa_events small,.bDRFYa_emptyHistory{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}.bDRFYa_registrations{flex-direction:column;gap:10px;display:flex}.bDRFYa_registration{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;overflow:hidden}.bDRFYa_registrationHeader{align-items:center;gap:8px;min-height:48px;padding:8px 10px 8px 14px;display:flex}.bDRFYa_sessionButton{min-width:0;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:1;align-items:center;gap:4px;padding:3px 0;display:flex}.bDRFYa_title{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:600;line-height:20px;overflow:hidden}.bDRFYa_statusBadge{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, transparent);color:var(--dsw-alias-label-primary);border-radius:5px;flex:none;padding:2px 7px;font-size:11px;line-height:16px}.bDRFYa_actions{flex:none;align-items:center;gap:6px;display:flex}.bDRFYa_summary{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);padding:0 14px 6px;font-size:13px;line-height:19px}.bDRFYa_counts{gap:12px;padding:0 14px 10px;display:flex}.bDRFYa_timerSummary{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:4px 12px;margin:-4px 0 10px;padding:0 14px;font-size:11px;line-height:16px;display:flex}.bDRFYa_overdue{color:var(--dsw-alias-state-error-primary);font-weight:600}.bDRFYa_waits,.bDRFYa_monitors{border-top:1px solid var(--dsw-alias-border-l2)}.bDRFYa_waits li,.bDRFYa_monitors li{align-items:center;gap:9px;min-height:40px;padding:8px 10px 8px 14px;display:flex}.bDRFYa_waits li+li,.bDRFYa_monitors li+li{border-top:1px solid var(--dsw-alias-border-l2)}.bDRFYa_waitText{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;line-height:18px}.bDRFYa_waitContent{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.bDRFYa_waitContent small{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary);font-size:11px;line-height:16px}.bDRFYa_stateDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:7px;height:7px}.bDRFYa_stateDot[data-state=active]{background:var(--dsw-alias-state-success-primary)}.bDRFYa_stateDot[data-state=paused]{background:var(--dsw-alias-label-tertiary)}.bDRFYa_stateDot[data-state=claimed],.bDRFYa_stateDot[data-state=triggered]{background:var(--dsw-alias-state-business-primary)}.bDRFYa_stateDot[data-state=degraded],.bDRFYa_stateDot[data-state=failed]{background:var(--dsw-alias-state-error-primary)}.bDRFYa_monitorMain{flex:1;align-items:center;gap:9px;min-width:0;display:flex}.bDRFYa_monitorTimes{flex-direction:column;min-width:0;font-size:12px;line-height:18px;display:flex}.bDRFYa_monitorTimes small{overflow-wrap:anywhere}.bDRFYa_cadenceAction{flex:none;align-items:center;gap:6px;display:flex}.bDRFYa_cadenceAction label{color:var(--dsw-alias-label-secondary);font-size:11px}.bDRFYa_cadenceAction input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:74px;min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;padding:5px 7px}.bDRFYa_cadenceAction input:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.bDRFYa_confirmation{min-width:0;color:var(--dsw-alias-label-secondary);flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:6px;font-size:11px;display:flex}@media (width<=620px){.bDRFYa_registrationHeader{flex-wrap:wrap}.bDRFYa_actions{margin-left:auto}.bDRFYa_statusBadge{order:3}.bDRFYa_monitors li{flex-wrap:wrap}.bDRFYa_monitorMain{flex-basis:100%;width:100%}.bDRFYa_cadenceAction{flex-wrap:wrap;width:100%}.bDRFYa_details{grid-template-columns:1fr}}";
12
12
  const tagId = "relay-dsh-plugin-events/WaitingEventsSection.module.css";
13
13
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
14
14
  const tag = document.createElement("style");
@@ -18,63 +18,142 @@ window.__ModuleLoader__.load({
18
18
  document.head.appendChild(tag);
19
19
  }
20
20
  var WaitingEventsSection_module_css_default = {
21
- "stateDot": "bDRFYa_stateDot",
21
+ "error": "bDRFYa_error",
22
+ "bundlePermissions": "bDRFYa_bundlePermissions",
23
+ "details": "bDRFYa_details",
24
+ "eventHeader": "bDRFYa_eventHeader",
25
+ "pagination": "bDRFYa_pagination",
26
+ "cadenceAction": "bDRFYa_cadenceAction",
27
+ "connectorNote": "bDRFYa_connectorNote",
28
+ "counts": "bDRFYa_counts",
29
+ "registration": "bDRFYa_registration",
30
+ "statusBadge": "bDRFYa_statusBadge",
31
+ "filters": "bDRFYa_filters",
32
+ "emptyHistory": "bDRFYa_emptyHistory",
22
33
  "monitors": "bDRFYa_monitors",
23
- "waits": "bDRFYa_waits",
24
- "message": "bDRFYa_message",
34
+ "connectors": "bDRFYa_connectors",
35
+ "iconButton": "bDRFYa_iconButton",
36
+ "timerSummary": "bDRFYa_timerSummary",
37
+ "waitContent": "bDRFYa_waitContent",
38
+ "emptyCatalog": "bDRFYa_emptyCatalog",
39
+ "bundleRemediation": "bDRFYa_bundleRemediation",
40
+ "actions": "bDRFYa_actions",
41
+ "monitorMain": "bDRFYa_monitorMain",
42
+ "historyHeader": "bDRFYa_historyHeader",
43
+ "rowState": "bDRFYa_rowState",
44
+ "activation": "bDRFYa_activation",
45
+ "connector": "bDRFYa_connector",
46
+ "confirmation": "bDRFYa_confirmation",
25
47
  "summary": "bDRFYa_summary",
26
- "failure": "bDRFYa_failure",
48
+ "registrationHeader": "bDRFYa_registrationHeader",
27
49
  "registrations": "bDRFYa_registrations",
50
+ "section": "bDRFYa_section",
51
+ "secretAction": "bDRFYa_secretAction",
28
52
  "waitText": "bDRFYa_waitText",
29
- "toolbar": "bDRFYa_toolbar",
30
- "counts": "bDRFYa_counts",
53
+ "sessionButton": "bDRFYa_sessionButton",
54
+ "connectorHeader": "bDRFYa_connectorHeader",
55
+ "total": "bDRFYa_total",
31
56
  "monitorTimes": "bDRFYa_monitorTimes",
32
- "rowState": "bDRFYa_rowState",
57
+ "catalogHeader": "bDRFYa_catalogHeader",
58
+ "events": "bDRFYa_events",
59
+ "bundleTypes": "bDRFYa_bundleTypes",
60
+ "bundleHeader": "bDRFYa_bundleHeader",
61
+ "overdue": "bDRFYa_overdue",
62
+ "message": "bDRFYa_message",
33
63
  "title": "bDRFYa_title",
34
- "statusBadge": "bDRFYa_statusBadge",
35
- "actions": "bDRFYa_actions",
36
- "empty": "bDRFYa_empty",
37
- "total": "bDRFYa_total",
38
- "iconButton": "bDRFYa_iconButton",
39
- "sessionButton": "bDRFYa_sessionButton",
40
- "monitorMain": "bDRFYa_monitorMain",
41
- "section": "bDRFYa_section",
42
- "registrationHeader": "bDRFYa_registrationHeader",
43
- "registration": "bDRFYa_registration",
44
- "error": "bDRFYa_error"
64
+ "bundleCatalog": "bDRFYa_bundleCatalog",
65
+ "stateDot": "bDRFYa_stateDot",
66
+ "toolbar": "bDRFYa_toolbar",
67
+ "waits": "bDRFYa_waits",
68
+ "history": "bDRFYa_history",
69
+ "accounts": "bDRFYa_accounts",
70
+ "failure": "bDRFYa_failure",
71
+ "eventDetails": "bDRFYa_eventDetails",
72
+ "empty": "bDRFYa_empty"
45
73
  };
46
74
  //#endregion
47
75
  //#region src/client/WaitingEventsSection.tsx
48
76
  const ACTIVE_WAIT = /* @__PURE__ */ new Set(["active", "claimed"]);
49
77
  const RUNNABLE_MONITOR = /* @__PURE__ */ new Set(["active", "degraded"]);
78
+ const EVENT_PAGE_SIZE = 20;
79
+ const BUNDLE_PAGE_SIZE = 20;
80
+ const BACKGROUND_REFRESH_MS = 5e3;
50
81
  function WaitingEventsSection(props) {
51
- const { list, cancel, runNow, openSession, t, close, useSessions } = props;
52
- if (list === void 0 || cancel === void 0 || runNow === void 0 || openSession === void 0 || t === void 0) return null;
82
+ const { list, cancel, runNow, pauseMonitor, resumeMonitor, updateMonitorCadence, stopMonitor, retryActivation, retryNotification, connectorAction, openSession, t, getLocale, subscribeLocale, close, useSessions } = props;
83
+ if (list === void 0 || cancel === void 0 || runNow === void 0 || pauseMonitor === void 0 || resumeMonitor === void 0 || updateMonitorCadence === void 0 || stopMonitor === void 0 || retryActivation === void 0 || retryNotification === void 0 || connectorAction === void 0 || openSession === void 0 || t === void 0 || getLocale === void 0 || subscribeLocale === void 0) return null;
53
84
  const sessionTitles = useSessions((state) => state.byId);
85
+ const activeLocale = (0, react.useSyncExternalStore)(subscribeLocale, getLocale, getLocale);
54
86
  const [request, setRequest] = (0, react.useState)(0);
55
87
  const [state, setState] = (0, react.useState)({ status: "loading" });
88
+ const [refreshing, setRefreshing] = (0, react.useState)(false);
89
+ const [eventCursors, setEventCursors] = (0, react.useState)([null]);
90
+ const [bundleCursors, setBundleCursors] = (0, react.useState)([null]);
91
+ const [eventStateFilter, setEventStateFilter] = (0, react.useState)("all");
92
+ const [eventSourceFilter, setEventSourceFilter] = (0, react.useState)("");
56
93
  const [pending, setPending] = (0, react.useState)(null);
57
94
  const [confirming, setConfirming] = (0, react.useState)(null);
58
95
  const [operationError, setOperationError] = (0, react.useState)(null);
96
+ const [secretDraft, setSecretDraft] = (0, react.useState)("");
97
+ const [gmailApiDraft, setGmailApiDraft] = (0, react.useState)("");
98
+ const [gmailPushDraft, setGmailPushDraft] = (0, react.useState)("");
99
+ const [routerProviderDraft, setRouterProviderDraft] = (0, react.useState)("");
100
+ const [routerModelDraft, setRouterModelDraft] = (0, react.useState)("");
101
+ const [cadenceDrafts, setCadenceDrafts] = (0, react.useState)({});
102
+ const confirmationReturn = (0, react.useRef)(null);
59
103
  const load = (0, react.useCallback)(() => {
60
- setState({ status: "loading" });
104
+ setRefreshing(true);
61
105
  setRequest((value) => value + 1);
62
106
  }, []);
107
+ const eventCursor = eventCursors[eventCursors.length - 1] ?? null;
108
+ const bundleCursor = bundleCursors[bundleCursors.length - 1] ?? null;
63
109
  (0, react.useEffect)(() => {
64
110
  let current = true;
65
- list().then((snapshot) => {
66
- if (current) setState({
67
- status: "ready",
68
- snapshot
69
- });
111
+ list({
112
+ eventCursor,
113
+ eventLimit: EVENT_PAGE_SIZE,
114
+ bundleCursor,
115
+ bundleLimit: BUNDLE_PAGE_SIZE
116
+ }).then((snapshot) => {
117
+ if (current) {
118
+ setState({
119
+ status: "ready",
120
+ snapshot
121
+ });
122
+ setRefreshing(false);
123
+ }
70
124
  }, () => {
71
- if (current) setState({ status: "error" });
125
+ if (current) {
126
+ setState({ status: "error" });
127
+ setRefreshing(false);
128
+ }
72
129
  });
73
130
  return () => {
74
131
  current = false;
75
132
  };
76
- }, [list, request]);
133
+ }, [
134
+ list,
135
+ request,
136
+ eventCursor,
137
+ bundleCursor,
138
+ activeLocale
139
+ ]);
140
+ (0, react.useEffect)(() => {
141
+ const timer = window.setInterval(() => {
142
+ setRequest((value) => value + 1);
143
+ }, BACKGROUND_REFRESH_MS);
144
+ return () => {
145
+ window.clearInterval(timer);
146
+ };
147
+ }, []);
77
148
  const registrations = (0, react.useMemo)(() => state.status === "ready" ? state.snapshot.registrations : [], [state]);
149
+ const events = (0, react.useMemo)(() => state.status === "ready" ? state.snapshot.events ?? [] : [], [state]);
150
+ const bundleTypes = (0, react.useMemo)(() => state.status === "ready" ? state.snapshot.bundle_types ?? [] : [], [state]);
151
+ const visibleEvents = (0, react.useMemo)(() => events.filter((event) => (eventStateFilter === "all" || event.state === eventStateFilter || event.decision?.disposition === eventStateFilter) && (!eventSourceFilter.trim() || event.source.toLocaleLowerCase().includes(eventSourceFilter.trim().toLocaleLowerCase()))), [
152
+ events,
153
+ eventSourceFilter,
154
+ eventStateFilter
155
+ ]);
156
+ const connectors = (0, react.useMemo)(() => state.status === "ready" ? state.snapshot.connectors ?? [] : [], [state]);
78
157
  const perform = async (key, operation) => {
79
158
  setPending(key);
80
159
  setOperationError(null);
@@ -82,19 +161,78 @@ window.__ModuleLoader__.load({
82
161
  await operation();
83
162
  setConfirming(null);
84
163
  load();
85
- } catch {
86
- setOperationError(t("operationError"));
164
+ } catch (error) {
165
+ setOperationError(operationErrorText(error, t));
87
166
  } finally {
88
167
  setPending(null);
89
168
  }
90
169
  };
91
170
  const open = (sessionId) => {
92
- close();
93
- openSession(sessionId);
171
+ if (sessionTitles[sessionId] === void 0) {
172
+ setOperationError(t("missingSession"));
173
+ return;
174
+ }
175
+ try {
176
+ openSession(sessionId);
177
+ close();
178
+ } catch {
179
+ setOperationError(t("missingSession"));
180
+ }
181
+ };
182
+ const beginConfirmation = (key) => {
183
+ confirmationReturn.current = {
184
+ element: document.activeElement instanceof HTMLElement ? document.activeElement : null,
185
+ key
186
+ };
187
+ setConfirming(key);
94
188
  };
189
+ (0, react.useEffect)(() => {
190
+ if (confirming === null) {
191
+ const target = confirmationReturn.current;
192
+ requestAnimationFrame(() => {
193
+ const fallback = target === null ? null : document.querySelector(`[data-relay-confirmation-trigger="${CSS.escape(target.key)}"]`);
194
+ if (target?.element?.isConnected) target.element.focus();
195
+ else fallback?.focus();
196
+ confirmationReturn.current = null;
197
+ });
198
+ return;
199
+ }
200
+ const findDialog = () => [...document.querySelectorAll("[data-relay-confirmation]")].find((element) => element.dataset.relayConfirmation === confirming);
201
+ requestAnimationFrame(() => {
202
+ findDialog()?.querySelector("button:not(:disabled)")?.focus();
203
+ });
204
+ const onKeyDown = (event) => {
205
+ const dialog = findDialog();
206
+ if (!dialog) return;
207
+ if (event.key === "Escape") {
208
+ event.preventDefault();
209
+ event.stopPropagation();
210
+ setConfirming(null);
211
+ return;
212
+ }
213
+ if (event.key !== "Tab") return;
214
+ const controls = [...dialog.querySelectorAll("button:not(:disabled), input:not(:disabled), select:not(:disabled)")];
215
+ if (controls.length === 0) return;
216
+ const first = controls[0];
217
+ const last = controls[controls.length - 1];
218
+ if (event.shiftKey && document.activeElement === first) {
219
+ event.preventDefault();
220
+ last.focus();
221
+ } else if (!event.shiftKey && document.activeElement === last) {
222
+ event.preventDefault();
223
+ first.focus();
224
+ }
225
+ };
226
+ document.addEventListener("keydown", onKeyDown, true);
227
+ return () => {
228
+ document.removeEventListener("keydown", onKeyDown, true);
229
+ };
230
+ }, [confirming]);
95
231
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
232
+ "data-relay-management-root": true,
96
233
  className: WaitingEventsSection_module_css_default.section,
97
- "aria-busy": state.status === "loading",
234
+ "aria-busy": state.status === "loading" || refreshing,
235
+ "aria-live": "polite",
98
236
  children: [
99
237
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
100
238
  className: WaitingEventsSection_module_css_default.toolbar,
@@ -109,6 +247,7 @@ window.__ModuleLoader__.load({
109
247
  className: WaitingEventsSection_module_css_default.iconButton,
110
248
  type: "button",
111
249
  onClick: load,
250
+ disabled: refreshing,
112
251
  "aria-label": t("refresh"),
113
252
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, {})
114
253
  })
@@ -135,19 +274,469 @@ window.__ModuleLoader__.load({
135
274
  children: t("retry")
136
275
  })]
137
276
  }) : null,
138
- state.status === "ready" && registrations.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
277
+ state.status === "ready" && registrations.length === 0 && bundleTypes.length === 0 && events.length === 0 && connectors.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
139
278
  className: WaitingEventsSection_module_css_default.empty,
140
279
  children: t("empty")
141
280
  }) : null,
281
+ state.status === "ready" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
282
+ className: WaitingEventsSection_module_css_default.bundleCatalog,
283
+ "aria-labelledby": "relay-bundle-catalog-title",
284
+ "data-relay-bundle-catalog": true,
285
+ children: [
286
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
287
+ className: WaitingEventsSection_module_css_default.catalogHeader,
288
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
289
+ id: "relay-bundle-catalog-title",
290
+ children: t("bundleCatalog")
291
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("bundleTypeCount", { count: state.snapshot.bundle_page.total }) })]
292
+ }),
293
+ bundleTypes.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
294
+ className: WaitingEventsSection_module_css_default.emptyCatalog,
295
+ children: t("noBundleTypes")
296
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
297
+ className: WaitingEventsSection_module_css_default.bundleTypes,
298
+ children: bundleTypes.map((bundle, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
299
+ "data-relay-bundle-type": bundle.type_id,
300
+ "data-relay-bundle-status": bundle.status,
301
+ children: [
302
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
303
+ className: WaitingEventsSection_module_css_default.bundleHeader,
304
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: bundle.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
305
+ className: WaitingEventsSection_module_css_default.statusBadge,
306
+ children: statusText(bundle.status, t)
307
+ })]
308
+ }),
309
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: bundle.description }),
310
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
311
+ className: WaitingEventsSection_module_css_default.details,
312
+ children: [
313
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleIdentity") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dd", { children: [
314
+ bundle.type_id,
315
+ "@",
316
+ bundle.bundle_version
317
+ ] })] }),
318
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleOrigin") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: bundle.origin.kind === "plugin" ? t("pluginOrigin", { name: bundle.origin.plugin_id ?? t("unavailable") }) : t("agentOrigin") })] }),
319
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleEvents") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: bundle.event_types.join(", ") })] }),
320
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleCapabilities") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: bundle.capabilities.length > 0 ? bundle.capabilities.join(", ") : t("none") })] }),
321
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleLifecycle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: bundle.lifecycle.join(", ") })] }),
322
+ bundle.scope ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleScope") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: bundle.scope })] }) : null,
323
+ bundle.artifact_hash ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("artifactHash") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", {
324
+ title: bundle.artifact_hash,
325
+ children: shortId(bundle.artifact_hash)
326
+ })] }) : null,
327
+ bundle.expiry ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("bundleExpiry") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: formatTime(bundle.expiry, activeLocale) })] }) : null,
328
+ bundle.validation_state ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("validationState") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: statusText(bundle.validation_state, t) })] }) : null
329
+ ]
330
+ }),
331
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
332
+ className: WaitingEventsSection_module_css_default.bundlePermissions,
333
+ children: [
334
+ t("bundlePermissions"),
335
+ ": ",
336
+ bundle.permissions
337
+ ]
338
+ }),
339
+ bundle.status === "available" ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
340
+ className: WaitingEventsSection_module_css_default.bundleRemediation,
341
+ children: [
342
+ t("bundleRemediation"),
343
+ ": ",
344
+ bundle.remediation
345
+ ]
346
+ })
347
+ ]
348
+ }, `${bundle.type_id}@${bundle.bundle_version}:${bundle.artifact_hash ?? bundle.origin.plugin_id ?? index}`))
349
+ }),
350
+ bundleTypes.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
351
+ className: WaitingEventsSection_module_css_default.pagination,
352
+ "aria-label": t("bundlePagination"),
353
+ children: [
354
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
355
+ size: "sm",
356
+ variant: "outline",
357
+ disabled: refreshing || bundleCursors.length === 1,
358
+ onClick: () => {
359
+ setRefreshing(true);
360
+ setBundleCursors((current) => current.slice(0, -1));
361
+ },
362
+ children: t("previousPage")
363
+ }),
364
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("pageNumber", { count: bundleCursors.length }) }),
365
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
366
+ size: "sm",
367
+ variant: "outline",
368
+ disabled: refreshing || state.snapshot.bundle_page.next_cursor === null,
369
+ onClick: () => {
370
+ const next = state.snapshot.bundle_page.next_cursor;
371
+ if (next) {
372
+ setRefreshing(true);
373
+ setBundleCursors((current) => [...current, next]);
374
+ }
375
+ },
376
+ children: t("nextPage")
377
+ })
378
+ ]
379
+ }) : null
380
+ ]
381
+ }) : null,
382
+ connectors.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
383
+ className: WaitingEventsSection_module_css_default.connectors,
384
+ "aria-labelledby": "relay-connectors-title",
385
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
386
+ id: "relay-connectors-title",
387
+ children: t("connectors")
388
+ }), connectors.map((connector) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
389
+ className: WaitingEventsSection_module_css_default.connector,
390
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
391
+ className: WaitingEventsSection_module_css_default.connectorHeader,
392
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: connector.kind === "github" ? "GitHub" : connector.kind === "email" ? t("email") : connector.kind === "router" ? t("semanticRouter") : connector.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
393
+ className: WaitingEventsSection_module_css_default.statusBadge,
394
+ children: statusText(connector.state, t)
395
+ })]
396
+ }), connector.kind === "router" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
397
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
398
+ className: WaitingEventsSection_module_css_default.connectorNote,
399
+ children: connector.state === "unconfigured" ? t("routerFallbackWarning") : t("routerActive")
400
+ }),
401
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
402
+ className: WaitingEventsSection_module_css_default.details,
403
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("routerProvider") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.provider || t("notConfigured") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("routerModel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.model || t("notConfigured") })] })]
404
+ }),
405
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
406
+ className: WaitingEventsSection_module_css_default.secretAction,
407
+ children: [
408
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
409
+ htmlFor: `router-provider-${connector.id}`,
410
+ children: t("routerProvider")
411
+ }),
412
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
413
+ id: `router-provider-${connector.id}`,
414
+ value: routerProviderDraft,
415
+ placeholder: connector.provider || void 0,
416
+ maxLength: 256,
417
+ disabled: connector.configuration_writable === false,
418
+ onChange: (event) => {
419
+ setRouterProviderDraft(event.currentTarget.value);
420
+ }
421
+ }),
422
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
423
+ htmlFor: `router-model-${connector.id}`,
424
+ children: t("routerModel")
425
+ }),
426
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
427
+ id: `router-model-${connector.id}`,
428
+ value: routerModelDraft,
429
+ placeholder: connector.model || void 0,
430
+ maxLength: 512,
431
+ disabled: connector.configuration_writable === false,
432
+ onChange: (event) => {
433
+ setRouterModelDraft(event.currentTarget.value);
434
+ }
435
+ }),
436
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
437
+ size: "sm",
438
+ variant: "outline",
439
+ disabled: pending !== null || connector.configuration_writable === false || !routerProviderDraft.trim() || !routerModelDraft.trim(),
440
+ onClick: () => {
441
+ perform(`connector:${connector.id}:configure`, async () => {
442
+ await connectorAction(connector.id, "configure", {
443
+ provider: routerProviderDraft,
444
+ model: routerModelDraft
445
+ });
446
+ setRouterProviderDraft("");
447
+ setRouterModelDraft("");
448
+ });
449
+ },
450
+ children: connector.state === "unconfigured" ? t("configure") : t("update")
451
+ }),
452
+ connector.configuration_writable === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("routerReadOnly") }) : null,
453
+ connector.state !== "unconfigured" && connector.configuration_writable !== false ? confirming === `connector:${connector.id}:disable` ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
454
+ className: WaitingEventsSection_module_css_default.confirmation,
455
+ role: "alertdialog",
456
+ "aria-modal": "true",
457
+ "data-relay-confirmation": `connector:${connector.id}:disable`,
458
+ "aria-label": t("disableRouterConfirm"),
459
+ children: [
460
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("disableRouterConfirm") }),
461
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
462
+ size: "sm",
463
+ variant: "outline",
464
+ onClick: () => {
465
+ setConfirming(null);
466
+ },
467
+ children: t("keep")
468
+ }),
469
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
470
+ size: "sm",
471
+ variant: "primary",
472
+ onClick: () => {
473
+ perform(`connector:${connector.id}:disable`, () => connectorAction(connector.id, "disable"));
474
+ },
475
+ children: t("confirmDisable")
476
+ })
477
+ ]
478
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
479
+ size: "sm",
480
+ variant: "outline",
481
+ "data-relay-confirmation-trigger": `connector:${connector.id}:disable`,
482
+ onClick: () => {
483
+ beginConfirmation(`connector:${connector.id}:disable`);
484
+ },
485
+ children: t("disable")
486
+ }) : null
487
+ ]
488
+ })
489
+ ] }) : connector.kind === "github" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
490
+ className: WaitingEventsSection_module_css_default.details,
491
+ children: [
492
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("webhookPath") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.webhook_path ?? t("unavailable") })] }),
493
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("webhookSecret") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.secret_count ? t("configured") : t("notConfigured") })] }),
494
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("apiPolling") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.api_polling ? t("configured") : t("notConfigured") })] }),
495
+ connector.last_success_at ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("lastSuccess") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: formatTime(connector.last_success_at, activeLocale) })] }) : null,
496
+ connector.last_error_class ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("lastError") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.last_error_class })] }) : null
497
+ ]
498
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
499
+ className: WaitingEventsSection_module_css_default.secretAction,
500
+ children: [
501
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
502
+ htmlFor: `secret-${connector.id}`,
503
+ children: connector.secret_count ? t("newWebhookSecret") : t("webhookSecret")
504
+ }),
505
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
506
+ id: `secret-${connector.id}`,
507
+ type: "password",
508
+ autoComplete: "new-password",
509
+ value: secretDraft,
510
+ disabled: connector.secret_writable === false,
511
+ onChange: (event) => {
512
+ setSecretDraft(event.currentTarget.value);
513
+ }
514
+ }),
515
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
516
+ size: "sm",
517
+ variant: "outline",
518
+ disabled: pending !== null || secretDraft.length < 16 || connector.secret_writable === false,
519
+ onClick: () => {
520
+ perform(`connector:${connector.id}:rotate`, async () => {
521
+ await connectorAction(connector.id, "rotate_secret", { secret: secretDraft });
522
+ setSecretDraft("");
523
+ });
524
+ },
525
+ children: connector.secret_count ? t("rotate") : t("configure")
526
+ }),
527
+ connector.secret_writable === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("readOnlyCredential") }) : null,
528
+ connector.secret_count && connector.secret_writable !== false ? confirming === `connector:${connector.id}:revoke` ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
529
+ className: WaitingEventsSection_module_css_default.confirmation,
530
+ role: "alertdialog",
531
+ "aria-modal": "true",
532
+ "data-relay-confirmation": `connector:${connector.id}:revoke`,
533
+ "aria-label": t("revokeGitHubConfirm"),
534
+ children: [
535
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("revokeGitHubConfirm") }),
536
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
537
+ size: "sm",
538
+ variant: "outline",
539
+ onClick: () => {
540
+ setConfirming(null);
541
+ },
542
+ children: t("keep")
543
+ }),
544
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
545
+ size: "sm",
546
+ variant: "primary",
547
+ onClick: () => {
548
+ perform(`connector:${connector.id}:revoke`, () => connectorAction(connector.id, "revoke_secret"));
549
+ },
550
+ children: t("confirmRevoke")
551
+ })
552
+ ]
553
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
554
+ size: "sm",
555
+ variant: "outline",
556
+ "data-relay-confirmation-trigger": `connector:${connector.id}:revoke`,
557
+ onClick: () => {
558
+ beginConfirmation(`connector:${connector.id}:revoke`);
559
+ },
560
+ children: t("revoke")
561
+ }) : null
562
+ ]
563
+ })] }) : connector.kind === "email" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
564
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
565
+ className: WaitingEventsSection_module_css_default.connectorNote,
566
+ children: [
567
+ connector.push_configured ? t("pushConfigured") : t("pushNotConfigured"),
568
+ " · ",
569
+ t("emailPrivacy")
570
+ ]
571
+ }),
572
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
573
+ className: WaitingEventsSection_module_css_default.details,
574
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("gmailApiToken") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.api_configured ? t("configured") : t("notConfigured") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("gmailPushToken") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: connector.push_configured ? t("configured") : t("notConfigured") })] })]
575
+ }),
576
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
577
+ className: WaitingEventsSection_module_css_default.secretAction,
578
+ children: [
579
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
580
+ htmlFor: `gmail-api-${connector.id}`,
581
+ children: t("gmailApiToken")
582
+ }),
583
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
584
+ id: `gmail-api-${connector.id}`,
585
+ type: "password",
586
+ autoComplete: "new-password",
587
+ value: gmailApiDraft,
588
+ disabled: connector.credentials_writable === false,
589
+ onChange: (event) => {
590
+ setGmailApiDraft(event.currentTarget.value);
591
+ }
592
+ }),
593
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
594
+ htmlFor: `gmail-push-${connector.id}`,
595
+ children: t("gmailPushToken")
596
+ }),
597
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
598
+ id: `gmail-push-${connector.id}`,
599
+ type: "password",
600
+ autoComplete: "new-password",
601
+ value: gmailPushDraft,
602
+ disabled: connector.credentials_writable === false,
603
+ onChange: (event) => {
604
+ setGmailPushDraft(event.currentTarget.value);
605
+ }
606
+ }),
607
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
608
+ size: "sm",
609
+ variant: "outline",
610
+ disabled: pending !== null || connector.credentials_writable === false || gmailApiDraft.length < 16 || gmailPushDraft.length < 16,
611
+ onClick: () => {
612
+ perform(`connector:${connector.id}:configure`, async () => {
613
+ await connectorAction(connector.id, "configure_credentials", {
614
+ api_token: gmailApiDraft,
615
+ push_token: gmailPushDraft
616
+ });
617
+ setGmailApiDraft("");
618
+ setGmailPushDraft("");
619
+ });
620
+ },
621
+ children: connector.api_configured || connector.push_configured ? t("rotate") : t("configure")
622
+ }),
623
+ connector.credentials_writable === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("readOnlyCredential") }) : null,
624
+ (connector.api_configured || connector.push_configured) && connector.credentials_writable !== false ? confirming === `connector:${connector.id}:revoke` ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
625
+ className: WaitingEventsSection_module_css_default.confirmation,
626
+ role: "alertdialog",
627
+ "aria-modal": "true",
628
+ "data-relay-confirmation": `connector:${connector.id}:revoke`,
629
+ "aria-label": t("revokeGmailConfirm"),
630
+ children: [
631
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("revokeGmailConfirm") }),
632
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
633
+ size: "sm",
634
+ variant: "outline",
635
+ onClick: () => {
636
+ setConfirming(null);
637
+ },
638
+ children: t("keep")
639
+ }),
640
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
641
+ size: "sm",
642
+ variant: "primary",
643
+ onClick: () => {
644
+ perform(`connector:${connector.id}:revoke`, () => connectorAction(connector.id, "revoke_credentials"));
645
+ },
646
+ children: t("confirmRevoke")
647
+ })
648
+ ]
649
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
650
+ size: "sm",
651
+ variant: "outline",
652
+ "data-relay-confirmation-trigger": `connector:${connector.id}:revoke`,
653
+ onClick: () => {
654
+ beginConfirmation(`connector:${connector.id}:revoke`);
655
+ },
656
+ children: t("revoke")
657
+ }) : null
658
+ ]
659
+ }),
660
+ (connector.accounts?.length ?? 0) === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
661
+ className: WaitingEventsSection_module_css_default.emptyHistory,
662
+ children: t("noMailboxes")
663
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
664
+ className: WaitingEventsSection_module_css_default.accounts,
665
+ children: connector.accounts?.map((account) => {
666
+ const key = `connector:${connector.id}:disconnect:${account.account}`;
667
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
668
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: account.account }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
669
+ statusText(account.status, t),
670
+ " · ",
671
+ formatTime(account.updated_at, activeLocale),
672
+ account.last_error_class ? ` · ${account.last_error_class}` : ""
673
+ ] })] }),
674
+ account.status === "paused" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
675
+ size: "sm",
676
+ variant: "outline",
677
+ onClick: () => {
678
+ perform(`${key}:resume`, () => connectorAction(connector.id, "resume", { account: account.account }));
679
+ },
680
+ children: t("resume")
681
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
682
+ size: "sm",
683
+ variant: "outline",
684
+ onClick: () => {
685
+ perform(`${key}:pause`, () => connectorAction(connector.id, "pause", { account: account.account }));
686
+ },
687
+ children: t("pause")
688
+ }),
689
+ confirming === key ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
690
+ className: WaitingEventsSection_module_css_default.confirmation,
691
+ role: "alertdialog",
692
+ "aria-modal": "true",
693
+ "data-relay-confirmation": key,
694
+ "aria-label": t("disconnectMailboxConfirm", { account: account.account }),
695
+ children: [
696
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("disconnectMailboxConfirm", { account: account.account }) }),
697
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
698
+ size: "sm",
699
+ variant: "outline",
700
+ onClick: () => {
701
+ setConfirming(null);
702
+ },
703
+ children: t("keep")
704
+ }),
705
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
706
+ size: "sm",
707
+ variant: "primary",
708
+ onClick: () => {
709
+ perform(key, () => connectorAction(connector.id, "disconnect", { account: account.account }));
710
+ },
711
+ children: t("confirmDisconnect")
712
+ })
713
+ ]
714
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
715
+ size: "sm",
716
+ variant: "outline",
717
+ "data-relay-confirmation-trigger": key,
718
+ onClick: () => {
719
+ beginConfirmation(key);
720
+ },
721
+ children: t("disconnect")
722
+ })
723
+ ] }, account.account);
724
+ })
725
+ })
726
+ ] }) : null]
727
+ }, connector.id))]
728
+ }) : null,
142
729
  registrations.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
143
730
  className: WaitingEventsSection_module_css_default.registrations,
144
731
  children: registrations.map((registration) => {
145
732
  const liveWaits = registration.waits.filter((wait) => ACTIVE_WAIT.has(wait.status));
146
733
  const liveMonitors = registration.monitors.filter((monitor) => [
147
734
  "active",
735
+ "paused",
148
736
  "degraded",
149
737
  "triggered"
150
738
  ].includes(monitor.state));
739
+ const isLive = liveWaits.length > 0 || liveMonitors.length > 0;
151
740
  const title = sessionTitles[registration.session_id]?.displayTitle ?? registration.task_summary;
152
741
  const cancelKey = `cancel:${registration.session_id}`;
153
742
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
@@ -169,27 +758,38 @@ window.__ModuleLoader__.load({
169
758
  }),
170
759
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
171
760
  className: WaitingEventsSection_module_css_default.statusBadge,
172
- children: t("waiting")
761
+ children: t(isLive ? "waiting" : "history")
173
762
  }),
174
763
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
175
764
  className: WaitingEventsSection_module_css_default.actions,
176
- children: confirming === registration.session_id ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
177
- size: "sm",
178
- variant: "outline",
179
- disabled: pending !== null,
180
- onClick: () => {
181
- setConfirming(null);
182
- },
183
- children: t("keep")
184
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
185
- size: "sm",
186
- variant: "primary",
187
- disabled: pending !== null,
188
- onClick: () => {
189
- perform(cancelKey, () => cancel(registration.session_id));
190
- },
191
- children: t("confirmCancel")
192
- })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
765
+ children: !isLive ? null : confirming === registration.session_id ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
766
+ className: WaitingEventsSection_module_css_default.confirmation,
767
+ role: "alertdialog",
768
+ "aria-modal": "true",
769
+ "data-relay-confirmation": registration.session_id,
770
+ "aria-label": t("cancelTarget", { target: title }),
771
+ children: [
772
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("cancelTarget", { target: title }) }),
773
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
774
+ size: "sm",
775
+ variant: "outline",
776
+ disabled: pending !== null,
777
+ onClick: () => {
778
+ setConfirming(null);
779
+ },
780
+ children: t("keep")
781
+ }),
782
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
783
+ size: "sm",
784
+ variant: "primary",
785
+ disabled: pending !== null,
786
+ onClick: () => {
787
+ perform(cancelKey, () => cancel(registration.session_id));
788
+ },
789
+ children: t("confirmCancel")
790
+ })
791
+ ]
792
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
193
793
  label: t("cancel"),
194
794
  side: "bottom",
195
795
  delayMs: 400,
@@ -198,8 +798,9 @@ window.__ModuleLoader__.load({
198
798
  type: "button",
199
799
  disabled: pending !== null,
200
800
  "aria-label": t("cancel"),
801
+ "data-relay-confirmation-trigger": registration.session_id,
201
802
  onClick: () => {
202
- setConfirming(registration.session_id);
803
+ beginConfirmation(registration.session_id);
203
804
  },
204
805
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {})
205
806
  })
@@ -215,16 +816,52 @@ window.__ModuleLoader__.load({
215
816
  className: WaitingEventsSection_module_css_default.counts,
216
817
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("waitCount", { count: liveWaits.length }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("monitorCount", { count: liveMonitors.length }) })]
217
818
  }),
218
- liveWaits.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
819
+ registration.context?.deadline ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
820
+ className: WaitingEventsSection_module_css_default.timerSummary,
821
+ children: [
822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
823
+ t("deadline"),
824
+ ": ",
825
+ formatDeadline(registration.context.deadline, activeLocale)
826
+ ] }),
827
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
828
+ t("timezone"),
829
+ ": ",
830
+ Intl.DateTimeFormat().resolvedOptions().timeZone
831
+ ] }),
832
+ registration.context.deadline_intent?.kind === "relative" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("afterSeconds", { count: registration.context.deadline_intent.after_seconds ?? 0 }) }) : null,
833
+ Date.parse(registration.context.deadline) <= Date.now() ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
834
+ className: WaitingEventsSection_module_css_default.overdue,
835
+ children: t("overdue")
836
+ }) : null
837
+ ]
838
+ }) : null,
839
+ registration.waits.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
219
840
  className: WaitingEventsSection_module_css_default.waits,
220
- children: liveWaits.map((wait) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
841
+ children: registration.waits.map((wait) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
221
842
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
222
843
  className: WaitingEventsSection_module_css_default.stateDot,
223
844
  "data-state": wait.status
224
845
  }),
225
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
226
- className: WaitingEventsSection_module_css_default.waitText,
227
- children: wait.expected_event ?? wait.wait_id
846
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
847
+ className: WaitingEventsSection_module_css_default.waitContent,
848
+ children: [
849
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
850
+ className: WaitingEventsSection_module_css_default.waitText,
851
+ children: wait.expected_event ?? wait.wait_id
852
+ }),
853
+ wait.continuation?.next_action ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
854
+ t("nextAction"),
855
+ ": ",
856
+ wait.continuation.next_action
857
+ ] }) : null,
858
+ wait.continuation?.success_condition ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
859
+ t("successCondition"),
860
+ ": ",
861
+ wait.continuation.success_condition
862
+ ] }) : null,
863
+ (wait.continuation?.artifacts?.length ?? 0) > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("artifactCount", { count: wait.continuation?.artifacts?.length ?? 0 }) }) : null
864
+ ]
228
865
  }),
229
866
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
230
867
  className: WaitingEventsSection_module_css_default.rowState,
@@ -232,41 +869,379 @@ window.__ModuleLoader__.load({
232
869
  })
233
870
  ] }, wait.wait_id))
234
871
  }) : null,
235
- liveMonitors.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
872
+ registration.monitors.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
236
873
  className: WaitingEventsSection_module_css_default.monitors,
237
- children: liveMonitors.map((monitor) => {
874
+ children: registration.monitors.map((monitor) => {
238
875
  const runKey = `run:${monitor.monitor_id}`;
876
+ const pauseKey = `pause:${monitor.monitor_id}`;
877
+ const resumeKey = `resume:${monitor.monitor_id}`;
878
+ const stopKey = `stop:${monitor.monitor_id}`;
879
+ const cadenceKey = `cadence:${monitor.monitor_id}`;
880
+ const monitorConfirmation = `monitor:${monitor.monitor_id}`;
239
881
  const runnable = RUNNABLE_MONITOR.has(monitor.state);
240
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
241
- className: WaitingEventsSection_module_css_default.monitorMain,
242
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
243
- className: WaitingEventsSection_module_css_default.stateDot,
244
- "data-state": monitor.state
245
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
246
- className: WaitingEventsSection_module_css_default.monitorTimes,
247
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: statusText(monitor.state, t) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [monitor.next_check_at === null ? t("noSchedule") : `${t("nextCheck")} ${formatTime(monitor.next_check_at)}`, monitor.last_observation?.observed_at === void 0 ? "" : ` · ${t("lastCheck")} ${formatTime(monitor.last_observation.observed_at)}`] })]
248
- })]
249
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
250
- label: t("runNow"),
251
- side: "bottom",
252
- delayMs: 400,
253
- disabled: !runnable,
254
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
255
- className: WaitingEventsSection_module_css_default.iconButton,
256
- type: "button",
257
- disabled: !runnable || pending !== null,
258
- "aria-label": t("runNow"),
882
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
883
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
884
+ className: WaitingEventsSection_module_css_default.monitorMain,
885
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
886
+ className: WaitingEventsSection_module_css_default.stateDot,
887
+ "data-state": monitor.state
888
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
889
+ className: WaitingEventsSection_module_css_default.monitorTimes,
890
+ children: [
891
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: statusText(monitor.state, t) }),
892
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [monitor.next_check_at === null ? t("noSchedule") : `${t("nextCheck")} ${formatTime(monitor.next_check_at, activeLocale)}`, monitor.last_observation?.observed_at === void 0 ? "" : ` · ${t("lastCheck")} ${formatTime(monitor.last_observation.observed_at, activeLocale)}`] }),
893
+ monitorTarget(monitor) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
894
+ t("monitorTarget"),
895
+ ": ",
896
+ monitorTarget(monitor)
897
+ ] }) : null,
898
+ monitorObservationSummary(monitor, t) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: monitorObservationSummary(monitor, t) }) : null,
899
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
900
+ t("cadence"),
901
+ ": ",
902
+ t("secondsValue", { count: monitor.schedule?.interval_seconds ?? 0 }),
903
+ " · ",
904
+ t("failureCount", { count: monitor.consecutive_failures ?? 0 }),
905
+ monitor.last_check?.error_class ? ` · ${t("lastError")}: ${monitor.last_check.error_class}` : ""
906
+ ] }),
907
+ monitor.last_trigger?.created_at ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
908
+ t("lastTransition"),
909
+ ": ",
910
+ formatTime(monitor.last_trigger.created_at, activeLocale)
911
+ ] }) : null,
912
+ monitor.terminal_reason ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
913
+ t("terminalReason"),
914
+ ": ",
915
+ reasonText(monitor.terminal_reason.code, t),
916
+ monitor.terminal_reason.at ? ` · ${formatTime(monitor.terminal_reason.at, activeLocale)}` : ""
917
+ ] }) : null
918
+ ]
919
+ })]
920
+ }),
921
+ [
922
+ "active",
923
+ "paused",
924
+ "degraded"
925
+ ].includes(monitor.state) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
926
+ className: WaitingEventsSection_module_css_default.cadenceAction,
927
+ children: [
928
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
929
+ htmlFor: `relay-monitor-cadence-${monitor.monitor_id}`,
930
+ children: t("cadenceSeconds")
931
+ }),
932
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
933
+ id: `relay-monitor-cadence-${monitor.monitor_id}`,
934
+ type: "number",
935
+ min: 1,
936
+ max: 86400,
937
+ step: 1,
938
+ value: cadenceDrafts[monitor.monitor_id] ?? String(monitor.schedule?.interval_seconds ?? ""),
939
+ disabled: pending !== null,
940
+ onChange: (event) => {
941
+ const value = event.currentTarget.value;
942
+ setCadenceDrafts((current) => ({
943
+ ...current,
944
+ [monitor.monitor_id]: value
945
+ }));
946
+ }
947
+ }),
948
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
949
+ size: "sm",
950
+ variant: "outline",
951
+ disabled: pending !== null,
952
+ onClick: () => {
953
+ perform(cadenceKey, async () => {
954
+ const input = document.getElementById(`relay-monitor-cadence-${monitor.monitor_id}`);
955
+ const intervalSeconds = Number(input instanceof HTMLInputElement ? input.value : void 0);
956
+ if (!Number.isSafeInteger(intervalSeconds) || intervalSeconds < 1 || intervalSeconds > 86400) throw new Error("invalid cadence");
957
+ await updateMonitorCadence(monitor.monitor_id, intervalSeconds, monitor.version);
958
+ setCadenceDrafts((current) => Object.fromEntries(Object.entries(current).filter(([monitorId]) => monitorId !== monitor.monitor_id)));
959
+ });
960
+ },
961
+ children: t("update")
962
+ })
963
+ ]
964
+ }) : null,
965
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
966
+ label: t("runNow"),
967
+ side: "bottom",
968
+ delayMs: 400,
969
+ disabled: !runnable,
970
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
971
+ className: WaitingEventsSection_module_css_default.iconButton,
972
+ type: "button",
973
+ "data-relay-monitor-action": "run",
974
+ disabled: !runnable || pending !== null,
975
+ "aria-label": t("runNow"),
976
+ onClick: () => {
977
+ perform(runKey, () => runNow(monitor.monitor_id));
978
+ },
979
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, {})
980
+ })
981
+ }),
982
+ monitor.state === "paused" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
983
+ size: "sm",
984
+ variant: "outline",
985
+ "data-relay-monitor-action": "resume",
986
+ disabled: pending !== null,
987
+ onClick: () => {
988
+ perform(resumeKey, () => resumeMonitor(monitor.monitor_id, monitor.version));
989
+ },
990
+ children: t("resume")
991
+ }) : RUNNABLE_MONITOR.has(monitor.state) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
992
+ size: "sm",
993
+ variant: "outline",
994
+ "data-relay-monitor-action": "pause",
995
+ disabled: pending !== null,
259
996
  onClick: () => {
260
- perform(runKey, () => runNow(monitor.monitor_id));
997
+ perform(pauseKey, () => pauseMonitor(monitor.monitor_id, monitor.version));
261
998
  },
262
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, {})
999
+ children: t("pause")
1000
+ }) : null,
1001
+ ![
1002
+ "active",
1003
+ "paused",
1004
+ "degraded",
1005
+ "triggered"
1006
+ ].includes(monitor.state) ? null : confirming === monitorConfirmation ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1007
+ className: WaitingEventsSection_module_css_default.confirmation,
1008
+ role: "alertdialog",
1009
+ "aria-modal": "true",
1010
+ "data-relay-confirmation": monitorConfirmation,
1011
+ "aria-label": t("stopTarget", { target: shortId(monitor.monitor_id) }),
1012
+ children: [
1013
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("stopTarget", { target: shortId(monitor.monitor_id) }) }),
1014
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1015
+ size: "sm",
1016
+ variant: "outline",
1017
+ disabled: pending !== null,
1018
+ onClick: () => {
1019
+ setConfirming(null);
1020
+ },
1021
+ children: t("keep")
1022
+ }),
1023
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1024
+ size: "sm",
1025
+ variant: "primary",
1026
+ disabled: pending !== null,
1027
+ onClick: () => {
1028
+ perform(stopKey, () => stopMonitor(monitor.monitor_id, monitor.version));
1029
+ },
1030
+ children: t("confirmStop")
1031
+ })
1032
+ ]
1033
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1034
+ size: "sm",
1035
+ variant: "outline",
1036
+ "data-relay-monitor-action": "stop",
1037
+ disabled: pending !== null,
1038
+ "data-relay-confirmation-trigger": monitorConfirmation,
1039
+ onClick: () => {
1040
+ beginConfirmation(monitorConfirmation);
1041
+ },
1042
+ children: t("stop")
263
1043
  })
264
- })] }, monitor.monitor_id);
1044
+ ] }, monitor.monitor_id);
265
1045
  })
266
1046
  }) : null
267
1047
  ]
268
1048
  }, registration.session_id);
269
1049
  })
1050
+ }) : null,
1051
+ state.status === "ready" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1052
+ className: WaitingEventsSection_module_css_default.history,
1053
+ "aria-labelledby": "relay-event-history-title",
1054
+ children: [
1055
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1056
+ className: WaitingEventsSection_module_css_default.historyHeader,
1057
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
1058
+ id: "relay-event-history-title",
1059
+ children: t("eventHistory")
1060
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1061
+ "data-relay-event-total": state.snapshot.event_page.total,
1062
+ children: t("eventTotal", { count: state.snapshot.event_page.total })
1063
+ })]
1064
+ }),
1065
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1066
+ className: WaitingEventsSection_module_css_default.filters,
1067
+ "aria-label": t("eventFilters"),
1068
+ children: [
1069
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1070
+ htmlFor: "relay-event-state-filter",
1071
+ children: t("eventStateFilter")
1072
+ }),
1073
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1074
+ id: "relay-event-state-filter",
1075
+ value: eventStateFilter,
1076
+ onChange: (event) => {
1077
+ setEventStateFilter(event.currentTarget.value);
1078
+ },
1079
+ children: [
1080
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1081
+ value: "all",
1082
+ children: t("all")
1083
+ }),
1084
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1085
+ value: "resolved",
1086
+ children: t("resolved")
1087
+ }),
1088
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1089
+ value: "received",
1090
+ children: t("received")
1091
+ }),
1092
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1093
+ value: "deliver",
1094
+ children: t("delivered")
1095
+ }),
1096
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1097
+ value: "escalate",
1098
+ children: t("escalated")
1099
+ }),
1100
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1101
+ value: "dismiss",
1102
+ children: t("dismissed")
1103
+ })
1104
+ ]
1105
+ }),
1106
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1107
+ htmlFor: "relay-event-source-filter",
1108
+ children: t("eventSourceFilter")
1109
+ }),
1110
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1111
+ id: "relay-event-source-filter",
1112
+ value: eventSourceFilter,
1113
+ maxLength: 128,
1114
+ onChange: (event) => {
1115
+ setEventSourceFilter(event.currentTarget.value);
1116
+ }
1117
+ })
1118
+ ]
1119
+ }),
1120
+ events.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1121
+ className: WaitingEventsSection_module_css_default.emptyHistory,
1122
+ children: t("noEventHistory")
1123
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
1124
+ className: WaitingEventsSection_module_css_default.events,
1125
+ children: visibleEvents.map((event) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
1126
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1127
+ className: WaitingEventsSection_module_css_default.eventHeader,
1128
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: event.payload?.type ?? t("unknownEvent") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1129
+ className: WaitingEventsSection_module_css_default.rowState,
1130
+ children: event.decision?.disposition ?? event.state
1131
+ })]
1132
+ }),
1133
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: event.decision?.summary ?? t("noDecisionSummary") }),
1134
+ (event.decision?.evidence?.length ?? 0) > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [
1135
+ t("evidence"),
1136
+ ": ",
1137
+ event.decision?.evidence?.join(" · ")
1138
+ ] }) : null,
1139
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
1140
+ event.source,
1141
+ " · ",
1142
+ formatTime(event.received_at, activeLocale),
1143
+ " · ",
1144
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1145
+ title: event.event_id,
1146
+ children: shortId(event.event_id)
1147
+ })
1148
+ ] }),
1149
+ (event.deliveries?.length ?? 0) > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
1150
+ className: WaitingEventsSection_module_css_default.eventDetails,
1151
+ "aria-label": t("deliveries"),
1152
+ children: event.deliveries?.map((delivery) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
1153
+ t("deliveryTo", { target: shortId(delivery.session_id) }),
1154
+ " · ",
1155
+ statusText(delivery.state, t),
1156
+ delivery.relation ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: delivery.relation }) : null
1157
+ ] }, delivery.delivery_id))
1158
+ }) : null,
1159
+ event.notification ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1160
+ className: WaitingEventsSection_module_css_default.activation,
1161
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
1162
+ t("notification"),
1163
+ ": ",
1164
+ statusText(event.notification.state, t),
1165
+ event.notification.error_class ? ` · ${event.notification.error_class}` : "",
1166
+ event.notification.receipt_id ? ` · ${t("notificationReceipt")} ${shortId(event.notification.receipt_id)}` : "",
1167
+ event.notification.attempt_count ? ` · ${t("attemptCount", { count: event.notification.attempt_count })}` : ""
1168
+ ] }), ["failed", "unavailable"].includes(event.notification.state) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1169
+ size: "sm",
1170
+ variant: "outline",
1171
+ disabled: pending !== null,
1172
+ onClick: () => {
1173
+ perform(`notification:${event.event_id}`, () => retryNotification(event.event_id));
1174
+ },
1175
+ children: t("retryNotification")
1176
+ }) : null]
1177
+ }) : null,
1178
+ event.activations?.map((activation) => {
1179
+ const retryKey = `retry:${activation.activation_id}`;
1180
+ const retryable = activation.terminal_reason_code === "delivery_retry_exhausted";
1181
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1182
+ className: WaitingEventsSection_module_css_default.activation,
1183
+ children: [
1184
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
1185
+ t("activation"),
1186
+ " ",
1187
+ shortId(activation.activation_id),
1188
+ " · ",
1189
+ t("attemptCount", { count: activation.attempt_count ?? 0 })
1190
+ ] }),
1191
+ activation.next_attempt_at ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
1192
+ t("nextAttempt"),
1193
+ " ",
1194
+ formatTime(activation.next_attempt_at, activeLocale)
1195
+ ] }) : null,
1196
+ retryable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1197
+ size: "sm",
1198
+ variant: "outline",
1199
+ disabled: pending !== null,
1200
+ onClick: () => {
1201
+ perform(retryKey, () => retryActivation(activation.activation_id));
1202
+ },
1203
+ children: t("retryDelivery")
1204
+ }) : null
1205
+ ]
1206
+ }, activation.activation_id);
1207
+ })
1208
+ ] }, event.event_id))
1209
+ }),
1210
+ events.length > 0 && visibleEvents.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1211
+ className: WaitingEventsSection_module_css_default.emptyHistory,
1212
+ children: t("noMatchingEvents")
1213
+ }) : null,
1214
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
1215
+ className: WaitingEventsSection_module_css_default.pagination,
1216
+ "aria-label": t("eventPagination"),
1217
+ children: [
1218
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1219
+ size: "sm",
1220
+ variant: "outline",
1221
+ disabled: refreshing || eventCursors.length === 1,
1222
+ onClick: () => {
1223
+ setRefreshing(true);
1224
+ setEventCursors((current) => current.slice(0, -1));
1225
+ },
1226
+ children: t("previousPage")
1227
+ }),
1228
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("pageNumber", { count: eventCursors.length }) }),
1229
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1230
+ size: "sm",
1231
+ variant: "outline",
1232
+ disabled: refreshing || state.snapshot.event_page.next_cursor === null,
1233
+ onClick: () => {
1234
+ const next = state.snapshot.event_page.next_cursor;
1235
+ if (next) {
1236
+ setRefreshing(true);
1237
+ setEventCursors((current) => [...current, next]);
1238
+ }
1239
+ },
1240
+ children: t("nextPage")
1241
+ })
1242
+ ]
1243
+ })
1244
+ ]
270
1245
  }) : null
271
1246
  ]
272
1247
  });
@@ -274,24 +1249,98 @@ window.__ModuleLoader__.load({
274
1249
  function statusText(status, t) {
275
1250
  return (/* @__PURE__ */ new Set([
276
1251
  "active",
1252
+ "paused",
277
1253
  "claimed",
278
1254
  "degraded",
279
1255
  "triggered",
280
1256
  "failed",
281
1257
  "completed",
282
- "cancelled"
1258
+ "cancelled",
1259
+ "consumed",
1260
+ "superseded",
1261
+ "expired",
1262
+ "received",
1263
+ "routing",
1264
+ "dispatched",
1265
+ "resolved",
1266
+ "queued",
1267
+ "running",
1268
+ "delivered",
1269
+ "unavailable",
1270
+ "healthy",
1271
+ "unconfigured",
1272
+ "available",
1273
+ "configuration_required",
1274
+ "incompatible",
1275
+ "validated",
1276
+ "installing",
1277
+ "installed"
283
1278
  ])).has(status) ? t(status) : status;
284
1279
  }
285
- function formatTime(value) {
1280
+ function monitorTarget(monitor) {
1281
+ if (monitor.artifact?.stable_subject) return monitor.artifact.stable_subject;
1282
+ if (monitor.artifact?.repository && monitor.artifact.pull_number !== void 0) return `${monitor.artifact.repository}#${monitor.artifact.pull_number}`;
1283
+ return monitor.artifact?.name ?? null;
1284
+ }
1285
+ function monitorObservationSummary(monitor, t) {
1286
+ const data = monitor.last_observation?.data;
1287
+ if (!data) return null;
1288
+ const parts = [];
1289
+ if (typeof data.head_sha === "string") parts.push(`${t("headRevision")}: ${shortId(data.head_sha)}`);
1290
+ if (typeof data.state === "string") parts.push(`${t("pullRequestState")}: ${data.state}`);
1291
+ if (typeof data.review_decision === "string") parts.push(`${t("reviewDecision")}: ${data.review_decision}`);
1292
+ if (Array.isArray(data.checks)) {
1293
+ const checks = data.checks.filter((item) => item !== null && typeof item === "object");
1294
+ const passed = checks.filter((check) => check.conclusion === "success").length;
1295
+ parts.push(t("checkSummary", {
1296
+ passed,
1297
+ total: checks.length
1298
+ }));
1299
+ }
1300
+ return parts.length > 0 ? parts.join(" · ") : null;
1301
+ }
1302
+ function operationErrorText(error, t) {
1303
+ const message = error instanceof Error ? error.message : String(error);
1304
+ if (/invalid cadence/iu.test(message)) return t("invalidCadence");
1305
+ if (/version changed|stale|conflict/iu.test(message)) return t("staleOperation");
1306
+ if (/busy|lease|in progress/iu.test(message)) return t("busyOperation");
1307
+ if (/not installed|not available|unavailable|provider/iu.test(message)) return t("providerUnavailable");
1308
+ return t("operationError");
1309
+ }
1310
+ function reasonText(reason, t) {
1311
+ const key = `reason_${reason}`;
1312
+ return key in reasonKeys ? t(key) : reason;
1313
+ }
1314
+ const reasonKeys = {
1315
+ reason_stopped_by_user: true,
1316
+ reason_delivery_retry_exhausted: true
1317
+ };
1318
+ function shortId(value) {
1319
+ return value.length <= 20 ? value : `${value.slice(0, 8)}…${value.slice(-6)}`;
1320
+ }
1321
+ function formatTime(value, locale) {
286
1322
  const date = new Date(value);
287
1323
  if (Number.isNaN(date.getTime())) return value;
288
- return new Intl.DateTimeFormat(void 0, {
1324
+ return new Intl.DateTimeFormat(locale.startsWith("zh") ? "zh-CN" : "en-US", {
289
1325
  month: "short",
290
1326
  day: "numeric",
291
1327
  hour: "2-digit",
292
1328
  minute: "2-digit"
293
1329
  }).format(date);
294
1330
  }
1331
+ function formatDeadline(value, locale) {
1332
+ const date = new Date(value);
1333
+ if (Number.isNaN(date.getTime())) return value;
1334
+ return new Intl.DateTimeFormat(locale.startsWith("zh") ? "zh-CN" : "en-US", {
1335
+ year: "numeric",
1336
+ month: "short",
1337
+ day: "numeric",
1338
+ hour: "2-digit",
1339
+ minute: "2-digit",
1340
+ second: "2-digit",
1341
+ timeZoneName: "short"
1342
+ }).format(date);
1343
+ }
295
1344
  //#endregion
296
1345
  //#region src/client/locales.ts
297
1346
  const zh = {
@@ -306,9 +1355,15 @@ window.__ModuleLoader__.load({
306
1355
  confirmCancel: "确认取消",
307
1356
  keep: "保留",
308
1357
  runNow: "立即检查",
1358
+ pause: "暂停",
1359
+ resume: "恢复",
1360
+ stop: "停止",
1361
+ confirmStop: "确认停止",
309
1362
  waiting: "等待中",
1363
+ history: "历史记录",
310
1364
  claimed: "处理中",
311
1365
  active: "运行中",
1366
+ paused: "已暂停",
312
1367
  degraded: "检查异常",
313
1368
  triggered: "已触发",
314
1369
  failed: "已失败",
@@ -316,10 +1371,136 @@ window.__ModuleLoader__.load({
316
1371
  cancelled: "已取消",
317
1372
  nextCheck: "下次检查",
318
1373
  lastCheck: "最近检查",
1374
+ lastTransition: "最近变化",
319
1375
  noSchedule: "等待外部事件",
1376
+ monitorTarget: "监控目标",
1377
+ cadence: "检查频率",
1378
+ cadenceSeconds: "检查间隔(秒)",
1379
+ secondsValue: "{count} 秒",
1380
+ failureCount: "连续失败 {count} 次",
1381
+ invalidCadence: "检查间隔必须是 1 到 86400 之间的整数秒。",
1382
+ headRevision: "版本",
1383
+ pullRequestState: "PR 状态",
1384
+ reviewDecision: "评审",
1385
+ checkSummary: "检查 {passed}/{total} 通过",
320
1386
  waitCount: "{count} 个条件",
321
1387
  monitorCount: "{count} 个监控",
322
- operationError: "操作失败,请重试。"
1388
+ operationError: "操作失败,请重试。",
1389
+ staleOperation: "状态已被其他操作更新,请刷新后重试。",
1390
+ busyOperation: "目标正在执行检查,请等待完成后重试。",
1391
+ providerUnavailable: "所需提供方当前不可用,请检查插件或连接配置。",
1392
+ missingSession: "所属对话已删除或不可用。当前页面不会跳转。",
1393
+ cancelTarget: "取消“{target}”的全部活动等待和监控?",
1394
+ eventHistory: "事件历史",
1395
+ eventTotal: "共 {count} 条",
1396
+ eventFilters: "事件筛选",
1397
+ eventStateFilter: "状态",
1398
+ eventSourceFilter: "来源",
1399
+ all: "全部",
1400
+ escalated: "已升级处理",
1401
+ dismissed: "已忽略",
1402
+ noMatchingEvents: "当前页没有符合筛选条件的事件",
1403
+ eventPagination: "事件历史分页",
1404
+ previousPage: "上一页",
1405
+ nextPage: "下一页",
1406
+ pageNumber: "第 {count} 页",
1407
+ noEventHistory: "暂无事件记录",
1408
+ unknownEvent: "未知事件",
1409
+ noDecisionSummary: "暂无决策摘要",
1410
+ nextAction: "下一步",
1411
+ successCondition: "完成条件",
1412
+ artifactCount: "{count} 个关联产物",
1413
+ terminalReason: "终止原因",
1414
+ stopTarget: "停止监控 {target}",
1415
+ evidence: "依据",
1416
+ deliveries: "投递记录",
1417
+ deliveryTo: "投递到 {target}",
1418
+ notification: "通知",
1419
+ notificationReceipt: "回执",
1420
+ retryNotification: "重试通知",
1421
+ activation: "激活记录",
1422
+ attemptCount: "已尝试 {count} 次",
1423
+ nextAttempt: "下次重试",
1424
+ retryDelivery: "重试投递",
1425
+ consumed: "已处理",
1426
+ superseded: "已替换",
1427
+ expired: "已过期",
1428
+ received: "已接收",
1429
+ routing: "路由中",
1430
+ dispatched: "投递中",
1431
+ resolved: "已解决",
1432
+ queued: "等待投递",
1433
+ running: "执行中",
1434
+ delivered: "已通知",
1435
+ unavailable: "不可用",
1436
+ reason_stopped_by_user: "由用户停止",
1437
+ reason_delivery_retry_exhausted: "投递重试次数已用尽",
1438
+ connectors: "连接器",
1439
+ email: "邮件",
1440
+ webhookPath: "Webhook 地址",
1441
+ webhookSecret: "Webhook 密钥",
1442
+ newWebhookSecret: "新 Webhook 密钥",
1443
+ apiPolling: "API 轮询",
1444
+ configured: "已配置",
1445
+ notConfigured: "未配置",
1446
+ configure: "配置",
1447
+ rotate: "轮换",
1448
+ revoke: "撤销",
1449
+ confirmRevoke: "确认撤销",
1450
+ revokeGitHubConfirm: "撤销后,所有 GitHub Webhook 将立即被拒绝。",
1451
+ revokeGmailConfirm: "撤销后,Gmail API 读取和 Push 通知将立即被拒绝。",
1452
+ readOnlyCredential: "凭据由启动环境或只读配置提供,请在该来源中修改。",
1453
+ gmailApiToken: "Gmail API 令牌",
1454
+ gmailPushToken: "Gmail Push 令牌",
1455
+ lastSuccess: "最近成功",
1456
+ lastError: "最近错误",
1457
+ pushConfigured: "Push 鉴权已配置",
1458
+ pushNotConfigured: "Push 鉴权未配置",
1459
+ emailPrivacy: "邮件正文和附件内容不会显示在连接状态中。",
1460
+ noMailboxes: "尚无已同步邮箱",
1461
+ disconnect: "断开",
1462
+ confirmDisconnect: "确认断开",
1463
+ disconnectMailboxConfirm: "断开邮箱 {account} 并删除其增量游标?",
1464
+ healthy: "正常",
1465
+ unconfigured: "未配置",
1466
+ deadline: "截止时间",
1467
+ timezone: "时区",
1468
+ afterSeconds: "{count} 秒后",
1469
+ overdue: "已到期",
1470
+ semanticRouter: "语义路由",
1471
+ routerFallbackWarning: "尚未配置语义模型。Relay 保持健康,并仅使用精确路由。",
1472
+ routerActive: "无可信归属的事件会使用所选模型进行一次受限路由判断。",
1473
+ routerProvider: "模型提供方",
1474
+ routerModel: "模型",
1475
+ routerReadOnly: "当前 DSH Profile 没有可写的设置存储,请在启动配置中修改。",
1476
+ update: "更新",
1477
+ disable: "停用",
1478
+ confirmDisable: "确认停用",
1479
+ disableRouterConfirm: "停用语义路由并恢复为仅精确路由?",
1480
+ bundleCatalog: "支持的 Monitor Bundle",
1481
+ bundleTypeCount: "{count} 个类型",
1482
+ noBundleTypes: "当前没有可创建的 Monitor Bundle 类型",
1483
+ bundleIdentity: "类型与版本",
1484
+ bundleOrigin: "来源",
1485
+ pluginOrigin: "插件 {name}",
1486
+ agentOrigin: "Agent 临时创建",
1487
+ bundleEvents: "事件",
1488
+ bundleCapabilities: "只读能力",
1489
+ bundleLifecycle: "生命周期",
1490
+ bundleScope: "范围",
1491
+ artifactHash: "制品哈希",
1492
+ bundleExpiry: "到期时间",
1493
+ validationState: "验证状态",
1494
+ bundlePermissions: "权限说明",
1495
+ bundleRemediation: "修复建议",
1496
+ none: "无",
1497
+ available: "可用",
1498
+ configuration_required: "需要配置",
1499
+ incompatible: "不兼容",
1500
+ validated: "已验证",
1501
+ installing: "安装中",
1502
+ installed: "已安装",
1503
+ bundlePagination: "Monitor Bundle 目录分页"
323
1504
  };
324
1505
  const en = {
325
1506
  nav: "Waiting events",
@@ -333,9 +1514,15 @@ window.__ModuleLoader__.load({
333
1514
  confirmCancel: "Confirm cancel",
334
1515
  keep: "Keep",
335
1516
  runNow: "Check now",
1517
+ pause: "Pause",
1518
+ resume: "Resume",
1519
+ stop: "Stop",
1520
+ confirmStop: "Confirm stop",
336
1521
  waiting: "Waiting",
1522
+ history: "History",
337
1523
  claimed: "Processing",
338
1524
  active: "Active",
1525
+ paused: "Paused",
339
1526
  degraded: "Check degraded",
340
1527
  triggered: "Triggered",
341
1528
  failed: "Failed",
@@ -343,10 +1530,136 @@ window.__ModuleLoader__.load({
343
1530
  cancelled: "Cancelled",
344
1531
  nextCheck: "Next check",
345
1532
  lastCheck: "Last check",
1533
+ lastTransition: "Last transition",
346
1534
  noSchedule: "External event",
1535
+ monitorTarget: "Monitor target",
1536
+ cadence: "Cadence",
1537
+ cadenceSeconds: "Check interval (seconds)",
1538
+ secondsValue: "{count} seconds",
1539
+ failureCount: "{count} consecutive failures",
1540
+ invalidCadence: "The check interval must be a whole number from 1 to 86400 seconds.",
1541
+ headRevision: "Revision",
1542
+ pullRequestState: "PR state",
1543
+ reviewDecision: "Review",
1544
+ checkSummary: "{passed}/{total} checks passed",
347
1545
  waitCount: "{count} conditions",
348
1546
  monitorCount: "{count} monitors",
349
- operationError: "The operation failed. Try again."
1547
+ operationError: "The operation failed. Try again.",
1548
+ staleOperation: "The state changed in another operation. Refresh and try again.",
1549
+ busyOperation: "The target is being checked. Wait for it to finish and try again.",
1550
+ providerUnavailable: "The required provider is unavailable. Check the plugin or connection configuration.",
1551
+ missingSession: "The owning conversation was deleted or is unavailable. Navigation was not changed.",
1552
+ cancelTarget: "Cancel every active wait and monitor for “{target}”?",
1553
+ eventHistory: "Event history",
1554
+ eventTotal: "{count} events",
1555
+ eventFilters: "Event filters",
1556
+ eventStateFilter: "State",
1557
+ eventSourceFilter: "Source",
1558
+ all: "All",
1559
+ escalated: "Escalated",
1560
+ dismissed: "Dismissed",
1561
+ noMatchingEvents: "No events on this page match the filters",
1562
+ eventPagination: "Event history pagination",
1563
+ previousPage: "Previous",
1564
+ nextPage: "Next",
1565
+ pageNumber: "Page {count}",
1566
+ noEventHistory: "No event history",
1567
+ unknownEvent: "Unknown event",
1568
+ noDecisionSummary: "No decision summary",
1569
+ nextAction: "Next action",
1570
+ successCondition: "Success condition",
1571
+ artifactCount: "{count} linked artifacts",
1572
+ terminalReason: "Terminal reason",
1573
+ stopTarget: "Stop monitor {target}",
1574
+ evidence: "Evidence",
1575
+ deliveries: "Deliveries",
1576
+ deliveryTo: "Delivery to {target}",
1577
+ notification: "Notification",
1578
+ notificationReceipt: "Receipt",
1579
+ retryNotification: "Retry notification",
1580
+ activation: "Activation",
1581
+ attemptCount: "{count} attempts",
1582
+ nextAttempt: "Next retry",
1583
+ retryDelivery: "Retry delivery",
1584
+ consumed: "Consumed",
1585
+ superseded: "Superseded",
1586
+ expired: "Expired",
1587
+ received: "Received",
1588
+ routing: "Routing",
1589
+ dispatched: "Dispatching",
1590
+ resolved: "Resolved",
1591
+ queued: "Queued",
1592
+ running: "Running",
1593
+ delivered: "Delivered",
1594
+ unavailable: "Unavailable",
1595
+ reason_stopped_by_user: "Stopped by user",
1596
+ reason_delivery_retry_exhausted: "Delivery retry budget exhausted",
1597
+ connectors: "Connectors",
1598
+ email: "Email",
1599
+ webhookPath: "Webhook URL",
1600
+ webhookSecret: "Webhook secret",
1601
+ newWebhookSecret: "New webhook secret",
1602
+ apiPolling: "API polling",
1603
+ configured: "Configured",
1604
+ notConfigured: "Not configured",
1605
+ configure: "Configure",
1606
+ rotate: "Rotate",
1607
+ revoke: "Revoke",
1608
+ confirmRevoke: "Confirm revoke",
1609
+ revokeGitHubConfirm: "Revoking immediately rejects every GitHub webhook.",
1610
+ revokeGmailConfirm: "Revoking immediately rejects Gmail API reads and push notifications.",
1611
+ readOnlyCredential: "The credential comes from the launch environment or read-only configuration. Change it at that source.",
1612
+ gmailApiToken: "Gmail API token",
1613
+ gmailPushToken: "Gmail push token",
1614
+ lastSuccess: "Last success",
1615
+ lastError: "Last error",
1616
+ pushConfigured: "Push authentication configured",
1617
+ pushNotConfigured: "Push authentication not configured",
1618
+ emailPrivacy: "Message bodies and attachment contents are never shown in connection status.",
1619
+ noMailboxes: "No synchronized mailboxes",
1620
+ disconnect: "Disconnect",
1621
+ confirmDisconnect: "Confirm disconnect",
1622
+ disconnectMailboxConfirm: "Disconnect mailbox {account} and remove its incremental cursor?",
1623
+ healthy: "Healthy",
1624
+ unconfigured: "Not configured",
1625
+ deadline: "Deadline",
1626
+ timezone: "Timezone",
1627
+ afterSeconds: "In {count} seconds",
1628
+ overdue: "Overdue",
1629
+ semanticRouter: "Semantic Router",
1630
+ routerFallbackWarning: "No semantic model is configured. Relay remains healthy and uses exact routing only.",
1631
+ routerActive: "Events without trusted ownership use the selected model for one constrained routing decision.",
1632
+ routerProvider: "Model provider",
1633
+ routerModel: "Model",
1634
+ routerReadOnly: "This DSH profile has no writable settings store. Change the startup configuration instead.",
1635
+ update: "Update",
1636
+ disable: "Disable",
1637
+ confirmDisable: "Confirm disable",
1638
+ disableRouterConfirm: "Disable semantic routing and return to exact routing only?",
1639
+ bundleCatalog: "Supported Monitor Bundles",
1640
+ bundleTypeCount: "{count} types",
1641
+ noBundleTypes: "No Monitor Bundle Types can be created right now",
1642
+ bundleIdentity: "Type and version",
1643
+ bundleOrigin: "Origin",
1644
+ pluginOrigin: "Plugin {name}",
1645
+ agentOrigin: "Agent-authored",
1646
+ bundleEvents: "Events",
1647
+ bundleCapabilities: "Read capabilities",
1648
+ bundleLifecycle: "Lifecycle",
1649
+ bundleScope: "Scope",
1650
+ artifactHash: "Artifact hash",
1651
+ bundleExpiry: "Expiry",
1652
+ validationState: "Validation state",
1653
+ bundlePermissions: "Permissions",
1654
+ bundleRemediation: "Remediation",
1655
+ none: "None",
1656
+ available: "Available",
1657
+ configuration_required: "Configuration required",
1658
+ incompatible: "Incompatible",
1659
+ validated: "Validated",
1660
+ installing: "Installing",
1661
+ installed: "Installed",
1662
+ bundlePagination: "Monitor Bundle catalog pagination"
350
1663
  };
351
1664
  //#endregion
352
1665
  //#region node_modules/zod/v4/core/core.js
@@ -435,6 +1748,13 @@ window.__ModuleLoader__.load({
435
1748
  const end = source.endsWith("$") ? source.length - 1 : source.length;
436
1749
  return source.slice(start, end);
437
1750
  }
1751
+ function floatSafeRemainder(val, step) {
1752
+ const ratio = val / step;
1753
+ const roundedRatio = Math.round(ratio);
1754
+ const tolerance = Number.EPSILON * Math.max(Math.abs(ratio), 1);
1755
+ if (Math.abs(ratio - roundedRatio) < tolerance) return 0;
1756
+ return ratio - roundedRatio;
1757
+ }
438
1758
  const EVALUATING = /* @__PURE__*/ Symbol("evaluating");
439
1759
  function defineLazy(object, key, getter) {
440
1760
  let value = void 0;
@@ -539,7 +1859,13 @@ window.__ModuleLoader__.load({
539
1859
  return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
540
1860
  });
541
1861
  }
542
- Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, -Number.MAX_VALUE, Number.MAX_VALUE;
1862
+ const NUMBER_FORMAT_RANGES = {
1863
+ safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
1864
+ int32: [-2147483648, 2147483647],
1865
+ uint32: [0, 4294967295],
1866
+ float32: [-34028234663852886e22, 34028234663852886e22],
1867
+ float64: [-Number.MAX_VALUE, Number.MAX_VALUE]
1868
+ };
543
1869
  function pick(schema, mask) {
544
1870
  const currDef = schema._zod.def;
545
1871
  const checks = currDef.checks;
@@ -942,6 +2268,8 @@ window.__ModuleLoader__.load({
942
2268
  const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
943
2269
  return new RegExp(`^${regex}$`);
944
2270
  };
2271
+ const integer = /^-?\d+$/;
2272
+ const number$1 = /^-?\d+(?:\.\d+)?$/;
945
2273
  const lowercase = /^[^A-Z]*$/;
946
2274
  const uppercase = /^[^a-z]*$/;
947
2275
  //#endregion
@@ -952,6 +2280,145 @@ window.__ModuleLoader__.load({
952
2280
  inst._zod.def = def;
953
2281
  (_a = inst._zod).onattach ?? (_a.onattach = []);
954
2282
  });
2283
+ const numericOriginMap = {
2284
+ number: "number",
2285
+ bigint: "bigint",
2286
+ object: "date"
2287
+ };
2288
+ const $ZodCheckLessThan = /*@__PURE__*/ $constructor("$ZodCheckLessThan", (inst, def) => {
2289
+ $ZodCheck.init(inst, def);
2290
+ const origin = numericOriginMap[typeof def.value];
2291
+ inst._zod.onattach.push((inst) => {
2292
+ const bag = inst._zod.bag;
2293
+ const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;
2294
+ if (def.value < curr) if (def.inclusive) bag.maximum = def.value;
2295
+ else bag.exclusiveMaximum = def.value;
2296
+ });
2297
+ inst._zod.check = (payload) => {
2298
+ if (def.inclusive ? payload.value <= def.value : payload.value < def.value) return;
2299
+ payload.issues.push({
2300
+ origin,
2301
+ code: "too_big",
2302
+ maximum: typeof def.value === "object" ? def.value.getTime() : def.value,
2303
+ input: payload.value,
2304
+ inclusive: def.inclusive,
2305
+ inst,
2306
+ continue: !def.abort
2307
+ });
2308
+ };
2309
+ });
2310
+ const $ZodCheckGreaterThan = /*@__PURE__*/ $constructor("$ZodCheckGreaterThan", (inst, def) => {
2311
+ $ZodCheck.init(inst, def);
2312
+ const origin = numericOriginMap[typeof def.value];
2313
+ inst._zod.onattach.push((inst) => {
2314
+ const bag = inst._zod.bag;
2315
+ const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;
2316
+ if (def.value > curr) if (def.inclusive) bag.minimum = def.value;
2317
+ else bag.exclusiveMinimum = def.value;
2318
+ });
2319
+ inst._zod.check = (payload) => {
2320
+ if (def.inclusive ? payload.value >= def.value : payload.value > def.value) return;
2321
+ payload.issues.push({
2322
+ origin,
2323
+ code: "too_small",
2324
+ minimum: typeof def.value === "object" ? def.value.getTime() : def.value,
2325
+ input: payload.value,
2326
+ inclusive: def.inclusive,
2327
+ inst,
2328
+ continue: !def.abort
2329
+ });
2330
+ };
2331
+ });
2332
+ const $ZodCheckMultipleOf = /*@__PURE__*/ $constructor("$ZodCheckMultipleOf", (inst, def) => {
2333
+ $ZodCheck.init(inst, def);
2334
+ inst._zod.onattach.push((inst) => {
2335
+ var _a;
2336
+ (_a = inst._zod.bag).multipleOf ?? (_a.multipleOf = def.value);
2337
+ });
2338
+ inst._zod.check = (payload) => {
2339
+ if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check.");
2340
+ if (typeof payload.value === "bigint" ? payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0) return;
2341
+ payload.issues.push({
2342
+ origin: typeof payload.value,
2343
+ code: "not_multiple_of",
2344
+ divisor: def.value,
2345
+ input: payload.value,
2346
+ inst,
2347
+ continue: !def.abort
2348
+ });
2349
+ };
2350
+ });
2351
+ const $ZodCheckNumberFormat = /*@__PURE__*/ $constructor("$ZodCheckNumberFormat", (inst, def) => {
2352
+ $ZodCheck.init(inst, def);
2353
+ def.format = def.format || "float64";
2354
+ const isInt = def.format?.includes("int");
2355
+ const origin = isInt ? "int" : "number";
2356
+ const [minimum, maximum] = NUMBER_FORMAT_RANGES[def.format];
2357
+ inst._zod.onattach.push((inst) => {
2358
+ const bag = inst._zod.bag;
2359
+ bag.format = def.format;
2360
+ bag.minimum = minimum;
2361
+ bag.maximum = maximum;
2362
+ if (isInt) bag.pattern = integer;
2363
+ });
2364
+ inst._zod.check = (payload) => {
2365
+ const input = payload.value;
2366
+ if (isInt) {
2367
+ if (!Number.isInteger(input)) {
2368
+ payload.issues.push({
2369
+ expected: origin,
2370
+ format: def.format,
2371
+ code: "invalid_type",
2372
+ continue: false,
2373
+ input,
2374
+ inst
2375
+ });
2376
+ return;
2377
+ }
2378
+ if (!Number.isSafeInteger(input)) {
2379
+ if (input > 0) payload.issues.push({
2380
+ input,
2381
+ code: "too_big",
2382
+ maximum: Number.MAX_SAFE_INTEGER,
2383
+ note: "Integers must be within the safe integer range.",
2384
+ inst,
2385
+ origin,
2386
+ inclusive: true,
2387
+ continue: !def.abort
2388
+ });
2389
+ else payload.issues.push({
2390
+ input,
2391
+ code: "too_small",
2392
+ minimum: Number.MIN_SAFE_INTEGER,
2393
+ note: "Integers must be within the safe integer range.",
2394
+ inst,
2395
+ origin,
2396
+ inclusive: true,
2397
+ continue: !def.abort
2398
+ });
2399
+ return;
2400
+ }
2401
+ }
2402
+ if (input < minimum) payload.issues.push({
2403
+ origin: "number",
2404
+ input,
2405
+ code: "too_small",
2406
+ minimum,
2407
+ inclusive: true,
2408
+ inst,
2409
+ continue: !def.abort
2410
+ });
2411
+ if (input > maximum) payload.issues.push({
2412
+ origin: "number",
2413
+ input,
2414
+ code: "too_big",
2415
+ maximum,
2416
+ inclusive: true,
2417
+ inst,
2418
+ continue: !def.abort
2419
+ });
2420
+ };
2421
+ });
955
2422
  const $ZodCheckMaxLength = /*@__PURE__*/ $constructor("$ZodCheckMaxLength", (inst, def) => {
956
2423
  var _a;
957
2424
  $ZodCheck.init(inst, def);
@@ -1573,6 +3040,30 @@ window.__ModuleLoader__.load({
1573
3040
  });
1574
3041
  };
1575
3042
  });
3043
+ const $ZodNumber = /*@__PURE__*/ $constructor("$ZodNumber", (inst, def) => {
3044
+ $ZodType.init(inst, def);
3045
+ inst._zod.pattern = inst._zod.bag.pattern ?? number$1;
3046
+ inst._zod.parse = (payload, _ctx) => {
3047
+ if (def.coerce) try {
3048
+ payload.value = Number(payload.value);
3049
+ } catch (_) {}
3050
+ const input = payload.value;
3051
+ if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) return payload;
3052
+ const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0;
3053
+ payload.issues.push({
3054
+ expected: "number",
3055
+ code: "invalid_type",
3056
+ input,
3057
+ inst,
3058
+ ...received ? { received } : {}
3059
+ });
3060
+ return payload;
3061
+ };
3062
+ });
3063
+ const $ZodNumberFormat = /*@__PURE__*/ $constructor("$ZodNumberFormat", (inst, def) => {
3064
+ $ZodCheckNumberFormat.init(inst, def);
3065
+ $ZodNumber.init(inst, def);
3066
+ });
1576
3067
  const $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => {
1577
3068
  $ZodType.init(inst, def);
1578
3069
  inst._zod.parse = (payload) => payload;
@@ -2016,6 +3507,115 @@ window.__ModuleLoader__.load({
2016
3507
  result.value = merged.data;
2017
3508
  return result;
2018
3509
  }
3510
+ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
3511
+ $ZodType.init(inst, def);
3512
+ inst._zod.parse = (payload, ctx) => {
3513
+ const input = payload.value;
3514
+ if (!isPlainObject(input)) {
3515
+ payload.issues.push({
3516
+ expected: "record",
3517
+ code: "invalid_type",
3518
+ input,
3519
+ inst
3520
+ });
3521
+ return payload;
3522
+ }
3523
+ const proms = [];
3524
+ const values = def.keyType._zod.values;
3525
+ if (values) {
3526
+ payload.value = {};
3527
+ const recordKeys = /* @__PURE__ */ new Set();
3528
+ for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
3529
+ recordKeys.add(typeof key === "number" ? key.toString() : key);
3530
+ const keyResult = def.keyType._zod.run({
3531
+ value: key,
3532
+ issues: []
3533
+ }, ctx);
3534
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
3535
+ if (keyResult.issues.length) {
3536
+ payload.issues.push({
3537
+ code: "invalid_key",
3538
+ origin: "record",
3539
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
3540
+ input: key,
3541
+ path: [key],
3542
+ inst
3543
+ });
3544
+ continue;
3545
+ }
3546
+ const outKey = keyResult.value;
3547
+ const result = def.valueType._zod.run({
3548
+ value: input[key],
3549
+ issues: []
3550
+ }, ctx);
3551
+ if (result instanceof Promise) proms.push(result.then((result) => {
3552
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
3553
+ payload.value[outKey] = result.value;
3554
+ }));
3555
+ else {
3556
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
3557
+ payload.value[outKey] = result.value;
3558
+ }
3559
+ }
3560
+ let unrecognized;
3561
+ for (const key in input) if (!recordKeys.has(key)) {
3562
+ unrecognized = unrecognized ?? [];
3563
+ unrecognized.push(key);
3564
+ }
3565
+ if (unrecognized && unrecognized.length > 0) payload.issues.push({
3566
+ code: "unrecognized_keys",
3567
+ input,
3568
+ inst,
3569
+ keys: unrecognized
3570
+ });
3571
+ } else {
3572
+ payload.value = {};
3573
+ for (const key of Reflect.ownKeys(input)) {
3574
+ if (key === "__proto__") continue;
3575
+ if (!Object.prototype.propertyIsEnumerable.call(input, key)) continue;
3576
+ let keyResult = def.keyType._zod.run({
3577
+ value: key,
3578
+ issues: []
3579
+ }, ctx);
3580
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
3581
+ if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
3582
+ const retryResult = def.keyType._zod.run({
3583
+ value: Number(key),
3584
+ issues: []
3585
+ }, ctx);
3586
+ if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
3587
+ if (retryResult.issues.length === 0) keyResult = retryResult;
3588
+ }
3589
+ if (keyResult.issues.length) {
3590
+ if (def.mode === "loose") payload.value[key] = input[key];
3591
+ else payload.issues.push({
3592
+ code: "invalid_key",
3593
+ origin: "record",
3594
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
3595
+ input: key,
3596
+ path: [key],
3597
+ inst
3598
+ });
3599
+ continue;
3600
+ }
3601
+ const result = def.valueType._zod.run({
3602
+ value: input[key],
3603
+ issues: []
3604
+ }, ctx);
3605
+ if (result instanceof Promise) proms.push(result.then((result) => {
3606
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
3607
+ payload.value[keyResult.value] = result.value;
3608
+ }));
3609
+ else {
3610
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
3611
+ payload.value[keyResult.value] = result.value;
3612
+ }
3613
+ }
3614
+ }
3615
+ if (proms.length) return Promise.all(proms).then(() => payload);
3616
+ return payload;
3617
+ };
3618
+ });
2019
3619
  const $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => {
2020
3620
  $ZodType.init(inst, def);
2021
3621
  const values = getEnumValues(def.entries);
@@ -2587,6 +4187,24 @@ window.__ModuleLoader__.load({
2587
4187
  });
2588
4188
  }
2589
4189
  // @__NO_SIDE_EFFECTS__
4190
+ function _number(Class, params) {
4191
+ return new Class({
4192
+ type: "number",
4193
+ checks: [],
4194
+ ...normalizeParams(params)
4195
+ });
4196
+ }
4197
+ // @__NO_SIDE_EFFECTS__
4198
+ function _int(Class, params) {
4199
+ return new Class({
4200
+ type: "number",
4201
+ check: "number_format",
4202
+ abort: false,
4203
+ format: "safeint",
4204
+ ...normalizeParams(params)
4205
+ });
4206
+ }
4207
+ // @__NO_SIDE_EFFECTS__
2590
4208
  function _unknown(Class) {
2591
4209
  return new Class({ type: "unknown" });
2592
4210
  }
@@ -2598,6 +4216,50 @@ window.__ModuleLoader__.load({
2598
4216
  });
2599
4217
  }
2600
4218
  // @__NO_SIDE_EFFECTS__
4219
+ function _lt(value, params) {
4220
+ return new $ZodCheckLessThan({
4221
+ check: "less_than",
4222
+ ...normalizeParams(params),
4223
+ value,
4224
+ inclusive: false
4225
+ });
4226
+ }
4227
+ // @__NO_SIDE_EFFECTS__
4228
+ function _lte(value, params) {
4229
+ return new $ZodCheckLessThan({
4230
+ check: "less_than",
4231
+ ...normalizeParams(params),
4232
+ value,
4233
+ inclusive: true
4234
+ });
4235
+ }
4236
+ // @__NO_SIDE_EFFECTS__
4237
+ function _gt(value, params) {
4238
+ return new $ZodCheckGreaterThan({
4239
+ check: "greater_than",
4240
+ ...normalizeParams(params),
4241
+ value,
4242
+ inclusive: false
4243
+ });
4244
+ }
4245
+ // @__NO_SIDE_EFFECTS__
4246
+ function _gte(value, params) {
4247
+ return new $ZodCheckGreaterThan({
4248
+ check: "greater_than",
4249
+ ...normalizeParams(params),
4250
+ value,
4251
+ inclusive: true
4252
+ });
4253
+ }
4254
+ // @__NO_SIDE_EFFECTS__
4255
+ function _multipleOf(value, params) {
4256
+ return new $ZodCheckMultipleOf({
4257
+ check: "multiple_of",
4258
+ ...normalizeParams(params),
4259
+ value
4260
+ });
4261
+ }
4262
+ // @__NO_SIDE_EFFECTS__
2601
4263
  function _maxLength(maximum, params) {
2602
4264
  return new $ZodCheckMaxLength({
2603
4265
  check: "max_length",
@@ -3068,6 +4730,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3068
4730
  }))];
3069
4731
  }
3070
4732
  };
4733
+ const numberProcessor = (schema, ctx, _json, _params) => {
4734
+ const json = _json;
4735
+ const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
4736
+ if (typeof format === "string" && format.includes("int")) json.type = "integer";
4737
+ else json.type = "number";
4738
+ const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
4739
+ const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
4740
+ const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
4741
+ if (exMin) if (legacy) {
4742
+ json.minimum = exclusiveMinimum;
4743
+ json.exclusiveMinimum = true;
4744
+ } else json.exclusiveMinimum = exclusiveMinimum;
4745
+ else if (typeof minimum === "number") json.minimum = minimum;
4746
+ if (exMax) if (legacy) {
4747
+ json.maximum = exclusiveMaximum;
4748
+ json.exclusiveMaximum = true;
4749
+ } else json.exclusiveMaximum = exclusiveMaximum;
4750
+ else if (typeof maximum === "number") json.maximum = maximum;
4751
+ if (typeof multipleOf === "number") json.multipleOf = multipleOf;
4752
+ };
3071
4753
  const neverProcessor = (_schema, _ctx, json, _params) => {
3072
4754
  json.not = {};
3073
4755
  };
@@ -3160,6 +4842,39 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3160
4842
  const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
3161
4843
  json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
3162
4844
  };
4845
+ const recordProcessor = (schema, ctx, _json, params) => {
4846
+ const json = _json;
4847
+ const def = schema._zod.def;
4848
+ json.type = "object";
4849
+ const keyType = def.keyType;
4850
+ const patterns = keyType._zod.bag?.patterns;
4851
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
4852
+ const valueSchema = process(def.valueType, ctx, {
4853
+ ...params,
4854
+ path: [
4855
+ ...params.path,
4856
+ "patternProperties",
4857
+ "*"
4858
+ ]
4859
+ });
4860
+ json.patternProperties = {};
4861
+ for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
4862
+ } else {
4863
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process(def.keyType, ctx, {
4864
+ ...params,
4865
+ path: [...params.path, "propertyNames"]
4866
+ });
4867
+ json.additionalProperties = process(def.valueType, ctx, {
4868
+ ...params,
4869
+ path: [...params.path, "additionalProperties"]
4870
+ });
4871
+ }
4872
+ const keyValues = keyType._zod.values;
4873
+ if (keyValues) {
4874
+ const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
4875
+ if (validKeyValues.length > 0) json.required = validKeyValues;
4876
+ }
4877
+ };
3163
4878
  const nullableProcessor = (schema, ctx, json, params) => {
3164
4879
  const def = schema._zod.def;
3165
4880
  const inner = process(def.innerType, ctx, params);
@@ -3628,6 +5343,74 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3628
5343
  $ZodJWT.init(inst, def);
3629
5344
  ZodStringFormat.init(inst, def);
3630
5345
  });
5346
+ const ZodNumber = /*@__PURE__*/ $constructor("ZodNumber", (inst, def) => {
5347
+ $ZodNumber.init(inst, def);
5348
+ ZodType.init(inst, def);
5349
+ inst._zod.processJSONSchema = (ctx, json, params) => numberProcessor(inst, ctx, json, params);
5350
+ _installLazyMethods(inst, "ZodNumber", {
5351
+ gt(value, params) {
5352
+ return this.check(/* @__PURE__ */ _gt(value, params));
5353
+ },
5354
+ gte(value, params) {
5355
+ return this.check(/* @__PURE__ */ _gte(value, params));
5356
+ },
5357
+ min(value, params) {
5358
+ return this.check(/* @__PURE__ */ _gte(value, params));
5359
+ },
5360
+ lt(value, params) {
5361
+ return this.check(/* @__PURE__ */ _lt(value, params));
5362
+ },
5363
+ lte(value, params) {
5364
+ return this.check(/* @__PURE__ */ _lte(value, params));
5365
+ },
5366
+ max(value, params) {
5367
+ return this.check(/* @__PURE__ */ _lte(value, params));
5368
+ },
5369
+ int(params) {
5370
+ return this.check(int(params));
5371
+ },
5372
+ safe(params) {
5373
+ return this.check(int(params));
5374
+ },
5375
+ positive(params) {
5376
+ return this.check(/* @__PURE__ */ _gt(0, params));
5377
+ },
5378
+ nonnegative(params) {
5379
+ return this.check(/* @__PURE__ */ _gte(0, params));
5380
+ },
5381
+ negative(params) {
5382
+ return this.check(/* @__PURE__ */ _lt(0, params));
5383
+ },
5384
+ nonpositive(params) {
5385
+ return this.check(/* @__PURE__ */ _lte(0, params));
5386
+ },
5387
+ multipleOf(value, params) {
5388
+ return this.check(/* @__PURE__ */ _multipleOf(value, params));
5389
+ },
5390
+ step(value, params) {
5391
+ return this.check(/* @__PURE__ */ _multipleOf(value, params));
5392
+ },
5393
+ finite() {
5394
+ return this;
5395
+ }
5396
+ });
5397
+ const bag = inst._zod.bag;
5398
+ inst.minValue = Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null;
5399
+ inst.maxValue = Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null;
5400
+ inst.isInt = (bag.format ?? "").includes("int") || Number.isSafeInteger(bag.multipleOf ?? .5);
5401
+ inst.isFinite = true;
5402
+ inst.format = bag.format ?? null;
5403
+ });
5404
+ function number(params) {
5405
+ return /* @__PURE__ */ _number(ZodNumber, params);
5406
+ }
5407
+ const ZodNumberFormat = /*@__PURE__*/ $constructor("ZodNumberFormat", (inst, def) => {
5408
+ $ZodNumberFormat.init(inst, def);
5409
+ ZodNumber.init(inst, def);
5410
+ });
5411
+ function int(params) {
5412
+ return /* @__PURE__ */ _int(ZodNumberFormat, params);
5413
+ }
3631
5414
  const ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
3632
5415
  $ZodUnknown.init(inst, def);
3633
5416
  ZodType.init(inst, def);
@@ -3767,6 +5550,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3767
5550
  right
3768
5551
  });
3769
5552
  }
5553
+ const ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
5554
+ $ZodRecord.init(inst, def);
5555
+ ZodType.init(inst, def);
5556
+ inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
5557
+ inst.keyType = def.keyType;
5558
+ inst.valueType = def.valueType;
5559
+ });
5560
+ function record(keyType, valueType, params) {
5561
+ if (!valueType || !valueType._zod) return new ZodRecord({
5562
+ type: "record",
5563
+ keyType: string(),
5564
+ valueType: keyType,
5565
+ ...normalizeParams(valueType)
5566
+ });
5567
+ return new ZodRecord({
5568
+ type: "record",
5569
+ keyType,
5570
+ valueType,
5571
+ ...normalizeParams(params)
5572
+ });
5573
+ }
3770
5574
  const ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
3771
5575
  $ZodEnum.init(inst, def);
3772
5576
  ZodType.init(inst, def);
@@ -3974,7 +5778,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
3974
5778
  //#region remote-schema.js
3975
5779
  const sessionId = string().min(1);
3976
5780
  const monitorId = string().min(1);
5781
+ const activationId = string().min(1);
5782
+ const eventId = string().min(1);
5783
+ const expectedVersion = number().int().nonnegative().optional();
3977
5784
  const registrations = array(unknown());
5785
+ const events = array(unknown());
5786
+ const connectors = array(unknown());
5787
+ const managementListOptions = object({
5788
+ eventCursor: string().min(1).max(2048).nullable().optional(),
5789
+ eventLimit: number().int().min(1).max(100).optional(),
5790
+ bundleCursor: string().min(1).max(2048).nullable().optional(),
5791
+ bundleLimit: number().int().min(1).max(100).optional(),
5792
+ locale: _enum(["en-US", "zh-CN"]).optional()
5793
+ });
3978
5794
  const direct = (id, service, method, parameters, result, typeSymbol) => ({
3979
5795
  id: `relay-dsh-plugin-events#${id}`,
3980
5796
  service,
@@ -4003,12 +5819,51 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4003
5819
  const RELAY_REMOTE = {
4004
5820
  package: "relay-dsh-plugin-events",
4005
5821
  descriptors: [
4006
- direct("relayManagement/list", "relayManagement", "list", [], object({ registrations }), "RelayManagementSnapshot"),
5822
+ direct("relayManagement/list", "relayManagement", "list", [jsonParameter("options", managementListOptions, "RelayManagementListOptions")], object({
5823
+ registrations,
5824
+ bundle_types: array(unknown()),
5825
+ bundle_page: object({
5826
+ next_cursor: string().nullable(),
5827
+ total: number().int().nonnegative(),
5828
+ limit: number().int().positive()
5829
+ }),
5830
+ events,
5831
+ connectors,
5832
+ event_page: object({
5833
+ next_cursor: string().nullable(),
5834
+ total: number().int().nonnegative(),
5835
+ limit: number().int().positive()
5836
+ })
5837
+ }), "RelayManagementSnapshot"),
4007
5838
  direct("relayManagement/cancel", "relayManagement", "cancel", [jsonParameter("sessionId", sessionId, "SessionId")], object({ registration: unknown() }), "RelayCancelResult"),
4008
5839
  direct("relayManagement/runNow", "relayManagement", "runNow", [jsonParameter("monitorId", monitorId, "MonitorId")], object({
4009
5840
  result: unknown(),
4010
5841
  registrations
4011
- }), "RelayRunNowResult")
5842
+ }), "RelayRunNowResult"),
5843
+ direct("relayManagement/inspectMonitor", "relayManagement", "inspectMonitor", [jsonParameter("monitorId", monitorId, "MonitorId")], object({ monitor: unknown().nullable() }), "RelayInspectMonitorResult"),
5844
+ direct("relayManagement/pauseMonitor", "relayManagement", "pauseMonitor", [jsonParameter("monitorId", monitorId, "MonitorId"), jsonParameter("expectedVersion", expectedVersion, "ExpectedVersion")], object({ monitor: unknown() }), "RelayMonitorMutationResult"),
5845
+ direct("relayManagement/resumeMonitor", "relayManagement", "resumeMonitor", [jsonParameter("monitorId", monitorId, "MonitorId"), jsonParameter("expectedVersion", expectedVersion, "ExpectedVersion")], object({ monitor: unknown() }), "RelayMonitorMutationResult"),
5846
+ direct("relayManagement/updateMonitorCadence", "relayManagement", "updateMonitorCadence", [
5847
+ jsonParameter("monitorId", monitorId, "MonitorId"),
5848
+ jsonParameter("intervalSeconds", number().int().min(1).max(86400), "IntervalSeconds"),
5849
+ jsonParameter("expectedVersion", expectedVersion, "ExpectedVersion")
5850
+ ], object({ monitor: unknown() }), "RelayMonitorMutationResult"),
5851
+ direct("relayManagement/stopMonitor", "relayManagement", "stopMonitor", [
5852
+ jsonParameter("monitorId", monitorId, "MonitorId"),
5853
+ jsonParameter("expectedVersion", expectedVersion, "ExpectedVersion"),
5854
+ jsonParameter("reasonCode", string().min(1).max(128), "MonitorReasonCode"),
5855
+ jsonParameter("detail", string().max(2e3), "MonitorReasonDetail")
5856
+ ], object({ monitor: unknown() }), "RelayMonitorMutationResult"),
5857
+ direct("relayManagement/retryActivation", "relayManagement", "retryActivation", [jsonParameter("activationId", activationId, "ActivationId")], object({
5858
+ activation: unknown(),
5859
+ result: unknown()
5860
+ }), "RelayActivationRetryResult"),
5861
+ direct("relayManagement/retryNotification", "relayManagement", "retryNotification", [jsonParameter("eventId", eventId, "EventId")], object({ notification: unknown() }), "RelayNotificationRetryResult"),
5862
+ direct("relayManagement/connectorAction", "relayManagement", "connectorAction", [
5863
+ jsonParameter("connectorId", string().min(1).max(64), "ConnectorId"),
5864
+ jsonParameter("action", string().min(1).max(64), "ConnectorAction"),
5865
+ jsonParameter("input", record(string(), unknown()), "ConnectorActionInput")
5866
+ ], object({ connector: unknown() }), "RelayConnectorActionResult")
4012
5867
  ]
4013
5868
  };
4014
5869
  //#endregion
@@ -4036,17 +5891,43 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4036
5891
  throw new Error(result.error?.message ?? "Relay Events management request failed");
4037
5892
  };
4038
5893
  const injected = () => ({
4039
- list: async () => unwrap(await remote.list()),
5894
+ list: async (options) => unwrap(await remote.list({
5895
+ ...options,
5896
+ locale: ctx.locale.getSnapshot().active.startsWith("zh") ? "zh-CN" : "en-US"
5897
+ })),
4040
5898
  cancel: async (sessionId) => {
4041
5899
  unwrap(await remote.cancel(sessionId));
4042
5900
  },
4043
5901
  runNow: async (monitorId) => {
4044
5902
  unwrap(await remote.runNow(monitorId));
4045
5903
  },
5904
+ pauseMonitor: async (monitorId, version) => {
5905
+ unwrap(await remote.pauseMonitor(monitorId, version));
5906
+ },
5907
+ resumeMonitor: async (monitorId, version) => {
5908
+ unwrap(await remote.resumeMonitor(monitorId, version));
5909
+ },
5910
+ updateMonitorCadence: async (monitorId, intervalSeconds, version) => {
5911
+ unwrap(await remote.updateMonitorCadence(monitorId, intervalSeconds, version));
5912
+ },
5913
+ stopMonitor: async (monitorId, version) => {
5914
+ unwrap(await remote.stopMonitor(monitorId, version, "stopped_by_user", ""));
5915
+ },
5916
+ retryActivation: async (activationId) => {
5917
+ unwrap(await remote.retryActivation(activationId));
5918
+ },
5919
+ retryNotification: async (eventId) => {
5920
+ unwrap(await remote.retryNotification(eventId));
5921
+ },
5922
+ connectorAction: async (connectorId, action, input = {}) => {
5923
+ unwrap(await remote.connectorAction(connectorId, action, input));
5924
+ },
4046
5925
  openSession: (sessionId) => {
4047
5926
  ctx.sessions.open(sessionId);
4048
5927
  },
4049
- t
5928
+ t,
5929
+ getLocale: () => ctx.locale.getSnapshot().active,
5930
+ subscribeLocale: (listener) => ctx.locale.subscribe(listener)
4050
5931
  });
4051
5932
  ctx.slots.inject("settings.section", () => ctx.slots.register({
4052
5933
  name: "settings.section",