@hhuangpanda/dsh-automation 0.0.0-stage → 0.3.34

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.
Files changed (63) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +133 -2
  3. package/README.zh.md +134 -0
  4. package/cordis.patch.yml +3 -0
  5. package/docs/images/automation-overview-en.png +0 -0
  6. package/docs/images/automation-overview-zh.png +0 -0
  7. package/docs/reference.md +55 -0
  8. package/docs/reference.zh.md +55 -0
  9. package/lib/agent-configuration.d.ts +27 -0
  10. package/lib/agent-configuration.js +217 -0
  11. package/lib/api.d.ts +5 -0
  12. package/lib/api.js +253 -0
  13. package/lib/client/AutomationPanel.d.ts +9 -0
  14. package/lib/client/EmptyState.d.ts +10 -0
  15. package/lib/client/ModelSelection.d.ts +17 -0
  16. package/lib/client/ScheduleSection.d.ts +32 -0
  17. package/lib/client/SchedulerHealth.d.ts +10 -0
  18. package/lib/client/SkillPicker.d.ts +15 -0
  19. package/lib/client/TaskDetail.d.ts +34 -0
  20. package/lib/client/TaskEditor.d.ts +38 -0
  21. package/lib/client/TaskRow.d.ts +12 -0
  22. package/lib/client/editor-layout.d.ts +20 -0
  23. package/lib/client/i18n.d.ts +15 -0
  24. package/lib/client/icons.d.ts +30 -0
  25. package/lib/client/index.d.ts +6 -0
  26. package/lib/client/locales.d.ts +260 -0
  27. package/lib/client/rrule-editor.d.ts +15 -0
  28. package/lib/client/session-selection.d.ts +4 -0
  29. package/lib/client/shared.d.ts +77 -0
  30. package/lib/client/store.d.ts +40 -0
  31. package/lib/client.js +3014 -0
  32. package/lib/controller.d.ts +36 -0
  33. package/lib/controller.js +154 -0
  34. package/lib/domain.d.ts +44 -0
  35. package/lib/domain.js +473 -0
  36. package/lib/errors.d.ts +14 -0
  37. package/lib/errors.js +16 -0
  38. package/lib/im-delivery.d.ts +30 -0
  39. package/lib/im-delivery.js +69 -0
  40. package/lib/index.d.ts +25 -0
  41. package/lib/index.js +92 -0
  42. package/lib/recurrence.d.ts +14 -0
  43. package/lib/recurrence.js +203 -0
  44. package/lib/runner.d.ts +27 -0
  45. package/lib/runner.js +295 -0
  46. package/lib/runtime-marker.d.ts +3 -0
  47. package/lib/runtime-marker.js +2 -0
  48. package/lib/scheduler.d.ts +58 -0
  49. package/lib/scheduler.js +287 -0
  50. package/lib/store.d.ts +14 -0
  51. package/lib/store.js +108 -0
  52. package/lib/tool-configuration.d.ts +8 -0
  53. package/lib/tool-configuration.js +220 -0
  54. package/lib/tool-support.d.ts +67 -0
  55. package/lib/tool-support.js +47 -0
  56. package/lib/tools.d.ts +6 -0
  57. package/lib/tools.js +140 -0
  58. package/lib/types.d.ts +465 -0
  59. package/lib/types.js +99 -0
  60. package/lib/validation.d.ts +34 -0
  61. package/lib/validation.js +99 -0
  62. package/package.json +163 -4
  63. package/screenshots.json +1 -0
