@dsh-plus/notify-email 0.1.40 → 0.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -7,6 +7,77 @@ window.__ModuleLoader__.load({
7
7
  let react_jsx_runtime = require("react/jsx-runtime");
8
8
  let react = require("react");
9
9
  require("@deepseek-ai/dsh-client-ui-primitives");
10
+ //#region ../shared/src/client/fields.tsx
11
+ /** 卡片按钮(与 CardChrome 页脚同一套类名与视觉)。 */
12
+ function Button(props) {
13
+ const p = props.prefix ?? "dshp";
14
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15
+ type: "button",
16
+ className: `${p}-btn ${props.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
17
+ disabled: props.disabled === true,
18
+ onClick: props.onClick,
19
+ children: props.label
20
+ });
21
+ }
22
+ function TextField(props) {
23
+ const p = props.prefix ?? "dshp";
24
+ const invalid = props.invalid === true;
25
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
26
+ className: `${p}-field`,
27
+ children: [
28
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
29
+ className: `${p}-head`,
30
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
31
+ className: `${p}-label`,
32
+ htmlFor: props.id,
33
+ children: props.label
34
+ }), props.badge !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
35
+ className: `${p}-badge ${props.badge.set ? `${p}-badgeSet` : `${p}-badgeUnset`}`,
36
+ children: props.badge.text
37
+ }) : null]
38
+ }),
39
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
40
+ id: props.id,
41
+ className: `${p}-input${invalid ? ` ${p}-inputInvalid` : ""}`,
42
+ type: props.password === true ? "password" : "text",
43
+ inputMode: props.numeric === true ? "numeric" : void 0,
44
+ autoComplete: props.password === true ? "off" : void 0,
45
+ "aria-invalid": invalid || void 0,
46
+ value: props.value,
47
+ disabled: props.disabled === true,
48
+ onChange: (event) => props.onEdit(event.target.value)
49
+ }),
50
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
51
+ className: invalid ? `${p}-invalid` : `${p}-hint`,
52
+ children: invalid ? props.invalidLabel ?? "" : props.hint ?? ""
53
+ })
54
+ ]
55
+ });
56
+ }
57
+ /**
58
+ * 勾选行:自绘圆角扁平开关(switch),对齐官方 WebUI 无原生 checkbox 的
59
+ * 设计语言(官方选择类控件全走胶囊/菜单,见 cardCss 的 -switch 规则)。
60
+ * 语义保持 checkbox(无障碍树与表单语义不变),视觉自绘。
61
+ */
62
+ function CheckRow(props) {
63
+ const p = props.prefix ?? "dshp";
64
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
65
+ className: `${p}-checkRow`,
66
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
67
+ id: props.id,
68
+ type: "checkbox",
69
+ role: "switch",
70
+ "aria-checked": props.checked,
71
+ checked: props.checked,
72
+ disabled: props.disabled === true,
73
+ onChange: (event) => props.onEdit(event.target.checked)
74
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
75
+ htmlFor: props.id,
76
+ children: props.label
77
+ })]
78
+ });
79
+ }
80
+ //#endregion
10
81
  //#region ../shared/src/client/card.tsx
11
82
  const IDLE_STATUS = {
12
83
  kind: "idle",
@@ -55,12 +126,12 @@ window.__ModuleLoader__.load({
55
126
  className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
56
127
  role: "status",
57
128
  children: props.status.text
58
- }) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
59
- type: "button",
60
- className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
61
- disabled: action.disabled === true,
62
- onClick: action.onClick,
63
- children: action.label
129
+ }) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
130
+ prefix: p,
131
+ label: action.label,
132
+ variant: action.variant,
133
+ disabled: action.disabled,
134
+ onClick: action.onClick
64
135
  }, action.key))]
65
136
  })
66
137
  ]
@@ -115,66 +186,6 @@ window.__ModuleLoader__.load({
115
186
  * @module @dsh-plus/shared/client/draft
116
187
  */
117
188
  //#endregion
118
- //#region ../shared/src/client/fields.tsx
119
- function TextField(props) {
120
- const p = props.prefix ?? "dshp";
121
- const invalid = props.invalid === true;
122
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
123
- className: `${p}-field`,
124
- children: [
125
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
126
- className: `${p}-head`,
127
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
128
- className: `${p}-label`,
129
- htmlFor: props.id,
130
- children: props.label
131
- }), props.badge !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
132
- className: `${p}-badge ${props.badge.set ? `${p}-badgeSet` : `${p}-badgeUnset`}`,
133
- children: props.badge.text
134
- }) : null]
135
- }),
136
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
137
- id: props.id,
138
- className: `${p}-input${invalid ? ` ${p}-inputInvalid` : ""}`,
139
- type: props.password === true ? "password" : "text",
140
- inputMode: props.numeric === true ? "numeric" : void 0,
141
- autoComplete: props.password === true ? "off" : void 0,
142
- "aria-invalid": invalid || void 0,
143
- value: props.value,
144
- disabled: props.disabled === true,
145
- onChange: (event) => props.onEdit(event.target.value)
146
- }),
147
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
148
- className: invalid ? `${p}-invalid` : `${p}-hint`,
149
- children: invalid ? props.invalidLabel ?? "" : props.hint ?? ""
150
- })
151
- ]
152
- });
153
- }
154
- /**
155
- * 勾选行:自绘圆角扁平开关(switch),对齐官方 WebUI 无原生 checkbox 的
156
- * 设计语言(官方选择类控件全走胶囊/菜单,见 cardCss 的 -switch 规则)。
157
- * 语义保持 checkbox(无障碍树与表单语义不变),视觉自绘。
158
- */
159
- function CheckRow(props) {
160
- const p = props.prefix ?? "dshp";
161
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
162
- className: `${p}-checkRow`,
163
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
164
- id: props.id,
165
- type: "checkbox",
166
- role: "switch",
167
- "aria-checked": props.checked,
168
- checked: props.checked,
169
- disabled: props.disabled === true,
170
- onChange: (event) => props.onEdit(event.target.checked)
171
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
172
- htmlFor: props.id,
173
- children: props.label
174
- })]
175
- });
176
- }
177
- //#endregion
178
189
  //#region ../shared/src/client/i18n.ts
179
190
  /** 卡片通用文案(save/discard/unsaved/loading 等四插件共有键)。 */
180
191
  const commonZh = {
@@ -184,7 +195,7 @@ window.__ModuleLoader__.load({
184
195
  unsaved: "未保存",
185
196
  loading: "加载中…",
186
197
  unavailable: "配置服务不可用。",
187
- readOnly: "当前部署无 settings provider,配置为只读;请编辑 settings.yaml。",
198
+ readOnly: "当前部署无 settings provider,配置为只读;请在 profile 的 cordis.patch.yml 行级配置。",
188
199
  invalidNumber: "请输入正整数。",
189
200
  collapse: "收起",
190
201
  expand: "展开",
@@ -201,7 +212,7 @@ window.__ModuleLoader__.load({
201
212
  unsaved: "Unsaved",
202
213
  loading: "Loading…",
203
214
  unavailable: "Settings service unavailable.",
204
- readOnly: "No settings provider in this deployment; config is read-only. Edit settings.yaml.",
215
+ readOnly: "No settings provider in this deployment; config is read-only. Configure it at the profile row in cordis.patch.yml.",
205
216
  invalidNumber: "Enter a positive integer.",
206
217
  collapse: "Collapse",
207
218
  expand: "Expand",
@@ -408,7 +419,7 @@ ${extra}
408
419
  //#region src/ns.ts
409
420
  /**
410
421
  * settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
411
- * 服务端直接以字面量注册(0.1.2-alpha.2 起 dsh-settings 对命名空间做编译期
422
+ * 服务端直接以字面量注册(dsh-settings 对命名空间做编译期
412
423
  * 语法校验,见 config.ts);浏览器半把它作为配置卡片的注册键
413
424
  * (插件页配置卡片挂在 row/bundle config 槽位上,与命名空间解耦,
414
425
  * 见 shared/config-slots),
@@ -619,7 +630,7 @@ ${extra}
619
630
  * 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/TextField/CheckRow),
620
631
  * 本文件只保留业务字段与保存/测试逻辑。交互对齐官方卡片:折叠/展开、
621
632
  * staged draft、未保存标记、保存/放弃;另加「发送测试邮件」。
622
- * 配置读写经 ctx.remote.settings 直连(0.1.2-alpha.1 起 connection.api.settings
633
+ * 配置读写经 ctx.remote.settings 直连(connection.api.settings
623
634
  * 已移除):value 为 schema 解析后的脱敏视图
624
635
  * (smtp.pass 不出现,passConfigured 由 describe 的 secrets 探测),
625
636
  * 保存经 settings.update 深合并(空 pass 剔除 = 保持不变)。
package/lib/index.d.ts CHANGED
@@ -71,7 +71,7 @@ declare const Config: z<Schemastery.ObjectS<NoInfer<{
71
71
  maxBodyChars: z<number, number, "volatile-defined">;
72
72
  dryRun: z<boolean, boolean, "volatile-defined">;
73
73
  }>>, "plain">;
74
- /** 活动字段形态(0.1.7 loader 解析产物:volatile 字段为活动引用)。 */
74
+ /** 活动字段形态(loader 解析产物:volatile 字段为活动引用)。 */
75
75
  type NotifyEmailConfigFields = Schemastery.TypeT<typeof Config>;
76
76
  /** 平面配置形态(消费面的读取形态,由活动引用解包得到)。 */
77
77
  type NotifyEmailConfig = UnwrapVolatile<NotifyEmailConfigFields>;
package/lib/index.js CHANGED
@@ -74,9 +74,9 @@ function registerTestApi(ctx, service) {
74
74
  //#region src/config.ts
75
75
  /**
76
76
  * 配置单一事实源:cordis 行级 Config(组合默认值,dev/prod patch 层可覆盖)
77
- * 与 settings namespace(用户层,经 dsh-settings-file 持久化到 $DSH_HOME/settings.yaml)
77
+ * 与 settings namespace(用户层=profile 行级覆盖层 cordis.patch.yml)
78
78
  * 共用同一 schemastery schema。SMTP 密码走官方 credentials seam
79
- * (refs/NOTIFY_EMAIL_SMTP_PASS),不进 settings.yaml(存储规范)。
79
+ * (refs/NOTIFY_EMAIL_SMTP_PASS),不进 settings 用户层(存储规范)。
80
80
  * @module notify-email/config
81
81
  */
82
82
  /** SMTP 密码在官方 credentials seam 中的引用名。 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-plus/notify-email",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "description": "dsh-plus service+ui plugin: 任务结束/等待决策/出错时向指定邮箱发送邮件通知",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "nodemailer": "9.0.6",
35
- "@dsh-plus/shared": "0.1.34"
35
+ "@dsh-plus/shared": "0.1.36"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@deepseek-ai/cordis": "^4.0.5-alpha.1",
@@ -4,7 +4,7 @@
4
4
  * 外壳与基础控件走 @dsh-plus/shared/client 套件(CardChrome/TextField/CheckRow),
5
5
  * 本文件只保留业务字段与保存/测试逻辑。交互对齐官方卡片:折叠/展开、
6
6
  * staged draft、未保存标记、保存/放弃;另加「发送测试邮件」。
7
- * 配置读写经 ctx.remote.settings 直连(0.1.2-alpha.1 起 connection.api.settings
7
+ * 配置读写经 ctx.remote.settings 直连(connection.api.settings
8
8
  * 已移除):value 为 schema 解析后的脱敏视图
9
9
  * (smtp.pass 不出现,passConfigured 由 describe 的 secrets 探测),
10
10
  * 保存经 settings.update 深合并(空 pass 剔除 = 保持不变)。
@@ -7,8 +7,8 @@
7
7
  *
8
8
  * 类型说明:浏览器半只用到 slots/locale/remote 的很窄一面,
9
9
  * scope 与基础控件走 @dsh-plus/shared/client 套件(收编自本插件原实现)。
10
- * 配置读写经 ctx.remote.settings 直连(0.1.2-alpha.1 起 connection.api.settings
11
- * 已移除;0.1.7 起 settingsScope 服务亦删除(configForms 取代)——插件卡片自始
10
+ * 配置读写经 ctx.remote.settings 直连(connection.api.settings
11
+ * 已移除; settingsScope 服务亦删除(configForms 取代)——插件卡片自始
12
12
  * 直连 remote.settings);自定义端点仅剩「发送测试邮件」(api.ts)。
13
13
  * 卡片 key/rowId 约定见 @dsh-plus/shared/client/config-slots。
14
14
  * @module @dsh-plus/notify-email/client
package/src/config-api.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 自定义端点 HTTP 通道:配置读写走官方 settings 命名空间(0.1.2-alpha.1 起
2
+ * 自定义端点 HTTP 通道:配置读写走官方 settings 命名空间(
3
3
  * 第三方命名空间全量开放),这里只保留官方传输没有的「发送测试邮件」端点。
4
4
  * 仅监听 dsh web 同源(webserver 默认 127.0.0.1),与 GUI 其余面同等暴露面。
5
5
  * @module notify-email/config-api
package/src/config.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * 配置单一事实源:cordis 行级 Config(组合默认值,dev/prod patch 层可覆盖)
3
- * 与 settings namespace(用户层,经 dsh-settings-file 持久化到 $DSH_HOME/settings.yaml)
3
+ * 与 settings namespace(用户层=profile 行级覆盖层 cordis.patch.yml)
4
4
  * 共用同一 schemastery schema。SMTP 密码走官方 credentials seam
5
- * (refs/NOTIFY_EMAIL_SMTP_PASS),不进 settings.yaml(存储规范)。
5
+ * (refs/NOTIFY_EMAIL_SMTP_PASS),不进 settings 用户层(存储规范)。
6
6
  * @module notify-email/config
7
7
  */
8
8
 
@@ -11,7 +11,7 @@ import type { UnwrapVolatile } from '@dsh-plus/shared'
11
11
 
12
12
  import { SETTINGS_NS as NS_LITERAL } from './ns.ts'
13
13
 
14
- /** settings 命名空间(字面量即合法命名空间,0.1.2-alpha.2 起编译期校验;webui 配置卡片与插件运行期读取同一份)。 */
14
+ /** settings 命名空间(字面量即合法命名空间,编译期校验;webui 配置卡片与插件运行期读取同一份)。 */
15
15
  export const SETTINGS_NS = NS_LITERAL
16
16
 
17
17
  /** SMTP 密码在官方 credentials seam 中的引用名。 */
@@ -65,7 +65,7 @@ export const Config = z.object({
65
65
  dryRun: z.boolean().description('仅记录日志不真实发送(开发调试用)').default(false).volatile(),
66
66
  })
67
67
 
68
- /** 活动字段形态(0.1.7 loader 解析产物:volatile 字段为活动引用)。 */
68
+ /** 活动字段形态(loader 解析产物:volatile 字段为活动引用)。 */
69
69
  export type NotifyEmailConfigFields = Schemastery.TypeT<typeof Config>
70
70
  /** 平面配置形态(消费面的读取形态,由活动引用解包得到)。 */
71
71
  export type NotifyEmailConfig = UnwrapVolatile<NotifyEmailConfigFields>
package/src/ns.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * settings 命名空间字面量(纯常量,零依赖,浏览器半可安全引入)。
3
- * 服务端直接以字面量注册(0.1.2-alpha.2 起 dsh-settings 对命名空间做编译期
3
+ * 服务端直接以字面量注册(dsh-settings 对命名空间做编译期
4
4
  * 语法校验,见 config.ts);浏览器半把它作为配置卡片的注册键
5
5
  * (插件页配置卡片挂在 row/bundle config 槽位上,与命名空间解耦,
6
6
  * 见 shared/config-slots),
package/src/service.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * NotifyEmailService:通知编排中枢。
3
- * - 配置:0.1.7 volatile 活动引用(loader 解析层并入用户层,GUI 写入原位提交
3
+ * - 配置:volatile 活动引用(loader 解析层并入用户层,GUI 写入原位提交
4
4
  * 热生效),无 settings provider 时即 cordis 行级 config 本身;
5
5
  * - 触发器:registerTrigger 是第三方插件的扩展接口;内置官方适配器同路径注册。
6
6
  * - 投递:首个非空 EmailNotice 经 Mailer 发送;单个触发器抛错不影响其余。
@@ -32,9 +32,9 @@ function credentialsOf(ctx: Context): CredentialsSeamLike {
32
32
  }
33
33
 
34
34
  export class NotifyEmailService extends Service {
35
- // cordis 4.0.2 以普通静态属性读取插件级 inject(Context.inject 符号在该版本
36
- // 不存在,computed key 会静默变成字符串 'undefined' 使声明失效——0.1.18 的
37
- // 553 回归即源于此:credentials 未就绪时构造读 ctx.credentials 抛
35
+ // cordis 以普通静态属性读取插件级 inject(Context.inject 符号不存在,
36
+ // computed key 会静默变成字符串 'undefined' 使声明失效——曾因此出过回归:
37
+ // credentials 未就绪时构造读 ctx.credentials 抛
38
38
  // "cannot get property credentials without inject",服务 fiber 静默 FAILED)。
39
39
  static inject = ['agents', 'tools', 'credentials']
40
40
 
@@ -44,7 +44,7 @@ export class NotifyEmailService extends Service {
44
44
 
45
45
  constructor(ctx: Context, config: NotifyEmailConfig | NotifyEmailConfigFields) {
46
46
  super(ctx, 'notifyEmail')
47
- // 0.1.7 替代 0.1.6 installSection/setSource:活动引用原位提交,现取即热。
47
+ // 替代已删除的 installSection/setSource:活动引用原位提交,现取即热。
48
48
  this.current = () => unwrapVolatile(config)
49
49
  const logger = ctx.logger('notify-email')
50
50
  const audit = createJsonlAuditSink(pluginDataPath('notify-email', 'audit.jsonl'), (message) =>