package/lib/client.js ADDED
@@ -0,0 +1,3014 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "@hhuangpanda/dsh-automation",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ "use strict";
7
+ var __create = Object.create;
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __getProtoOf = Object.getPrototypeOf;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
26
+ // If the importer is in node compatibility mode or this is not an ESM
27
+ // file that has been converted to a CommonJS file using a Babel-
28
+ // compatible transform (i.e. "__esModule" has not been set), then set
29
+ // "default" to the CommonJS "module.exports" for node compatibility.
30
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
31
+ mod
32
+ ));
33
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
+
35
+ // src/client/index.tsx
36
+ var index_exports = {};
37
+ __export(index_exports, {
38
+ apply: () => apply,
39
+ inject: () => inject
40
+ });
41
+ module.exports = __toCommonJS(index_exports);
42
+ var import_react14 = __toESM(require("react"), 1);
43
+
44
+ // src/client/icons.tsx
45
+ var import_jsx_runtime = require("react/jsx-runtime");
46
+ function Svg({ size = 16, className, viewBox = "0 0 16 16", children }) {
47
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: size, height: size, className, viewBox, fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", strokeWidth: 1, children });
48
+ }
49
+ function IconAgentPresetOutline16(props) {
50
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
51
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.51867 12.3282C7.29816 12.6011 8.16475 12.6514 9.02269 12.4216C9.57879 12.2726 10.0784 12.0185 10.5087 11.6888C10.7819 12.0555 11.1606 12.3304 11.5913 12.4805C10.9688 13.029 10.2149 13.4478 9.35911 13.6771C8.13946 14.0038 6.90632 13.8971 5.82126 13.4533C6.15821 13.1562 6.4021 12.7652 6.51867 12.3282ZM9.17629 2.89409C11.1101 3.34433 12.739 4.81872 13.2889 6.87043C13.4219 7.3665 13.4811 7.8649 13.4774 8.35466C13.0924 8.13213 12.6422 8.01837 12.1741 8.05276L12.1711 8.05257C12.1539 7.77199 12.109 7.48889 12.0334 7.20684C11.6363 5.72533 10.5048 4.6372 9.13549 4.22844C9.25559 3.87667 9.29214 3.49087 9.22309 3.09892C9.2108 3.02922 9.19451 2.96108 9.17629 2.89409ZM4.7311 3.89107L4.78302 4.11879C4.87648 4.4488 5.04146 4.74263 5.25579 4.98896C3.98078 6.01355 3.35848 7.72904 3.8089 9.41059C3.81828 9.44559 3.82866 9.48025 3.83885 9.51479C3.38217 9.61268 2.98548 9.84137 2.68107 10.1556C2.63414 10.022 2.5897 9.88632 2.55244 9.74726C1.93301 7.43489 2.86717 5.07173 4.71504 3.76697L4.7311 3.89107Z", fill: "currentColor" }),
52
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7.99136 5.28105C8.87501 5.28105 9.59136 4.56471 9.59136 3.68105C9.59136 2.7974 8.87501 2.08105 7.99136 2.08105C7.1077 2.08105 6.39136 2.7974 6.39136 3.68105C6.39136 4.56471 7.1077 5.28105 7.99136 5.28105Z", stroke: "currentColor" }),
53
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3.94009 12.9417C4.82374 12.9417 5.54009 12.2254 5.54009 11.3417C5.54009 10.458 4.82374 9.7417 3.94009 9.7417C3.05643 9.7417 2.34009 10.458 2.34009 11.3417C2.34009 12.2254 3.05643 12.9417 3.94009 12.9417Z", stroke: "currentColor" }),
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12.0851 12.9417C12.9688 12.9417 13.6851 12.2254 13.6851 11.3417C13.6851 10.458 12.9688 9.7417 12.0851 9.7417C11.2015 9.7417 10.4851 10.458 10.4851 11.3417C10.4851 12.2254 11.2015 12.9417 12.0851 12.9417Z", stroke: "currentColor" })
55
+ ] });
56
+ }
57
+ function IconAlarmClockOutline16(props) {
58
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, viewBox: "0 0 17 17", children: [
59
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4.09372 11.9895L3.11865 14.0387", stroke: "currentColor" }),
60
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12.1392 11.9895L13.1143 14.0387", stroke: "currentColor" }),
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.11646 4.78442V8.03442L10.6165 9.53442", stroke: "currentColor" }),
62
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.11646 13.4094C11.154 13.4094 13.6165 10.947 13.6165 7.90942C13.6165 4.87186 11.154 2.40942 8.11646 2.40942C5.07889 2.40942 2.61646 4.87186 2.61646 7.90942C2.61646 10.947 5.07889 13.4094 8.11646 13.4094Z", stroke: "currentColor" }),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1.75952 4.74323C2.30657 3.65639 3.12646 2.73047 4.12926 2.05542", stroke: "currentColor" }),
64
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14.3345 4.74323C13.7874 3.65639 12.9675 2.73047 11.9647 2.05542", stroke: "currentColor" })
65
+ ] });
66
+ }
67
+ function IconCheckOutline16(props) {
68
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.25 8.5L5.49732 11.7473C5.90519 12.1552 6.57263 12.1344 6.95426 11.7018L13.75 4", stroke: "currentColor" }) });
69
+ }
70
+ function IconChevronDownOutline14(props) {
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { ...props, size: props.size ?? 14, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M4 6L7.29289 9.29289C7.68342 9.68342 8.31658 9.68342 8.70711 9.29289L12 6", stroke: "currentColor" }) });
72
+ }
73
+ function IconChevronLeftOutline14(props) {
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { ...props, size: props.size ?? 14, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 4L6.70711 7.29289C6.31658 7.68342 6.31658 8.31658 6.70711 8.70711L10 12", stroke: "currentColor" }) });
75
+ }
76
+ function IconChevronRightOutline14(props) {
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { ...props, size: props.size ?? 14, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 12L9.29289 8.70711C9.68342 8.31658 9.68342 7.68342 9.29289 7.29289L6 4", stroke: "currentColor" }) });
78
+ }
79
+ function IconClockOutline16(props) {
80
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
81
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14Z", stroke: "currentColor" }),
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 4.31V8.46L11 10.08", stroke: "currentColor" })
83
+ ] });
84
+ }
85
+ function IconCloseOutline16(props) {
86
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
87
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.5 2.5L13.5 13.5", stroke: "currentColor" }),
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M13.5 2.5L2.5 13.5", stroke: "currentColor" })
89
+ ] });
90
+ }
91
+ function IconCopyOutline16(props) {
92
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "1.52075", y: "4.07373", width: "10.3932", height: "10.3932", rx: "2", stroke: "currentColor" }),
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M11.9792 1.53296C13.36 1.53296 14.4792 2.65225 14.4792 4.03296V9.42847C14.4792 10.3756 13.9521 11.1987 13.1755 11.6228V10.3298C13.3652 10.0787 13.4792 9.7674 13.4792 9.42847V4.03296C13.4792 3.20453 12.8077 2.53296 11.9792 2.53296H6.58374C6.27966 2.53301 5.99684 2.6235 5.7605 2.77905H4.42358C4.85652 2.03463 5.66056 1.53304 6.58374 1.53296H11.9792Z", fill: "currentColor" })
95
+ ] });
96
+ }
97
+ function IconEditOutline16(props) {
98
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
99
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.85596 2.69971H4.19971C3.37141 2.69971 2.69992 3.37146 2.69971 4.19971V11.8003C2.69992 12.6285 3.37141 13.3003 4.19971 13.3003H11.8003C12.6283 13.2999 13.3001 12.6283 13.3003 11.8003V7.89893H14.3003V11.8003C14.3001 13.1806 13.1806 14.2999 11.8003 14.3003H4.19971C2.81913 14.3003 1.69992 13.1808 1.69971 11.8003V4.19971C1.69992 2.81918 2.81913 1.69971 4.19971 1.69971H8.85596V2.69971Z", fill: "currentColor" }),
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7.7849 8.23878L13.888 2.13574", stroke: "currentColor" })
101
+ ] });
102
+ }
103
+ function IconEllipsisOutline16(props) {
104
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 9C3.55228 9 4 8.55228 4 8C4 7.44772 3.55228 7 3 7C2.44772 7 2 7.44772 2 8C2 8.55228 2.44772 9 3 9Z", fill: "currentColor" }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 9C8.55228 9 9 8.55228 9 8C9 7.44772 8.55228 7 8 7C7.44772 7 7 7.44772 7 8C7 8.55228 7.44772 9 8 9Z", fill: "currentColor" }),
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M13 9C13.5523 9 14 8.55228 14 8C14 7.44772 13.5523 7 13 7C12.4477 7 12 7.44772 12 8C12 8.55228 12.4477 9 13 9Z", fill: "currentColor" })
108
+ ] });
109
+ }
110
+ function IconFolderOpenOutline16(props) {
111
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12.3994 13.5986H2.04956C1.49728 13.5986 1.04956 13.1509 1.04956 12.5986V3.40137C1.04956 2.84908 1.49728 2.40137 2.04956 2.40137H4.76632C5.01016 2.40137 5.24561 2.49046 5.42836 2.6519L6.94088 3.98799C7.12364 4.14943 7.35908 4.23852 7.60293 4.23852H12.3994C12.9517 4.23852 13.3994 4.68624 13.3994 5.23852V7.16991", stroke: "currentColor" }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.55911 7.93683C2.67584 7.49906 3.07229 7.19446 3.52536 7.19446H13.6491C14.3061 7.19446 14.7846 7.81725 14.6153 8.45209L13.4411 12.856C13.3244 13.2938 12.9279 13.5984 12.4748 13.5984H2.35113C1.69411 13.5984 1.21562 12.9756 1.38489 12.3407L2.55911 7.93683Z", stroke: "currentColor" })
114
+ ] });
115
+ }
116
+ function IconLoadingOutline16(props) {
117
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12.596 12.596C11.687 13.5049 10.5288 14.1239 9.26798 14.3747C8.00716 14.6255 6.70028 14.4968 5.51261 14.0048C4.32494 13.5129 3.30981 12.6798 2.59557 11.611C1.88134 10.5421 1.50008 9.2855 1.5 7.99998C1.50008 6.71446 1.88134 5.45783 2.59557 4.38898C3.30981 3.32013 4.32494 2.48707 5.51261 1.99513C6.70028 1.50319 8.00716 1.37447 9.26798 1.62524C10.5288 1.87602 11.687 2.49502 12.596 3.40398", stroke: "currentColor" }) });
118
+ }
119
+ function IconPauseOutline16(props) {
120
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
121
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5Z", stroke: "currentColor" }),
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.5 5V11", stroke: "currentColor" }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9.5 5V11", stroke: "currentColor" })
124
+ ] });
125
+ }
126
+ function IconPlayOutline16(props) {
127
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5Z", stroke: "currentColor" }),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10.3329 7.91346C10.3996 7.95195 10.3996 8.04818 10.3329 8.08667L6.78304 10.1362C6.71638 10.1747 6.63304 10.1266 6.63304 10.0496L6.63304 5.95055C6.63304 5.87357 6.71638 5.82546 6.78304 5.86395L10.3329 7.91346Z", stroke: "currentColor" })
130
+ ] });
131
+ }
132
+ function IconPlusOutline16(props) {
133
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 2V14", stroke: "currentColor" }),
135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 8H14", stroke: "currentColor" })
136
+ ] });
137
+ }
138
+ function IconQuestionOutline14(props) {
139
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, size: props.size ?? 14, children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5Z", stroke: "currentColor" }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5.75 6.69646C5.75 6.29865 5.88196 5.90976 6.12919 5.57899C6.37643 5.24821 6.72783 4.99041 7.13896 4.83817C7.5501 4.68593 8.0025 4.6461 8.43895 4.72371C8.87541 4.80132 9.27632 4.99289 9.59099 5.27419C9.90566 5.55549 10.12 5.91388 10.2068 6.30406C10.2936 6.69423 10.249 7.09866 10.0787 7.4662C9.90843 7.83373 9.62004 8.14787 9.25003 8.36889C9.19476 8.4019 9.13803 8.43262 9.08004 8.46099C8.52566 8.73217 8 9.20817 8 9.82532", stroke: "currentColor" }),
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 10.7416V11.7416", stroke: "currentColor" })
143
+ ] });
144
+ }
145
+ function IconRefreshOutline16(props) {
146
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14.5001 8C14.5 9.28552 14.1188 10.5422 13.4045 11.611C12.6903 12.6799 11.6752 13.5129 10.4875 14.0049C9.29982 14.4968 7.99295 14.6255 6.73212 14.3747C5.4713 14.124 4.31314 13.505 3.4041 12.596C2.49514 11.687 1.87614 10.5288 1.62537 9.26798C1.37459 8.00716 1.50331 6.70028 1.99525 5.51261C2.48719 4.32494 3.32025 3.30981 4.3891 2.59557C5.45795 1.88134 6.71458 1.50008 8.0001 1.5C9.9001 1.5 11.7001 2.3 13.0001 3.6L14.5001 5.1", stroke: "currentColor" }),
148
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14.4999 1.5V5.1H10.8999", stroke: "currentColor" })
149
+ ] });
150
+ }
151
+ function IconRightUpOutline14(props) {
152
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconRightUpOutline16, { ...props, size: props.size ?? 14 });
153
+ }
154
+ function IconRightUpOutline16(props) {
155
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M11.7256 2.77441C12.5538 2.77469 13.2256 3.44616 13.2256 4.27441V10.1416H12.2256V4.27441C12.2256 3.99844 12.0015 3.77469 11.7256 3.77441H5.7207V2.77441H11.7256Z", fill: "currentColor" }),
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.77441 13.2255L12.3756 3.62427", stroke: "currentColor" })
158
+ ] });
159
+ }
160
+ function IconSearchOutline16(props) {
161
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.58727 11.8586C9.55061 11.8586 11.9529 9.45637 11.9529 6.49304C11.9529 3.5297 9.55061 1.12744 6.58727 1.12744C3.62394 1.12744 1.22168 3.5297 1.22168 6.49304C1.22168 9.45637 3.62394 11.8586 6.58727 11.8586Z", stroke: "currentColor" }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10.2991 10.3933L14.7783 14.8725", stroke: "currentColor" })
164
+ ] });
165
+ }
166
+ function IconStopFill16(props) {
167
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12.5 2.5H3.5C2.94772 2.5 2.5 2.94772 2.5 3.5V12.5C2.5 13.0523 2.94772 13.5 3.5 13.5H12.5C13.0523 13.5 13.5 13.0523 13.5 12.5V3.5C13.5 2.94772 13.0523 2.5 12.5 2.5Z", fill: "currentColor" }) });
168
+ }
169
+ function IconTrashOutline16(props) {
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1.28149 3.88831H14.7187", stroke: "currentColor" }),
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5.41602 3.88833V2.47962C5.41602 2.29282 5.52492 2.11366 5.71876 1.98157C5.9126 1.84948 6.17551 1.77527 6.44964 1.77527H9.55053C9.82466 1.77527 10.0876 1.84948 10.2814 1.98157C10.4753 2.11366 10.5842 2.29282 10.5842 2.47962V3.88833", stroke: "currentColor" }),
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.57349 3.88831L3.19366 13.2943C3.21937 13.5502 3.33952 13.7872 3.53065 13.9593C3.72178 14.1313 3.97016 14.2259 4.22729 14.2246H11.7728C12.0299 14.2259 12.2783 14.1313 12.4694 13.9593C12.6605 13.7872 12.7807 13.5502 12.8064 13.2943L13.4266 3.88831", stroke: "currentColor" }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.44946 6.98926V11.1238", stroke: "currentColor" }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9.55054 6.98926V11.1238", stroke: "currentColor" })
176
+ ] });
177
+ }
178
+ function IconWarningOutline16(props) {
179
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { ...props, children: [
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5Z", stroke: "currentColor" }),
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 4.29199V9.79199", stroke: "currentColor" }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 10.708V11.708", stroke: "currentColor" })
183
+ ] });
184
+ }
185
+
186
+ // src/client/i18n.ts
187
+ var import_react = __toESM(require("react"), 1);
188
+
189
+ // src/client/locales.ts
190
+ var en = {
191
+ automations: "Automations",
192
+ openAutomations: "Open Automations",
193
+ newAutomation: "New automation",
194
+ guidedCreationPrompt: "Help me create a new automation for this workspace. Ask only for missing essentials. Use automation_options before selecting Host ids. Before creating it, preview Name, Schedule/time zone, Workspace, Agent preset, Provider/Model, Reasoning effort (default or a supported level), ordered Skills, exact Host Permission, Notifications, and failure-pause policy, including any approval warning; then wait for my explicit confirmation. Do not call automation_create until I confirm.",
195
+ refresh: "Refresh",
196
+ close: "Close",
197
+ details: "Details",
198
+ configuration: "Settings",
199
+ loadFailed: "Could not load tasks",
200
+ loadFailedHint: "Check the connection and try again. No tasks have been changed.",
201
+ noScheduledRun: "No upcoming run",
202
+ noFilteredTasks: "No tasks in this view",
203
+ resetFilters: "Show all tasks",
204
+ discardTitle: "Discard changes?",
205
+ discardDescription: "Your changes have not been saved. Keep editing or discard them to continue.",
206
+ keepEditing: "Keep editing",
207
+ discardChanges: "Discard changes",
208
+ unsavedChanges: "Unsaved changes",
209
+ editorConfigInvalid: "Review agent execution and permissions: some selected options are unavailable or incomplete.",
210
+ editorRequiredFields: "Complete the required fields; values cannot contain only spaces.",
211
+ copy: "Copy",
212
+ taskCount: "Tasks \xB7 {count}",
213
+ loading: "Loading automations\u2026",
214
+ noAutomations: "Start with an idea",
215
+ createHint: "Give recurring work a schedule. Choose an example or start a new task, then confirm what to do and when in a conversation.",
216
+ exampleDraftHint: "Nothing is sent automatically. Review or rewrite the prompt, then send it when ready.",
217
+ creatingConversation: "Opening a new conversation\u2026",
218
+ workspaceUnavailable: "Open a workspace before creating an automation.",
219
+ newConversationFailed: "Could not open a new conversation: {error}",
220
+ exampleReleaseTitle: "Tomorrow\u2019s release check",
221
+ exampleReleaseDescription: "Tomorrow 09:00 \xB7 read only \xB7 failures only",
222
+ exampleReleasePrompt: "Create a one-time automation for tomorrow at 9:00 AM in my current time zone. Name it \u201CRelease readiness check\u201D. When it runs, inspect this workspace for release blockers and run relevant existing checks without modifying source files. End with Ready or Blocked, followed by blockers and evidence. Use read-only permission and notify me only if the run fails. Before creating it, show the complete creation preview and wait for my confirmation.",
223
+ exampleDependenciesTitle: "Monday dependency watch",
224
+ exampleDependenciesDescription: "Mondays 09:30 \xB7 read only \xB7 every run",
225
+ exampleDependenciesPrompt: "Create a recurring automation for every Monday at 9:30 AM in my current time zone. Name it \u201CDependency watch\u201D. When it runs, inspect dependency manifests and lockfiles for important updates, compatibility risks, and security concerns without modifying files. Report high-risk findings first and give a concrete recommendation for each. Use read-only permission, notify me after every run, and pause after 3 consecutive failures. Before creating it, show the complete creation preview and wait for my confirmation.",
226
+ exampleHandoffTitle: "Weekday handoff",
227
+ exampleHandoffDescription: "Weekdays 18:00 \xB7 read only \xB7 every run",
228
+ exampleHandoffPrompt: "Create a recurring automation for every weekday at 6:00 PM in my current time zone. Name it \u201CDaily handoff\u201D. When it runs, inspect today\u2019s workspace changes without modifying files and produce a concise handoff with Completed, Decisions, Next actions, and Blockers. Use read-only permission and notify me after every run. Before creating it, show the complete creation preview and wait for my confirmation.",
229
+ once: "Once",
230
+ next: "Next",
231
+ schedule: "Schedule",
232
+ workspace: "Workspace",
233
+ executionDestination: "Execution destination",
234
+ executionMode: "Session mode",
235
+ executionExisting: "Use an existing session",
236
+ targetSession: "Target session",
237
+ selectSession: "Select a session",
238
+ currentSession: "Current session",
239
+ sessionSearch: "Search session title or ID",
240
+ sessionWorkspaceHint: "Only sessions in this task\u2019s workspace: {cwd}",
241
+ pinnedSessionHint: "Append each run to this session with its existing context and Agent/model configuration; skills are not reloaded. The task\u2019s permission preset is applied to the session. Busy or unavailable sessions fail without creating a new one.",
242
+ sessionTargetLocked: "Wait until queued or running work finishes before changing the session.",
243
+ sessionsLoading: "Loading sessions\u2026",
244
+ sessionsFailure: "Could not refresh sessions: {error}",
245
+ sessionsNotReady: "No session list was received. Try again.",
246
+ noSessionMatches: "No matching sessions in this workspace.",
247
+ targetSessionUnavailable: "The saved session is unavailable in this workspace. Select another session or use a new session.",
248
+ sessionTargetSaveHint: "Saving applies this execution destination to future runs: {target}.",
249
+ executionFresh: "New session for every run",
250
+ executionPinned: "Continue existing session \xB7 {sessionId} \xB7 fallback: fail",
251
+ permission: "Permission",
252
+ permissionReadOnly: "Read only",
253
+ permissionFullAccess: "Full access",
254
+ agentExecution: "Agent execution",
255
+ agentPreset: "Agent preset",
256
+ provider: "Provider",
257
+ model: "Model",
258
+ reasoningEffort: "Reasoning effort",
259
+ reasoningDefault: "Default (no override)",
260
+ reasoningDefaultShort: "Default",
261
+ modelAndReasoning: "Model and reasoning",
262
+ reasoningHint: "Default leaves reasoning settings unchanged. Other levels come from the selected model.",
263
+ reasoningSelectModel: "Choose a provider and model to set a reasoning level.",
264
+ reasoningUnsupported: "This model does not offer selectable reasoning levels.",
265
+ reasoningUnavailable: "The Host did not return reasoning options. Restart DSH if the plugin was just updated.",
266
+ reasoningFailure: "Could not load reasoning levels: {error}",
267
+ reasoningSession: "Use target session settings",
268
+ selectedSkills: "Selected skills",
269
+ noSelectedSkills: "No selected skills",
270
+ noSkills: "No user-invocable skills are available for this preset.",
271
+ modelInvocable: "also model-invocable",
272
+ hostDefault: "Host default",
273
+ unavailable: "unavailable",
274
+ notInCatalog: "not listed (validated when saved)",
275
+ optionsLoading: "Loading Host options\u2026",
276
+ optionsFailure: "Could not load Host options: {error}",
277
+ providerFailure: "{provider} model catalog failed: {error}",
278
+ selectModel: "Select a model",
279
+ approvalAskWarning: "This permission asks for approval. Unattended runs never auto-approve and may wait until their timeout.",
280
+ confirmPermissionChange: "I confirm future runs may use {permission}.",
281
+ messageDelivery: "Message delivery",
282
+ deliveryEnabled: "Send via dsh-im",
283
+ deliveryHint: "Enabling sends results outside DSH. Saved changes apply to future runs.",
284
+ deliveryHelp: "About message delivery",
285
+ deliveryHelpText: "Send Automation results and failure reports through dsh-im installed on the same Host. Configure a bot and save a target in dsh-im first. No pinned Session or two-way sync is required.",
286
+ deliveryBot: "Bot",
287
+ deliveryTarget: "Saved target",
288
+ selectDeliveryBot: "Select a bot",
289
+ selectDeliveryTarget: "Select a saved target",
290
+ deliveryLocked: "Wait until queued or running work finishes before changing delivery.",
291
+ deliveryLoading: "Loading delivery options\u2026",
292
+ deliveryLoadFailed: "Could not load delivery options: {error}",
293
+ deliveryUnavailable: "dsh-im delivery is unavailable. You can keep the saved destination or turn delivery off.",
294
+ deliverySavedUnavailable: "The saved bot or target is unavailable. Keep it unchanged, choose another, or turn delivery off.",
295
+ deliveryNoBots: "No bots available. Configure a bot in dsh-im, then refresh.",
296
+ deliveryNoTargets: "No saved targets. Add a target in dsh-im settings, then refresh.",
297
+ deliverySaveHint: "Saving sends future task results and failure reports outside DSH to {bot} / {target}.",
298
+ deliverySending: "Sending",
299
+ deliverySent: "Platform accepted",
300
+ deliveryFailed: "Delivery failed",
301
+ deliveryUnknown: "Delivery unknown",
302
+ deliveryError: "Message delivery: {error}",
303
+ deliveryAttemptedAt: "Delivery attempted",
304
+ deliveryFinishedAt: "Delivery finished",
305
+ notifications: "Notifications",
306
+ notificationFailures: "Failures only",
307
+ notificationAlways: "Every completion",
308
+ notificationNever: "Never",
309
+ pauseAfterFailures: "Pause after 3 failures",
310
+ enabled: "Enabled",
311
+ disabled: "Disabled",
312
+ consecutiveFailures: "Consecutive failures",
313
+ unreadNotifications: "{count} unread automation notifications",
314
+ runNow: "Run now",
315
+ retry: "Retry",
316
+ stopRun: "Stop run",
317
+ pause: "Pause",
318
+ resume: "Resume",
319
+ resumeAndRun: "Resume & run",
320
+ openLatestSession: "Open latest session",
321
+ edit: "Edit",
322
+ editTask: "Edit automation",
323
+ editFutureRunsHint: "Changes apply to future runs.",
324
+ sectionBasics: "Basics",
325
+ nameLabel: "Name",
326
+ promptLabel: "Instructions",
327
+ scheduleType: "Schedule type",
328
+ oneTimeSchedule: "One time",
329
+ recurringSchedule: "Recurring",
330
+ runAt: "Run at",
331
+ recurrenceRule: "Recurrence",
332
+ ruleMode: "Recurrence editor mode",
333
+ visualMode: "Visual",
334
+ advancedMode: "Advanced RRULE",
335
+ advancedRuleHint: "Use a single RFC 5545 RRULE without DTSTART.",
336
+ unsupportedRuleHint: "This rule uses advanced options. Edit the RRULE string or simplify it before switching to Visual.",
337
+ frequency: "Frequency",
338
+ frequencyDaily: "Daily",
339
+ frequencyWeekly: "Weekly",
340
+ frequencyMonthly: "Monthly",
341
+ everyDay: "Every day",
342
+ everyDays: "Every {count} days",
343
+ everyWeek: "Every week",
344
+ everyWeeks: "Every {count} weeks",
345
+ everyMonth: "Every month",
346
+ everyMonths: "Every {count} months",
347
+ dayOfMonth: "day {day}",
348
+ repeatEvery: "Repeat every",
349
+ intervalDays: "day(s)",
350
+ intervalWeeks: "week(s)",
351
+ intervalMonths: "month(s)",
352
+ repeatOn: "Repeat on",
353
+ monthlyOnDay: "Day of month",
354
+ useStartDayHint: "No selection uses the weekday from the start date.",
355
+ ends: "Ends",
356
+ endsNever: "Never",
357
+ endsAfter: "After a number of runs",
358
+ endsOnDate: "On a date",
359
+ occurrences: "Number of runs",
360
+ endDate: "End date",
361
+ weekdayLabel: "{day}",
362
+ weekdaySeparator: ", ",
363
+ weekdayMonday: "Mon",
364
+ weekdayTuesday: "Tue",
365
+ weekdayWednesday: "Wed",
366
+ weekdayThursday: "Thu",
367
+ weekdayFriday: "Fri",
368
+ weekdaySaturday: "Sat",
369
+ weekdaySunday: "Sun",
370
+ timeZone: "Time zone",
371
+ startsAt: "Starts at",
372
+ saveChanges: "Save changes",
373
+ saving: "Saving\u2026",
374
+ delete: "Delete",
375
+ cancel: "Cancel",
376
+ confirmDelete: "Delete task",
377
+ deleteConfirm: "Delete \u201C{name}\u201D? Existing run sessions will remain.",
378
+ latestResult: "Latest result",
379
+ recentRuns: "Recent runs ({count})",
380
+ open: "Open",
381
+ requestFailed: "Automation request failed ({status}).",
382
+ taskId: "Task ID",
383
+ schedulerRetrying: "Scheduling temporarily failed and will retry automatically: {error}",
384
+ schedulerStopped: "Scheduling is stopped. Restart DSH to resume automations.",
385
+ unknownError: "Unknown error",
386
+ statusActive: "active",
387
+ statusPaused: "paused",
388
+ statusCompleted: "completed",
389
+ statusQueued: "queued",
390
+ statusRunning: "running",
391
+ statusSucceeded: "succeeded",
392
+ statusFailed: "failed",
393
+ statusInterrupted: "interrupted",
394
+ statusOutcomeUnknown: "outcome unknown",
395
+ statusTimedOut: "timed out",
396
+ statusCanceled: "canceled",
397
+ triggerManual: "manual",
398
+ triggerScheduled: "scheduled",
399
+ searchPlaceholder: "Search automations",
400
+ filterAll: "All",
401
+ filterActive: "Active",
402
+ filterPaused: "Paused",
403
+ filterCompleted: "Completed",
404
+ noMatches: "No automation matches \u201C{query}\u201D.",
405
+ clearSearch: "Clear search",
406
+ selectTaskHint: "Select an automation to see its schedule, configuration, and run history.",
407
+ backToList: "Back to list",
408
+ moreActions: "More actions",
409
+ overview: "Overview",
410
+ runHistory: "Run history",
411
+ noRuns: "No run records.",
412
+ deleteRun: "Delete record",
413
+ deletingRun: "Deleting\u2026",
414
+ deleteRunTitle: "Delete this run record?",
415
+ deleteRunConfirm: "Only this run record will be deleted. Its session and sent messages are kept, and future runs are unaffected. This cannot be undone.",
416
+ deleteRunBlocked: "Wait until execution and message delivery have finished before deleting this record.",
417
+ deleteRunFailed: "Could not delete the record: {error}. You can try again.",
418
+ schedulerHealthy: "Scheduler healthy",
419
+ schedulerHealthRetrying: "Scheduler retrying",
420
+ schedulerHealthStopped: "Scheduler stopped",
421
+ schedulerLastError: "Last error",
422
+ schedulerLastFailedAt: "Last failed",
423
+ schedulerRetryAt: "Next retry",
424
+ schedulerFailureCount: "Consecutive scheduling failures",
425
+ createdAt: "Created",
426
+ createdBySession: "Created in session",
427
+ pausedAt: "Paused at",
428
+ pausedNextRunAt: "Next run when resumed",
429
+ runId: "Run ID",
430
+ enqueuedAt: "Queued",
431
+ startedAt: "Started",
432
+ finishedAt: "Finished",
433
+ duration: "Duration",
434
+ trigger: "Trigger",
435
+ runTarget: "Run target",
436
+ skillSearchPlaceholder: "Filter skills",
437
+ noSkillMatches: "No skill matches the filter.",
438
+ selectedCount: "{count} selected",
439
+ clearSkills: "Clear all",
440
+ openSession: "Open session",
441
+ copied: "Copied",
442
+ tasksHeading: "Automations",
443
+ deleteTitle: "Delete automation",
444
+ editingTask: "Editing \u201C{name}\u201D",
445
+ requiresWorkspace: "Open a workspace first to create an automation."
446
+ };
447
+ var zh = {
448
+ automations: "\u81EA\u52A8\u5316\u4EFB\u52A1",
449
+ openAutomations: "\u6253\u5F00\u81EA\u52A8\u5316\u4EFB\u52A1",
450
+ newAutomation: "\u65B0\u5EFA\u81EA\u52A8\u5316",
451
+ guidedCreationPrompt: "\u8BF7\u5E2E\u6211\u4E3A\u5F53\u524D\u5DE5\u4F5C\u533A\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u81EA\u52A8\u5316\u4EFB\u52A1\uFF0C\u53EA\u8BE2\u95EE\u7F3A\u5C11\u7684\u5FC5\u8981\u4FE1\u606F\u3002\u9009\u62E9 Host id \u524D\u5148\u8C03\u7528 automation_options\u3002\u521B\u5EFA\u524D\u9884\u89C8\u540D\u79F0\u3001\u8BA1\u5212/\u65F6\u533A\u3001\u5DE5\u4F5C\u533A\u3001Agent \u9884\u8BBE\u3001\u63D0\u4F9B\u5546/\u6A21\u578B\u3001\u63A8\u7406\u7B49\u7EA7\uFF08\u9ED8\u8BA4\u6216\u6A21\u578B\u652F\u6301\u7684\u7B49\u7EA7\uFF09\u3001\u6709\u5E8F\u6280\u80FD\u3001\u51C6\u786E\u7684 Host \u6743\u9650\u3001\u901A\u77E5\u548C\u5931\u8D25\u6682\u505C\u7B56\u7565\uFF0C\u5E76\u5305\u542B\u5BA1\u6279\u8B66\u544A\uFF1B\u7136\u540E\u7B49\u5F85\u6211\u660E\u786E\u786E\u8BA4\u3002\u5728\u6211\u786E\u8BA4\u524D\u4E0D\u8981\u8C03\u7528 automation_create\u3002",
452
+ refresh: "\u5237\u65B0",
453
+ close: "\u5173\u95ED",
454
+ details: "\u8BE6\u60C5",
455
+ configuration: "\u914D\u7F6E",
456
+ loadFailed: "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u4EFB\u52A1",
457
+ loadFailedHint: "\u8BF7\u68C0\u67E5\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002\u5DF2\u6709\u4EFB\u52A1\u4E0D\u4F1A\u88AB\u4FEE\u6539\u3002",
458
+ noScheduledRun: "\u6682\u65E0\u4E0B\u6B21\u8FD0\u884C",
459
+ noFilteredTasks: "\u5F53\u524D\u5206\u7C7B\u4E0B\u6682\u65E0\u4EFB\u52A1",
460
+ resetFilters: "\u67E5\u770B\u5168\u90E8\u4EFB\u52A1",
461
+ discardTitle: "\u653E\u5F03\u672A\u4FDD\u5B58\u7684\u4FEE\u6539\uFF1F",
462
+ discardDescription: "\u4FEE\u6539\u5C1A\u672A\u4FDD\u5B58\u3002\u4F60\u53EF\u4EE5\u7EE7\u7EED\u7F16\u8F91\uFF0C\u6216\u653E\u5F03\u4FEE\u6539\u540E\u79BB\u5F00\u3002",
463
+ keepEditing: "\u7EE7\u7EED\u7F16\u8F91",
464
+ discardChanges: "\u653E\u5F03\u4FEE\u6539",
465
+ unsavedChanges: "\u6709\u672A\u4FDD\u5B58\u7684\u4FEE\u6539",
466
+ editorConfigInvalid: "\u8BF7\u68C0\u67E5 Agent \u6267\u884C\u914D\u7F6E\u548C\u6743\u9650\uFF1A\u90E8\u5206\u9009\u9879\u4E0D\u53EF\u7528\u6216\u4E0D\u5B8C\u6574\u3002",
467
+ editorRequiredFields: "\u8BF7\u586B\u5199\u5FC5\u586B\u9879\uFF0C\u5185\u5BB9\u4E0D\u80FD\u4EC5\u4E3A\u7A7A\u683C\u3002",
468
+ copy: "\u590D\u5236",
469
+ taskCount: "\u4EFB\u52A1 \xB7 {count}",
470
+ loading: "\u6B63\u5728\u52A0\u8F7D\u81EA\u52A8\u5316\u4EFB\u52A1\u2026",
471
+ noAutomations: "\u4ECE\u4E00\u4E2A\u60F3\u6CD5\u5F00\u59CB",
472
+ createHint: "\u628A\u91CD\u590D\u7684\u5DE5\u4F5C\u4EA4\u7ED9\u81EA\u52A8\u5316\u3002\u9009\u62E9\u4E00\u4E2A\u793A\u4F8B\uFF0C\u6216\u65B0\u5EFA\u4EFB\u52A1\uFF0C\u5728\u5BF9\u8BDD\u4E2D\u786E\u8BA4\u8FD0\u884C\u65F6\u95F4\u548C\u8981\u505A\u7684\u4E8B\u3002",
473
+ exampleDraftHint: "\u63D0\u793A\u8BCD\u4E0D\u4F1A\u81EA\u52A8\u53D1\u9001\u3002\u4F60\u53EF\u4EE5\u5148\u68C0\u67E5\u6216\u4FEE\u6539\uFF0C\u518D\u51B3\u5B9A\u662F\u5426\u53D1\u9001\u3002",
474
+ creatingConversation: "\u6B63\u5728\u6253\u5F00\u65B0\u5BF9\u8BDD\u2026",
475
+ workspaceUnavailable: "\u8BF7\u5148\u6253\u5F00\u4E00\u4E2A\u5DE5\u4F5C\u533A\uFF0C\u518D\u521B\u5EFA\u81EA\u52A8\u5316\u3002",
476
+ newConversationFailed: "\u65E0\u6CD5\u6253\u5F00\u65B0\u5BF9\u8BDD\uFF1A{error}",
477
+ exampleReleaseTitle: "\u660E\u5929\u7684\u53D1\u5E03\u68C0\u67E5",
478
+ exampleReleaseDescription: "\u660E\u5929 09:00 \xB7 \u53EA\u8BFB \xB7 \u4EC5\u5931\u8D25\u901A\u77E5",
479
+ exampleReleasePrompt: "\u8BF7\u521B\u5EFA\u4E00\u4E2A\u660E\u5929\u4E0A\u5348 9:00\uFF08\u4F7F\u7528\u6211\u7684\u5F53\u524D\u65F6\u533A\uFF09\u8FD0\u884C\u7684\u5355\u6B21\u81EA\u52A8\u5316\uFF0C\u540D\u79F0\u4E3A\u201C\u53D1\u5E03\u51C6\u5907\u68C0\u67E5\u201D\u3002\u8FD0\u884C\u65F6\u68C0\u67E5\u5F53\u524D\u5DE5\u4F5C\u533A\u7684\u53D1\u5E03\u963B\u585E\u5E76\u6267\u884C\u76F8\u5173\u73B0\u6709\u68C0\u67E5\uFF0C\u4E0D\u8981\u4FEE\u6539\u6E90\u6587\u4EF6\u3002\u7ED3\u5C3E\u660E\u786E\u7ED9\u51FA\u201C\u53EF\u53D1\u5E03\u201D\u6216\u201C\u88AB\u963B\u585E\u201D\uFF0C\u5E76\u5217\u51FA\u963B\u585E\u9879\u548C\u8BC1\u636E\u3002\u4F7F\u7528\u53EA\u8BFB\u6743\u9650\uFF0C\u4EC5\u8FD0\u884C\u5931\u8D25\u65F6\u901A\u77E5\u6211\u3002\u521B\u5EFA\u524D\u5C55\u793A\u5B8C\u6574\u9884\u89C8\u5E76\u7B49\u5F85\u6211\u786E\u8BA4\u3002",
480
+ exampleDependenciesTitle: "\u5468\u4E00\u4F9D\u8D56\u5DE1\u68C0",
481
+ exampleDependenciesDescription: "\u5468\u4E00 09:30 \xB7 \u53EA\u8BFB \xB7 \u6BCF\u6B21\u901A\u77E5",
482
+ exampleDependenciesPrompt: "\u8BF7\u521B\u5EFA\u4E00\u4E2A\u6BCF\u5468\u4E00\u4E0A\u5348 9:30\uFF08\u4F7F\u7528\u6211\u7684\u5F53\u524D\u65F6\u533A\uFF09\u8FD0\u884C\u7684\u5468\u671F\u81EA\u52A8\u5316\uFF0C\u540D\u79F0\u4E3A\u201C\u4F9D\u8D56\u5DE1\u68C0\u201D\u3002\u8FD0\u884C\u65F6\u53EA\u8BFB\u68C0\u67E5\u4F9D\u8D56\u6E05\u5355\u548C\u9501\u6587\u4EF6\u4E2D\u7684\u91CD\u8981\u66F4\u65B0\u3001\u517C\u5BB9\u98CE\u9669\u4E0E\u5B89\u5168\u95EE\u9898\uFF0C\u4E0D\u8981\u4FEE\u6539\u6587\u4EF6\u3002\u4F18\u5148\u62A5\u544A\u9AD8\u98CE\u9669\u9879\uFF0C\u5E76\u4E3A\u6BCF\u9879\u7ED9\u51FA\u660E\u786E\u5EFA\u8BAE\u3002\u4F7F\u7528\u53EA\u8BFB\u6743\u9650\uFF0C\u6BCF\u6B21\u8FD0\u884C\u540E\u901A\u77E5\u6211\uFF0C\u8FDE\u7EED\u5931\u8D25 3 \u6B21\u540E\u6682\u505C\u3002\u521B\u5EFA\u524D\u5C55\u793A\u5B8C\u6574\u9884\u89C8\u5E76\u7B49\u5F85\u6211\u786E\u8BA4\u3002",
483
+ exampleHandoffTitle: "\u5DE5\u4F5C\u65E5\u4EA4\u63A5",
484
+ exampleHandoffDescription: "\u5DE5\u4F5C\u65E5 18:00 \xB7 \u53EA\u8BFB \xB7 \u6BCF\u6B21\u901A\u77E5",
485
+ exampleHandoffPrompt: "\u8BF7\u521B\u5EFA\u4E00\u4E2A\u6BCF\u4E2A\u5DE5\u4F5C\u65E5\u4E0B\u5348 6:00\uFF08\u4F7F\u7528\u6211\u7684\u5F53\u524D\u65F6\u533A\uFF09\u8FD0\u884C\u7684\u5468\u671F\u81EA\u52A8\u5316\uFF0C\u540D\u79F0\u4E3A\u201C\u6BCF\u65E5\u4EA4\u63A5\u201D\u3002\u8FD0\u884C\u65F6\u53EA\u8BFB\u68C0\u67E5\u4ECA\u5929\u7684\u5DE5\u4F5C\u533A\u6539\u52A8\uFF0C\u4E0D\u8981\u4FEE\u6539\u6587\u4EF6\uFF0C\u5E76\u6309\u201C\u5DF2\u5B8C\u6210\u3001\u5173\u952E\u51B3\u7B56\u3001\u4E0B\u4E00\u6B65\u3001\u963B\u585E\u9879\u201D\u8F93\u51FA\u7B80\u6D01\u4EA4\u63A5\u3002\u4F7F\u7528\u53EA\u8BFB\u6743\u9650\uFF0C\u6BCF\u6B21\u8FD0\u884C\u540E\u901A\u77E5\u6211\u3002\u521B\u5EFA\u524D\u5C55\u793A\u5B8C\u6574\u9884\u89C8\u5E76\u7B49\u5F85\u6211\u786E\u8BA4\u3002",
486
+ once: "\u5355\u6B21",
487
+ next: "\u4E0B\u6B21\u8FD0\u884C",
488
+ schedule: "\u8BA1\u5212",
489
+ workspace: "\u5DE5\u4F5C\u533A",
490
+ executionDestination: "\u6267\u884C\u76EE\u6807",
491
+ executionMode: "\u4F1A\u8BDD\u65B9\u5F0F",
492
+ executionExisting: "\u4F7F\u7528\u5DF2\u6709\u4F1A\u8BDD",
493
+ targetSession: "\u76EE\u6807\u4F1A\u8BDD",
494
+ selectSession: "\u9009\u62E9\u4F1A\u8BDD",
495
+ currentSession: "\u5F53\u524D\u4F1A\u8BDD",
496
+ sessionSearch: "\u641C\u7D22\u4F1A\u8BDD\u6807\u9898\u6216 ID",
497
+ sessionWorkspaceHint: "\u4EC5\u53EF\u9009\u62E9\u4EFB\u52A1\u6240\u5C5E\u5DE5\u4F5C\u533A\u7684\u4F1A\u8BDD\uFF1A{cwd}",
498
+ pinnedSessionHint: "\u6BCF\u6B21\u5728\u6B64\u4F1A\u8BDD\u8FFD\u52A0\u4EFB\u52A1\uFF0C\u6CBF\u7528\u4E0A\u4E0B\u6587\u53CA Agent\uFF0F\u6A21\u578B\u914D\u7F6E\uFF0C\u4E0D\u91CD\u65B0\u52A0\u8F7D\u6280\u80FD\u3002\u4EFB\u52A1\u6743\u9650\u4F1A\u5E94\u7528\u5230\u6B64\u4F1A\u8BDD\u3002\u4F1A\u8BDD\u5FD9\u788C\u6216\u4E0D\u53EF\u7528\u65F6\u8FD0\u884C\u5931\u8D25\uFF0C\u4E0D\u53E6\u5EFA\u4F1A\u8BDD\u3002",
499
+ sessionTargetLocked: "\u4EFB\u52A1\u6B63\u5728\u6392\u961F\u6216\u8FD0\u884C\uFF0C\u8BF7\u7ED3\u675F\u540E\u518D\u4FEE\u6539\u6267\u884C\u4F1A\u8BDD\u3002",
500
+ sessionsLoading: "\u6B63\u5728\u52A0\u8F7D\u4F1A\u8BDD\u2026",
501
+ sessionsFailure: "\u5237\u65B0\u4F1A\u8BDD\u5931\u8D25\uFF1A{error}",
502
+ sessionsNotReady: "\u672A\u80FD\u83B7\u53D6\u4F1A\u8BDD\u5217\u8868\uFF0C\u8BF7\u91CD\u8BD5\u3002",
503
+ noSessionMatches: "\u6B64\u5DE5\u4F5C\u533A\u6CA1\u6709\u5339\u914D\u7684\u4F1A\u8BDD\u3002",
504
+ targetSessionUnavailable: "\u539F\u4F1A\u8BDD\u5728\u6B64\u5DE5\u4F5C\u533A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u4F1A\u8BDD\u6216\u6539\u4E3A\u65B0\u5EFA\u4F1A\u8BDD\u3002",
505
+ sessionTargetSaveHint: "\u4FDD\u5B58\u540E\uFF0C\u540E\u7EED\u8FD0\u884C\u5C06\u4F7F\u7528\u6B64\u6267\u884C\u76EE\u6807\uFF1A{target}\u3002",
506
+ executionFresh: "\u6BCF\u6B21\u8FD0\u884C\u521B\u5EFA\u65B0\u4F1A\u8BDD",
507
+ executionPinned: "\u7EE7\u7EED\u5DF2\u6709\u4F1A\u8BDD \xB7 {sessionId} \xB7 \u4E0D\u56DE\u9000\u521B\u5EFA\u65B0\u4F1A\u8BDD",
508
+ permission: "\u6743\u9650",
509
+ permissionReadOnly: "\u53EA\u8BFB",
510
+ permissionFullAccess: "\u5B8C\u5168\u8BBF\u95EE",
511
+ agentExecution: "Agent \u6267\u884C\u914D\u7F6E",
512
+ agentPreset: "Agent \u9884\u8BBE",
513
+ provider: "\u63D0\u4F9B\u5546",
514
+ model: "\u6A21\u578B",
515
+ reasoningEffort: "\u63A8\u7406\u7B49\u7EA7",
516
+ reasoningDefault: "\u9ED8\u8BA4\uFF08\u4E0D\u8986\u76D6\uFF09",
517
+ reasoningDefaultShort: "\u9ED8\u8BA4",
518
+ modelAndReasoning: "\u6A21\u578B\u548C\u63A8\u7406\u7B49\u7EA7",
519
+ reasoningHint: "\u9ED8\u8BA4\u65F6\u4E0D\u8986\u76D6\u63A8\u7406\u8BBE\u7F6E\uFF0C\u5176\u4ED6\u7B49\u7EA7\u7531\u5F53\u524D\u6A21\u578B\u63D0\u4F9B\u3002",
520
+ reasoningSelectModel: "\u9009\u62E9\u5177\u4F53\u7684\u63D0\u4F9B\u5546\u548C\u6A21\u578B\u540E\uFF0C\u53EF\u8BBE\u7F6E\u63A8\u7406\u7B49\u7EA7\u3002",
521
+ reasoningUnsupported: "\u6B64\u6A21\u578B\u672A\u63D0\u4F9B\u53EF\u9009\u63A8\u7406\u7B49\u7EA7\u3002",
522
+ reasoningUnavailable: "Host \u672A\u8FD4\u56DE\u63A8\u7406\u9009\u9879\uFF1B\u82E5\u521A\u66F4\u65B0\u63D2\u4EF6\uFF0C\u8BF7\u91CD\u542F DSH\u3002",
523
+ reasoningFailure: "\u65E0\u6CD5\u52A0\u8F7D\u63A8\u7406\u7B49\u7EA7\uFF1A{error}",
524
+ reasoningSession: "\u6CBF\u7528\u76EE\u6807\u4F1A\u8BDD\u8BBE\u7F6E",
525
+ selectedSkills: "\u5DF2\u9009\u6280\u80FD",
526
+ noSelectedSkills: "\u672A\u9009\u62E9\u6280\u80FD",
527
+ noSkills: "\u6B64\u9884\u8BBE\u6CA1\u6709\u53EF\u7531\u7528\u6237\u8C03\u7528\u7684\u6280\u80FD\u3002",
528
+ modelInvocable: "\u6A21\u578B\u4E5F\u53EF\u8C03\u7528",
529
+ hostDefault: "Host \u9ED8\u8BA4\u503C",
530
+ unavailable: "\u4E0D\u53EF\u7528",
531
+ notInCatalog: "\u76EE\u5F55\u672A\u5217\u51FA\uFF08\u4FDD\u5B58\u65F6\u9A8C\u8BC1\uFF09",
532
+ optionsLoading: "\u6B63\u5728\u52A0\u8F7D Host \u9009\u9879\u2026",
533
+ optionsFailure: "\u65E0\u6CD5\u52A0\u8F7D Host \u9009\u9879\uFF1A{error}",
534
+ providerFailure: "{provider} \u6A21\u578B\u76EE\u5F55\u52A0\u8F7D\u5931\u8D25\uFF1A{error}",
535
+ selectModel: "\u9009\u62E9\u6A21\u578B",
536
+ approvalAskWarning: "\u6B64\u6743\u9650\u4F1A\u8BF7\u6C42\u6279\u51C6\u3002\u65E0\u4EBA\u503C\u5B88\u8FD0\u884C\u4E0D\u4F1A\u81EA\u52A8\u6279\u51C6\uFF0C\u53EF\u80FD\u4E00\u76F4\u7B49\u5F85\u5230\u8D85\u65F6\u3002",
537
+ confirmPermissionChange: "\u6211\u786E\u8BA4\u540E\u7EED\u8FD0\u884C\u53EF\u4EE5\u4F7F\u7528{permission}\u6743\u9650\u3002",
538
+ messageDelivery: "\u6D88\u606F\u6295\u9012",
539
+ deliveryEnabled: "\u901A\u8FC7 dsh-im \u53D1\u9001",
540
+ deliveryHint: "\u5F00\u542F\u540E\u4F1A\u5C06\u7ED3\u679C\u53D1\u9001\u5230 DSH \u5916\u90E8\uFF1B\u4FDD\u5B58\u7684\u66F4\u6539\u5E94\u7528\u4E8E\u540E\u7EED\u8FD0\u884C\u3002",
541
+ deliveryHelp: "\u6D88\u606F\u6295\u9012\u8BF4\u660E",
542
+ deliveryHelpText: "\u901A\u8FC7\u540C\u4E00 Host \u4E0A\u5B89\u88C5\u7684 dsh-im \u53D1\u9001 Automation \u4EFB\u52A1\u7ED3\u679C\u548C\u5931\u8D25\u62A5\u544A\u3002\u8BF7\u5148\u5728 dsh-im \u4E2D\u914D\u7F6E\u673A\u5668\u4EBA\u5E76\u4FDD\u5B58\u6295\u9012\u76EE\u6807\u3002\u65E0\u9700\u56FA\u5B9A Session\uFF0C\u4E5F\u65E0\u9700\u5F00\u542F\u53CC\u5411\u540C\u6B65\u3002",
543
+ deliveryBot: "\u673A\u5668\u4EBA",
544
+ deliveryTarget: "\u5DF2\u4FDD\u5B58\u76EE\u6807",
545
+ selectDeliveryBot: "\u9009\u62E9\u673A\u5668\u4EBA",
546
+ selectDeliveryTarget: "\u9009\u62E9\u5DF2\u4FDD\u5B58\u76EE\u6807",
547
+ deliveryLocked: "\u4EFB\u52A1\u6392\u961F\u6216\u8FD0\u884C\u671F\u95F4\u4E0D\u80FD\u4FEE\u6539\u6D88\u606F\u6295\u9012\u3002",
548
+ deliveryLoading: "\u6B63\u5728\u52A0\u8F7D\u6295\u9012\u9009\u9879\u2026",
549
+ deliveryLoadFailed: "\u65E0\u6CD5\u52A0\u8F7D\u6295\u9012\u9009\u9879\uFF1A{error}",
550
+ deliveryUnavailable: "dsh-im \u6295\u9012\u670D\u52A1\u4E0D\u53EF\u7528\u3002\u53EF\u4FDD\u7559\u5DF2\u4FDD\u5B58\u7684\u76EE\u6807\uFF0C\u6216\u5173\u95ED\u6295\u9012\u3002",
551
+ deliverySavedUnavailable: "\u5DF2\u4FDD\u5B58\u7684\u673A\u5668\u4EBA\u6216\u76EE\u6807\u4E0D\u53EF\u7528\u3002\u53EF\u4FDD\u6301\u4E0D\u53D8\u3001\u9009\u62E9\u5176\u4ED6\u76EE\u6807\uFF0C\u6216\u5173\u95ED\u6295\u9012\u3002",
552
+ deliveryNoBots: "\u6682\u65E0\u53EF\u7528\u673A\u5668\u4EBA\u3002\u8BF7\u5148\u5728 dsh-im \u4E2D\u914D\u7F6E\uFF0C\u518D\u5237\u65B0\u3002",
553
+ deliveryNoTargets: "\u6682\u65E0\u5DF2\u4FDD\u5B58\u76EE\u6807\u3002\u8BF7\u5148\u5728 dsh-im \u8BBE\u7F6E\u4E2D\u6DFB\u52A0\uFF0C\u518D\u5237\u65B0\u3002",
554
+ deliverySaveHint: "\u4FDD\u5B58\u540E\uFF0C\u540E\u7EED\u4EFB\u52A1\u7ED3\u679C\u548C\u5931\u8D25\u62A5\u544A\u5C06\u53D1\u9001\u5230 DSH \u5916\u90E8\uFF1A{bot} / {target}\u3002",
555
+ deliverySending: "\u53D1\u9001\u4E2D",
556
+ deliverySent: "\u5E73\u53F0\u5DF2\u63A5\u53D7",
557
+ deliveryFailed: "\u6295\u9012\u5931\u8D25",
558
+ deliveryUnknown: "\u6295\u9012\u7ED3\u679C\u672A\u77E5",
559
+ deliveryError: "\u6D88\u606F\u6295\u9012\uFF1A{error}",
560
+ deliveryAttemptedAt: "\u5C1D\u8BD5\u6295\u9012\u65F6\u95F4",
561
+ deliveryFinishedAt: "\u6295\u9012\u7ED3\u675F\u65F6\u95F4",
562
+ notifications: "\u901A\u77E5",
563
+ notificationFailures: "\u4EC5\u5931\u8D25",
564
+ notificationAlways: "\u6BCF\u6B21\u5B8C\u6210",
565
+ notificationNever: "\u4ECE\u4E0D",
566
+ pauseAfterFailures: "\u8FDE\u7EED\u5931\u8D25 3 \u6B21\u540E\u6682\u505C",
567
+ enabled: "\u5DF2\u5F00\u542F",
568
+ disabled: "\u672A\u5F00\u542F",
569
+ consecutiveFailures: "\u8FDE\u7EED\u5931\u8D25",
570
+ unreadNotifications: "{count} \u6761\u672A\u8BFB\u81EA\u52A8\u5316\u901A\u77E5",
571
+ runNow: "\u7ACB\u5373\u8FD0\u884C",
572
+ retry: "\u91CD\u8BD5",
573
+ stopRun: "\u505C\u6B62\u8FD0\u884C",
574
+ pause: "\u6682\u505C",
575
+ resume: "\u6062\u590D",
576
+ resumeAndRun: "\u6062\u590D\u5E76\u8FD0\u884C",
577
+ openLatestSession: "\u6253\u5F00\u6700\u8FD1\u4F1A\u8BDD",
578
+ edit: "\u7F16\u8F91",
579
+ editTask: "\u7F16\u8F91\u81EA\u52A8\u5316",
580
+ editFutureRunsHint: "\u4FEE\u6539\u4EC5\u5F71\u54CD\u540E\u7EED\u8FD0\u884C\u3002",
581
+ sectionBasics: "\u57FA\u672C\u4FE1\u606F",
582
+ nameLabel: "\u540D\u79F0",
583
+ promptLabel: "\u4EFB\u52A1\u6307\u4EE4",
584
+ scheduleType: "\u8BA1\u5212\u7C7B\u578B",
585
+ oneTimeSchedule: "\u5355\u6B21",
586
+ recurringSchedule: "\u5468\u671F",
587
+ runAt: "\u8FD0\u884C\u65F6\u95F4",
588
+ recurrenceRule: "\u91CD\u590D\u89C4\u5219",
589
+ ruleMode: "\u91CD\u590D\u89C4\u5219\u7F16\u8F91\u6A21\u5F0F",
590
+ visualMode: "\u53EF\u89C6\u5316",
591
+ advancedMode: "\u9AD8\u7EA7 RRULE",
592
+ advancedRuleHint: "\u8BF7\u8F93\u5165\u5355\u6761 RFC 5545 RRULE\uFF0C\u4E0D\u8981\u5305\u542B DTSTART\u3002",
593
+ unsupportedRuleHint: "\u8FD9\u6761\u89C4\u5219\u5305\u542B\u9AD8\u7EA7\u9009\u9879\u3002\u8BF7\u7F16\u8F91 RRULE \u5B57\u7B26\u4E32\uFF0C\u6216\u5148\u7B80\u5316\u89C4\u5219\u518D\u5207\u6362\u5230\u53EF\u89C6\u5316\u6A21\u5F0F\u3002",
594
+ frequency: "\u9891\u7387",
595
+ frequencyDaily: "\u6BCF\u5929",
596
+ frequencyWeekly: "\u6BCF\u5468",
597
+ frequencyMonthly: "\u6BCF\u6708",
598
+ everyDay: "\u6BCF\u5929",
599
+ everyDays: "\u6BCF {count} \u5929",
600
+ everyWeek: "\u6BCF\u5468",
601
+ everyWeeks: "\u6BCF {count} \u5468",
602
+ everyMonth: "\u6BCF\u6708",
603
+ everyMonths: "\u6BCF {count} \u4E2A\u6708",
604
+ dayOfMonth: "{day} \u65E5",
605
+ repeatEvery: "\u6BCF\u9694",
606
+ intervalDays: "\u5929",
607
+ intervalWeeks: "\u5468",
608
+ intervalMonths: "\u4E2A\u6708",
609
+ repeatOn: "\u91CD\u590D\u65E5\u671F",
610
+ monthlyOnDay: "\u6BCF\u6708\u65E5\u671F",
611
+ useStartDayHint: "\u672A\u9009\u62E9\u65F6\uFF0C\u5C06\u4F7F\u7528\u5F00\u59CB\u65E5\u671F\u5BF9\u5E94\u7684\u661F\u671F\u3002",
612
+ ends: "\u7ED3\u675F\u6761\u4EF6",
613
+ endsNever: "\u6C38\u4E0D\u7ED3\u675F",
614
+ endsAfter: "\u8FD0\u884C\u6307\u5B9A\u6B21\u6570\u540E",
615
+ endsOnDate: "\u5728\u6307\u5B9A\u65E5\u671F\u7ED3\u675F",
616
+ occurrences: "\u8FD0\u884C\u6B21\u6570",
617
+ endDate: "\u7ED3\u675F\u65E5\u671F",
618
+ weekdayLabel: "\u5468{day}",
619
+ weekdaySeparator: "\u3001",
620
+ weekdayMonday: "\u4E00",
621
+ weekdayTuesday: "\u4E8C",
622
+ weekdayWednesday: "\u4E09",
623
+ weekdayThursday: "\u56DB",
624
+ weekdayFriday: "\u4E94",
625
+ weekdaySaturday: "\u516D",
626
+ weekdaySunday: "\u65E5",
627
+ timeZone: "\u65F6\u533A",
628
+ startsAt: "\u5F00\u59CB\u65F6\u95F4",
629
+ saveChanges: "\u4FDD\u5B58\u4FEE\u6539",
630
+ saving: "\u6B63\u5728\u4FDD\u5B58\u2026",
631
+ delete: "\u5220\u9664",
632
+ cancel: "\u53D6\u6D88",
633
+ confirmDelete: "\u786E\u8BA4\u5220\u9664",
634
+ deleteConfirm: "\u5220\u9664\u201C{name}\u201D\uFF1F\u5DF2\u6709\u7684\u8FD0\u884C\u4F1A\u8BDD\u4ECD\u4F1A\u4FDD\u7559\u3002",
635
+ latestResult: "\u6700\u8FD1\u7ED3\u679C",
636
+ recentRuns: "\u6700\u8FD1\u8FD0\u884C\uFF08{count}\uFF09",
637
+ open: "\u6253\u5F00",
638
+ requestFailed: "\u81EA\u52A8\u5316\u8BF7\u6C42\u5931\u8D25\uFF08{status}\uFF09\u3002",
639
+ taskId: "\u4EFB\u52A1 ID",
640
+ schedulerRetrying: "\u8C03\u5EA6\u6682\u65F6\u5931\u8D25\uFF0C\u5C06\u81EA\u52A8\u91CD\u8BD5\uFF1A{error}",
641
+ schedulerStopped: "\u8C03\u5EA6\u5DF2\u505C\u6B62\uFF0C\u8BF7\u91CD\u542F DSH \u4EE5\u6062\u590D\u81EA\u52A8\u5316\u4EFB\u52A1\u3002",
642
+ unknownError: "\u672A\u77E5\u9519\u8BEF",
643
+ statusActive: "\u5DF2\u542F\u7528",
644
+ statusPaused: "\u5DF2\u6682\u505C",
645
+ statusCompleted: "\u5DF2\u5B8C\u6210",
646
+ statusQueued: "\u6392\u961F\u4E2D",
647
+ statusRunning: "\u8FD0\u884C\u4E2D",
648
+ statusSucceeded: "\u6210\u529F",
649
+ statusFailed: "\u5931\u8D25",
650
+ statusInterrupted: "\u5DF2\u4E2D\u65AD",
651
+ statusOutcomeUnknown: "\u7ED3\u679C\u672A\u77E5",
652
+ statusTimedOut: "\u5DF2\u8D85\u65F6",
653
+ statusCanceled: "\u5DF2\u53D6\u6D88",
654
+ triggerManual: "\u624B\u52A8",
655
+ triggerScheduled: "\u5B9A\u65F6",
656
+ searchPlaceholder: "\u641C\u7D22\u81EA\u52A8\u5316",
657
+ filterAll: "\u5168\u90E8",
658
+ filterActive: "\u5DF2\u542F\u7528",
659
+ filterPaused: "\u5DF2\u6682\u505C",
660
+ filterCompleted: "\u5DF2\u5B8C\u6210",
661
+ noMatches: "\u6CA1\u6709\u5339\u914D\u201C{query}\u201D\u7684\u81EA\u52A8\u5316\u3002",
662
+ clearSearch: "\u6E05\u9664\u641C\u7D22",
663
+ selectTaskHint: "\u9009\u62E9\u4E00\u4E2A\u81EA\u52A8\u5316\uFF0C\u67E5\u770B\u5B83\u7684\u8BA1\u5212\u3001\u914D\u7F6E\u4E0E\u8FD0\u884C\u5386\u53F2\u3002",
664
+ backToList: "\u8FD4\u56DE\u5217\u8868",
665
+ moreActions: "\u66F4\u591A\u64CD\u4F5C",
666
+ overview: "\u6982\u89C8",
667
+ runHistory: "\u8FD0\u884C\u5386\u53F2",
668
+ noRuns: "\u6682\u65E0\u8FD0\u884C\u8BB0\u5F55\u3002",
669
+ deleteRun: "\u5220\u9664\u8BB0\u5F55",
670
+ deletingRun: "\u6B63\u5728\u5220\u9664\u2026",
671
+ deleteRunTitle: "\u5220\u9664\u8FD9\u6761\u8FD0\u884C\u8BB0\u5F55\uFF1F",
672
+ deleteRunConfirm: "\u4EC5\u5220\u9664\u8FD9\u6761\u8FD0\u884C\u8BB0\u5F55\uFF0C\u4FDD\u7559\u5BF9\u5E94\u4F1A\u8BDD\u548C\u5DF2\u53D1\u9001\u7684\u6D88\u606F\uFF0C\u4E0D\u5F71\u54CD\u4EFB\u52A1\u540E\u7EED\u8FD0\u884C\u3002\u5220\u9664\u540E\u65E0\u6CD5\u6062\u590D\u3002",
673
+ deleteRunBlocked: "\u8BF7\u7B49\u5F85\u6267\u884C\u548C\u6D88\u606F\u6295\u9012\u7ED3\u675F\u540E\uFF0C\u518D\u5220\u9664\u8FD9\u6761\u8BB0\u5F55\u3002",
674
+ deleteRunFailed: "\u5220\u9664\u8BB0\u5F55\u5931\u8D25\uFF1A{error}\u3002\u4F60\u53EF\u4EE5\u91CD\u8BD5\u3002",
675
+ schedulerHealthy: "\u8C03\u5EA6\u5668\u6B63\u5E38",
676
+ schedulerHealthRetrying: "\u8C03\u5EA6\u5668\u91CD\u8BD5\u4E2D",
677
+ schedulerHealthStopped: "\u8C03\u5EA6\u5668\u5DF2\u505C\u6B62",
678
+ schedulerLastError: "\u6700\u8FD1\u9519\u8BEF",
679
+ schedulerLastFailedAt: "\u6700\u8FD1\u5931\u8D25\u4E8E",
680
+ schedulerRetryAt: "\u4E0B\u6B21\u91CD\u8BD5",
681
+ schedulerFailureCount: "\u8C03\u5EA6\u8FDE\u7EED\u5931\u8D25\u6B21\u6570",
682
+ createdAt: "\u521B\u5EFA\u4E8E",
683
+ createdBySession: "\u521B\u5EFA\u4F1A\u8BDD",
684
+ pausedAt: "\u6682\u505C\u4E8E",
685
+ pausedNextRunAt: "\u6062\u590D\u540E\u7684\u4E0B\u6B21\u8FD0\u884C",
686
+ runId: "\u8FD0\u884C ID",
687
+ enqueuedAt: "\u5165\u961F",
688
+ startedAt: "\u5F00\u59CB",
689
+ finishedAt: "\u7ED3\u675F",
690
+ duration: "\u8017\u65F6",
691
+ trigger: "\u89E6\u53D1\u65B9\u5F0F",
692
+ runTarget: "\u8FD0\u884C\u76EE\u6807",
693
+ skillSearchPlaceholder: "\u7B5B\u9009\u6280\u80FD",
694
+ noSkillMatches: "\u6CA1\u6709\u5339\u914D\u7684\u6280\u80FD\u3002",
695
+ selectedCount: "\u5DF2\u9009 {count} \u9879",
696
+ clearSkills: "\u5168\u90E8\u6E05\u9664",
697
+ openSession: "\u6253\u5F00\u4F1A\u8BDD",
698
+ copied: "\u5DF2\u590D\u5236",
699
+ tasksHeading: "\u81EA\u52A8\u5316",
700
+ deleteTitle: "\u5220\u9664\u81EA\u52A8\u5316",
701
+ editingTask: "\u6B63\u5728\u7F16\u8F91\u201C{name}\u201D",
702
+ requiresWorkspace: "\u8BF7\u5148\u6253\u5F00\u4E00\u4E2A\u5DE5\u4F5C\u533A\uFF0C\u518D\u521B\u5EFA\u81EA\u52A8\u5316\u3002"
703
+ };
704
+
705
+ // src/client/i18n.ts
706
+ var import_client = require("@deepseek-ai/dsh-client-locale/client");
707
+ var NAMESPACE = "dsh-automation";
708
+ var localeService;
709
+ var translate;
710
+ function installLocale(ctx) {
711
+ const locale = ctx.locale;
712
+ const dispose = locale.register(NAMESPACE, { en, zh });
713
+ localeService = locale;
714
+ translate = locale.bind(NAMESPACE);
715
+ return () => {
716
+ dispose();
717
+ if (localeService === locale) {
718
+ localeService = void 0;
719
+ translate = void 0;
720
+ }
721
+ };
722
+ }
723
+ function t(key, params) {
724
+ return translate?.(key, params) ?? en[key];
725
+ }
726
+ var subscribe = (listener) => localeService?.subscribe(listener) ?? (() => void 0);
727
+ var snapshot = () => localeService?.getSnapshot();
728
+ function useLocale() {
729
+ const current = import_react.default.useSyncExternalStore(subscribe, snapshot, snapshot);
730
+ return { t, locale: current?.active ?? "en" };
731
+ }
732
+
733
+ // src/client/AutomationPanel.tsx
734
+ var import_react13 = __toESM(require("react"), 1);
735
+ var import_dsh_client_ui_primitives9 = require("@deepseek-ai/dsh-client-ui-primitives");
736
+
737
+ // src/client/EmptyState.tsx
738
+ var import_react3 = require("react");
739
+
740
+ // src/client/shared.tsx
741
+ var import_react2 = __toESM(require("react"), 1);
742
+ var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
743
+ var import_jsx_runtime2 = require("react/jsx-runtime");
744
+ var STATE = {
745
+ active: "done",
746
+ paused: "idle",
747
+ completed: "idle",
748
+ queued: "idle",
749
+ running: "ongoing",
750
+ succeeded: "done",
751
+ failed: "error",
752
+ interrupted: "warning",
753
+ outcome_unknown: "warning",
754
+ timed_out: "warning",
755
+ canceled: "idle"
756
+ };
757
+ var TONE = {
758
+ active: "success",
759
+ paused: "neutral",
760
+ completed: "quiet",
761
+ queued: "neutral",
762
+ running: "info",
763
+ succeeded: "success",
764
+ failed: "danger",
765
+ interrupted: "warning",
766
+ outcome_unknown: "warning",
767
+ timed_out: "warning",
768
+ canceled: "quiet"
769
+ };
770
+ function statusState(status) {
771
+ return STATE[status] ?? "idle";
772
+ }
773
+ function statusTone(status) {
774
+ return TONE[status] ?? "neutral";
775
+ }
776
+ function statusLabel(status, t2) {
777
+ if (status === "active") return t2("statusActive");
778
+ if (status === "paused") return t2("statusPaused");
779
+ if (status === "completed") return t2("statusCompleted");
780
+ if (status === "queued") return t2("statusQueued");
781
+ if (status === "running") return t2("statusRunning");
782
+ if (status === "succeeded") return t2("statusSucceeded");
783
+ if (status === "failed") return t2("statusFailed");
784
+ if (status === "interrupted") return t2("statusInterrupted");
785
+ if (status === "outcome_unknown") return t2("statusOutcomeUnknown");
786
+ if (status === "timed_out") return t2("statusTimedOut");
787
+ if (status === "canceled") return t2("statusCanceled");
788
+ return status;
789
+ }
790
+ function triggerLabel(trigger, t2) {
791
+ if (trigger === "manual") return t2("triggerManual");
792
+ if (trigger === "scheduled") return t2("triggerScheduled");
793
+ return trigger;
794
+ }
795
+ function formatDate(value, locale, timeZone) {
796
+ return new Date(value).toLocaleString(locale, { dateStyle: "medium", timeStyle: "short", ...timeZone === void 0 ? {} : { timeZone } });
797
+ }
798
+ function formatRelative(value, locale) {
799
+ const seconds = Math.round((Date.parse(value) - Date.now()) / 1e3);
800
+ const formatter = new Intl.RelativeTimeFormat(locale, { numeric: "auto", style: "long" });
801
+ if (Math.abs(seconds) < 60) return formatter.format(seconds, "second");
802
+ const minutes = Math.round(seconds / 60);
803
+ if (Math.abs(minutes) < 60) return formatter.format(minutes, "minute");
804
+ const hours = Math.round(minutes / 60);
805
+ if (Math.abs(hours) < 24) return formatter.format(hours, "hour");
806
+ return formatter.format(Math.round(hours / 24), "day");
807
+ }
808
+ function formatRunDuration(startedAt, finishedAt, locale) {
809
+ if (startedAt === void 0 || finishedAt === void 0) return void 0;
810
+ let seconds = Math.max(0, Math.round((Date.parse(finishedAt) - Date.parse(startedAt)) / 1e3));
811
+ const hours = Math.floor(seconds / 3600);
812
+ seconds %= 3600;
813
+ const minutes = Math.floor(seconds / 60);
814
+ seconds %= 60;
815
+ const format = (value, unit) => new Intl.NumberFormat(locale, { style: "unit", unit, unitDisplay: "narrow" }).format(value);
816
+ if (hours > 0) return [format(hours, "hour"), minutes > 0 && format(minutes, "minute")].filter(Boolean).join(" ");
817
+ if (minutes > 0) return [format(minutes, "minute"), seconds > 0 && format(seconds, "second")].filter(Boolean).join(" ");
818
+ return format(seconds, "second");
819
+ }
820
+ function basename(path) {
821
+ const trimmed = path.replace(/[\\/]+$/, "");
822
+ const index = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
823
+ return index === -1 ? trimmed : trimmed.slice(index + 1);
824
+ }
825
+ function Select({ value, options, onChange, disabled, id, ariaLabel }) {
826
+ const [open, setOpen] = import_react2.default.useState(false);
827
+ const selected = options.find((option) => option.value === value);
828
+ const entries = options.map((option) => ({
829
+ id: option.value,
830
+ label: option.hint === void 0 ? option.label : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "am-option", children: [
831
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: option.label }),
832
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: option.hint })
833
+ ] }),
834
+ ...option.disabled === true ? { disabled: true } : {}
835
+ }));
836
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
837
+ import_dsh_client_ui_primitives.Menu,
838
+ {
839
+ open: open && !disabled,
840
+ portal: true,
841
+ align: "start",
842
+ selectedId: value,
843
+ items: entries,
844
+ onSelect: (next) => {
845
+ setOpen(false);
846
+ if (next !== value) onChange(next);
847
+ },
848
+ onClose: () => setOpen(false),
849
+ className: "am-select-menu",
850
+ anchor: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
851
+ "button",
852
+ {
853
+ type: "button",
854
+ id,
855
+ className: "am-select",
856
+ disabled,
857
+ "aria-label": ariaLabel,
858
+ "aria-haspopup": "listbox",
859
+ "aria-expanded": open,
860
+ onClick: () => setOpen((current) => !current),
861
+ children: [
862
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "am-select-value", children: selected?.label ?? value }),
863
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconChevronDownOutline14, {})
864
+ ]
865
+ }
866
+ )
867
+ }
868
+ );
869
+ }
870
+ function CopyButton({ value, t: t2 }) {
871
+ const [copied, setCopied] = import_react2.default.useState(false);
872
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives.Tooltip, { label: copied ? t2("copied") : t2("copy"), side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
873
+ "button",
874
+ {
875
+ type: "button",
876
+ className: "am-copy",
877
+ "aria-label": t2("copy"),
878
+ onClick: () => {
879
+ void navigator.clipboard?.writeText(value).then(() => {
880
+ setCopied(true);
881
+ window.setTimeout(() => setCopied(false), 1500);
882
+ }).catch(() => void 0);
883
+ },
884
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheckOutline16, {}) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCopyOutline16, {})
885
+ }
886
+ ) });
887
+ }
888
+ function Fact({ icon, label, children, full }) {
889
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: full === true ? "am-fact is-full" : "am-fact", children: [
890
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "am-fact-icon", "aria-hidden": "true", children: icon }),
891
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "am-fact-body", children: [
892
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "am-fact-label", children: label }),
893
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "am-fact-value", children })
894
+ ] })
895
+ ] });
896
+ }
897
+ function StatusTag({ status, t: t2 }) {
898
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dsh_client_ui_primitives.Tag, { tone: statusTone(status), className: "am-status", children: [
899
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives.StateDot, { state: statusState(status), size: 8 }),
900
+ statusLabel(status, t2)
901
+ ] });
902
+ }
903
+ function Glyph({ paths, size = 16 }) {
904
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: size, height: size, fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: paths.map((path) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: path }, path)) });
905
+ }
906
+ var IconShield = ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Glyph, { size, paths: ["M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z", "m9 12 2 2 4-4"] });
907
+ var IconBell = ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Glyph, { size, paths: ["M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9", "M10.3 21a1.94 1.94 0 0 0 3.4 0"] });
908
+ var IconCalendar = ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Glyph, { size, paths: ["M3 9h18", "M7 3v4", "M17 3v4", "M5 5h14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2Z"] });
909
+
910
+ // src/client/EmptyState.tsx
911
+ var import_jsx_runtime3 = require("react/jsx-runtime");
912
+ function EmptyState({ t: t2, creating, disabled, onStart }) {
913
+ const examples = [
914
+ { id: "release", icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconCalendar, { size: 18 }), title: t2("exampleReleaseTitle"), description: t2("exampleReleaseDescription"), prompt: t2("exampleReleasePrompt") },
915
+ { id: "dependencies", icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconShield, { size: 18 }), title: t2("exampleDependenciesTitle"), description: t2("exampleDependenciesDescription"), prompt: t2("exampleDependenciesPrompt") },
916
+ { id: "handoff", icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconAlarmClockOutline16, { size: 18 }), title: t2("exampleHandoffTitle"), description: t2("exampleHandoffDescription"), prompt: t2("exampleHandoffPrompt") }
917
+ ];
918
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "am-onboarding", children: [
919
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "am-onboarding-icon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconAlarmClockOutline16, { size: 28 }) }),
920
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { children: t2("noAutomations") }),
921
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: t2("createHint") }),
922
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "am-examples", children: examples.map((example) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
923
+ "button",
924
+ {
925
+ type: "button",
926
+ className: "am-example",
927
+ disabled: disabled || creating !== void 0,
928
+ "aria-busy": creating === example.id,
929
+ onClick: () => onStart(example.id, example.prompt),
930
+ children: [
931
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "am-example-icon", "aria-hidden": "true", children: example.icon }),
932
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "am-example-copy", children: [
933
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: example.title }),
934
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: creating === example.id ? t2("creatingConversation") : example.description })
935
+ ] }),
936
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconRightUpOutline14, { className: "am-example-arrow" })
937
+ ]
938
+ },
939
+ example.id
940
+ )) }),
941
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("small", { children: disabled ? t2("requiresWorkspace") : t2("exampleDraftHint") })
942
+ ] });
943
+ }
944
+
945
+ // src/client/SchedulerHealth.tsx
946
+ var import_react4 = require("react");
947
+ var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
948
+ var import_jsx_runtime4 = require("react/jsx-runtime");
949
+ function SchedulerHealth({ health, locale, t: t2 }) {
950
+ if (health === void 0) return null;
951
+ const state = health.status === "healthy" ? "done" : health.status === "retrying" ? "warning" : "error";
952
+ const label = health.status === "healthy" ? t2("schedulerHealthy") : health.status === "retrying" ? t2("schedulerHealthRetrying") : t2("schedulerHealthStopped");
953
+ const detailed = health.consecutiveFailures > 0 || health.lastError !== void 0 || health.lastFailedAt !== void 0 || health.retryAt !== void 0;
954
+ const chip = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "am-scheduler", children: [
955
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_dsh_client_ui_primitives2.StateDot, { state, size: 8 }),
956
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: label })
957
+ ] });
958
+ if (!detailed) return chip;
959
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
960
+ import_dsh_client_ui_primitives2.HoverCard,
961
+ {
962
+ anchor: chip,
963
+ copyLabel: t2("copy"),
964
+ copiedLabel: t2("copied"),
965
+ ...health.lastError !== void 0 ? { copyText: health.lastError } : {},
966
+ content: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("dl", { className: "am-scheduler-card", children: [
967
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { children: t2("schedulerFailureCount") }),
968
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: health.consecutiveFailures }),
969
+ health.lastFailedAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
970
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { children: t2("schedulerLastFailedAt") }),
971
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: formatDate(health.lastFailedAt, locale) })
972
+ ] }),
973
+ health.retryAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
974
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { children: t2("schedulerRetryAt") }),
975
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: formatDate(health.retryAt, locale) })
976
+ ] }),
977
+ health.lastError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
978
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { children: t2("schedulerLastError") }),
979
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: health.lastError })
980
+ ] })
981
+ ] })
982
+ }
983
+ );
984
+ }
985
+
986
+ // src/client/session-selection.ts
987
+ function selectedSessionId(sessions) {
988
+ return Object.values(sessions.byId).find((session) => (session.retainedBy.mainView ?? 0) > 0)?.id;
989
+ }
990
+
991
+ // src/client/TaskRow.tsx
992
+ var import_react5 = require("react");
993
+ var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
994
+ var import_jsx_runtime5 = require("react/jsx-runtime");
995
+ function TaskRow({ task, locale, t: t2, selected, onSelect }) {
996
+ const displayStatus = task.running ? "running" : task.status;
997
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
998
+ "button",
999
+ {
1000
+ type: "button",
1001
+ className: selected ? "am-row is-selected" : "am-row",
1002
+ "aria-current": selected,
1003
+ onClick: onSelect,
1004
+ children: [
1005
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: statusState(displayStatus), size: 8, className: "am-row-dot" }),
1006
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "am-row-body", children: [
1007
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "am-row-name", children: task.name }),
1008
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "am-row-meta", children: [
1009
+ statusLabel(displayStatus, t2),
1010
+ task.nextRunAt !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1011
+ " \xB7 ",
1012
+ formatRelative(task.nextRunAt, locale)
1013
+ ] })
1014
+ ] })
1015
+ ] }),
1016
+ task.consecutiveFailures > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "am-failure-chip", title: `${t2("consecutiveFailures")} \xB7 ${task.consecutiveFailures}`, children: [
1017
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(IconWarningOutline16, { size: 12 }),
1018
+ task.consecutiveFailures
1019
+ ] })
1020
+ ]
1021
+ }
1022
+ );
1023
+ }
1024
+
1025
+ // src/client/TaskDetail.tsx
1026
+ var import_react6 = __toESM(require("react"), 1);
1027
+ var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
1028
+
1029
+ // src/client/rrule-editor.ts
1030
+ var WEEKDAYS = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"];
1031
+ function defaultCommonRRule(monthDay = "1") {
1032
+ return { frequency: "DAILY", interval: "1", weekdays: [], monthDay, end: "never", count: "10", until: "" };
1033
+ }
1034
+ function parseCommonRRule(value, defaultMonthDay = "") {
1035
+ const text = value.trim().replace(/^RRULE:/i, "");
1036
+ if (!text || text.includes("\n") || text.includes("\r")) return void 0;
1037
+ const fields = /* @__PURE__ */ new Map();
1038
+ for (const part of text.split(";")) {
1039
+ const separator = part.indexOf("=");
1040
+ if (separator <= 0) return void 0;
1041
+ const key = part.slice(0, separator).toUpperCase();
1042
+ const field = part.slice(separator + 1).toUpperCase();
1043
+ if (!field || fields.has(key) || !["FREQ", "INTERVAL", "BYDAY", "BYMONTHDAY", "COUNT", "UNTIL"].includes(key)) return void 0;
1044
+ fields.set(key, field);
1045
+ }
1046
+ const frequency = fields.get("FREQ");
1047
+ if (frequency !== "DAILY" && frequency !== "WEEKLY" && frequency !== "MONTHLY") return void 0;
1048
+ const interval = fields.get("INTERVAL") ?? "1";
1049
+ if (!/^[1-9]\d*$/.test(interval)) return void 0;
1050
+ const byDay = fields.get("BYDAY");
1051
+ const weekdays = byDay === void 0 ? [] : byDay.split(",");
1052
+ if (byDay !== void 0 && (frequency !== "WEEKLY" || weekdays.some((day) => !WEEKDAYS.includes(day)) || new Set(weekdays).size !== weekdays.length)) return void 0;
1053
+ const byMonthDay = fields.get("BYMONTHDAY");
1054
+ if (byMonthDay !== void 0 && (frequency !== "MONTHLY" || !/^(?:[1-9]|[12]\d|3[01])$/.test(byMonthDay))) return void 0;
1055
+ const count = fields.get("COUNT");
1056
+ const untilValue = fields.get("UNTIL");
1057
+ if (count !== void 0 && (untilValue !== void 0 || !/^[1-9]\d*$/.test(count))) return void 0;
1058
+ const untilMatch = untilValue?.match(/^(\d{4})(\d{2})(\d{2})(?:T235959Z)?$/);
1059
+ if (untilValue !== void 0 && untilMatch === null) return void 0;
1060
+ const until = untilMatch == null ? "" : `${untilMatch[1]}-${untilMatch[2]}-${untilMatch[3]}`;
1061
+ const untilEpoch = until ? Date.parse(`${until}T00:00:00Z`) : 0;
1062
+ if (until && (!Number.isFinite(untilEpoch) || new Date(untilEpoch).toISOString().slice(0, 10) !== until)) return void 0;
1063
+ return {
1064
+ frequency,
1065
+ interval,
1066
+ weekdays,
1067
+ monthDay: byMonthDay ?? defaultMonthDay,
1068
+ end: count === void 0 ? until ? "until" : "never" : "count",
1069
+ count: count ?? "10",
1070
+ until
1071
+ };
1072
+ }
1073
+ function buildCommonRRule(rule) {
1074
+ const fields = [`FREQ=${rule.frequency}`];
1075
+ if (rule.interval !== "1") fields.push(`INTERVAL=${rule.interval}`);
1076
+ if (rule.frequency === "WEEKLY" && rule.weekdays.length > 0) {
1077
+ fields.push(`BYDAY=${WEEKDAYS.filter((day) => rule.weekdays.includes(day)).join(",")}`);
1078
+ }
1079
+ if (rule.frequency === "MONTHLY" && rule.monthDay) fields.push(`BYMONTHDAY=${rule.monthDay}`);
1080
+ if (rule.end === "count") fields.push(`COUNT=${rule.count}`);
1081
+ if (rule.end === "until") fields.push(`UNTIL=${rule.until.replaceAll("-", "")}T235959Z`);
1082
+ return fields.join(";");
1083
+ }
1084
+
1085
+ // src/client/TaskDetail.tsx
1086
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1087
+ var WEEKDAY_KEYS = {
1088
+ MO: "weekdayMonday",
1089
+ TU: "weekdayTuesday",
1090
+ WE: "weekdayWednesday",
1091
+ TH: "weekdayThursday",
1092
+ FR: "weekdayFriday",
1093
+ SA: "weekdaySaturday",
1094
+ SU: "weekdaySunday"
1095
+ };
1096
+ function scheduleLabel(task, locale, t2) {
1097
+ if (task.schedule.kind === "once") return `${t2("once")} \xB7 ${formatDate(task.schedule.fireAt, locale)}`;
1098
+ const rule = parseCommonRRule(task.schedule.rrule);
1099
+ if (rule === void 0) return `${task.schedule.rrule} \xB7 ${task.schedule.timeZone}`;
1100
+ const interval = Number(rule.interval);
1101
+ const repeat = rule.frequency === "DAILY" ? t2(interval === 1 ? "everyDay" : "everyDays", { count: interval }) : rule.frequency === "WEEKLY" ? t2(interval === 1 ? "everyWeek" : "everyWeeks", { count: interval }) : t2(interval === 1 ? "everyMonth" : "everyMonths", { count: interval });
1102
+ let detail = "";
1103
+ if (rule.frequency === "WEEKLY" && rule.weekdays.length > 0) {
1104
+ detail = WEEKDAYS.filter((day) => rule.weekdays.includes(day)).map((day) => t2("weekdayLabel", { day: t2(WEEKDAY_KEYS[day]) })).join(t2("weekdaySeparator"));
1105
+ }
1106
+ if (rule.frequency === "MONTHLY" && rule.monthDay) detail = t2("dayOfMonth", { day: rule.monthDay });
1107
+ return [repeat, detail, task.schedule.startAt.slice(11, 16), task.schedule.timeZone].filter(Boolean).join(" \xB7 ");
1108
+ }
1109
+ function notificationPolicyLabel(policy, t2) {
1110
+ if (policy === "always") return t2("notificationAlways");
1111
+ if (policy === "never") return t2("notificationNever");
1112
+ return t2("notificationFailures");
1113
+ }
1114
+ function executionLabel(task, t2) {
1115
+ const preset = task.execution.agentPreset ?? t2("hostDefault");
1116
+ const model = task.execution.provider === void 0 ? t2("hostDefault") : `${task.execution.provider}/${task.execution.model}`;
1117
+ const skills = task.execution.skills.length === 0 ? t2("noSelectedSkills") : task.execution.skills.join(", ");
1118
+ return `${preset} \xB7 ${model} \xB7 ${skills}`;
1119
+ }
1120
+ function permissionLabel(preset, t2, displayName) {
1121
+ if (displayName !== void 0) return displayName;
1122
+ if (preset === "read-only") return t2("permissionReadOnly");
1123
+ if (preset === "danger-full-access") return t2("permissionFullAccess");
1124
+ return preset;
1125
+ }
1126
+ function deliveryStatusLabel(status, t2) {
1127
+ const keys = { sending: "deliverySending", sent: "deliverySent", failed: "deliveryFailed", unknown: "deliveryUnknown" };
1128
+ return t2(keys[status]);
1129
+ }
1130
+ var RETRYABLE = ["failed", "timed_out", "interrupted", "outcome_unknown"];
1131
+ function RunRow({ run, locale, t: t2, disabled, pending, onRetry, onOpen, onDelete }) {
1132
+ const [open, setOpen] = import_react6.default.useState(false);
1133
+ const duration = formatRunDuration(run.startedAt, run.finishedAt, locale);
1134
+ const deleteBlocked = run.status === "queued" || run.status === "running" || run.delivery?.status === "sending";
1135
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1136
+ import_dsh_client_ui_primitives4.DisclosureRow,
1137
+ {
1138
+ className: "am-run",
1139
+ open,
1140
+ expandable: true,
1141
+ expandOnRowClick: true,
1142
+ onToggle: () => setOpen((current) => !current),
1143
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.StateDot, { state: statusState(run.status), size: 8 }),
1144
+ title: statusLabel(run.status, t2),
1145
+ collapsedContent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "am-run-line", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: triggerLabel(run.trigger, t2) }),
1147
+ duration !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1148
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
1149
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: duration })
1150
+ ] }),
1151
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
1152
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("time", { dateTime: run.startedAt ?? run.enqueuedAt, children: formatDate(run.startedAt ?? run.enqueuedAt, locale) }),
1153
+ run.delivery !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: run.delivery.status === "failed" ? "am-status am-danger" : "am-status", children: [
1154
+ t2("messageDelivery"),
1155
+ " \xB7 ",
1156
+ deliveryStatusLabel(run.delivery.status, t2)
1157
+ ] })
1158
+ ] }),
1159
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-run-body", children: [
1160
+ run.summary !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-run-summary", children: run.summary }),
1161
+ run.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-alert is-error", children: run.error }),
1162
+ run.delivery?.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-alert is-error", children: t2("deliveryError", { error: run.delivery.error }) }),
1163
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dl", { className: "am-run-facts", children: [
1164
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("trigger") }),
1165
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: triggerLabel(run.trigger, t2) }),
1166
+ run.scheduledAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1167
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("schedule") }),
1168
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: formatDate(run.scheduledAt, locale) })
1169
+ ] }),
1170
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("enqueuedAt") }),
1171
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: formatDate(run.enqueuedAt, locale) }),
1172
+ run.startedAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1173
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("startedAt") }),
1174
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: formatDate(run.startedAt, locale) })
1175
+ ] }),
1176
+ run.finishedAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1177
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("finishedAt") }),
1178
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: formatDate(run.finishedAt, locale) })
1179
+ ] }),
1180
+ duration !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1181
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("duration") }),
1182
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: duration })
1183
+ ] }),
1184
+ run.executionTarget !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1185
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("runTarget") }),
1186
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: run.executionTarget.mode === "pinned-session" ? t2("executionPinned", { sessionId: `${(run.executionTarget.sessionId ?? "").slice(0, 12)}\u2026` }) : t2("executionFresh") })
1187
+ ] }),
1188
+ run.sessionId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1189
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("openSession") }),
1190
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dd", { className: "am-mono-row", children: [
1191
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: run.sessionId }),
1192
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyButton, { value: run.sessionId, t: t2 })
1193
+ ] })
1194
+ ] }),
1195
+ run.delivery !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1196
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("messageDelivery") }),
1197
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: deliveryStatusLabel(run.delivery.status, t2) }),
1198
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("deliveryBot") }),
1199
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: run.delivery.botId }) }),
1200
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("deliveryTarget") }),
1201
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: run.delivery.targetId }) }),
1202
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("deliveryAttemptedAt") }),
1203
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: formatDate(run.delivery.attemptedAt, locale) }),
1204
+ run.delivery.finishedAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1205
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("deliveryFinishedAt") }),
1206
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { children: formatDate(run.delivery.finishedAt, locale) })
1207
+ ] })
1208
+ ] }),
1209
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { children: t2("runId") }),
1210
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dd", { className: "am-mono-row", children: [
1211
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: run.id }),
1212
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyButton, { value: run.id, t: t2 })
1213
+ ] })
1214
+ ] }),
1215
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-run-actions", children: [
1216
+ RETRYABLE.includes(run.status) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "outline", size: "sm", disabled, onClick: onRetry, children: t2("retry") }),
1217
+ run.sessionId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1218
+ import_dsh_client_ui_primitives4.Button,
1219
+ {
1220
+ type: "button",
1221
+ variant: "ghost",
1222
+ size: "sm",
1223
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRightUpOutline14, {}),
1224
+ onClick: () => onOpen(run.sessionId),
1225
+ children: t2("open")
1226
+ }
1227
+ ),
1228
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-spacer" }),
1229
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Tooltip, { label: t2("deleteRunBlocked"), disabled: !deleteBlocked, side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "ghost", size: "sm", "data-am-delete-run": run.id, disabled: pending || deleteBlocked, onClick: (event) => onDelete(event.currentTarget), children: t2("deleteRun") }) }) })
1230
+ ] })
1231
+ ] })
1232
+ }
1233
+ );
1234
+ }
1235
+ function TaskDetail({ task, locale, t: t2, pending, actions }) {
1236
+ const [menuOpen, setMenuOpen] = import_react6.default.useState(false);
1237
+ const [view, setView] = import_react6.default.useState("overview");
1238
+ const busy = task.running;
1239
+ const disabled = busy || pending;
1240
+ const displayStatus = busy ? "running" : task.status;
1241
+ const latestResult = [...task.runs].reverse().find((run) => run.summary !== void 0);
1242
+ const latestSession = [...task.runs].reverse().find((run) => run.sessionId !== void 0)?.sessionId ?? (task.execution.target?.mode === "pinned-session" ? task.execution.target.sessionId : void 0);
1243
+ const menuItems = [
1244
+ ...latestSession === void 0 ? [] : [{
1245
+ id: "open-latest",
1246
+ label: t2("openLatestSession"),
1247
+ icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRightUpOutline16, {})
1248
+ }],
1249
+ ...task.status === "paused" ? [{ id: "resume-run", label: t2("resumeAndRun"), icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconPlayOutline16, {}), disabled }] : [],
1250
+ { type: "separator", id: "sep" },
1251
+ { id: "delete", label: t2("delete"), icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconTrashOutline16, {}), danger: true, disabled: pending }
1252
+ ];
1253
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-detail", children: [
1254
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("header", { className: "am-detail-header", children: [
1255
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "am-back", "aria-label": t2("backToList"), onClick: actions.back, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconChevronLeftOutline14, {}) }),
1256
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-detail-title", children: [
1257
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: task.name }),
1258
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-detail-badges", children: [
1259
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "am-status", children: [
1260
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.StateDot, { state: statusState(displayStatus), size: 7 }),
1261
+ statusLabel(displayStatus, t2)
1262
+ ] }),
1263
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-detail-workspace", title: task.execution.cwd, children: basename(task.execution.cwd) }),
1264
+ task.consecutiveFailures > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Tooltip, { label: `${t2("consecutiveFailures")} \xB7 ${task.consecutiveFailures}`, side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "am-failure-chip", children: [
1265
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconWarningOutline16, { size: 12 }),
1266
+ task.consecutiveFailures
1267
+ ] }) })
1268
+ ] })
1269
+ ] }),
1270
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", "data-am-edit": true, variant: "ghost", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconEditOutline16, {}), disabled: pending, onClick: actions.edit, children: t2("edit") }),
1271
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1272
+ import_dsh_client_ui_primitives4.Menu,
1273
+ {
1274
+ open: menuOpen,
1275
+ portal: true,
1276
+ align: "end",
1277
+ items: menuItems,
1278
+ onSelect: (id) => {
1279
+ setMenuOpen(false);
1280
+ if (id === "open-latest" && latestSession !== void 0) actions.openSession(latestSession);
1281
+ if (id === "resume-run") actions.resume(true);
1282
+ if (id === "delete") actions.requestDelete();
1283
+ },
1284
+ onClose: () => setMenuOpen(false),
1285
+ anchor: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "am-icon-button", "aria-label": t2("moreActions"), onClick: () => setMenuOpen((current) => !current), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconEllipsisOutline16, {}) })
1286
+ }
1287
+ )
1288
+ ] }),
1289
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-detail-scroll", children: [
1290
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-next-run", children: [
1291
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-next-run-label", children: t2("next") }),
1292
+ task.nextRunAt !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1293
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: formatRelative(task.nextRunAt, locale) }),
1294
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "am-next-run-when", children: [
1295
+ formatDate(task.nextRunAt, locale, task.schedule.kind === "recurring" ? task.schedule.timeZone : void 0),
1296
+ task.schedule.kind === "recurring" ? ` \xB7 ${task.schedule.timeZone}` : ""
1297
+ ] })
1298
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { className: "am-muted", children: task.status === "paused" ? t2("statusPaused") : task.status === "completed" ? t2("statusCompleted") : t2("noScheduledRun") }),
1299
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-next-run-schedule", children: scheduleLabel(task, locale, t2) })
1300
+ ] }),
1301
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-actions", children: [
1302
+ !busy && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "outline", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconPlayOutline16, {}), disabled, onClick: actions.run, children: t2("runNow") }),
1303
+ busy && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "outline", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconStopFill16, {}), disabled: pending, onClick: actions.stop, children: t2("stopRun") }),
1304
+ task.status === "active" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "outline", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconPauseOutline16, {}), disabled: pending, onClick: actions.pause, children: t2("pause") }),
1305
+ task.status === "paused" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "outline", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconPlayOutline16, {}), disabled: pending, onClick: () => actions.resume(false), children: t2("resume") }) })
1306
+ ] }),
1307
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("nav", { className: "am-detail-nav", "aria-label": t2("details"), children: ["overview", "runHistory", "configuration"].map((id) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "data-am-view": id, className: view === id ? "am-tab is-active" : "am-tab", "aria-pressed": view === id, onClick: () => setView(id), children: [
1308
+ t2(id),
1309
+ id === "runHistory" && task.runs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: task.runs.length })
1310
+ ] }, id)) }),
1311
+ view === "overview" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1312
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "am-block", children: [
1313
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h4", { className: "am-block-title", children: [
1314
+ t2("promptLabel"),
1315
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-block-tools", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyButton, { value: task.prompt, t: t2 }) })
1316
+ ] }),
1317
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-prompt", children: task.prompt })
1318
+ ] }),
1319
+ latestResult?.summary !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "am-block", children: [
1320
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("h4", { className: "am-block-title", children: [
1321
+ t2("latestResult"),
1322
+ latestResult.sessionId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-block-tools", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives4.Button, { type: "button", variant: "ghost", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRightUpOutline14, {}), onClick: () => actions.openSession(latestResult.sessionId), children: t2("openSession") }) })
1323
+ ] }),
1324
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-summary", children: latestResult.summary })
1325
+ ] }),
1326
+ task.runs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-detail-note", children: t2("noRuns") })
1327
+ ] }),
1328
+ view === "configuration" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "am-block", children: [
1329
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h4", { className: "am-block-title", children: t2("configuration") }),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "am-facts", children: [
1331
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconCalendar, {}), label: t2("schedule"), children: scheduleLabel(task, locale, t2) }),
1332
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconFolderOpenOutline16, {}), label: t2("workspace"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { title: task.execution.cwd, children: basename(task.execution.cwd) }) }),
1333
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRightUpOutline16, {}), label: t2("executionDestination"), children: task.execution.target?.mode === "pinned-session" ? t2("executionPinned", { sessionId: `${task.execution.target.sessionId.slice(0, 12)}\u2026` }) : t2("executionFresh") }),
1334
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconShield, {}), label: t2("permission"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: task.security.permissionPreset === "danger-full-access" ? "am-danger" : void 0, children: permissionLabel(task.security.permissionPreset, t2, task.permissionDisplayName) }) }),
1335
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconAgentPresetOutline16, {}), label: t2("agentExecution"), full: true, children: executionLabel(task, t2) }),
1336
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconAgentPresetOutline16, {}), label: t2("reasoningEffort"), full: true, children: task.execution.target?.mode === "pinned-session" ? t2("reasoningSession") : task.execution.reasoningEffort ?? t2("reasoningDefault") }),
1337
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRightUpOutline16, {}), label: t2("messageDelivery"), full: true, children: task.delivery === void 0 ? t2("disabled") : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("code", { children: [
1338
+ task.delivery.botId,
1339
+ " / ",
1340
+ task.delivery.targetId
1341
+ ] }) }),
1342
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconBell, {}), label: t2("notifications"), children: notificationPolicyLabel(task.notificationPolicy, t2) }),
1343
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconPauseOutline16, {}), label: t2("pauseAfterFailures"), children: task.pauseAfterConsecutiveFailures ? t2("enabled") : t2("disabled") }),
1344
+ task.consecutiveFailures > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconWarningOutline16, {}), label: t2("consecutiveFailures"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "am-danger", children: task.consecutiveFailures }) }),
1345
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconClockOutline16, {}), label: t2("createdAt"), children: formatDate(task.createdAt, locale) }),
1346
+ task.pausedAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconPauseOutline16, {}), label: t2("pausedAt"), children: formatDate(task.pausedAt, locale) }),
1347
+ task.pausedNextRunAt !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconClockOutline16, {}), label: t2("pausedNextRunAt"), children: formatDate(task.pausedNextRunAt, locale) }),
1348
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconRightUpOutline16, {}), label: t2("createdBySession"), full: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "am-mono-row", children: [
1349
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: task.createdBySessionId }),
1350
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyButton, { value: task.createdBySessionId, t: t2 }),
1351
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1352
+ import_dsh_client_ui_primitives4.Button,
1353
+ {
1354
+ type: "button",
1355
+ variant: "ghost",
1356
+ size: "sm",
1357
+ onClick: () => actions.openSession(task.createdBySessionId),
1358
+ children: t2("open")
1359
+ }
1360
+ )
1361
+ ] }) }),
1362
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Fact, { icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconAgentPresetOutline16, {}), label: t2("taskId"), full: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "am-mono-row", children: [
1363
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: task.id }),
1364
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyButton, { value: task.id, t: t2 })
1365
+ ] }) })
1366
+ ] })
1367
+ ] }),
1368
+ view === "runHistory" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "am-block", children: [
1369
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h4", { className: "am-block-title", children: task.runs.length === 0 ? t2("runHistory") : t2("recentRuns", { count: task.runs.length }) }),
1370
+ task.runs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "am-empty-note", children: t2("noRuns") }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "am-runs", children: [...task.runs].reverse().map((run) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1371
+ RunRow,
1372
+ {
1373
+ run,
1374
+ locale,
1375
+ t: t2,
1376
+ disabled,
1377
+ pending,
1378
+ onRetry: actions.run,
1379
+ onOpen: actions.openSession,
1380
+ onDelete: (trigger) => actions.requestDeleteRun(run, trigger)
1381
+ },
1382
+ run.id
1383
+ )) })
1384
+ ] })
1385
+ ] })
1386
+ ] });
1387
+ }
1388
+
1389
+ // src/client/TaskEditor.tsx
1390
+ var import_react12 = __toESM(require("react"), 1);
1391
+ var import_dsh_client_ui_primitives8 = require("@deepseek-ai/dsh-client-ui-primitives");
1392
+
1393
+ // src/client/ScheduleSection.tsx
1394
+ var import_react8 = __toESM(require("react"), 1);
1395
+ var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
1396
+
1397
+ // src/client/editor-layout.tsx
1398
+ var import_react7 = require("react");
1399
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1400
+ function Field({ label, children, full, hint, htmlFor }) {
1401
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: full === true ? "am-field is-full" : "am-field", children: [
1402
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "am-field-label", htmlFor, children: label }),
1403
+ children,
1404
+ hint !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("small", { className: "am-field-hint", children: hint })
1405
+ ] });
1406
+ }
1407
+ function Section({ title, children }) {
1408
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "am-form-section", children: [
1409
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { className: "am-form-section-title", children: title }),
1410
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "am-form-grid", children })
1411
+ ] });
1412
+ }
1413
+ function Disclosure({ title, children }) {
1414
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { className: "am-editor-disclosure", children: [
1415
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("summary", { className: "am-form-section-title", children: [
1416
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconChevronRightOutline14, { className: "am-disclosure-chevron" }),
1417
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: title })
1418
+ ] }),
1419
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "am-form-grid", children })
1420
+ ] });
1421
+ }
1422
+
1423
+ // src/client/ScheduleSection.tsx
1424
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1425
+ var WEEKDAY_KEYS2 = {
1426
+ MO: "weekdayMonday",
1427
+ TU: "weekdayTuesday",
1428
+ WE: "weekdayWednesday",
1429
+ TH: "weekdayThursday",
1430
+ FR: "weekdayFriday",
1431
+ SA: "weekdaySaturday",
1432
+ SU: "weekdaySunday"
1433
+ };
1434
+ var INTERVAL_UNIT_KEYS = {
1435
+ DAILY: "intervalDays",
1436
+ WEEKLY: "intervalWeeks",
1437
+ MONTHLY: "intervalMonths"
1438
+ };
1439
+ function toLocalDateTime(value) {
1440
+ const date = new Date(value);
1441
+ return new Date(date.getTime() - date.getTimezoneOffset() * 6e4).toISOString().slice(0, 19);
1442
+ }
1443
+ function useScheduleEditor(task) {
1444
+ const fallbackInstant = task.schedule.kind === "once" ? task.schedule.fireAt : task.nextRunAt ?? new Date(Date.now() + 60 * 6e4).toISOString();
1445
+ const [kind, setKind] = import_react8.default.useState(task.schedule.kind);
1446
+ const [onceAt, setOnceAt] = import_react8.default.useState(toLocalDateTime(fallbackInstant));
1447
+ const defaultMonthDay = String(Number((task.schedule.kind === "recurring" ? task.schedule.startAt : toLocalDateTime(fallbackInstant)).slice(8, 10)));
1448
+ const initialRrule = task.schedule.kind === "recurring" ? task.schedule.rrule : "FREQ=DAILY";
1449
+ const initialCommonRule = parseCommonRRule(initialRrule, defaultMonthDay);
1450
+ const initialComparableRrule = initialCommonRule === void 0 ? initialRrule : buildCommonRRule(initialCommonRule);
1451
+ const [rrule, setRrule] = import_react8.default.useState(initialRrule);
1452
+ const [advancedRule, setAdvancedRule] = import_react8.default.useState(initialCommonRule === void 0);
1453
+ const [commonRule, setCommonRule] = import_react8.default.useState(initialCommonRule ?? defaultCommonRRule(defaultMonthDay));
1454
+ const [timeZone, setTimeZone] = import_react8.default.useState(task.schedule.kind === "recurring" ? task.schedule.timeZone : Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC");
1455
+ const [startAt, setStartAt] = import_react8.default.useState(task.schedule.kind === "recurring" ? task.schedule.startAt : toLocalDateTime(fallbackInstant));
1456
+ const normalizedStartAt = startAt.length === 16 ? `${startAt}:00` : startAt;
1457
+ const effectiveRrule = advancedRule ? rrule : buildCommonRRule(commonRule);
1458
+ const parsedRawRule = parseCommonRRule(rrule, defaultMonthDay);
1459
+ const scheduleChanged = task.schedule.kind !== kind || (kind === "once" ? task.schedule.kind !== "once" || onceAt !== toLocalDateTime(task.schedule.fireAt) : task.schedule.kind !== "recurring" || effectiveRrule !== initialComparableRrule || timeZone !== task.schedule.timeZone || normalizedStartAt !== task.schedule.startAt);
1460
+ const valid = kind === "once" ? onceAt.trim() !== "" && Number.isFinite(new Date(onceAt).getTime()) : effectiveRrule.trim() !== "" && timeZone.trim() !== "" && startAt.trim() !== "";
1461
+ const getSchedule = () => !scheduleChanged ? void 0 : kind === "once" ? { kind: "once", fireAt: new Date(onceAt).toISOString() } : { kind: "recurring", rrule: effectiveRrule, timeZone, startAt: normalizedStartAt };
1462
+ return {
1463
+ kind,
1464
+ setKind,
1465
+ onceAt,
1466
+ setOnceAt,
1467
+ rrule,
1468
+ setRrule,
1469
+ advancedRule,
1470
+ setAdvancedRule,
1471
+ commonRule,
1472
+ setCommonRule,
1473
+ timeZone,
1474
+ setTimeZone,
1475
+ startAt,
1476
+ setStartAt,
1477
+ parsedRawRule,
1478
+ scheduleChanged,
1479
+ valid,
1480
+ getSchedule
1481
+ };
1482
+ }
1483
+ function ScheduleSection({ schedule, saving, t: t2 }) {
1484
+ const {
1485
+ kind,
1486
+ setKind,
1487
+ onceAt,
1488
+ setOnceAt,
1489
+ rrule,
1490
+ setRrule,
1491
+ advancedRule,
1492
+ setAdvancedRule,
1493
+ commonRule,
1494
+ setCommonRule,
1495
+ timeZone,
1496
+ setTimeZone,
1497
+ startAt,
1498
+ setStartAt,
1499
+ parsedRawRule
1500
+ } = schedule;
1501
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Section, { title: t2("schedule"), children: [
1502
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("scheduleType"), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1503
+ Select,
1504
+ {
1505
+ value: kind,
1506
+ disabled: saving,
1507
+ ariaLabel: t2("scheduleType"),
1508
+ options: [
1509
+ { value: "once", label: t2("oneTimeSchedule") },
1510
+ { value: "recurring", label: t2("recurringSchedule") }
1511
+ ],
1512
+ onChange: (next) => setKind(next)
1513
+ }
1514
+ ) }),
1515
+ kind === "once" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("runAt"), htmlFor: "am-once", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-once", className: "am-input", required: true, type: "datetime-local", step: "1", disabled: saving, value: onceAt, onChange: (event) => setOnceAt(event.target.value) }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1516
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "am-field is-full", children: [
1517
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "am-field-label", children: t2("recurrenceRule") }),
1518
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "am-pill-group", role: "group", "aria-label": t2("ruleMode"), children: [
1519
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1520
+ import_dsh_client_ui_primitives5.Pill,
1521
+ {
1522
+ type: "button",
1523
+ active: !advancedRule,
1524
+ disabled: saving || advancedRule && parsedRawRule === void 0,
1525
+ title: advancedRule && parsedRawRule === void 0 ? t2("unsupportedRuleHint") : void 0,
1526
+ onClick: () => {
1527
+ if (parsedRawRule === void 0) return;
1528
+ setCommonRule(parsedRawRule);
1529
+ setAdvancedRule(false);
1530
+ },
1531
+ children: t2("visualMode")
1532
+ }
1533
+ ),
1534
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1535
+ import_dsh_client_ui_primitives5.Pill,
1536
+ {
1537
+ type: "button",
1538
+ active: advancedRule,
1539
+ disabled: saving,
1540
+ onClick: () => {
1541
+ if (!advancedRule) setRrule(buildCommonRRule(commonRule));
1542
+ setAdvancedRule(true);
1543
+ },
1544
+ children: t2("advancedMode")
1545
+ }
1546
+ )
1547
+ ] }),
1548
+ advancedRule ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "am-rule-advanced", children: [
1549
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { className: "am-input", "aria-label": t2("recurrenceRule"), required: true, disabled: saving, value: rrule, placeholder: "FREQ=WEEKLY;BYDAY=MO", onChange: (event) => setRrule(event.target.value) }),
1550
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("small", { className: "am-field-hint", children: parsedRawRule === void 0 ? t2("unsupportedRuleHint") : t2("advancedRuleHint") })
1551
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "am-form-grid am-rule-builder", children: [
1552
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("frequency"), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1553
+ Select,
1554
+ {
1555
+ value: commonRule.frequency,
1556
+ disabled: saving,
1557
+ ariaLabel: t2("frequency"),
1558
+ options: [
1559
+ { value: "DAILY", label: t2("frequencyDaily") },
1560
+ { value: "WEEKLY", label: t2("frequencyWeekly") },
1561
+ { value: "MONTHLY", label: t2("frequencyMonthly") }
1562
+ ],
1563
+ onChange: (next) => setCommonRule({ ...commonRule, frequency: next })
1564
+ }
1565
+ ) }),
1566
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("repeatEvery"), htmlFor: "am-interval", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "am-interval", children: [
1567
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-interval", className: "am-input", required: true, type: "number", min: "1", step: "1", disabled: saving, value: commonRule.interval, onChange: (event) => setCommonRule({ ...commonRule, interval: event.target.value }) }),
1568
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: t2(INTERVAL_UNIT_KEYS[commonRule.frequency]) })
1569
+ ] }) }),
1570
+ commonRule.frequency === "WEEKLY" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1571
+ Field,
1572
+ {
1573
+ full: true,
1574
+ label: t2("repeatOn"),
1575
+ hint: commonRule.weekdays.length === 0 ? t2("useStartDayHint") : void 0,
1576
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "am-pill-group", role: "group", "aria-label": t2("repeatOn"), children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1577
+ import_dsh_client_ui_primitives5.Pill,
1578
+ {
1579
+ type: "button",
1580
+ active: commonRule.weekdays.includes(day),
1581
+ disabled: saving,
1582
+ "aria-pressed": commonRule.weekdays.includes(day),
1583
+ onClick: () => setCommonRule({
1584
+ ...commonRule,
1585
+ weekdays: commonRule.weekdays.includes(day) ? commonRule.weekdays.filter((value) => value !== day) : [...commonRule.weekdays, day]
1586
+ }),
1587
+ children: t2(WEEKDAY_KEYS2[day])
1588
+ },
1589
+ day
1590
+ )) })
1591
+ }
1592
+ ),
1593
+ commonRule.frequency === "MONTHLY" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("monthlyOnDay"), htmlFor: "am-monthday", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-monthday", className: "am-input", required: true, type: "number", min: "1", max: "31", step: "1", disabled: saving, value: commonRule.monthDay, onChange: (event) => setCommonRule({ ...commonRule, monthDay: event.target.value }) }) }),
1594
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("ends"), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1595
+ Select,
1596
+ {
1597
+ value: commonRule.end,
1598
+ disabled: saving,
1599
+ ariaLabel: t2("ends"),
1600
+ options: [
1601
+ { value: "never", label: t2("endsNever") },
1602
+ { value: "count", label: t2("endsAfter") },
1603
+ { value: "until", label: t2("endsOnDate") }
1604
+ ],
1605
+ onChange: (next) => setCommonRule({ ...commonRule, end: next })
1606
+ }
1607
+ ) }),
1608
+ commonRule.end === "count" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("occurrences"), htmlFor: "am-count", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-count", className: "am-input", required: true, type: "number", min: "1", step: "1", disabled: saving, value: commonRule.count, onChange: (event) => setCommonRule({ ...commonRule, count: event.target.value }) }) }),
1609
+ commonRule.end === "until" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("endDate"), htmlFor: "am-until", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-until", className: "am-input", required: true, type: "date", disabled: saving, value: commonRule.until, onChange: (event) => setCommonRule({ ...commonRule, until: event.target.value }) }) })
1610
+ ] })
1611
+ ] }),
1612
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("timeZone"), htmlFor: "am-tz", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-tz", className: "am-input", required: true, disabled: saving, value: timeZone, placeholder: "Asia/Shanghai", onChange: (event) => setTimeZone(event.target.value) }) }),
1613
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: t2("startsAt"), htmlFor: "am-start", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dsh_client_ui_primitives5.Input, { id: "am-start", className: "am-input", required: true, type: "datetime-local", step: "1", disabled: saving, value: startAt, onChange: (event) => setStartAt(event.target.value) }) })
1614
+ ] })
1615
+ ] });
1616
+ }
1617
+
1618
+ // src/client/store.ts
1619
+ var import_react9 = __toESM(require("react"), 1);
1620
+ var API = "/api/automation/v1";
1621
+ var OPEN_INTERVAL = 5e3;
1622
+ var IDLE_INTERVAL = 3e4;
1623
+ async function request(path, options = {}) {
1624
+ const response = await fetch(`${API}${path}`, {
1625
+ ...options,
1626
+ headers: {
1627
+ "x-dsh-automation": "1",
1628
+ ...options.body === void 0 ? {} : { "content-type": "application/json" },
1629
+ ...options.headers
1630
+ }
1631
+ });
1632
+ const value = await response.json();
1633
+ if (!response.ok) {
1634
+ const message = typeof value === "object" && value !== null && "error" in value ? String(value.error) : t("requestFailed", { status: response.status });
1635
+ throw new Error(message);
1636
+ }
1637
+ return value;
1638
+ }
1639
+ var snapshot2 = { tasks: [], scheduler: void 0, unread: 0, loading: false, error: void 0 };
1640
+ var listeners = /* @__PURE__ */ new Set();
1641
+ var timer;
1642
+ var inflight;
1643
+ var mutationRevision = 0;
1644
+ var loaded = false;
1645
+ var panelOpen = false;
1646
+ function emit(next) {
1647
+ snapshot2 = next;
1648
+ for (const listener of listeners) listener();
1649
+ }
1650
+ function refresh() {
1651
+ if (inflight !== void 0) return inflight;
1652
+ const first = !loaded;
1653
+ const revision = mutationRevision;
1654
+ if (first) emit({ ...snapshot2, loading: true });
1655
+ inflight = (async () => {
1656
+ try {
1657
+ const value = await request("/tasks");
1658
+ if (revision !== mutationRevision) return;
1659
+ loaded = true;
1660
+ emit({
1661
+ tasks: value.tasks,
1662
+ scheduler: value.scheduler,
1663
+ unread: value.tasks.reduce((sum, task) => sum + task.unreadNotifications, 0),
1664
+ loading: false,
1665
+ error: void 0
1666
+ });
1667
+ } catch (reason) {
1668
+ if (first) {
1669
+ loaded = true;
1670
+ emit({ ...snapshot2, loading: false, error: reason instanceof Error ? reason.message : String(reason) });
1671
+ }
1672
+ } finally {
1673
+ inflight = void 0;
1674
+ }
1675
+ })();
1676
+ return inflight;
1677
+ }
1678
+ async function deleteRunRecord(taskId, runId) {
1679
+ await request(`/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}`, { method: "DELETE" });
1680
+ mutationRevision += 1;
1681
+ emit({
1682
+ ...snapshot2,
1683
+ tasks: snapshot2.tasks.map((task) => task.id === taskId ? { ...task, runs: task.runs.filter((run) => run.id !== runId) } : task)
1684
+ });
1685
+ void refresh();
1686
+ }
1687
+ function reschedule() {
1688
+ if (timer !== void 0) window.clearInterval(timer);
1689
+ timer = listeners.size === 0 ? void 0 : window.setInterval(() => void refresh(), panelOpen ? OPEN_INTERVAL : IDLE_INTERVAL);
1690
+ }
1691
+ function subscribe2(listener) {
1692
+ listeners.add(listener);
1693
+ if (listeners.size === 1) {
1694
+ void refresh();
1695
+ reschedule();
1696
+ }
1697
+ return () => {
1698
+ listeners.delete(listener);
1699
+ if (listeners.size === 0 && timer !== void 0) {
1700
+ window.clearInterval(timer);
1701
+ timer = void 0;
1702
+ }
1703
+ };
1704
+ }
1705
+ function useAutomations() {
1706
+ return import_react9.default.useSyncExternalStore(subscribe2, () => snapshot2, () => snapshot2);
1707
+ }
1708
+ function clearError() {
1709
+ if (snapshot2.error !== void 0) emit({ ...snapshot2, error: void 0 });
1710
+ }
1711
+ function reportError(message) {
1712
+ emit({ ...snapshot2, error: message });
1713
+ }
1714
+ function clearUnread() {
1715
+ if (snapshot2.unread !== 0) emit({ ...snapshot2, unread: 0 });
1716
+ }
1717
+ var panelListeners = /* @__PURE__ */ new Set();
1718
+ function setPanelOpen(open) {
1719
+ if (panelOpen === open) return;
1720
+ panelOpen = open;
1721
+ reschedule();
1722
+ for (const listener of panelListeners) listener();
1723
+ }
1724
+ function usePanelOpen() {
1725
+ return import_react9.default.useSyncExternalStore(
1726
+ (listener) => {
1727
+ panelListeners.add(listener);
1728
+ return () => panelListeners.delete(listener);
1729
+ },
1730
+ () => panelOpen
1731
+ );
1732
+ }
1733
+ var pendingDrafts = /* @__PURE__ */ new Map();
1734
+ var draftListeners = /* @__PURE__ */ new Set();
1735
+ var draftRevision = 0;
1736
+ function queueDraft(sessionId, text) {
1737
+ pendingDrafts.set(sessionId, text);
1738
+ draftRevision += 1;
1739
+ for (const listener of draftListeners) listener();
1740
+ }
1741
+ function consumeDraft(sessionId) {
1742
+ const text = pendingDrafts.get(sessionId);
1743
+ if (text === void 0) return void 0;
1744
+ pendingDrafts.delete(sessionId);
1745
+ draftRevision += 1;
1746
+ for (const listener of draftListeners) listener();
1747
+ return text;
1748
+ }
1749
+ function useDraftRevision() {
1750
+ return import_react9.default.useSyncExternalStore(
1751
+ (listener) => {
1752
+ draftListeners.add(listener);
1753
+ return () => draftListeners.delete(listener);
1754
+ },
1755
+ () => draftRevision
1756
+ );
1757
+ }
1758
+ function resetStore() {
1759
+ if (timer !== void 0) window.clearInterval(timer);
1760
+ timer = void 0;
1761
+ panelOpen = false;
1762
+ loaded = false;
1763
+ panelListeners = /* @__PURE__ */ new Set();
1764
+ }
1765
+
1766
+ // src/client/SkillPicker.tsx
1767
+ var import_react10 = __toESM(require("react"), 1);
1768
+ var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
1769
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1770
+ function SkillPicker({ skills, options, disabled, t: t2, onChange }) {
1771
+ const [query, setQuery] = import_react10.default.useState("");
1772
+ const names = [.../* @__PURE__ */ new Set([...skills, ...options?.skills.map((entry) => entry.name) ?? []])];
1773
+ const needle = query.trim().toLowerCase();
1774
+ const shown = needle === "" ? names : names.filter((name) => {
1775
+ const option = options?.skills.find((entry) => entry.name === name);
1776
+ return name.toLowerCase().includes(needle) || (option?.description ?? "").toLowerCase().includes(needle);
1777
+ });
1778
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "am-skills", children: [
1779
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "am-skills-bar", children: [
1780
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1781
+ import_dsh_client_ui_primitives6.Input,
1782
+ {
1783
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconSearchOutline16, {}),
1784
+ value: query,
1785
+ disabled,
1786
+ placeholder: t2("skillSearchPlaceholder"),
1787
+ "aria-label": t2("skillSearchPlaceholder"),
1788
+ onChange: (event) => setQuery(event.target.value)
1789
+ }
1790
+ ),
1791
+ skills.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_dsh_client_ui_primitives6.Button, { type: "button", variant: "ghost", size: "sm", disabled, onClick: () => onChange([]), children: t2("clearSkills") })
1792
+ ] }),
1793
+ skills.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "am-skill-chips", children: [
1794
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "am-skills-count", children: t2("selectedCount", { count: skills.length }) }),
1795
+ skills.map((name) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1796
+ "button",
1797
+ {
1798
+ type: "button",
1799
+ className: "am-chip-remove",
1800
+ disabled,
1801
+ "aria-label": `${name} \xB7 ${t2("cancel")}`,
1802
+ onClick: () => onChange(skills.filter((entry) => entry !== name)),
1803
+ children: [
1804
+ name,
1805
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconCloseOutline16, { size: 12 })
1806
+ ]
1807
+ },
1808
+ name
1809
+ ))
1810
+ ] }),
1811
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "am-skill-list", children: [
1812
+ shown.map((name) => {
1813
+ const option = options?.skills.find((entry) => entry.name === name);
1814
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: option === void 0 ? "am-skill is-unavailable" : "am-skill", children: [
1815
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1816
+ "input",
1817
+ {
1818
+ type: "checkbox",
1819
+ checked: skills.includes(name),
1820
+ disabled,
1821
+ onChange: (event) => onChange(event.target.checked ? [...skills, name] : skills.filter((entry) => entry !== name))
1822
+ }
1823
+ ),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "am-skill-copy", children: [
1825
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("b", { children: name }),
1826
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("small", { children: [
1827
+ option === void 0 ? t2("unavailable") : option.description,
1828
+ option?.modelInvocable === true ? ` \xB7 ${t2("modelInvocable")}` : ""
1829
+ ] })
1830
+ ] })
1831
+ ] }, name);
1832
+ }),
1833
+ shown.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("small", { className: "am-empty-note", children: names.length === 0 ? t2("noSkills") : t2("noSkillMatches") })
1834
+ ] })
1835
+ ] });
1836
+ }
1837
+
1838
+ // src/client/ModelSelection.tsx
1839
+ var import_react11 = __toESM(require("react"), 1);
1840
+ var import_dsh_client_ui_primitives7 = require("@deepseek-ai/dsh-client-ui-primitives");
1841
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1842
+ function ModelSelection({ model, effort, models, efforts, disabled, modelDisabled, effortDisabled, onModel, onEffort, t: t2 }) {
1843
+ const [open, setOpen] = import_react11.default.useState(false);
1844
+ const [pane, setPane] = import_react11.default.useState("root");
1845
+ const firstEntry = import_react11.default.useRef(null);
1846
+ import_react11.default.useEffect(() => {
1847
+ if (!open || disabled) return;
1848
+ const frame = requestAnimationFrame(() => firstEntry.current?.closest("button")?.focus());
1849
+ return () => cancelAnimationFrame(frame);
1850
+ }, [open, pane, disabled]);
1851
+ const modelLabel = models.find((option) => option.value === model)?.label ?? model;
1852
+ const effortLabel = effort === "" ? t2("reasoningDefaultShort") : efforts.find((option) => option.value === effort)?.label ?? effort;
1853
+ const choices = (options) => options.map((option) => ({
1854
+ id: option.value,
1855
+ label: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { ref: option === options.find((entry) => !entry.disabled) ? firstEntry : void 0, className: option.hint === void 0 ? void 0 : "am-option", children: [
1856
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: option.label }),
1857
+ option.hint !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { children: option.hint })
1858
+ ] }),
1859
+ ...option.disabled === true ? { disabled: true } : {}
1860
+ }));
1861
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1862
+ import_dsh_client_ui_primitives7.Menu,
1863
+ {
1864
+ open: open && !disabled,
1865
+ portal: true,
1866
+ autoFocus: true,
1867
+ align: "start",
1868
+ className: "am-model-menu",
1869
+ selectedId: pane === "model" ? model : pane === "effort" ? effort : void 0,
1870
+ items: pane === "root" ? [
1871
+ {
1872
+ id: "model",
1873
+ disabled: modelDisabled,
1874
+ label: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { ref: modelDisabled ? void 0 : firstEntry, className: "am-model-menu-row", children: [
1875
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: t2("model") }),
1876
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: modelLabel }),
1877
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IconChevronRightOutline14, {})
1878
+ ] })
1879
+ },
1880
+ {
1881
+ id: "effort",
1882
+ disabled: effortDisabled,
1883
+ label: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { ref: modelDisabled ? firstEntry : void 0, className: "am-model-menu-row", children: [
1884
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: t2("reasoningEffort") }),
1885
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: effortLabel }),
1886
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IconChevronRightOutline14, {})
1887
+ ] })
1888
+ }
1889
+ ] : choices(pane === "model" ? models : efforts),
1890
+ onSelect: (id) => {
1891
+ if (pane === "root") {
1892
+ setPane(id === "model" ? "model" : "effort");
1893
+ return;
1894
+ }
1895
+ setOpen(false);
1896
+ if (pane === "model" && id !== model) onModel(id);
1897
+ if (pane === "effort" && id !== effort) onEffort(id);
1898
+ },
1899
+ onClose: () => setOpen(false),
1900
+ anchor: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1901
+ "button",
1902
+ {
1903
+ type: "button",
1904
+ className: "am-select",
1905
+ disabled,
1906
+ "aria-label": t2("modelAndReasoning"),
1907
+ "aria-haspopup": "menu",
1908
+ "aria-expanded": open && !disabled,
1909
+ onClick: () => {
1910
+ if (!open) setPane("root");
1911
+ setOpen((value) => !value);
1912
+ },
1913
+ children: [
1914
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "am-select-value am-model-summary", children: [
1915
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: modelLabel }),
1916
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: effortLabel })
1917
+ ] }),
1918
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IconChevronDownOutline14, {})
1919
+ ]
1920
+ }
1921
+ )
1922
+ },
1923
+ pane
1924
+ );
1925
+ }
1926
+
1927
+ // src/client/TaskEditor.tsx
1928
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1929
+ function TaskEditor({ task, sessions, workspaceSessionIds, refreshSessions, saving, t: t2, onSave, onCancel, onDirtyChange }) {
1930
+ const initialTarget = task.execution.target;
1931
+ const [targetMode, setTargetMode] = import_react12.default.useState(initialTarget?.mode ?? "fresh");
1932
+ const [targetSessionId, setTargetSessionId] = import_react12.default.useState(initialTarget?.mode === "pinned-session" ? initialTarget.sessionId : "");
1933
+ const [sessionQuery, setSessionQuery] = import_react12.default.useState("");
1934
+ const [sessionsLoading, setSessionsLoading] = import_react12.default.useState(true);
1935
+ const [sessionsError, setSessionsError] = import_react12.default.useState();
1936
+ const [sessionRefresh, setSessionRefresh] = import_react12.default.useState(0);
1937
+ import_react12.default.useEffect(() => {
1938
+ let active = true;
1939
+ setSessionsLoading(true);
1940
+ setSessionsError(void 0);
1941
+ void refreshSessions().then(() => {
1942
+ if (active) setSessionsError(void 0);
1943
+ }, (error) => {
1944
+ if (active) setSessionsError(error instanceof Error ? error.message : String(error));
1945
+ }).finally(() => {
1946
+ if (active) setSessionsLoading(false);
1947
+ });
1948
+ return () => {
1949
+ active = false;
1950
+ };
1951
+ }, [refreshSessions, sessionRefresh]);
1952
+ const sessionLoadError = sessionsError ?? (!sessionsLoading && sessions.phase !== "ready" ? t2("sessionsNotReady") : void 0);
1953
+ const pinned = targetMode === "pinned-session";
1954
+ const targetChanged = targetMode !== (initialTarget?.mode ?? "fresh") || pinned && targetSessionId !== (initialTarget?.mode === "pinned-session" ? initialTarget.sessionId : "");
1955
+ const targetLocked = task.running || task.runs.some((run) => run.status === "queued" || run.status === "running");
1956
+ const candidates = sessions.ids.map((id) => sessions.byId[id]).filter((session) => session !== void 0).filter((session) => workspaceSessionIds.includes(session.id) && session.cwd === task.execution.cwd && session.origin !== "subagent");
1957
+ const selectedSession = candidates.find((session) => session.id === targetSessionId);
1958
+ const targetValid = !targetChanged || !targetLocked && (!pinned || !sessionsLoading && sessionLoadError === void 0 && sessions.phase === "ready" && selectedSession !== void 0);
1959
+ const currentSessionId = selectedSessionId(sessions);
1960
+ const needle = sessionQuery.trim().toLowerCase();
1961
+ const sessionOptions = [
1962
+ { value: "", label: t2("selectSession"), disabled: true },
1963
+ ...targetSessionId !== "" && selectedSession === void 0 ? [{ value: targetSessionId, label: `${targetSessionId} \xB7 ${t2("unavailable")}`, disabled: true }] : [],
1964
+ ...candidates.filter((session) => session.id === targetSessionId || `${session.displayTitle} ${session.id}`.toLowerCase().includes(needle)).map((session) => ({
1965
+ value: session.id,
1966
+ label: `${session.displayTitle}${session.id === currentSessionId ? ` \xB7 ${t2("currentSession")}` : ""}${session.running ? ` \xB7 ${t2("statusRunning")}` : ""}`,
1967
+ hint: `${session.id} \xB7 ${new Date(session.updatedAt).toLocaleString()}`
1968
+ }))
1969
+ ];
1970
+ const [deliveryEnabled, setDeliveryEnabled] = import_react12.default.useState(task.delivery !== void 0);
1971
+ const [deliveryBotId, setDeliveryBotId] = import_react12.default.useState(task.delivery?.botId ?? "");
1972
+ const [deliveryTargetId, setDeliveryTargetId] = import_react12.default.useState(task.delivery?.targetId ?? "");
1973
+ const [deliveryCatalog, setDeliveryCatalog] = import_react12.default.useState();
1974
+ const [deliveryLoading, setDeliveryLoading] = import_react12.default.useState(false);
1975
+ const [deliveryError, setDeliveryError] = import_react12.default.useState();
1976
+ const [deliveryRefresh, setDeliveryRefresh] = import_react12.default.useState(0);
1977
+ import_react12.default.useEffect(() => {
1978
+ if (!deliveryEnabled) return;
1979
+ const controller = new AbortController();
1980
+ setDeliveryLoading(true);
1981
+ setDeliveryError(void 0);
1982
+ const query = deliveryBotId === "" ? "" : `?botId=${encodeURIComponent(deliveryBotId)}`;
1983
+ void request(`/delivery-options${query}`, { signal: controller.signal }).then((value) => {
1984
+ if (!controller.signal.aborted) setDeliveryCatalog({ botId: deliveryBotId, options: value.options });
1985
+ }, (error) => {
1986
+ if (!controller.signal.aborted) setDeliveryError(error instanceof Error ? error.message : String(error));
1987
+ }).finally(() => {
1988
+ if (!controller.signal.aborted) setDeliveryLoading(false);
1989
+ });
1990
+ return () => controller.abort();
1991
+ }, [deliveryEnabled, deliveryBotId, deliveryRefresh]);
1992
+ const deliveryOptions = deliveryCatalog?.options;
1993
+ const deliveryTargets = deliveryCatalog?.botId === deliveryBotId ? deliveryOptions?.targets ?? [] : [];
1994
+ const selectedDeliveryBot = deliveryOptions?.bots.find((entry) => entry.botId === deliveryBotId);
1995
+ const selectedDeliveryTarget = deliveryTargets.find((entry) => entry.targetId === deliveryTargetId);
1996
+ const deliveryChanged = deliveryEnabled !== (task.delivery !== void 0) || deliveryEnabled && (deliveryBotId !== task.delivery?.botId || deliveryTargetId !== task.delivery?.targetId);
1997
+ const deliveryValid = !deliveryChanged || !targetLocked && (!deliveryEnabled || !deliveryLoading && deliveryError === void 0 && deliveryOptions?.available === true && selectedDeliveryBot !== void 0 && selectedDeliveryTarget !== void 0);
1998
+ const deliveryBotOptions = [
1999
+ { value: "", label: t2("selectDeliveryBot"), disabled: true },
2000
+ ...deliveryBotId !== "" && selectedDeliveryBot === void 0 ? [{ value: deliveryBotId, label: `${deliveryBotId} \xB7 ${t2("unavailable")}`, disabled: true }] : [],
2001
+ ...(deliveryOptions?.bots ?? []).map((entry) => ({ value: entry.botId, label: `${entry.channel} \xB7 ${entry.botId}` }))
2002
+ ];
2003
+ const deliveryTargetOptions = [
2004
+ { value: "", label: t2("selectDeliveryTarget"), disabled: true },
2005
+ ...deliveryTargetId !== "" && selectedDeliveryTarget === void 0 ? [{ value: deliveryTargetId, label: `${deliveryTargetId} \xB7 ${t2("unavailable")}`, disabled: true }] : [],
2006
+ ...deliveryTargets.map((entry) => ({
2007
+ value: entry.targetId,
2008
+ label: entry.name ? `${entry.name} \xB7 ${entry.targetId}` : entry.targetId,
2009
+ hint: entry.kind
2010
+ }))
2011
+ ];
2012
+ const [name, setName] = import_react12.default.useState(task.name);
2013
+ const [prompt, setPrompt] = import_react12.default.useState(task.prompt);
2014
+ const [notificationPolicy, setNotificationPolicy] = import_react12.default.useState(task.notificationPolicy);
2015
+ const [pauseAfterFailures, setPauseAfterFailures] = import_react12.default.useState(task.pauseAfterConsecutiveFailures);
2016
+ const [permissionPreset, setPermissionPreset] = import_react12.default.useState(task.security.permissionPreset);
2017
+ const [permissionConfirmed, setPermissionConfirmed] = import_react12.default.useState(false);
2018
+ const [agentPreset, setAgentPreset] = import_react12.default.useState(task.execution.agentPreset ?? "");
2019
+ const [provider, setProvider] = import_react12.default.useState(task.execution.provider ?? "");
2020
+ const [model, setModel] = import_react12.default.useState(task.execution.model ?? "");
2021
+ const [reasoningEffort, setReasoningEffort] = import_react12.default.useState(task.execution.reasoningEffort ?? "");
2022
+ const [skills, setSkills] = import_react12.default.useState(task.execution.skills);
2023
+ const [options, setOptions] = import_react12.default.useState();
2024
+ const [optionsLoading, setOptionsLoading] = import_react12.default.useState(true);
2025
+ const [optionsError, setOptionsError] = import_react12.default.useState();
2026
+ const scheduleEditor = useScheduleEditor(task);
2027
+ const { scheduleChanged } = scheduleEditor;
2028
+ const permissionChanged = permissionPreset !== task.security.permissionPreset;
2029
+ const modelChanged = provider !== (task.execution.provider ?? "") || model !== (task.execution.model ?? "");
2030
+ const reasoningChanged = reasoningEffort !== (task.execution.reasoningEffort ?? "");
2031
+ const reasoning = options?.reasoning?.provider === provider && options.reasoning.model === model ? options.reasoning : void 0;
2032
+ const reasoningValid = reasoningEffort === "" || reasoning?.efforts.some((entry) => entry.id === reasoningEffort) === true;
2033
+ const agentExecutionChanged = !pinned && (agentPreset !== (task.execution.agentPreset ?? "") || modelChanged || reasoningChanged || skills.join("\0") !== task.execution.skills.join("\0"));
2034
+ const executionChanged = targetChanged || agentExecutionChanged;
2035
+ const changed = name.trim() !== task.name || prompt.trim() !== task.prompt || scheduleChanged || permissionChanged || executionChanged || deliveryChanged || notificationPolicy !== task.notificationPolicy || pauseAfterFailures !== task.pauseAfterConsecutiveFailures;
2036
+ const selectedPermission = options?.permissions.find((entry) => entry.id === permissionPreset);
2037
+ const selectedProvider = options?.models.find((entry) => entry.provider === provider);
2038
+ const selectedPresetAvailable = agentPreset === "" || options?.presets.some((entry) => entry.id === agentPreset && entry.broken === void 0);
2039
+ const skillsAvailable = skills.every((entry) => options?.skills.some((option) => option.name === entry));
2040
+ const legacyPartialModelUnchanged = !modelChanged && task.execution.provider === void 0 !== (task.execution.model === void 0);
2041
+ const configValid = selectedPermission !== void 0 && (pinned || selectedPresetAvailable !== false && skillsAvailable && reasoningValid && (provider === "" === (model === "") || legacyPartialModelUnchanged));
2042
+ const requiredFieldsValid = name.trim() !== "" && prompt.trim() !== "" && scheduleEditor.valid;
2043
+ const blocked = saving || optionsLoading || optionsError !== void 0 || !configValid || !targetValid || !deliveryValid || !requiredFieldsValid || !changed || permissionChanged && !permissionConfirmed;
2044
+ import_react12.default.useEffect(() => {
2045
+ onDirtyChange?.(changed);
2046
+ }, [changed, onDirtyChange]);
2047
+ const optionsRequestSequence = import_react12.default.useRef(0);
2048
+ const loadOptions = import_react12.default.useCallback(async () => {
2049
+ const sequence = ++optionsRequestSequence.current;
2050
+ try {
2051
+ setOptionsLoading(true);
2052
+ setOptionsError(void 0);
2053
+ const query = `?${new URLSearchParams({ agentPreset, provider: model === "" ? "" : provider, model: provider === "" ? "" : model })}`;
2054
+ const value = await request(`/tasks/${encodeURIComponent(task.id)}/options${query}`);
2055
+ if (sequence === optionsRequestSequence.current) setOptions(value.options);
2056
+ } catch (reason) {
2057
+ if (sequence === optionsRequestSequence.current) {
2058
+ setOptionsError(reason instanceof Error ? reason.message : String(reason));
2059
+ }
2060
+ } finally {
2061
+ if (sequence === optionsRequestSequence.current) setOptionsLoading(false);
2062
+ }
2063
+ }, [task.id, agentPreset, provider, model]);
2064
+ import_react12.default.useEffect(() => {
2065
+ void loadOptions();
2066
+ return () => {
2067
+ optionsRequestSequence.current += 1;
2068
+ };
2069
+ }, [loadOptions]);
2070
+ const presetOptions = [
2071
+ { value: "", label: t2("hostDefault") },
2072
+ ...agentPreset !== "" && options?.presets.some((entry) => entry.id === agentPreset) !== true ? [{ value: agentPreset, label: `${agentPreset} \xB7 ${t2("unavailable")}` }] : [],
2073
+ ...(options?.presets ?? []).map((entry) => ({
2074
+ value: entry.id,
2075
+ label: `${entry.name}${entry.broken === void 0 ? "" : ` \xB7 ${t2("unavailable")}`}`,
2076
+ ...entry.description === void 0 ? {} : { hint: entry.description },
2077
+ ...entry.broken === void 0 ? {} : { disabled: true }
2078
+ }))
2079
+ ];
2080
+ const providerOptions = [
2081
+ { value: "", label: t2("hostDefault") },
2082
+ ...provider !== "" && options?.models.some((entry) => entry.provider === provider) !== true ? [{ value: provider, label: `${provider} \xB7 ${t2("unavailable")}` }] : [],
2083
+ ...(options?.models ?? []).map((entry) => ({ value: entry.provider, label: entry.name }))
2084
+ ];
2085
+ const modelOptions = [
2086
+ { value: "", label: provider === "" ? t2("hostDefault") : t2("selectModel") },
2087
+ ...model !== "" && selectedProvider?.models.some((entry) => entry.id === model) !== true ? [{ value: model, label: `${model} \xB7 ${t2("notInCatalog")}` }] : [],
2088
+ ...(selectedProvider?.models ?? []).map((entry) => ({
2089
+ value: entry.id,
2090
+ label: entry.name,
2091
+ ...entry.description === void 0 ? {} : { hint: entry.description }
2092
+ }))
2093
+ ];
2094
+ const reasoningOptions = [
2095
+ { value: "", label: t2("reasoningDefault") },
2096
+ ...reasoningEffort !== "" && reasoning?.efforts.some((entry) => entry.id === reasoningEffort) !== true ? [{ value: reasoningEffort, label: `${reasoningEffort} \xB7 ${t2("unavailable")}`, disabled: true }] : [],
2097
+ ...(reasoning?.efforts ?? []).map((entry) => ({
2098
+ value: entry.id,
2099
+ label: entry.name,
2100
+ ...entry.description === void 0 ? {} : { hint: entry.description }
2101
+ }))
2102
+ ];
2103
+ const reasoningHint = provider === "" || model === "" ? t2("reasoningSelectModel") : reasoning === void 0 ? t2("reasoningUnavailable") : reasoning.error !== void 0 ? t2("reasoningFailure", { error: reasoning.error }) : reasoning.efforts.length === 0 ? t2("reasoningUnsupported") : t2("reasoningHint");
2104
+ const permissionOptions = [
2105
+ ...options?.permissions.some((entry) => entry.id === permissionPreset) !== true ? [{ value: permissionPreset, label: `${permissionPreset} \xB7 ${t2("unavailable")}` }] : [],
2106
+ ...(options?.permissions ?? []).map((entry) => ({
2107
+ value: entry.id,
2108
+ label: entry.name,
2109
+ ...entry.description === void 0 ? {} : { hint: entry.description }
2110
+ }))
2111
+ ];
2112
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2113
+ "form",
2114
+ {
2115
+ className: "am-editor",
2116
+ onSubmit: (event) => {
2117
+ event.preventDefault();
2118
+ if (blocked || !event.currentTarget.reportValidity()) return;
2119
+ const schedule = scheduleEditor.getSchedule();
2120
+ onSave({
2121
+ ...name.trim() === task.name ? {} : { name },
2122
+ ...prompt.trim() === task.prompt ? {} : { prompt },
2123
+ ...schedule === void 0 ? {} : { schedule },
2124
+ ...notificationPolicy === task.notificationPolicy ? {} : { notificationPolicy },
2125
+ ...pauseAfterFailures === task.pauseAfterConsecutiveFailures ? {} : { pauseAfterConsecutiveFailures: pauseAfterFailures },
2126
+ ...permissionChanged ? { permissionPreset, confirmPermissionChange: true } : {},
2127
+ ...targetChanged ? { confirmSessionTargetChange: true } : {},
2128
+ ...deliveryChanged ? deliveryEnabled ? { delivery: { botId: deliveryBotId, targetId: deliveryTargetId }, confirmDeliveryChange: true } : { delivery: null } : {},
2129
+ ...executionChanged ? {
2130
+ execution: {
2131
+ ...targetChanged ? { target: pinned ? { mode: "pinned-session", sessionId: targetSessionId } : { mode: "fresh" } } : {},
2132
+ ...!agentExecutionChanged ? {} : {
2133
+ ...agentPreset === (task.execution.agentPreset ?? "") ? {} : { agentPreset: agentPreset || null },
2134
+ ...provider === (task.execution.provider ?? "") && model === (task.execution.model ?? "") ? {} : {
2135
+ provider: provider || null,
2136
+ model: model || null
2137
+ },
2138
+ ...reasoningChanged ? { reasoningEffort: reasoningEffort || null } : {},
2139
+ ...skills.join("\0") === task.execution.skills.join("\0") ? {} : { skills }
2140
+ }
2141
+ }
2142
+ } : {}
2143
+ });
2144
+ },
2145
+ children: [
2146
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "am-editor-scroll", children: [
2147
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-editor-hint", children: t2("editFutureRunsHint") }),
2148
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Section, { title: t2("sectionBasics"), children: [
2149
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("nameLabel"), htmlFor: "am-name", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Input, { id: "am-name", className: "am-input", required: true, disabled: saving, value: name, onChange: (event) => setName(event.target.value) }) }),
2150
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("promptLabel"), htmlFor: "am-prompt", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("textarea", { id: "am-prompt", className: "am-textarea", required: true, rows: 6, disabled: saving, value: prompt, onChange: (event) => setPrompt(event.target.value) }) })
2151
+ ] }),
2152
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScheduleSection, { schedule: scheduleEditor, saving, t: t2 }),
2153
+ optionsLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info", role: "status", children: t2("optionsLoading") }),
2154
+ optionsError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("optionsFailure", { error: optionsError }) }),
2155
+ options?.modelFailures.map((failure) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("providerFailure", { provider: failure.provider, error: failure.error }) }, failure.provider)),
2156
+ !configValid && !optionsLoading && optionsError === void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("editorConfigInvalid") }),
2157
+ (optionsError !== void 0 || !configValid || reasoning?.error !== void 0 || (options?.modelFailures.length ?? 0) > 0) && !optionsLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Button, { type: "button", variant: "ghost", size: "sm", disabled: saving, onClick: () => {
2158
+ void loadOptions();
2159
+ }, children: t2("retry") }),
2160
+ !requiredFieldsValid && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("editorRequiredFields") }),
2161
+ permissionChanged && !permissionConfirmed && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "am-alert is-warning", role: "status", children: [
2162
+ t2("permission"),
2163
+ " \xB7 ",
2164
+ t2("confirmPermissionChange", { permission: selectedPermission?.name ?? permissionPreset })
2165
+ ] }),
2166
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Section, { title: t2("executionDestination"), children: [
2167
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("executionMode"), hint: t2("sessionWorkspaceHint", { cwd: task.execution.cwd }), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2168
+ Select,
2169
+ {
2170
+ value: targetMode,
2171
+ ariaLabel: t2("executionMode"),
2172
+ disabled: saving || targetLocked,
2173
+ options: [{ value: "fresh", label: t2("executionFresh") }, { value: "pinned-session", label: t2("executionExisting") }],
2174
+ onChange: (value) => setTargetMode(value)
2175
+ }
2176
+ ) }),
2177
+ targetLocked && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info is-full", children: t2("sessionTargetLocked") }),
2178
+ pinned && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2179
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Field, { full: true, label: t2("targetSession"), hint: t2("pinnedSessionHint"), children: [
2180
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2181
+ import_dsh_client_ui_primitives8.Input,
2182
+ {
2183
+ icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconSearchOutline16, {}),
2184
+ value: sessionQuery,
2185
+ disabled: saving || targetLocked,
2186
+ placeholder: t2("sessionSearch"),
2187
+ "aria-label": t2("sessionSearch"),
2188
+ onChange: (event) => setSessionQuery(event.target.value)
2189
+ }
2190
+ ),
2191
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2192
+ Select,
2193
+ {
2194
+ value: targetSessionId,
2195
+ ariaLabel: t2("targetSession"),
2196
+ disabled: saving || targetLocked || sessionsLoading || sessionLoadError !== void 0 || sessions.phase !== "ready",
2197
+ options: sessionOptions,
2198
+ onChange: setTargetSessionId
2199
+ }
2200
+ ),
2201
+ !sessionsLoading && sessionLoadError === void 0 && sessionOptions.length === 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "am-field-hint", children: t2("noSessionMatches") })
2202
+ ] }),
2203
+ (sessionsLoading || sessions.phase !== "ready") && sessionLoadError === void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info is-full", role: "status", children: t2("sessionsLoading") }),
2204
+ sessionLoadError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "is-full", children: [
2205
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("sessionsFailure", { error: sessionLoadError }) }),
2206
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Button, { type: "button", variant: "ghost", size: "sm", disabled: saving || sessionsLoading, onClick: () => setSessionRefresh((value) => value + 1), children: t2("retry") })
2207
+ ] }),
2208
+ !sessionsLoading && sessionLoadError === void 0 && targetSessionId !== "" && selectedSession === void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-warning is-full", children: t2("targetSessionUnavailable") })
2209
+ ] }),
2210
+ targetChanged && (!pinned || targetSessionId !== "") && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "am-field-hint is-full", children: t2("sessionTargetSaveHint", { target: pinned ? selectedSession?.displayTitle ?? targetSessionId : t2("executionFresh") }) })
2211
+ ] }),
2212
+ !pinned && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Disclosure, { title: t2("agentExecution"), children: [
2213
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2214
+ Field,
2215
+ {
2216
+ full: true,
2217
+ label: t2("agentPreset"),
2218
+ hint: agentPreset === "" ? void 0 : options?.presets.find((entry) => entry.id === agentPreset)?.description,
2219
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2220
+ Select,
2221
+ {
2222
+ value: agentPreset,
2223
+ disabled: saving || optionsLoading,
2224
+ ariaLabel: t2("agentPreset"),
2225
+ options: presetOptions,
2226
+ onChange: setAgentPreset
2227
+ }
2228
+ )
2229
+ }
2230
+ ),
2231
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { label: t2("provider"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2232
+ Select,
2233
+ {
2234
+ value: provider,
2235
+ disabled: saving || optionsLoading,
2236
+ ariaLabel: t2("provider"),
2237
+ options: providerOptions,
2238
+ onChange: (next) => {
2239
+ setProvider(next);
2240
+ setModel("");
2241
+ setReasoningEffort("");
2242
+ }
2243
+ }
2244
+ ) }),
2245
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { label: t2("model"), hint: provider !== "" && model !== "" && (reasoning === void 0 || reasoning.error !== void 0 || reasoning.efforts.length === 0) ? reasoningHint : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2246
+ ModelSelection,
2247
+ {
2248
+ model,
2249
+ effort: reasoningEffort,
2250
+ models: modelOptions,
2251
+ efforts: reasoningOptions,
2252
+ disabled: saving || optionsLoading || provider === "" && reasoningEffort === "",
2253
+ modelDisabled: provider === "",
2254
+ effortDisabled: (reasoning?.efforts.length ?? 0) === 0 && reasoningEffort === "",
2255
+ onModel: (next) => {
2256
+ setModel(next);
2257
+ setReasoningEffort("");
2258
+ },
2259
+ onEffort: setReasoningEffort,
2260
+ t: t2
2261
+ }
2262
+ ) }),
2263
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("selectedSkills"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SkillPicker, { skills, options, disabled: saving || optionsLoading, t: t2, onChange: setSkills }) })
2264
+ ] }),
2265
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Disclosure, { title: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2266
+ t2("messageDelivery"),
2267
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Tooltip, { label: t2("deliveryHelpText"), side: "bottom", maxWidth: 320, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2268
+ "button",
2269
+ {
2270
+ type: "button",
2271
+ className: "am-icon-button am-help-button",
2272
+ "aria-label": t2("deliveryHelp"),
2273
+ "aria-description": t2("deliveryHelpText"),
2274
+ onClick: (event) => {
2275
+ event.preventDefault();
2276
+ event.stopPropagation();
2277
+ event.currentTarget.focus();
2278
+ },
2279
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconQuestionOutline14, {})
2280
+ }
2281
+ ) })
2282
+ ] }), children: [
2283
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("deliveryEnabled"), hint: t2("deliveryHint"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2284
+ import_dsh_client_ui_primitives8.Switch,
2285
+ {
2286
+ checked: deliveryEnabled,
2287
+ disabled: saving || targetLocked,
2288
+ label: t2("deliveryEnabled"),
2289
+ onChange: setDeliveryEnabled
2290
+ }
2291
+ ) }),
2292
+ targetLocked && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info is-full", children: t2("deliveryLocked") }),
2293
+ deliveryEnabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2294
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("deliveryBot"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2295
+ Select,
2296
+ {
2297
+ value: deliveryBotId,
2298
+ options: deliveryBotOptions,
2299
+ ariaLabel: t2("deliveryBot"),
2300
+ disabled: saving || targetLocked || deliveryOptions?.available !== true,
2301
+ onChange: (id) => {
2302
+ setDeliveryBotId(id);
2303
+ setDeliveryTargetId("");
2304
+ }
2305
+ }
2306
+ ) }),
2307
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { full: true, label: t2("deliveryTarget"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2308
+ Select,
2309
+ {
2310
+ value: deliveryTargetId,
2311
+ options: deliveryTargetOptions,
2312
+ ariaLabel: t2("deliveryTarget"),
2313
+ disabled: saving || targetLocked || deliveryLoading || deliveryError !== void 0 || deliveryOptions?.available !== true || deliveryBotId === "",
2314
+ onChange: setDeliveryTargetId
2315
+ }
2316
+ ) }),
2317
+ deliveryLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info is-full", role: "status", children: t2("deliveryLoading") }),
2318
+ !deliveryLoading && deliveryError === void 0 && deliveryOptions?.available === true && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "is-full", children: [
2319
+ deliveryOptions.bots.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info", children: t2("deliveryNoBots") }),
2320
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Button, { type: "button", variant: "ghost", size: "sm", disabled: saving, onClick: () => setDeliveryRefresh((value) => value + 1), children: t2("refresh") })
2321
+ ] }),
2322
+ !deliveryLoading && (deliveryError !== void 0 || deliveryOptions?.available === false) && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "is-full", children: [
2323
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-warning", role: "alert", children: deliveryError !== void 0 ? t2("deliveryLoadFailed", { error: deliveryError }) : t2("deliveryUnavailable") }),
2324
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Button, { type: "button", variant: "ghost", size: "sm", disabled: saving, onClick: () => setDeliveryRefresh((value) => value + 1), children: t2("retry") })
2325
+ ] }),
2326
+ !deliveryLoading && deliveryError === void 0 && deliveryOptions?.available === true && (deliveryBotId !== "" && selectedDeliveryBot === void 0 || deliveryTargetId !== "" && selectedDeliveryTarget === void 0) && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-warning is-full", children: t2("deliverySavedUnavailable") }),
2327
+ !deliveryLoading && deliveryError === void 0 && deliveryOptions?.available === true && deliveryBotId !== "" && selectedDeliveryBot !== void 0 && deliveryTargets.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-info is-full", children: t2("deliveryNoTargets") }),
2328
+ deliveryChanged && deliveryBotId !== "" && deliveryTargetId !== "" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "am-field-hint is-full", children: t2("deliverySaveHint", { bot: deliveryBotId, target: deliveryTargetId }) })
2329
+ ] })
2330
+ ] }),
2331
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Disclosure, { title: t2("notifications"), children: [
2332
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { label: t2("notifications"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2333
+ Select,
2334
+ {
2335
+ value: notificationPolicy,
2336
+ disabled: saving,
2337
+ ariaLabel: t2("notifications"),
2338
+ options: [
2339
+ { value: "failures", label: t2("notificationFailures") },
2340
+ { value: "always", label: t2("notificationAlways") },
2341
+ { value: "never", label: t2("notificationNever") }
2342
+ ],
2343
+ onChange: (next) => setNotificationPolicy(next)
2344
+ }
2345
+ ) }),
2346
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Field, { label: t2("pauseAfterFailures"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2347
+ import_dsh_client_ui_primitives8.Switch,
2348
+ {
2349
+ checked: pauseAfterFailures,
2350
+ disabled: saving,
2351
+ label: t2("pauseAfterFailures"),
2352
+ onChange: setPauseAfterFailures
2353
+ }
2354
+ ) })
2355
+ ] }),
2356
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Disclosure, { title: t2("permission"), children: [
2357
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2358
+ Field,
2359
+ {
2360
+ full: true,
2361
+ label: t2("permission"),
2362
+ hint: selectedPermission === void 0 ? void 0 : [selectedPermission.description, `${selectedPermission.sandbox} \xB7 approval: ${selectedPermission.approval}`].filter(Boolean).join(" \xB7 "),
2363
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2364
+ Select,
2365
+ {
2366
+ value: permissionPreset,
2367
+ disabled: saving || optionsLoading,
2368
+ ariaLabel: t2("permission"),
2369
+ options: permissionOptions,
2370
+ onChange: (next) => {
2371
+ setPermissionPreset(next);
2372
+ setPermissionConfirmed(false);
2373
+ }
2374
+ }
2375
+ )
2376
+ }
2377
+ ),
2378
+ selectedPermission?.approval === "ask" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "am-alert is-warning is-full", role: "alert", children: t2("approvalAskWarning") }),
2379
+ permissionChanged && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "am-alert is-warning is-full am-confirm", children: [
2380
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2381
+ import_dsh_client_ui_primitives8.Switch,
2382
+ {
2383
+ checked: permissionConfirmed,
2384
+ disabled: saving,
2385
+ label: t2("confirmPermissionChange", { permission: selectedPermission?.name ?? permissionPreset }),
2386
+ onChange: setPermissionConfirmed
2387
+ }
2388
+ ),
2389
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { "aria-hidden": "true", children: t2("confirmPermissionChange", { permission: selectedPermission?.name ?? permissionPreset }) })
2390
+ ] })
2391
+ ] })
2392
+ ] }),
2393
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("footer", { className: "am-editor-footer", children: [
2394
+ !configValid && !optionsLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Tag, { tone: "danger", children: t2("unavailable") }),
2395
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "am-spacer" }),
2396
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Button, { type: "button", variant: "ghost", size: "sm", disabled: saving, onClick: onCancel, children: t2("cancel") }),
2397
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_dsh_client_ui_primitives8.Button, { type: "submit", variant: "primary", size: "sm", disabled: blocked, children: saving ? t2("saving") : t2("saveChanges") })
2398
+ ] })
2399
+ ]
2400
+ }
2401
+ );
2402
+ }
2403
+
2404
+ // src/client/AutomationPanel.tsx
2405
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2406
+ function orderTasks(tasks) {
2407
+ return [...tasks].sort((left, right) => {
2408
+ if (left.running !== right.running) return left.running ? -1 : 1;
2409
+ if (left.nextRunAt === null || right.nextRunAt === null) {
2410
+ if (left.nextRunAt === right.nextRunAt) return left.name.localeCompare(right.name);
2411
+ return left.nextRunAt === null ? 1 : -1;
2412
+ }
2413
+ const delta = Date.parse(left.nextRunAt) - Date.parse(right.nextRunAt);
2414
+ return delta === 0 ? left.name.localeCompare(right.name) : delta;
2415
+ });
2416
+ }
2417
+ function AutomationPanel({ ctx, useSessions, useWorkspaces }) {
2418
+ const open = usePanelOpen();
2419
+ const { t: t2, locale } = useLocale();
2420
+ const { tasks, scheduler, loading, error } = useAutomations();
2421
+ const sessions = useSessions((state) => state);
2422
+ const currentSessionId = selectedSessionId(sessions);
2423
+ const refreshSessions = import_react13.default.useCallback(() => ctx.sessions.refresh(), [ctx]);
2424
+ const workspaces = useWorkspaces((state) => state);
2425
+ const workspaceId = currentSessionId === void 0 ? void 0 : workspaces.items.find((workspace) => workspace.sessionIds.includes(currentSessionId))?.workspaceId;
2426
+ const [selectedId, setSelectedId] = import_react13.default.useState();
2427
+ const [query, setQuery] = import_react13.default.useState("");
2428
+ const [filter, setFilter] = import_react13.default.useState("all");
2429
+ const [actingTaskId, setActingTaskId] = import_react13.default.useState();
2430
+ const [editing, setEditing] = import_react13.default.useState(false);
2431
+ const [deletingId, setDeletingId] = import_react13.default.useState();
2432
+ const [deletingRun, setDeletingRun] = import_react13.default.useState();
2433
+ const [deleteRunError, setDeleteRunError] = import_react13.default.useState();
2434
+ const deletingRunPending = import_react13.default.useRef(false);
2435
+ const deleteRunFocus = import_react13.default.useRef(null);
2436
+ const [creatingExampleId, setCreatingExampleId] = import_react13.default.useState();
2437
+ const [narrowDetail, setNarrowDetail] = import_react13.default.useState(false);
2438
+ const [dirty, setDirty] = import_react13.default.useState(false);
2439
+ const [leaveAction, setLeaveAction] = import_react13.default.useState(null);
2440
+ const saving = actingTaskId !== void 0;
2441
+ const guardLeave = import_react13.default.useCallback((action) => {
2442
+ if (saving) return;
2443
+ if (editing && dirty) setLeaveAction(() => action);
2444
+ else action();
2445
+ }, [editing, dirty, saving]);
2446
+ const closePanel = import_react13.default.useCallback(() => guardLeave(() => setPanelOpen(false)), [guardLeave]);
2447
+ const cancelEditing = import_react13.default.useCallback(() => guardLeave(() => {
2448
+ setEditing(false);
2449
+ setDirty(false);
2450
+ }), [guardLeave]);
2451
+ const panelRef = import_react13.default.useRef(null);
2452
+ const restoreFocusRef = import_react13.default.useRef(null);
2453
+ const wasEditing = import_react13.default.useRef(false);
2454
+ import_react13.default.useEffect(() => {
2455
+ if (deletingRun !== void 0 || deleteRunFocus.current === null) return;
2456
+ const trigger = deleteRunFocus.current;
2457
+ deleteRunFocus.current = null;
2458
+ const frame = window.requestAnimationFrame(() => {
2459
+ const target = trigger.isConnected && !trigger.hasAttribute("disabled") ? trigger : panelRef.current?.querySelector('[data-am-view="runHistory"]');
2460
+ target?.focus();
2461
+ });
2462
+ return () => window.cancelAnimationFrame(frame);
2463
+ }, [deletingRun]);
2464
+ import_react13.default.useEffect(() => {
2465
+ if (deletingRun === void 0) return;
2466
+ const dialog = document.querySelector(".am-run-delete-modal");
2467
+ const onKeyDown = (event) => {
2468
+ if (event.key === "Escape") {
2469
+ event.preventDefault();
2470
+ event.stopImmediatePropagation();
2471
+ if (!deletingRunPending.current) setDeletingRun(void 0);
2472
+ return;
2473
+ }
2474
+ if (event.key !== "Tab" || dialog === null) return;
2475
+ const buttons = Array.from(dialog.querySelectorAll("button:not(:disabled)"));
2476
+ const first = buttons[0];
2477
+ const last = buttons.at(-1);
2478
+ const focusIsEnabled = buttons.some((button) => button === document.activeElement);
2479
+ if (!focusIsEnabled) {
2480
+ event.preventDefault();
2481
+ (event.shiftKey ? last : first)?.focus();
2482
+ } else if (event.shiftKey && document.activeElement === first) {
2483
+ event.preventDefault();
2484
+ last?.focus();
2485
+ } else if (!event.shiftKey && document.activeElement === last) {
2486
+ event.preventDefault();
2487
+ first?.focus();
2488
+ }
2489
+ };
2490
+ document.addEventListener("keydown", onKeyDown, true);
2491
+ return () => document.removeEventListener("keydown", onKeyDown, true);
2492
+ }, [deletingRun]);
2493
+ import_react13.default.useEffect(() => {
2494
+ const changed = editing !== wasEditing.current;
2495
+ wasEditing.current = editing;
2496
+ if (!open || !changed) return;
2497
+ const frame = window.requestAnimationFrame(() => {
2498
+ const target = panelRef.current?.querySelector(editing ? "#am-name" : "[data-am-edit]");
2499
+ target?.focus();
2500
+ });
2501
+ return () => window.cancelAnimationFrame(frame);
2502
+ }, [open, editing]);
2503
+ import_react13.default.useEffect(() => {
2504
+ if (!open || !editing || !dirty) return;
2505
+ const warn = (event) => {
2506
+ event.preventDefault();
2507
+ event.returnValue = "";
2508
+ };
2509
+ window.addEventListener("beforeunload", warn);
2510
+ return () => window.removeEventListener("beforeunload", warn);
2511
+ }, [open, editing, dirty]);
2512
+ const ordered = import_react13.default.useMemo(() => orderTasks(tasks), [tasks]);
2513
+ const needle = query.trim().toLowerCase();
2514
+ const visible = import_react13.default.useMemo(() => ordered.filter((task) => {
2515
+ if (filter !== "all" && task.status !== filter) return false;
2516
+ if (needle === "") return true;
2517
+ return task.name.toLowerCase().includes(needle) || task.prompt.toLowerCase().includes(needle);
2518
+ }), [ordered, filter, needle]);
2519
+ const selected = selectedId === void 0 ? void 0 : tasks.find((task) => task.id === selectedId);
2520
+ import_react13.default.useEffect(() => {
2521
+ if (!open) return;
2522
+ if (selected !== void 0 && (editing || visible.some((task) => task.id === selected.id))) return;
2523
+ const next = visible[0];
2524
+ setSelectedId(next?.id);
2525
+ setEditing(false);
2526
+ }, [open, selected, visible, editing]);
2527
+ import_react13.default.useEffect(() => {
2528
+ if (open) void refresh();
2529
+ }, [open]);
2530
+ import_react13.default.useEffect(() => {
2531
+ if (!open) {
2532
+ setEditing(false);
2533
+ setDirty(false);
2534
+ setLeaveAction(null);
2535
+ setDeletingId(void 0);
2536
+ setDeletingRun(void 0);
2537
+ setDeleteRunError(void 0);
2538
+ setNarrowDetail(false);
2539
+ return;
2540
+ }
2541
+ const onKeyDown = (event) => {
2542
+ if (event.defaultPrevented) return;
2543
+ if (!panelRef.current?.contains(event.target)) return;
2544
+ if (event.key === "Escape") {
2545
+ if (saving || leaveAction !== null || deletingId !== void 0 || deletingRun !== void 0) return;
2546
+ event.preventDefault();
2547
+ if (editing) cancelEditing();
2548
+ else if (narrowDetail) setNarrowDetail(false);
2549
+ else closePanel();
2550
+ return;
2551
+ }
2552
+ if (editing || deletingId !== void 0 || deletingRun !== void 0 || leaveAction !== null) return;
2553
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
2554
+ const active = document.activeElement;
2555
+ if (!(active instanceof HTMLElement) || !active.classList.contains("am-row")) return;
2556
+ if (visible.length === 0) return;
2557
+ event.preventDefault();
2558
+ const index = visible.findIndex((task) => task.id === selectedId);
2559
+ const step = event.key === "ArrowDown" ? 1 : -1;
2560
+ const next = visible[Math.max(0, Math.min(visible.length - 1, (index === -1 ? 0 : index) + step))];
2561
+ if (next !== void 0) {
2562
+ setSelectedId(next.id);
2563
+ const rows = panelRef.current?.querySelectorAll(".am-row");
2564
+ rows?.[visible.indexOf(next)]?.focus();
2565
+ }
2566
+ };
2567
+ window.addEventListener("keydown", onKeyDown);
2568
+ return () => window.removeEventListener("keydown", onKeyDown);
2569
+ }, [open, editing, deletingId, deletingRun, narrowDetail, visible, selectedId, saving, leaveAction, cancelEditing, closePanel]);
2570
+ import_react13.default.useEffect(() => {
2571
+ if (!open) {
2572
+ if (restoreFocusRef.current !== null) {
2573
+ restoreFocusRef.current.focus();
2574
+ restoreFocusRef.current = null;
2575
+ }
2576
+ return;
2577
+ }
2578
+ if (restoreFocusRef.current === null && document.activeElement instanceof HTMLElement) {
2579
+ restoreFocusRef.current = document.activeElement;
2580
+ }
2581
+ const container = panelRef.current;
2582
+ if (container === null) return;
2583
+ container.focus();
2584
+ const onKeyDown = (event) => {
2585
+ if (event.key !== "Tab") return;
2586
+ const current = panelRef.current;
2587
+ if (current === null) return;
2588
+ if (!current.contains(document.activeElement)) return;
2589
+ const focusables = Array.from(current.querySelectorAll(
2590
+ 'button, [href], input, select, textarea, summary, [tabindex]:not([tabindex="-1"])'
2591
+ )).filter((element) => !element.hasAttribute("disabled") && element.offsetParent !== null);
2592
+ const first = focusables[0];
2593
+ const last = focusables[focusables.length - 1];
2594
+ if (first === void 0 || last === void 0) return;
2595
+ const active = document.activeElement;
2596
+ if (event.shiftKey) {
2597
+ if (active === first || active === current) {
2598
+ event.preventDefault();
2599
+ last.focus();
2600
+ }
2601
+ } else if (active === last) {
2602
+ event.preventDefault();
2603
+ first.focus();
2604
+ }
2605
+ };
2606
+ window.addEventListener("keydown", onKeyDown);
2607
+ return () => window.removeEventListener("keydown", onKeyDown);
2608
+ }, [open]);
2609
+ const act = import_react13.default.useCallback(async (taskId, path, options) => {
2610
+ try {
2611
+ setActingTaskId(taskId);
2612
+ clearError();
2613
+ await request(path, options);
2614
+ await refresh();
2615
+ } catch (reason) {
2616
+ reportError(reason instanceof Error ? reason.message : String(reason));
2617
+ } finally {
2618
+ setActingTaskId(void 0);
2619
+ }
2620
+ }, []);
2621
+ const confirmDeleteRun = async () => {
2622
+ if (deletingRun === void 0 || deletingRunPending.current || saving) return;
2623
+ deletingRunPending.current = true;
2624
+ setActingTaskId(deletingRun.taskId);
2625
+ setDeleteRunError(void 0);
2626
+ try {
2627
+ await deleteRunRecord(deletingRun.taskId, deletingRun.run.id);
2628
+ setDeletingRun(void 0);
2629
+ } catch (reason) {
2630
+ setDeleteRunError(reason instanceof Error ? reason.message : String(reason));
2631
+ } finally {
2632
+ deletingRunPending.current = false;
2633
+ setActingTaskId(void 0);
2634
+ }
2635
+ };
2636
+ const closeDeleteRun = () => {
2637
+ if (!deletingRunPending.current) setDeletingRun(void 0);
2638
+ };
2639
+ const updateTask = import_react13.default.useCallback(async (taskId, body) => {
2640
+ try {
2641
+ setActingTaskId(taskId);
2642
+ clearError();
2643
+ await request(`/tasks/${encodeURIComponent(taskId)}`, { method: "PATCH", body: JSON.stringify(body) });
2644
+ await refresh();
2645
+ setDirty(false);
2646
+ setEditing(false);
2647
+ } catch (reason) {
2648
+ reportError(reason instanceof Error ? reason.message : String(reason));
2649
+ } finally {
2650
+ setActingTaskId(void 0);
2651
+ }
2652
+ }, []);
2653
+ const startExample = import_react13.default.useCallback(async (exampleId, prompt) => {
2654
+ if (workspaceId === void 0) {
2655
+ reportError(t2("workspaceUnavailable"));
2656
+ return;
2657
+ }
2658
+ try {
2659
+ setCreatingExampleId(exampleId);
2660
+ clearError();
2661
+ const sessionId = await ctx.uiWorkspace.connectWorkspace(workspaceId);
2662
+ queueDraft(sessionId, prompt);
2663
+ ctx.uiWorkspace.openSession(sessionId);
2664
+ setPanelOpen(false);
2665
+ } catch (reason) {
2666
+ reportError(t2("newConversationFailed", { error: reason instanceof Error ? reason.message : String(reason) }));
2667
+ } finally {
2668
+ setCreatingExampleId(void 0);
2669
+ }
2670
+ }, [ctx, t2, workspaceId]);
2671
+ if (!open) return null;
2672
+ const openSession = (sessionId) => {
2673
+ ctx.uiWorkspace.openSession(sessionId);
2674
+ setPanelOpen(false);
2675
+ };
2676
+ const actions = selected === void 0 ? void 0 : {
2677
+ run: () => void act(selected.id, `/tasks/${encodeURIComponent(selected.id)}/run`, { method: "POST" }),
2678
+ stop: () => void act(selected.id, `/tasks/${encodeURIComponent(selected.id)}/stop`, { method: "POST" }),
2679
+ pause: () => void act(selected.id, `/tasks/${encodeURIComponent(selected.id)}/pause`, { method: "POST" }),
2680
+ resume: (runNow) => void act(selected.id, `/tasks/${encodeURIComponent(selected.id)}/resume`, { method: "POST", body: JSON.stringify({ runNow }) }),
2681
+ edit: () => {
2682
+ setDirty(false);
2683
+ setEditing(true);
2684
+ },
2685
+ requestDelete: () => setDeletingId(selected.id),
2686
+ requestDeleteRun: (run, trigger) => {
2687
+ deleteRunFocus.current = trigger;
2688
+ setDeleteRunError(void 0);
2689
+ setDeletingRun({ taskId: selected.id, run });
2690
+ },
2691
+ openSession,
2692
+ back: () => setNarrowDetail(false)
2693
+ };
2694
+ const deletingTask = deletingId === void 0 ? void 0 : tasks.find((task) => task.id === deletingId);
2695
+ const creationBlocked = workspaceId === void 0;
2696
+ const filters = [
2697
+ { id: "all", label: t2("filterAll") },
2698
+ { id: "active", label: t2("filterActive") },
2699
+ { id: "paused", label: t2("filterPaused") },
2700
+ { id: "completed", label: t2("filterCompleted") }
2701
+ ];
2702
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2703
+ "div",
2704
+ {
2705
+ className: "am-overlay",
2706
+ role: "presentation",
2707
+ onMouseDown: (event) => {
2708
+ if (event.target === event.currentTarget && leaveAction === null && deletingId === void 0 && deletingRun === void 0) closePanel();
2709
+ },
2710
+ children: [
2711
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2712
+ "section",
2713
+ {
2714
+ ref: panelRef,
2715
+ tabIndex: -1,
2716
+ className: `am-panel${narrowDetail ? " is-detail" : ""}${tasks.length === 0 ? " is-empty" : ""}`,
2717
+ role: "dialog",
2718
+ "aria-modal": "true",
2719
+ "aria-label": t2("automations"),
2720
+ "aria-busy": loading,
2721
+ children: [
2722
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("header", { className: "am-header", children: [
2723
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-header-heading", children: [
2724
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "am-header-title", children: t2("tasksHeading") }),
2725
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "am-header-count", children: t2("taskCount", { count: tasks.length }) })
2726
+ ] }),
2727
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "am-spacer" }),
2728
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Tooltip, { label: creationBlocked ? t2("requiresWorkspace") : t2("newAutomation"), side: "bottom", disabled: false, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2729
+ import_dsh_client_ui_primitives9.Button,
2730
+ {
2731
+ type: "button",
2732
+ variant: "primary",
2733
+ size: "sm",
2734
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconPlusOutline16, {}),
2735
+ disabled: creationBlocked || creatingExampleId !== void 0,
2736
+ onClick: () => guardLeave(() => void startExample("new", t2("guidedCreationPrompt"))),
2737
+ children: creatingExampleId === "new" ? t2("creatingConversation") : t2("newAutomation")
2738
+ }
2739
+ ) }),
2740
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Tooltip, { label: t2("refresh"), side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "am-icon-button", disabled: loading, "aria-label": t2("refresh"), onClick: () => void refresh(), children: loading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "am-spin", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconLoadingOutline16, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconRefreshOutline16, {}) }) }),
2741
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Tooltip, { label: t2("close"), side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "am-icon-button", "aria-label": t2("close"), onClick: closePanel, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconCloseOutline16, {}) }) })
2742
+ ] }),
2743
+ (error !== void 0 || scheduler?.status === "retrying" || scheduler?.status === "stopped") && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-banners", children: [
2744
+ error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "am-alert is-error", role: "alert", children: error }),
2745
+ scheduler?.status === "retrying" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "am-alert is-warning", role: "alert", children: t2("schedulerRetrying", { error: scheduler.lastError ?? t2("unknownError") }) }),
2746
+ scheduler?.status === "stopped" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("schedulerStopped") })
2747
+ ] }),
2748
+ tasks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "am-body is-single", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-onboarding", "aria-live": "polite", children: [
2749
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "am-onboarding-icon am-spin", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconLoadingOutline16, { size: 24 }) }),
2750
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: t2("loading") })
2751
+ ] }) : error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-onboarding", children: [
2752
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconWarningOutline16, { size: 24 }),
2753
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: t2("loadFailed") }),
2754
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: t2("loadFailedHint") }),
2755
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "outline", size: "sm", onClick: () => void refresh(), children: t2("retry") })
2756
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EmptyState, { t: t2, creating: creatingExampleId, disabled: creationBlocked, onStart: (id, prompt) => void startExample(id, prompt) }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-body", children: [
2757
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-list-pane", children: [
2758
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-list-tools", children: [
2759
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2760
+ import_dsh_client_ui_primitives9.Input,
2761
+ {
2762
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconSearchOutline16, {}),
2763
+ value: query,
2764
+ placeholder: t2("searchPlaceholder"),
2765
+ "aria-label": t2("searchPlaceholder"),
2766
+ onChange: (event) => {
2767
+ const value = event.target.value;
2768
+ guardLeave(() => {
2769
+ setEditing(false);
2770
+ setQuery(value);
2771
+ });
2772
+ }
2773
+ }
2774
+ ),
2775
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "am-pill-group", role: "group", "aria-label": t2("filterAll"), children: filters.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2776
+ "button",
2777
+ {
2778
+ className: filter === entry.id ? "am-tab is-active" : "am-tab",
2779
+ type: "button",
2780
+ "aria-pressed": filter === entry.id,
2781
+ onClick: () => guardLeave(() => {
2782
+ setEditing(false);
2783
+ setFilter(entry.id);
2784
+ }),
2785
+ children: entry.label
2786
+ },
2787
+ entry.id
2788
+ )) })
2789
+ ] }),
2790
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-list", children: [
2791
+ visible.map((task) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2792
+ TaskRow,
2793
+ {
2794
+ task,
2795
+ locale,
2796
+ t: t2,
2797
+ selected: task.id === selectedId,
2798
+ onSelect: () => {
2799
+ if (task.id === selectedId) {
2800
+ setNarrowDetail(true);
2801
+ return;
2802
+ }
2803
+ guardLeave(() => {
2804
+ setSelectedId(task.id);
2805
+ setEditing(false);
2806
+ setNarrowDetail(true);
2807
+ });
2808
+ }
2809
+ },
2810
+ task.id
2811
+ )),
2812
+ visible.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-list-empty", children: [
2813
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: needle === "" ? t2("noFilteredTasks") : t2("noMatches", { query: query.trim() }) }),
2814
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
2815
+ setQuery("");
2816
+ setFilter("all");
2817
+ }, children: t2("resetFilters") })
2818
+ ] })
2819
+ ] })
2820
+ ] }),
2821
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "am-detail-pane", children: selected === void 0 || actions === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "am-detail-hint", children: t2("selectTaskHint") }) : editing ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-detail", children: [
2822
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("header", { className: "am-detail-header", children: [
2823
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-detail-title", children: [
2824
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: t2("editTask") }),
2825
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "am-muted", children: t2("editingTask", { name: selected.name }) })
2826
+ ] }),
2827
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Tooltip, { label: t2("cancel"), side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "am-icon-button", "aria-label": t2("cancel"), onClick: cancelEditing, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconCloseOutline16, {}) }) })
2828
+ ] }),
2829
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2830
+ TaskEditor,
2831
+ {
2832
+ onDirtyChange: setDirty,
2833
+ task: selected,
2834
+ sessions,
2835
+ workspaceSessionIds: workspaces.items.find((workspace) => workspace.workspaceId === selected.execution.workspaceId)?.sessionIds.filter((id) => !workspaces.archivedSessionIds.includes(id)) ?? [],
2836
+ refreshSessions,
2837
+ saving: actingTaskId === selected.id,
2838
+ t: t2,
2839
+ onSave: (body) => void updateTask(selected.id, body),
2840
+ onCancel: cancelEditing
2841
+ },
2842
+ selected.id
2843
+ )
2844
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2845
+ TaskDetail,
2846
+ {
2847
+ task: selected,
2848
+ locale,
2849
+ t: t2,
2850
+ pending: actingTaskId === selected.id,
2851
+ actions
2852
+ },
2853
+ selected.id
2854
+ ) })
2855
+ ] }),
2856
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("footer", { className: "am-panel-footer", children: [
2857
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SchedulerHealth, { health: scheduler, locale, t: t2 }),
2858
+ dirty && editing && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: t2("unsavedChanges") })
2859
+ ] })
2860
+ ]
2861
+ }
2862
+ ),
2863
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2864
+ import_dsh_client_ui_primitives9.Modal,
2865
+ {
2866
+ open: leaveAction !== null,
2867
+ onClose: () => setLeaveAction(null),
2868
+ title: t2("discardTitle"),
2869
+ closeLabel: t2("close"),
2870
+ description: t2("discardDescription"),
2871
+ footer: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2872
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setLeaveAction(null), children: t2("keepEditing") }),
2873
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "primary", size: "sm", onClick: () => {
2874
+ const action = leaveAction;
2875
+ setLeaveAction(null);
2876
+ setDirty(false);
2877
+ setEditing(false);
2878
+ action?.();
2879
+ }, children: t2("discardChanges") })
2880
+ ] })
2881
+ }
2882
+ ),
2883
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2884
+ import_dsh_client_ui_primitives9.Modal,
2885
+ {
2886
+ open: deletingRun !== void 0,
2887
+ className: "am-run-delete-modal",
2888
+ onClose: closeDeleteRun,
2889
+ title: t2("deleteRunTitle"),
2890
+ closeLabel: t2("close"),
2891
+ description: t2("deleteRunConfirm"),
2892
+ footer: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2893
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "ghost", size: "sm", autoFocus: true, disabled: saving, onClick: closeDeleteRun, children: t2("cancel") }),
2894
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "primary", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconWarningOutline16, {}), "data-am-confirm-delete-run": true, disabled: saving, onClick: () => void confirmDeleteRun(), children: saving ? t2("deletingRun") : t2("deleteRun") })
2895
+ ] }),
2896
+ children: deletingRun !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-run-delete-confirm", children: [
2897
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "am-run-delete-context", children: [
2898
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatusTag, { status: deletingRun.run.status, t: t2 }),
2899
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("time", { dateTime: deletingRun.run.startedAt ?? deletingRun.run.enqueuedAt, children: formatDate(deletingRun.run.startedAt ?? deletingRun.run.enqueuedAt, locale) })
2900
+ ] }),
2901
+ deleteRunError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "am-alert is-error", role: "alert", children: t2("deleteRunFailed", { error: deleteRunError }) })
2902
+ ] })
2903
+ }
2904
+ ),
2905
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2906
+ import_dsh_client_ui_primitives9.Modal,
2907
+ {
2908
+ open: deletingTask !== void 0,
2909
+ onClose: () => setDeletingId(void 0),
2910
+ title: t2("deleteTitle"),
2911
+ closeLabel: t2("close"),
2912
+ description: deletingTask === void 0 ? "" : t2("deleteConfirm", { name: deletingTask.name }),
2913
+ footer: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2914
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dsh_client_ui_primitives9.Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setDeletingId(void 0), children: t2("cancel") }),
2915
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2916
+ import_dsh_client_ui_primitives9.Button,
2917
+ {
2918
+ type: "button",
2919
+ variant: "primary",
2920
+ size: "sm",
2921
+ icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconWarningOutline16, {}),
2922
+ onClick: () => {
2923
+ const id = deletingId;
2924
+ setDeletingId(void 0);
2925
+ if (id !== void 0) void act(id, `/tasks/${encodeURIComponent(id)}`, { method: "DELETE" });
2926
+ },
2927
+ children: t2("confirmDelete")
2928
+ }
2929
+ )
2930
+ ] }),
2931
+ children: deletingTask !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatusTag, { status: deletingTask.running ? "running" : deletingTask.status, t: t2 })
2932
+ }
2933
+ )
2934
+ ]
2935
+ }
2936
+ );
2937
+ }
2938
+
2939
+ // src/client/styles.css
2940
+ var styles_default = "/* Compact task inbox: Host typography and controls, no private theme tokens.\n * Keep the 13px reading density; primitives retain their own type and focus rules.\n */\n/* sidebar.footer.action supplies placement, not a button skin. Match Settings. */\n.am-nav { position:relative; display:flex; flex:none; align-items:center; gap:8px; box-sizing:border-box; width:100%; height:42px; margin:0; padding:0 10px 0 5.5px; border:0; border-radius:12px; background:transparent; color:var(--dsw-alias-label-primary); font:var(--dsw-font-s-14); cursor:pointer; }\n.am-nav:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.am-nav.is-rail { width:36px; height:36px; margin:8px 0 10px; justify-content:center; gap:0; padding:0; border-radius:50%; corner-shape:round; }\n.am-nav-icon { display:inline-flex; flex:none; align-items:center; justify-content:center; width:16px; height:16px; }\n.am-nav-icon svg { flex:none; }\n.am-nav.is-rail .am-nav-icon { width:18px; height:18px; }\n.am-nav-label { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\n.am-nav-badge { position:absolute; top:2px; right:2px; min-width:16px; padding:0 4px; border-radius:999px; background:var(--dsw-alias-button-primary-fill); color:var(--dsw-alias-label-primary-foreground); font:var(--dsw-font-xs-13); line-height:16px; text-align:center; }\n.am-nav.is-wide .am-nav-badge { position:static; margin-left:auto; }\n\n.am-overlay { position:fixed; inset:0; z-index:60; display:flex; align-items:center; justify-content:center; padding:32px; background:var(--dsw-alias-bg-mask-1); backdrop-filter:var(--dsw-mask-blur); }\n.am-panel { position:relative; display:flex; flex-direction:column; width:min(940px,100%); height:min(640px,100%); overflow:hidden; border:0; border-radius:16px; background:var(--dsw-alias-bg-layer-2); color:var(--dsw-alias-label-primary); box-shadow:var(--dsw-elevation-prominent); font:var(--dsw-font-xs-13); }\n.am-panel *, .am-panel *::before, .am-panel *::after { box-sizing:border-box; }\n.am-panel:focus { outline:none; }\n.am-panel code { font-family:var(--ds-font-family-code); font-size:inherit; }\n/* Empty/loading/error states need no two-pane canvas. */\n.am-panel.is-empty { width:min(640px,100%); height:auto; max-height:100%; }\n.am-header { display:flex; flex:none; align-items:center; gap:10px; padding:14px 20px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.am-header > button { flex-shrink:0; white-space:nowrap; }\n.am-header-heading { display:flex; align-items:baseline; flex-wrap:wrap; gap:6px 12px; }\n.am-header-title { margin:0; font:var(--dsw-font-base-16); font-weight:500; }\n.am-header-count { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-spacer { flex:1 1 auto; }\n.am-icon-button, .am-back, .am-copy { display:inline-flex; flex:none; align-items:center; justify-content:center; width:28px; height:28px; padding:0; border:0; border-radius:8px; background:transparent; color:var(--dsw-alias-label-secondary); cursor:pointer; }\n.am-icon-button:hover:not(:disabled), .am-back:hover, .am-copy:hover { background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); }\n.am-icon-button:disabled { opacity:.45; cursor:default; }\n.am-help-button { width:20px; height:20px; margin-inline-start:6px; vertical-align:middle; }\n.am-back { display:none; }\n.am-panel-footer { display:flex; flex:none; align-items:center; justify-content:space-between; gap:12px; min-height:30px; padding:6px 20px; border-top:1px solid var(--dsw-alias-border-l2); color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-scheduler { display:inline-flex; align-items:center; gap:6px; font:var(--dsw-font-xs-13); white-space:nowrap; }\n.am-scheduler-card { display:grid; grid-template-columns:auto 1fr; gap:6px 12px; min-width:220px; max-width:340px; margin:0; font:var(--dsw-font-xs-13); }\n.am-scheduler-card dt { color:var(--dsw-alias-label-tertiary); }\n.am-scheduler-card dd { margin:0; overflow-wrap:anywhere; }\n.am-banners { display:flex; flex:none; flex-direction:column; gap:6px; padding:12px 28px 0; }\n.am-alert { margin:0; padding:10px 12px; border:1px solid transparent; border-radius:8px; font:var(--dsw-font-xs-13); overflow-wrap:anywhere; }\n.am-alert.is-error { background:var(--dsw-alias-interactive-bg-hover-danger); color:var(--dsw-alias-state-error-primary); }\n.am-alert.is-warning { background:var(--dsw-alias-state-warn-tertiary); color:var(--dsw-alias-state-warn-label); }\n.am-alert.is-info { color:var(--dsw-alias-label-secondary); }\n.am-alert.is-full { grid-column:1 / -1; }\n.am-confirm { display:flex; align-items:center; gap:8px; }\n\n/* List and detail: one dividing rule, no nested cards. */\n.am-body { display:flex; flex:1 1 auto; min-height:0; }\n.am-body.is-single { justify-content:center; padding:24px; overflow:auto; }\n.am-list-pane { display:flex; flex:none; flex-direction:column; width:260px; min-height:0; border-right:1px solid var(--dsw-alias-border-l2); }\n.am-list-tools { display:flex; flex:none; flex-direction:column; gap:10px; padding:14px 14px 0; }\n.am-pill-group { display:flex; flex-wrap:wrap; gap:6px; }\n.am-list-tools input::placeholder { color:var(--dsw-alias-label-tertiary); opacity:1; }\n.am-list-tools .am-pill-group { flex-wrap:nowrap; justify-content:space-between; gap:8px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.am-tab { display:inline-flex; align-items:center; justify-content:center; gap:6px; padding:8px 2px 12px; border:0; border-bottom:2px solid transparent; background:transparent; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); font-weight:500; white-space:nowrap; cursor:pointer; }\n.am-tab:hover { color:var(--dsw-alias-label-primary); }\n.am-tab.is-active { border-bottom-color:currentColor; color:var(--dsw-alias-state-business-primary); }\n.am-tab > span { color:var(--dsw-alias-label-tertiary); font-size:13px; font-weight:400; }\n.am-list { flex:1 1 auto; min-height:0; padding:10px; overflow:auto; overscroll-behavior:contain; }\n.am-row { display:flex; align-items:center; gap:10px; width:100%; margin:2px 0; padding:10px 10px; border:0; border-radius:8px; background:transparent; color:inherit; text-align:left; cursor:pointer; transition:background 120ms ease; }\n.am-row:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.am-row.is-selected { background:var(--dsw-alias-button-ghost-active-fill); }\n.am-row-dot { flex:none; }\n.am-row-body { display:flex; flex:1 1 auto; flex-direction:column; gap:6px; min-width:0; }\n.am-row-name { overflow:hidden; font:var(--dsw-font-xs-13); white-space:nowrap; text-overflow:ellipsis; }\n.am-row-meta { overflow:hidden; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); white-space:nowrap; text-overflow:ellipsis; }\n.am-failure-chip { display:inline-flex; flex:none; align-items:center; gap:3px; color:var(--dsw-alias-state-error-primary); font:var(--dsw-font-xs-13); }\n.am-list-empty { display:flex; flex-direction:column; align-items:center; gap:12px; padding:40px 16px; color:var(--dsw-alias-label-tertiary); text-align:center; }\n.am-list-empty p { margin:0; overflow-wrap:anywhere; }\n.am-detail-pane { display:flex; flex:1 1 auto; flex-direction:column; min-width:0; min-height:0; overflow:hidden; }\n.am-detail-hint { margin:auto; padding:28px; color:var(--dsw-alias-label-tertiary); text-align:center; }\n.am-detail { display:flex; flex:1 1 auto; flex-direction:column; min-height:0; }\n.am-detail-header { display:flex; flex:none; align-items:flex-start; gap:10px; padding:20px 22px 10px; }\n.am-detail-title { display:flex; flex:1 1 auto; flex-direction:column; gap:10px; min-width:0; }\n.am-detail-title h3 { margin:0; font:var(--dsw-font-base-16); font-weight:500; overflow-wrap:anywhere; }\n.am-detail-badges { display:flex; flex-wrap:wrap; align-items:center; gap:14px; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-status { display:inline-flex; align-items:center; gap:6px; }\n.am-detail-workspace { max-width:230px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.am-detail-scroll, .am-editor-scroll { flex:1 1 auto; min-height:0; overflow:auto; overscroll-behavior:contain; }\n.am-muted { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-danger { color:var(--dsw-alias-state-error-primary); }\n\n/* Signature: the next occurrence and human schedule read together. */\n.am-next-run { display:flex; flex-wrap:wrap; align-items:baseline; gap:6px 12px; margin:2px 22px 12px; padding:8px 0 8px 12px; border-left:2px solid var(--dsw-alias-border-l3); }\n.am-next-run-label { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-next-run strong { font:var(--dsw-font-xs-13); }\n.am-next-run-when { color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); font-variant-numeric:tabular-nums; }\n.am-next-run-schedule { flex-basis:100%; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); overflow-wrap:anywhere; }\n.am-actions { display:flex; flex-wrap:wrap; gap:8px; padding:0 22px 12px; }\n.am-detail-nav { display:flex; gap:24px; margin:0 22px; border-bottom:1px solid var(--dsw-alias-border-l2); }\n.am-detail-nav .am-tab { padding:10px 0 12px; font-size:13px; }\n.am-block { display:flex; flex-direction:column; gap:10px; padding:14px 22px; }\n.am-block + .am-block { padding-top:8px; }\n.am-block-title { display:flex; align-items:center; gap:8px; margin:0; color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); }\n.am-block-tools { display:flex; align-items:center; gap:4px; margin-left:auto; }\n.am-prompt { margin:0; max-height:280px; overflow:auto; color:var(--dsw-alias-label-primary); font:var(--dsw-font-xs-13); line-height:1.6; white-space:pre-wrap; overflow-wrap:anywhere; }\n.am-summary { margin:0; padding:12px 14px; border-radius:8px; background:var(--dsw-alias-bg-module-platform); color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); line-height:1.6; white-space:pre-wrap; overflow-wrap:anywhere; }\n.am-empty-note, .am-detail-note { margin:0; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-detail-note { padding:0 22px 28px; }\n.am-facts { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(215px,100%),1fr)); gap:16px; }\n.am-fact { display:flex; gap:8px; min-width:0; }\n.am-fact.is-full { grid-column:1 / -1; }\n.am-fact-icon { display:inline-flex; flex:none; padding-top:2px; color:var(--dsw-alias-label-tertiary); }\n.am-fact-body { display:flex; flex-direction:column; gap:6px; min-width:0; }\n.am-fact-label { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-fact-value { font:var(--dsw-font-xs-13); overflow-wrap:anywhere; }\n.am-mono-row { display:inline-flex; flex-wrap:wrap; align-items:center; gap:5px; max-width:100%; min-width:0; }\n.am-mono-row code { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.am-runs { display:flex; flex-direction:column; gap:6px; }\n.am-run { border-bottom:1px solid var(--dsw-alias-border-l2); }\n.am-run-line { display:inline-flex; flex-wrap:wrap; align-items:center; gap:6px; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-run-body { display:flex; flex-direction:column; gap:12px; padding:8px 0 16px; }\n.am-run-summary { margin:0; color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); line-height:1.6; white-space:pre-wrap; overflow-wrap:anywhere; }\n.am-run-facts { display:grid; grid-template-columns:auto minmax(0,1fr); gap:8px 16px; margin:0; align-items:baseline; }\n.am-run-facts dt { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-run-facts dd { min-width:0; margin:0; font:var(--dsw-font-xs-13); overflow-wrap:anywhere; }\n.am-run-actions { display:flex; flex-wrap:wrap; gap:8px; }\n.am-run-delete-confirm { display:flex; flex-direction:column; gap:12px; }\n.am-run-delete-context { display:flex; flex-wrap:wrap; align-items:center; gap:12px; color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); }\n\n/* Editor: task and schedule first, secondary controls on demand. */\n.am-editor { display:flex; flex:1 1 auto; flex-direction:column; min-height:0; }\n.am-editor-hint { margin:0; padding:0 22px 8px; color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-editor-footer { display:flex; flex:none; align-items:center; gap:8px; padding:12px 22px; border-top:1px solid var(--dsw-alias-border-l2); }\n.am-form-section { display:flex; flex-direction:column; gap:12px; padding:16px 22px; }\n.am-form-section-title { margin:0; color:var(--dsw-alias-label-primary); font:var(--dsw-font-xs-13); }\n.am-form-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(215px,100%),1fr)); gap:16px; }\n.am-editor-disclosure { margin:0 22px; border-top:1px solid var(--dsw-alias-border-l2); }\n.am-editor-disclosure > summary { display:flex; align-items:center; gap:6px; padding:14px 0; list-style:none; cursor:pointer; }\n.am-editor-disclosure > summary::-webkit-details-marker { display:none; }\n.am-disclosure-chevron { flex:none; color:var(--dsw-alias-label-tertiary); transition:transform 120ms ease; }\n.am-editor-disclosure[open] > summary .am-disclosure-chevron { transform:rotate(90deg); }\n.am-editor-disclosure > .am-form-grid { padding:0 0 24px; }\n.am-editor-scroll > .am-alert { margin:10px 22px; }\n.am-editor-scroll > .am-alert .am-spacer { display:none; }\n.am-rule-builder, .am-rule-advanced { grid-column:1 / -1; }\n.am-rule-advanced { display:flex; flex-direction:column; gap:6px; }\n.am-interval { display:flex; align-items:center; gap:8px; }\n.am-interval .am-input { width:88px; }\n.am-field { display:flex; flex-direction:column; gap:7px; min-width:0; }\n.am-field-label { color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); }\n.am-field-hint { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); line-height:1.5; overflow-wrap:anywhere; }\n.am-field.is-full { grid-column:1 / -1; }\n.am-input { width:100%; }\n/* Host has no Textarea/Select primitive; use the Input surface and type ramp. */\n.am-textarea, .am-select { width:100%; border:.5px solid var(--dsw-alias-border-l4); border-radius:8px; background:var(--dsw-alias-bg-layer-1); color:var(--dsw-alias-label-primary); font:var(--dsw-font-s-14); }\n.am-textarea { min-height:140px; padding:8px; resize:vertical; }\n.am-select { display:flex; align-items:center; justify-content:space-between; gap:8px; height:32px; padding:0 8px; text-align:left; cursor:pointer; }\n.am-select:hover:not(:disabled), .am-textarea:focus { border-color:var(--dsw-alias-label-primary); }\n.am-textarea:focus { outline:none; }\n.am-select:disabled, .am-textarea:disabled { opacity:.5; cursor:default; }\n.am-select-value { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\n.am-select-menu { min-width:220px; }\n.am-model-summary { display:flex; align-items:center; gap:8px; min-width:0; }\n.am-model-summary > span { overflow:hidden; text-overflow:ellipsis; }\n.am-model-summary > span:last-child { flex:none; color:var(--dsw-alias-label-tertiary); }\n.am-model-menu { min-width:240px; }\n.am-model-menu-row { display:flex; align-items:center; justify-content:space-between; gap:16px; width:100%; }\n.am-model-menu-row > span:nth-child(2) { margin-left:auto; color:var(--dsw-alias-label-tertiary); max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.am-model-menu-row > svg { flex:none; color:var(--dsw-alias-label-tertiary); }\n.am-option { display:flex; flex-direction:column; gap:2px; }\n.am-option small { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-skills { display:flex; flex-direction:column; gap:12px; }\n.am-skills-bar { display:flex; align-items:center; gap:8px; }\n.am-skills-bar > :first-child { flex:1 1 auto; min-width:0; }\n.am-skill-chips { display:flex; flex-wrap:wrap; align-items:center; gap:6px; }\n.am-skills-count { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n.am-chip-remove { display:inline-flex; align-items:center; gap:5px; padding:5px 8px; border:0; border-radius:5px; background:var(--dsw-alias-interactive-bg-hover); color:var(--dsw-alias-label-primary); font:var(--dsw-font-xs-13); cursor:pointer; }\n.am-chip-remove:hover:not(:disabled) { color:var(--dsw-alias-state-error-primary); }\n.am-chip-remove:disabled { opacity:.5; cursor:default; }\n.am-skill-list { max-height:210px; overflow:auto; border:1px solid var(--dsw-alias-border-l2); border-radius:8px; }\n.am-skill { display:flex; gap:10px; padding:12px; border-bottom:1px solid var(--dsw-alias-border-l2); cursor:pointer; }\n.am-skill:last-child { border-bottom:0; }\n.am-skill:hover { background:var(--dsw-alias-interactive-bg-hover); }\n.am-skill.is-unavailable { opacity:.6; }\n.am-skill input { flex:none; margin:3px 0 0; accent-color:var(--dsw-alias-button-primary-fill,currentColor); }\n.am-skill-copy { display:flex; flex-direction:column; gap:4px; min-width:0; }\n.am-skill-copy b { font:var(--dsw-font-xs-13); overflow-wrap:anywhere; }\n.am-skill-copy small { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); overflow-wrap:anywhere; }\n.am-skill-list .am-empty-note { display:block; padding:20px; text-align:center; }\n\n.am-onboarding { display:flex; flex-direction:column; align-items:flex-start; gap:12px; width:min(520px,100%); margin:auto; }\n.am-onboarding-icon { display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; color:var(--dsw-alias-label-tertiary); }\n.am-onboarding h3 { margin:0; font:var(--dsw-font-base-16); font-weight:500; }\n.am-onboarding p { margin:0; color:var(--dsw-alias-label-secondary); font:var(--dsw-font-xs-13); line-height:1.6; }\n.am-onboarding small { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); line-height:1.6; }\n.am-examples { display:flex; flex-direction:column; width:100%; margin:8px 0; }\n.am-example { display:flex; align-items:center; gap:16px; width:100%; padding:12px 8px; border:0; border-bottom:1px solid var(--dsw-alias-border-l2); border-radius:0; background:transparent; color:var(--dsw-alias-label-primary); text-align:left; cursor:pointer; }\n.am-example-arrow { flex:none; color:var(--dsw-alias-label-tertiary); }\n.am-example:hover:not(:disabled) { background:var(--dsw-alias-interactive-bg-hover); }\n.am-example:disabled { opacity:.5; cursor:default; }\n.am-example-icon { display:inline-flex; flex:none; color:var(--dsw-alias-label-tertiary); }\n.am-example-copy { display:flex; flex:1 1 auto; flex-direction:column; gap:6px; min-width:0; }\n.am-example-copy strong { font:var(--dsw-font-xs-13); }\n.am-example-copy > span { color:var(--dsw-alias-label-tertiary); font:var(--dsw-font-xs-13); }\n\n/* Style only our controls: Host Input/Switch/Button own their focus treatment. */\n.am-nav:focus-visible, .am-panel :is(.am-tab,.am-row,.am-example,summary):focus-visible { outline:2px solid var(--dsw-alias-label-primary); outline-offset:-2px; }\n.am-panel :is(.am-icon-button,.am-back,.am-copy,.am-select,.am-chip-remove):focus-visible { outline:2px solid var(--dsw-alias-label-primary); outline-offset:2px; }\n.am-spin { display:inline-flex; animation:am-spin 900ms linear infinite; }\n@keyframes am-spin { to { transform:rotate(360deg); } }\n@media (prefers-reduced-motion:reduce) { .am-spin { animation:none; } .am-panel *, .am-nav { transition:none; scroll-behavior:auto; } }\n@media (max-width:760px) {\n .am-overlay { padding:0; }\n .am-panel, .am-panel.is-empty { width:100%; height:100%; max-height:100%; border-radius:0; }\n .am-list-pane { width:100%; border-right:0; }\n .am-list-tools .am-pill-group { justify-content:flex-start; gap:24px; }\n .am-detail-pane { display:none; }\n .am-panel.is-detail .am-list-pane { display:none; }\n .am-panel.is-detail .am-detail-pane { display:flex; }\n .am-back { display:inline-flex; }\n}\n@media (max-width:520px) {\n .am-header { gap:6px; padding:16px; }\n .am-header-count { font-size:13px; }\n .am-header .am-icon-button { width:28px; }\n .am-detail-header { padding:20px 16px 12px; gap:6px; }\n .am-next-run { margin:8px 16px 16px; }\n .am-actions { padding:0 16px 12px; }\n .am-detail-nav { margin:0 16px; gap:24px; }\n .am-block, .am-form-section { padding:14px 16px; }\n .am-editor-hint, .am-detail-note { padding-left:16px; padding-right:16px; }\n .am-editor-disclosure { margin:0 16px; }\n .am-editor-scroll > .am-alert { margin:10px 16px; }\n .am-editor-footer { padding:12px 16px; }\n .am-panel-footer { padding:8px 16px; }\n .am-form-grid, .am-facts { grid-template-columns:minmax(0,1fr); }\n .am-banners { padding:10px 16px 0; }\n}\n";
2941
+
2942
+ // src/client/index.tsx
2943
+ var import_client2 = require("@deepseek-ai/dsh-client-ui-layout/client");
2944
+ var import_client3 = require("@deepseek-ai/dsh-client-ui-sidebar/client");
2945
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2946
+ var inject = ["slots", "sessions", "uiWorkspace", "locale"];
2947
+ var STYLE_ATTRIBUTE = "data-dsh-automation-style";
2948
+ function installStyles() {
2949
+ if (document.querySelector(`style[${STYLE_ATTRIBUTE}]`) !== null) return () => void 0;
2950
+ const element = document.createElement("style");
2951
+ element.setAttribute(STYLE_ATTRIBUTE, "");
2952
+ element.textContent = styles_default;
2953
+ document.head.appendChild(element);
2954
+ return () => element.remove();
2955
+ }
2956
+ function DraftInjector({ sessionId, inputActions }) {
2957
+ const revision = useDraftRevision();
2958
+ import_react14.default.useEffect(() => {
2959
+ const text = consumeDraft(sessionId);
2960
+ if (text !== void 0) inputActions.setDraft(text);
2961
+ }, [revision, sessionId, inputActions]);
2962
+ return null;
2963
+ }
2964
+ function AutomationButton({ wide }) {
2965
+ const { t: t2 } = useLocale();
2966
+ const { unread } = useAutomations();
2967
+ const open = usePanelOpen();
2968
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2969
+ "button",
2970
+ {
2971
+ type: "button",
2972
+ className: `am-nav ${wide ? "is-wide" : "is-rail"}`,
2973
+ "aria-label": unread > 0 ? `${t2("openAutomations")}. ${t2("unreadNotifications", { count: unread })}` : t2("openAutomations"),
2974
+ title: t2("automations"),
2975
+ "aria-haspopup": "dialog",
2976
+ "aria-expanded": open,
2977
+ onClick: () => {
2978
+ setPanelOpen(true);
2979
+ void request("/notifications/read", { method: "POST" }).then(clearUnread).catch(() => void 0);
2980
+ },
2981
+ children: [
2982
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "am-nav-icon", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconClockOutline16, { size: wide ? 16 : 18 }) }),
2983
+ wide && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "am-nav-label", children: t2("automations") }),
2984
+ unread > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "am-nav-badge", "aria-hidden": "true", children: unread > 99 ? "99+" : unread })
2985
+ ]
2986
+ }
2987
+ );
2988
+ }
2989
+ function apply(ctx) {
2990
+ const disposers = [
2991
+ installStyles(),
2992
+ installLocale(ctx),
2993
+ ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register(
2994
+ { name: "sidebar.footer.action", id: "automation", order: 50, label: () => t("automations") },
2995
+ AutomationButton
2996
+ )),
2997
+ ctx.slots.inject("conversation.input.dock", () => ctx.slots.register(
2998
+ { name: "conversation.input.dock", id: "automation-example-draft", order: 100 },
2999
+ DraftInjector
3000
+ )),
3001
+ ctx.slots.inject("shell.overlay", () => ctx.slots.register(
3002
+ { name: "shell.overlay", id: "automation-panel", order: 50, label: () => t("automations") },
3003
+ (props) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AutomationPanel, { ...props, ctx })
3004
+ ))
3005
+ ];
3006
+ return () => {
3007
+ for (const dispose of disposers.reverse()) dispose();
3008
+ resetStore();
3009
+ };
3010
+ }
3011
+
3012
+ return module.exports;
3013
+ }
3014
+ });