@shgroup/dsh-serenity-hooks 1.84.0 → 1.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.84.0",
3
+ "version": "1.85.0",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——14 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档,deepseek-ai/deepseek-harness)。",
6
6
  "engines": {
@@ -227,7 +227,7 @@ async function listCccs(ctx, opts = {}) {
227
227
  if (typeof defaultRoot === "string" && defaultRoot !== "" && !c.roots.includes(defaultRoot)) c.roots.unshift(defaultRoot);
228
228
  let rolesOf = null;
229
229
  if (opts.withRoles === true) {
230
- const { listTrajectoryConstraints } = await import("./profile-CiRWh2a2.js").then((n) => n.i);
230
+ const { listTrajectoryConstraints } = await import("./profile-DnLSb7yv.js").then((n) => n.i);
231
231
  rolesOf = (root) => {
232
232
  try {
233
233
  return listTrajectoryConstraints(root).map((p) => p.code);
package/lib/client.js CHANGED
@@ -3810,6 +3810,25 @@ Instruction-following style:
3810
3810
  const [feishuName, setFeishuName] = (0, react.useState)("");
3811
3811
  const [feishuBusy, setFeishuBusy] = (0, react.useState)(false);
3812
3812
  const [feishuNotice, setFeishuNotice] = (0, react.useState)(null);
3813
+ /**
3814
+ * 添加账号的**渠道二选一**(owner 2026-10-21:「不对称,交互上要体现二选一」)。
3815
+ *
3816
+ * ## 改之前为什么"不对称"(这是真问题,不是审美)
3817
+ *
3818
+ * 微信与飞书各是**一张常驻卡片**,并且飞书那张的**三格表单一直展开**:
3819
+ * · 视觉上像是"**两件事都要填**",而实际是二选一;
3820
+ * · 微信只有一个按钮,飞书有一整块输入区 ⇒ 两边**分量不等**,读起来像"微信是次要的";
3821
+ * · 空着两格 App ID/Secret 长期占版面,把真正的动作(扫码)挤到上面去。
3822
+ *
3823
+ * ## 改成什么
3824
+ *
3825
+ * **一个「添加账号」入口 + 渠道切换**:先选渠道,再只显示该渠道的一条路径。
3826
+ * `null` = 还没选(**初始收起**,不默认展开任何一家 —— 默认展开就等于替用户做了选择)。
3827
+ *
3828
+ * ⚠️ **为什么仍是同一个块的两种形态,而不是两个并列卡片**:渠道是**互斥**的
3829
+ * (一个账号只属于一家),并列会把"互斥"读成"并列"。
3830
+ */
3831
+ const [addChannel, setAddChannel] = (0, react.useState)(null);
3813
3832
  (0, react.useEffect)(() => {
3814
3833
  let alive = true;
3815
3834
  (async () => {
@@ -4208,49 +4227,147 @@ Instruction-following style:
4208
4227
  })
4209
4228
  })]
4210
4229
  }) }, a.accountId)),
4211
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4212
- className: "ss-rowCard",
4213
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4214
- className: "ss-rowText",
4215
- children: [
4216
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4217
- className: "ss-rowName",
4218
- children: "扫码绑定微信"
4219
- }),
4220
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4230
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
4231
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4232
+ className: "ss-rowCard",
4233
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4234
+ className: "ss-rowText",
4235
+ children: [
4236
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4237
+ className: "ss-rowName",
4238
+ children: "添加账号"
4239
+ }),
4240
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4241
+ className: "ss-rowDesc",
4242
+ children: [
4243
+ addChannel === null && "选一个渠道,再按它的方式绑定(一个账号只属于一家)",
4244
+ addChannel === "weixin" && "微信:手机「扫一扫」确认——每扫一次绑定一个新账号",
4245
+ addChannel === "feishu" && "飞书:填企业自建应用的 App ID 与 App Secret——每提交一次新增一个账号"
4246
+ ]
4247
+ }),
4248
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4249
+ className: "ss-help",
4250
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4251
+ type: "button",
4252
+ className: "ss-helpMark",
4253
+ "aria-label": "添加账号帮助",
4254
+ children: "?"
4255
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4256
+ className: "ss-helpTip",
4257
+ children: "两个渠道二选一,绑定方式不同:\n· 微信:走腾讯 iLink 开放协议(个人微信 Bot API),扫码确认,不需要平台审核\n· 飞书:走企业自建应用,需要 App ID 与 App Secret(开放平台 → 开发者后台 → 凭证与基础信息)\n· 两者可以同时存在,但**每个账号只属于一家**;账号、路由、开关互不影响\n· 每绑定一次新增一个账号,各自独立连接"
4258
+ })]
4259
+ })
4260
+ ]
4261
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4262
+ className: "ss-rowControl",
4263
+ children: addChannel !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4264
+ type: "button",
4265
+ className: "ss-removeBtn",
4266
+ onClick: () => {
4267
+ setAddChannel(null);
4268
+ setFeishuNotice(null);
4269
+ },
4270
+ children: "收起"
4271
+ })
4272
+ })]
4273
+ }),
4274
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4275
+ className: "ss-channelPicker",
4276
+ role: "radiogroup",
4277
+ "aria-label": "选择添加渠道",
4278
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4279
+ type: "button",
4280
+ role: "radio",
4281
+ "aria-checked": addChannel === "weixin",
4282
+ className: `ss-channelOption${addChannel === "weixin" ? " ss-channelOptionOn" : ""}`,
4283
+ onClick: () => {
4284
+ setAddChannel("weixin");
4285
+ setFeishuNotice(null);
4286
+ },
4287
+ children: "微信"
4288
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4289
+ type: "button",
4290
+ role: "radio",
4291
+ "aria-checked": addChannel === "feishu",
4292
+ className: `ss-channelOption${addChannel === "feishu" ? " ss-channelOptionOn" : ""}`,
4293
+ onClick: () => {
4294
+ setAddChannel("feishu");
4295
+ setFeishuNotice(null);
4296
+ },
4297
+ children: "飞书"
4298
+ })]
4299
+ }),
4300
+ addChannel === "weixin" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4301
+ className: "ss-channelBody",
4302
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4303
+ className: "ss-rowText",
4304
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4221
4305
  className: "ss-rowDesc",
4222
4306
  children: [
4223
- loginPhase === "idle" && "微信「扫一扫」确认——每扫一次绑定一个新账号",
4307
+ loginPhase === "idle" && "点击后用手机微信「扫一扫」确认",
4224
4308
  loginPhase === "waiting" && "二维码已生成(5 分钟有效)——微信扫一扫 → 手机确认",
4225
4309
  loginPhase === "confirmed" && (loginNotice ?? "绑定成功"),
4226
4310
  loginPhase === "error" && (loginError ?? "绑定失败"),
4227
4311
  loginPhase === "expired" && "二维码已过期,请重新获取"
4228
4312
  ]
4313
+ })
4314
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4315
+ className: "ss-rowControl",
4316
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4317
+ type: "button",
4318
+ className: "ss-loginBtn",
4319
+ disabled: loginPhase === "waiting",
4320
+ onClick: () => void startLogin(),
4321
+ children: loginPhase === "waiting" ? "等待扫码…" : "扫码绑定"
4322
+ })
4323
+ })]
4324
+ }),
4325
+ addChannel === "feishu" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4326
+ className: "ss-channelBody ss-channelBodyCol",
4327
+ children: [
4328
+ feishuNotice !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4329
+ className: "ss-rowDesc",
4330
+ children: feishuNotice
4229
4331
  }),
4230
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4231
- className: "ss-help",
4232
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4332
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4333
+ className: "ss-feishuForm",
4334
+ children: [
4335
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4336
+ className: "ss-input",
4337
+ type: "text",
4338
+ placeholder: "App ID(cli_xxx)",
4339
+ value: feishuAppId,
4340
+ onChange: (e) => setFeishuAppId(e.target.value)
4341
+ }),
4342
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4343
+ className: "ss-input",
4344
+ type: "password",
4345
+ placeholder: "App Secret",
4346
+ value: feishuAppSecret,
4347
+ onChange: (e) => setFeishuAppSecret(e.target.value)
4348
+ }),
4349
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4350
+ className: "ss-input",
4351
+ type: "text",
4352
+ placeholder: "账号名(可选,如「家庭群机器人」)",
4353
+ value: feishuName,
4354
+ onChange: (e) => setFeishuName(e.target.value)
4355
+ })
4356
+ ]
4357
+ }),
4358
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4359
+ className: "ss-channelActions",
4360
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4233
4361
  type: "button",
4234
- className: "ss-helpMark",
4235
- "aria-label": "扫码绑定帮助",
4236
- children: "?"
4237
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4238
- className: "ss-helpTip",
4239
- children: "扫码绑定微信账号。\n· 走腾讯 iLink 开放协议(个人微信 Bot API)\n· 步骤:生成二维码 → 手机微信「扫一扫」→ 手机上确认\n· 每扫一次绑定一个新账号,可多账号,各自独立轮询\n· 二维码 5 分钟有效;不需要平台审核"
4240
- })]
4362
+ className: "ss-loginBtn",
4363
+ disabled: feishuBusy || feishuAppId.trim() === "" || feishuAppSecret.trim() === "",
4364
+ onClick: () => void addFeishuAccount(),
4365
+ children: feishuBusy ? "添加中…" : "添加飞书账号"
4366
+ })
4241
4367
  })
4242
4368
  ]
4243
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4244
- className: "ss-rowControl",
4245
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4246
- type: "button",
4247
- className: "ss-loginBtn",
4248
- disabled: loginPhase === "waiting",
4249
- onClick: () => void startLogin(),
4250
- children: loginPhase === "waiting" ? "等待扫码…" : "扫码绑定"
4251
- })
4252
- })]
4253
- }) }),
4369
+ })
4370
+ ] }),
4254
4371
  loginPhase === "waiting" && loginQrSvg !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4255
4372
  className: "ss-rowCard ss-qrRow",
4256
4373
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -4264,68 +4381,6 @@ Instruction-following style:
4264
4381
  })
4265
4382
  })]
4266
4383
  }) }),
4267
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4268
- className: "ss-rowCard",
4269
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4270
- className: "ss-rowText",
4271
- children: [
4272
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4273
- className: "ss-rowName",
4274
- children: "添加飞书账号"
4275
- }),
4276
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4277
- className: "ss-rowDesc",
4278
- children: feishuNotice ?? "填企业自建应用的 App ID 与 App Secret——每提交一次新增一个账号"
4279
- }),
4280
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4281
- className: "ss-help",
4282
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4283
- type: "button",
4284
- className: "ss-helpMark",
4285
- "aria-label": "飞书绑定帮助",
4286
- children: "?"
4287
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4288
- className: "ss-helpTip",
4289
- children: "添加飞书账号(企业自建应用)。\n· 飞书开放平台 → 开发者后台 → 你的应用 → 「凭证与基础信息」\n· 复制 App ID 与 App Secret 填在下面\n· 事件订阅选「长连接」并订阅 im.message.receive_v1\n· 每提交一次新增一个账号,各自独立连接\n· 与微信并列:账号、路由、开关互不影响"
4290
- })]
4291
- })
4292
- ]
4293
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4294
- className: "ss-rowControl",
4295
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4296
- type: "button",
4297
- className: "ss-loginBtn",
4298
- disabled: feishuBusy || feishuAppId.trim() === "" || feishuAppSecret.trim() === "",
4299
- onClick: () => void addFeishuAccount(),
4300
- children: feishuBusy ? "添加中…" : "添加飞书账号"
4301
- })
4302
- })]
4303
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4304
- className: "ss-feishuForm",
4305
- children: [
4306
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4307
- className: "ss-input",
4308
- type: "text",
4309
- placeholder: "App ID(cli_xxx)",
4310
- value: feishuAppId,
4311
- onChange: (e) => setFeishuAppId(e.target.value)
4312
- }),
4313
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4314
- className: "ss-input",
4315
- type: "password",
4316
- placeholder: "App Secret",
4317
- value: feishuAppSecret,
4318
- onChange: (e) => setFeishuAppSecret(e.target.value)
4319
- }),
4320
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4321
- className: "ss-input",
4322
- type: "text",
4323
- placeholder: "账号名(可选,如「家庭群机器人」)",
4324
- value: feishuName,
4325
- onChange: (e) => setFeishuName(e.target.value)
4326
- })
4327
- ]
4328
- })] }),
4329
4384
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4330
4385
  className: "ss-rowCard",
4331
4386
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4386,7 +4441,7 @@ Instruction-following style:
4386
4441
  }
4387
4442
  //#endregion
4388
4443
  //#region \0sp-css:src/client/SettingsSection
4389
- const css$2 = "/* SettingsSection — dsh 原生设置面板 serenity-hooks 简单配置页\n v1.21.1 看齐 dsh 自身:官方 settings 设计语言——\n section > title + intro + group(groupTitle) + rowCard 行卡;\n 全部 --dsw-alias-* token(与 ui-settings-models 同词汇表)。 */\n\n/* 页面容器(官方 .section:flex column gap 12) */\n.ss-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-width: 720px;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面标题(官方 .title:16px/24 500) */\n.ss-title {\n margin: 0;\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面说明(官方 .intro:14px/22 tertiary) */\n.ss-intro {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 分组(多级标题:分组标题 + 行卡列表) */\n.ss-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 分组标题(二级:12px/18 500 secondary——官方 fieldLabel 风格) */\n.ss-groupTitle {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* 行卡列表(官方 .rows:无 marker,gap 8) */\n.ss-rows {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 行卡(官方 .rowCard:border-l2 r12 padding 12/14) */\n.ss-rowCard {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n padding: 12px 14px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n/* ── v1.29 需求②:可展开行(整行点击 → 行内详设)── */\n.ss-expandable {\n flex-wrap: wrap; /* detail 换行占满整行 */\n cursor: default;\n}\n.ss-expandable .ss-rowText {\n cursor: pointer;\n}\n.ss-expandable .ss-rowText:hover .ss-rowName {\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n.ss-expanded {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n.ss-expandMark {\n display: inline-block;\n margin-left: 6px;\n font-size: 10px;\n color: var(--dsw-alias-label-tertiary);\n transition: transform 0.15s ease;\n}\n.ss-expanded .ss-expandMark {\n transform: rotate(90deg);\n}\n.ss-rowDetail {\n flex-basis: 100%;\n width: 100%;\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin-top: 10px;\n padding-top: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n min-width: 0;\n}\n.ss-detailStack {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.ss-detailIntro {\n margin: 0;\n font-size: 12px;\n line-height: 19px;\n color: var(--dsw-alias-label-secondary);\n white-space: pre-line;\n word-break: break-word;\n overflow-wrap: anywhere;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.06));\n}\n\n/* 行卡文本(标题 + 说明 左列) */\n.ss-rowText {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n flex: 1;\n}\n\n/* 行卡标题(官方 .rowName:14px/22 500) */\n.ss-rowName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* IM 桥:账号行的**渠道标签**(2026-10-19 泛化后新增)。\n 为什么是标签而不是\"把渠道拼进 id\":渠道是账号的属性,不是名字的一部分;\n 拼进去会让「同一个账号换了渠道」看起来像另一个账号。\n 🔴 不得定宽(v1.72.0 那次 `sp-label` 写死 76px 压住数值的教训)⇒ inline-block + 自适应。 */\n.ss-channelTag {\n display: inline-block;\n padding: 0 6px;\n margin-right: 6px;\n border-radius: 4px;\n font-size: 11px;\n line-height: 18px;\n font-weight: 600;\n vertical-align: 1px;\n background: rgba(11, 168, 117, .12);\n color: #0ba875;\n white-space: nowrap;\n}\n\n@media (prefers-color-scheme: dark) {\n .ss-channelTag { color: #3ddc9a; }\n}\n\n/* 行卡说明(12px/18 tertiary;v1.27.5 紧凑化:默认单行截断,hover title 看全文) */\n.ss-rowDesc {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* 行卡控件(右置) */\n.ss-rowControl {\n flex: none;\n display: flex;\n align-items: center;\n}\n\n/* 开关(官方 token 的自绘 toggle:track 22px,thumb 16px) */\n.ss-switch {\n position: relative;\n flex: none;\n width: 40px;\n height: 22px;\n cursor: pointer;\n}\n\n.ss-switch input {\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n cursor: pointer;\n}\n\n.ss-switchTrack {\n position: absolute;\n inset: 0;\n border-radius: 11px;\n background: var(--dsw-alias-border-l3);\n transition: background var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switchTrack::after {\n content: '';\n position: absolute;\n top: 3px;\n left: 3px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--dsw-alias-label-primary-foreground);\n transition: transform var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switch input:checked + .ss-switchTrack {\n background: var(--dsw-alias-brand-primary);\n}\n\n.ss-switch input:checked + .ss-switchTrack::after {\n transform: translateX(18px);\n}\n\n.ss-switch input:disabled + .ss-switchTrack {\n opacity: 0.4;\n cursor: default;\n}\n\n/* Skiff 调试端口输入(number;关闭时跟随 disabled 半透明) */\n.ss-portInput {\n width: 96px;\n padding: 6px 8px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.ss-portInput:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 自主轨迹「立即唤起」按钮(v1.26.14 调试语义;官方 button 语言:primary 弱化) */\n.ss-wakeBtn {\n flex: none;\n padding: 5px 12px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-wakeBtn:hover:not(:disabled) {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.ss-wakeBtn:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 错误提示(会话清理等) */\n.ss-error {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary, #ef4444);\n background: rgba(239, 68, 68, 0.08);\n border-radius: 8px;\n padding: 8px 10px;\n white-space: pre-line;\n word-break: break-word;\n}\n\n/* ── v1.27.5 紧凑化:折叠组(details/summary)── */\n.ss-collapse {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.ss-collapseHead {\n display: flex;\n align-items: baseline;\n gap: 10px;\n padding: 10px 14px;\n cursor: pointer;\n list-style: none;\n user-select: none;\n}\n\n.ss-collapseHead::-webkit-details-marker {\n display: none;\n}\n\n.ss-collapseHead::before {\n content: '▸';\n flex: none;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n transition: transform 0.15s ease;\n}\n\n.ss-collapse[open] > .ss-collapseHead::before {\n transform: rotate(90deg);\n}\n\n.ss-collapseHead:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.06));\n}\n\n.ss-collapseTitle {\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.ss-collapseDesc {\n font-size: 12px;\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n\n.ss-collapseBody {\n padding: 10px 14px 14px;\n border-top: 1px solid var(--dsw-alias-border-l1);\n}\n\n/* ── 开关 + 端口内联行 ── */\n.ss-switchRow {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* ── v1.27.6 「?」帮助浮层(hover/焦点显示三行以上严谨说明)── */\n.ss-help {\n position: relative;\n display: inline-flex;\n align-items: center;\n margin-top: 2px;\n}\n\n.ss-helpMark {\n flex: none;\n width: 16px;\n height: 16px;\n padding: 0;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 50%;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n line-height: 1;\n font-weight: 600;\n cursor: help;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s ease, color 0.15s ease;\n}\n\n.ss-helpMark:hover,\n.ss-helpMark:focus-visible {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n outline: none;\n}\n\n.ss-helpTip {\n position: absolute;\n left: 0;\n top: calc(100% + 6px);\n z-index: 30;\n width: 300px;\n max-width: 60vw;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-overlay);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);\n font-size: 12px;\n line-height: 19px;\n font-weight: 400;\n color: var(--dsw-alias-label-primary);\n white-space: pre-line;\n word-break: break-word;\n opacity: 0;\n pointer-events: none;\n transform: translateY(-4px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n}\n\n.ss-help:hover .ss-helpTip,\n.ss-helpMark:focus-visible + .ss-helpTip {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0);\n}\n\n/* 折叠组内帮助浮层定位修正(左侧行卡不会溢出面板) */\n.ss-rowCard .ss-helpTip {\n left: 0;\n}\n\n/* ── 微信桥(F4c-3,v1.27.0 实验性)── */\n\n/* CCC 选择器(下拉) */\n.ss-select {\n max-width: 280px;\n padding: 6px 8px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* 扫码绑定按钮(复用 wakeBtn 语言) */\n.ss-loginBtn {\n flex: none;\n padding: 5px 12px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-loginBtn:hover:not(:disabled) {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.ss-loginBtn:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 移除账号按钮(危险语义:红边框) */\n.ss-removeBtn {\n flex: none;\n padding: 5px 12px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-removeBtn:hover:not(:disabled) {\n border-color: var(--dsw-alias-state-error-primary, #ef4444);\n color: var(--dsw-alias-state-error-primary, #ef4444);\n}\n\n/* 二维码展示行 */\n.ss-qrRow {\n align-items: center;\n}\n\n.ss-qrSvg {\n flex: none;\n width: 120px; /* v1.27.5 紧凑化:160 → 120 */\n height: 120px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: #fff; /* 二维码需要白底才能被微信扫出 */\n padding: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.ss-qrSvg svg {\n width: 100%;\n height: 100%;\n}\n\n/* 飞书凭据表单(P4):三格竖排——appId / appSecret / 账号名。\n * 🔴 不做成一行三格:App Secret 通常 32 位,窄屏下会被压到看不见自己输了什么\n * (本文件 D152 记过同族:定宽 + 无断点会把值压到标签上)。竖排在小屏也保持可读。 */\n.ss-feishuForm {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 6px;\n}\n\n.ss-feishuForm .ss-input {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.ss-feishuForm .ss-input::placeholder {\n color: var(--dsw-alias-label-secondary);\n}\n\n/* 路由表 JSON 编辑框 */\n.ss-routesEditor {\n width: 100%;\n box-sizing: border-box;\n margin-top: 6px;\n padding: 8px 10px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-family: var(--ds-font-family-code);\n resize: vertical;\n}\n\n/* ── 窄屏(面板被塞进窄栏或手机浏览器)────────────────────────────────────\n * 排版问题只有一个根因:`.ss-rowCard` 是「左文本 + 右控件」的两列 flex,\n * 而控件里有端口输入(96px)/开关(40px)/端口+开关(150px)三档。\n * 窄到放不下时,flex 会先压文字(`min-width: 0` 已开)⇒ 标题被挤成一列竖排字。\n * 处理:窄屏把控件落到第二行(左对齐),文字保住整行宽。 */\n@media (max-width: 560px) {\n .ss-rowCard {\n flex-wrap: wrap;\n gap: 10px;\n }\n\n .ss-rowControl {\n flex-basis: 100%;\n justify-content: flex-start;\n }\n\n /* 行内说明在窄屏不必截断:整行宽足够,截断反而藏信息 */\n .ss-rowDesc {\n -webkit-line-clamp: unset;\n display: block;\n }\n\n /* 详情区与折叠头在窄屏收紧内边距(横向像素更值钱) */\n .ss-rowDetail,\n .ss-collapseBody {\n padding-left: 0;\n padding-right: 0;\n }\n}\n";
4444
+ const css$2 = "/* SettingsSection — dsh 原生设置面板 serenity-hooks 简单配置页\n v1.21.1 看齐 dsh 自身:官方 settings 设计语言——\n section > title + intro + group(groupTitle) + rowCard 行卡;\n 全部 --dsw-alias-* token(与 ui-settings-models 同词汇表)。 */\n\n/* 页面容器(官方 .section:flex column gap 12) */\n.ss-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-width: 720px;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面标题(官方 .title:16px/24 500) */\n.ss-title {\n margin: 0;\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面说明(官方 .intro:14px/22 tertiary) */\n.ss-intro {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 分组(多级标题:分组标题 + 行卡列表) */\n.ss-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 分组标题(二级:12px/18 500 secondary——官方 fieldLabel 风格) */\n.ss-groupTitle {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* 行卡列表(官方 .rows:无 marker,gap 8) */\n.ss-rows {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 行卡(官方 .rowCard:border-l2 r12 padding 12/14) */\n.ss-rowCard {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n padding: 12px 14px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n/* ── v1.29 需求②:可展开行(整行点击 → 行内详设)── */\n.ss-expandable {\n flex-wrap: wrap; /* detail 换行占满整行 */\n cursor: default;\n}\n.ss-expandable .ss-rowText {\n cursor: pointer;\n}\n.ss-expandable .ss-rowText:hover .ss-rowName {\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n.ss-expanded {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n.ss-expandMark {\n display: inline-block;\n margin-left: 6px;\n font-size: 10px;\n color: var(--dsw-alias-label-tertiary);\n transition: transform 0.15s ease;\n}\n.ss-expanded .ss-expandMark {\n transform: rotate(90deg);\n}\n.ss-rowDetail {\n flex-basis: 100%;\n width: 100%;\n border-top: 1px solid var(--dsw-alias-border-l2);\n margin-top: 10px;\n padding-top: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n min-width: 0;\n}\n.ss-detailStack {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.ss-detailIntro {\n margin: 0;\n font-size: 12px;\n line-height: 19px;\n color: var(--dsw-alias-label-secondary);\n white-space: pre-line;\n word-break: break-word;\n overflow-wrap: anywhere;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.06));\n}\n\n/* 行卡文本(标题 + 说明 左列) */\n.ss-rowText {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n flex: 1;\n}\n\n/* 行卡标题(官方 .rowName:14px/22 500) */\n.ss-rowName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* IM 桥:账号行的**渠道标签**(2026-10-19 泛化后新增)。\n 为什么是标签而不是\"把渠道拼进 id\":渠道是账号的属性,不是名字的一部分;\n 拼进去会让「同一个账号换了渠道」看起来像另一个账号。\n 🔴 不得定宽(v1.72.0 那次 `sp-label` 写死 76px 压住数值的教训)⇒ inline-block + 自适应。 */\n.ss-channelTag {\n display: inline-block;\n padding: 0 6px;\n margin-right: 6px;\n border-radius: 4px;\n font-size: 11px;\n line-height: 18px;\n font-weight: 600;\n vertical-align: 1px;\n background: rgba(11, 168, 117, .12);\n color: #0ba875;\n white-space: nowrap;\n}\n\n@media (prefers-color-scheme: dark) {\n .ss-channelTag { color: #3ddc9a; }\n}\n\n/* 行卡说明(12px/18 tertiary;v1.27.5 紧凑化:默认单行截断,hover title 看全文) */\n.ss-rowDesc {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* 行卡控件(右置) */\n.ss-rowControl {\n flex: none;\n display: flex;\n align-items: center;\n}\n\n/* 开关(官方 token 的自绘 toggle:track 22px,thumb 16px) */\n.ss-switch {\n position: relative;\n flex: none;\n width: 40px;\n height: 22px;\n cursor: pointer;\n}\n\n.ss-switch input {\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n cursor: pointer;\n}\n\n.ss-switchTrack {\n position: absolute;\n inset: 0;\n border-radius: 11px;\n background: var(--dsw-alias-border-l3);\n transition: background var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switchTrack::after {\n content: '';\n position: absolute;\n top: 3px;\n left: 3px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--dsw-alias-label-primary-foreground);\n transition: transform var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switch input:checked + .ss-switchTrack {\n background: var(--dsw-alias-brand-primary);\n}\n\n.ss-switch input:checked + .ss-switchTrack::after {\n transform: translateX(18px);\n}\n\n.ss-switch input:disabled + .ss-switchTrack {\n opacity: 0.4;\n cursor: default;\n}\n\n/* Skiff 调试端口输入(number;关闭时跟随 disabled 半透明) */\n.ss-portInput {\n width: 96px;\n padding: 6px 8px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.ss-portInput:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 自主轨迹「立即唤起」按钮(v1.26.14 调试语义;官方 button 语言:primary 弱化) */\n.ss-wakeBtn {\n flex: none;\n padding: 5px 12px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-wakeBtn:hover:not(:disabled) {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.ss-wakeBtn:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 错误提示(会话清理等) */\n.ss-error {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary, #ef4444);\n background: rgba(239, 68, 68, 0.08);\n border-radius: 8px;\n padding: 8px 10px;\n white-space: pre-line;\n word-break: break-word;\n}\n\n/* ── v1.27.5 紧凑化:折叠组(details/summary)── */\n.ss-collapse {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.ss-collapseHead {\n display: flex;\n align-items: baseline;\n gap: 10px;\n padding: 10px 14px;\n cursor: pointer;\n list-style: none;\n user-select: none;\n}\n\n.ss-collapseHead::-webkit-details-marker {\n display: none;\n}\n\n.ss-collapseHead::before {\n content: '▸';\n flex: none;\n font-size: 11px;\n color: var(--dsw-alias-label-tertiary);\n transition: transform 0.15s ease;\n}\n\n.ss-collapse[open] > .ss-collapseHead::before {\n transform: rotate(90deg);\n}\n\n.ss-collapseHead:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, 0.06));\n}\n\n.ss-collapseTitle {\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.ss-collapseDesc {\n font-size: 12px;\n color: var(--dsw-alias-label-tertiary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n\n.ss-collapseBody {\n padding: 10px 14px 14px;\n border-top: 1px solid var(--dsw-alias-border-l1);\n}\n\n/* ── 开关 + 端口内联行 ── */\n.ss-switchRow {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* ── v1.27.6 「?」帮助浮层(hover/焦点显示三行以上严谨说明)── */\n.ss-help {\n position: relative;\n display: inline-flex;\n align-items: center;\n margin-top: 2px;\n}\n\n.ss-helpMark {\n flex: none;\n width: 16px;\n height: 16px;\n padding: 0;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 50%;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-tertiary);\n font-size: 10px;\n line-height: 1;\n font-weight: 600;\n cursor: help;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s ease, color 0.15s ease;\n}\n\n.ss-helpMark:hover,\n.ss-helpMark:focus-visible {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n outline: none;\n}\n\n.ss-helpTip {\n position: absolute;\n left: 0;\n top: calc(100% + 6px);\n z-index: 30;\n width: 300px;\n max-width: 60vw;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-alias-bg-overlay);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);\n font-size: 12px;\n line-height: 19px;\n font-weight: 400;\n color: var(--dsw-alias-label-primary);\n white-space: pre-line;\n word-break: break-word;\n opacity: 0;\n pointer-events: none;\n transform: translateY(-4px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n}\n\n.ss-help:hover .ss-helpTip,\n.ss-helpMark:focus-visible + .ss-helpTip {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0);\n}\n\n/* 折叠组内帮助浮层定位修正(左侧行卡不会溢出面板) */\n.ss-rowCard .ss-helpTip {\n left: 0;\n}\n\n/* ── 微信桥(F4c-3,v1.27.0 实验性)── */\n\n/* CCC 选择器(下拉) */\n.ss-select {\n max-width: 280px;\n padding: 6px 8px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* 扫码绑定按钮(复用 wakeBtn 语言) */\n.ss-loginBtn {\n flex: none;\n padding: 5px 12px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-loginBtn:hover:not(:disabled) {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.ss-loginBtn:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 移除账号按钮(危险语义:红边框) */\n.ss-removeBtn {\n flex: none;\n padding: 5px 12px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-removeBtn:hover:not(:disabled) {\n border-color: var(--dsw-alias-state-error-primary, #ef4444);\n color: var(--dsw-alias-state-error-primary, #ef4444);\n}\n\n/* 二维码展示行 */\n.ss-qrRow {\n align-items: center;\n}\n\n.ss-qrSvg {\n flex: none;\n width: 120px; /* v1.27.5 紧凑化:160 → 120 */\n height: 120px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: #fff; /* 二维码需要白底才能被微信扫出 */\n padding: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.ss-qrSvg svg {\n width: 100%;\n height: 100%;\n}\n\n/* 飞书凭据表单(P4):三格竖排——appId / appSecret / 账号名。\n * 🔴 不做成一行三格:App Secret 通常 32 位,窄屏下会被压到看不见自己输了什么\n * (本文件 D152 记过同族:定宽 + 无断点会把值压到标签上)。竖排在小屏也保持可读。 */\n.ss-feishuForm {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 6px;\n}\n\n.ss-feishuForm .ss-input {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n}\n\n.ss-feishuForm .ss-input::placeholder {\n color: var(--dsw-alias-label-secondary);\n}\n\n/* 渠道二选一(owner 2026-10-21:「不对称,交互上要体现二选一」)。\n * 判据:**选中态必须一眼可见**(描边 + 文字色),因为这两个按钮的\"当前只有一个成立\"\n * 是这条交互的全部语义;没有选中态就退化成两个普通按钮,等于没做二选一。 */\n.ss-channelPicker {\n display: flex;\n gap: 6px;\n margin: 8px 0 0;\n}\n\n.ss-channelOption {\n flex: none;\n padding: 5px 14px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n line-height: 18px;\n font-weight: 500;\n cursor: pointer;\n transition: opacity var(--ds-transition-duration-fast, 0.15s) ease;\n}\n\n.ss-channelOption:hover {\n color: var(--dsw-alias-label-primary);\n}\n\n.ss-channelOptionOn {\n border-color: var(--dsw-alias-state-success-primary, #22c55e);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.12));\n}\n\n/* 渠道展开区:微信是「一行说明 + 按钮」,飞书是「竖排表单 + 按钮」 */\n.ss-channelBody {\n display: flex;\n align-items: center;\n gap: 12px;\n justify-content: space-between;\n margin-top: 8px;\n padding: 10px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.ss-channelBodyCol {\n flex-direction: column;\n align-items: stretch;\n}\n\n.ss-channelActions {\n display: flex;\n justify-content: flex-end;\n}\n\n/* 路由表 JSON 编辑框 */\n.ss-routesEditor {\n width: 100%;\n box-sizing: border-box;\n margin-top: 6px;\n padding: 8px 10px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 18px;\n font-family: var(--ds-font-family-code);\n resize: vertical;\n}\n\n/* ── 窄屏(面板被塞进窄栏或手机浏览器)────────────────────────────────────\n * 排版问题只有一个根因:`.ss-rowCard` 是「左文本 + 右控件」的两列 flex,\n * 而控件里有端口输入(96px)/开关(40px)/端口+开关(150px)三档。\n * 窄到放不下时,flex 会先压文字(`min-width: 0` 已开)⇒ 标题被挤成一列竖排字。\n * 处理:窄屏把控件落到第二行(左对齐),文字保住整行宽。 */\n@media (max-width: 560px) {\n .ss-rowCard {\n flex-wrap: wrap;\n gap: 10px;\n }\n\n .ss-rowControl {\n flex-basis: 100%;\n justify-content: flex-start;\n }\n\n /* 行内说明在窄屏不必截断:整行宽足够,截断反而藏信息 */\n .ss-rowDesc {\n -webkit-line-clamp: unset;\n display: block;\n }\n\n /* 详情区与折叠头在窄屏收紧内边距(横向像素更值钱) */\n .ss-rowDetail,\n .ss-collapseBody {\n padding-left: 0;\n padding-right: 0;\n }\n}\n";
4390
4445
  if (typeof document !== "undefined" && document.querySelector("style[data-sp-css=\"SettingsSection\"]") === null) {
4391
4446
  const tag = document.createElement("style");
4392
4447
  tag.setAttribute("data-sp-css", "SettingsSection");
package/lib/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { i as __toESM, n as __exportAll } from "./rolldown-runtime-B4iAMlE-.js";
2
- import { c as hostInjected, d as hostSessions, f as hostSettings, h as hostWebServer, i as cccRootForExec, l as hostLlm, m as hostWeb, n as agentCwdFor, o as listCccs, p as hostSubagents, r as cccRootForCwd, s as hostAgents, t as NO_CCC_FROM_AGENT_CWD, u as hostService } from "./ccc-roots-4LwGLCXa.js";
2
+ import { c as hostInjected, d as hostSessions, f as hostSettings, h as hostWebServer, i as cccRootForExec, l as hostLlm, m as hostWeb, n as agentCwdFor, o as listCccs, p as hostSubagents, r as cccRootForCwd, s as hostAgents, t as NO_CCC_FROM_AGENT_CWD, u as hostService } from "./ccc-roots-VCJ3aYJA.js";
3
3
  import { _ as resolveInside, a as findSerenityRoot$1, c as matchBlacklist, d as readCccName$1, f as readCheapWorkerConfig, h as readSafeModeHiddenTools, i as findGitRoot, l as pathInside, m as readExclusiveTools, n as SAFE_MODE_MARKER, o as isSafeModeOn, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-CyYJL4F2.js";
4
- import { A as sessionEvents, B as isoLocal, C as listSessions, E as parseTrajectoryCode, F as trajectoryDescOf, H as localHuman, I as useSession, L as TRAJECTORY_FILENAME, M as setActiveSessionInfo, N as showSession, O as readTrajectoryUid, P as summarize, R as TRAJECTORY_LEGACY_FILENAMES, S as listActiveTrajectories, T as parseSessionContextFromEvents, U as localIdStamp, V as localFileStamp, _ as createSession, a as readTrajectoryConstraintAt, b as getActiveSessionInfo, c as trajectoryConstraintForSession, f as COGNITIVE_TRAJECTORY_ACTIONS, g as clearActiveSessionInfo, h as archiveSession, j as sessionsRoot, k as resolveSessionByTitle, m as UID_FILENAME, n as isTrajectoryConstrained, o as readTrajectoryConstraintByCode, r as listTrajectoryConstraints, s as replacesDefaultIdentity, t as TRAJECTORY_CONSTRAINT_FILENAME, v as extractSessionMdPathFromText, w as namingTitleFor, y as findSession, z as readTrajectoryFile } from "./profile-CiRWh2a2.js";
4
+ import { A as sessionEvents, B as isoLocal, C as listSessions, E as parseTrajectoryCode, F as trajectoryDescOf, H as localHuman, I as useSession, L as TRAJECTORY_FILENAME, M as setActiveSessionInfo, N as showSession, O as readTrajectoryUid, P as summarize, R as TRAJECTORY_LEGACY_FILENAMES, S as listActiveTrajectories, T as parseSessionContextFromEvents, U as localIdStamp, V as localFileStamp, _ as createSession, a as readTrajectoryConstraintAt, b as getActiveSessionInfo, c as trajectoryConstraintForSession, f as COGNITIVE_TRAJECTORY_ACTIONS, g as clearActiveSessionInfo, h as archiveSession, j as sessionsRoot, k as resolveSessionByTitle, m as UID_FILENAME, n as isTrajectoryConstrained, o as readTrajectoryConstraintByCode, r as listTrajectoryConstraints, s as replacesDefaultIdentity, t as TRAJECTORY_CONSTRAINT_FILENAME, v as extractSessionMdPathFromText, w as namingTitleFor, y as findSession, z as readTrajectoryFile } from "./profile-DnLSb7yv.js";
5
5
  import { n as checkLocalstoreGitCompliance, o as readStore, s as runLocalStore, t as LOCALSTORE_SCOPES } from "./service-DDmHSglV.js";
6
- import { _ as resolveConstraintSystemPrompt, a as listBoundSessionIds, d as constraintCognitiveTrajectory, f as constraintSystemPromptSource, g as profileWriteWhitelist, h as profileToolWhitelist, i as carrierState, l as TRAJECTORY_CONSTRAINT_HINT, n as PLUGIN_SOURCE, o as readLastBound, r as appendBound, s as resolveSessionCognitiveTrajectoryLabel, t as ACC_MESSAGE_KIND, v as ACC_VERSION, y as findPackageRoot } from "./message-source-CfqdGIi2.js";
7
- import { A as buildResourceIndex, C as verifyPassword, D as recordToolUsage, E as verifyTotpCode, F as hasTrajectoryPrompt, M as isSafeSkillName, N as truncateContent, O as REFERENCE_DIR, P as TRAJECTORY_PROMPT_FILENAME, S as toWire, T as MECHANISM_PORTS, _ as registerEntrySkillSectionGlobal, a as trajectoryConstraintFor, b as projectKnownWorkspaces, c as trajectoryWorkspaceMdPath, d as CHEAP_WORKER_GUIDE, f as providerAvailabilityError, g as registerEntrySkillSection, h as registerCognitiveTrajectorySkillSection, i as getTrajectoryAgent, j as buildResourceNameSuffix, k as SKILL_ONTOLOGY_FILE, l as unregisterTrajectorySession, m as splitModel, n as createTrajectoryAgent, o as trajectoryConstraintMsmGate, p as requireWhitelistedModel, r as ensureWorkspacePromptSection, s as trajectoryConstraintParticipates, t as askTrajectory, u as workspaceCognitiveTrajectoryLine, v as applyWirePatch, w as FACE_PORTS, x as readAdvancedSettings, y as migrateLegacyLocalstore } from "./session-BF4C3hJL.js";
6
+ import { _ as resolveConstraintSystemPrompt, a as listBoundSessionIds, d as constraintCognitiveTrajectory, f as constraintSystemPromptSource, g as profileWriteWhitelist, h as profileToolWhitelist, i as carrierState, l as TRAJECTORY_CONSTRAINT_HINT, n as PLUGIN_SOURCE, o as readLastBound, r as appendBound, s as resolveSessionCognitiveTrajectoryLabel, t as ACC_MESSAGE_KIND, v as ACC_VERSION, y as findPackageRoot } from "./message-source-D7dVNDIh.js";
7
+ import { A as buildResourceIndex, C as verifyPassword, D as recordToolUsage, E as verifyTotpCode, F as hasTrajectoryPrompt, M as isSafeSkillName, N as truncateContent, O as REFERENCE_DIR, P as TRAJECTORY_PROMPT_FILENAME, S as toWire, T as MECHANISM_PORTS, _ as registerEntrySkillSectionGlobal, a as trajectoryConstraintFor, b as projectKnownWorkspaces, c as trajectoryWorkspaceMdPath, d as CHEAP_WORKER_GUIDE, f as providerAvailabilityError, g as registerEntrySkillSection, h as registerCognitiveTrajectorySkillSection, i as getTrajectoryAgent, j as buildResourceNameSuffix, k as SKILL_ONTOLOGY_FILE, l as unregisterTrajectorySession, m as splitModel, n as createTrajectoryAgent, o as trajectoryConstraintMsmGate, p as requireWhitelistedModel, r as ensureWorkspacePromptSection, s as trajectoryConstraintParticipates, t as askTrajectory, u as workspaceCognitiveTrajectoryLine, v as applyWirePatch, w as FACE_PORTS, x as readAdvancedSettings, y as migrateLegacyLocalstore } from "./session-I6SM2GT6.js";
8
8
  import { n as hasSessionLogById, r as sessionsRootDir } from "./cleanup-C-92qnDs.js";
9
- import { n as readSimpleSettings, r as registerSettingsSection } from "./settings-Dj4_ppTC.js";
9
+ import { n as readSimpleSettings, r as registerSettingsSection } from "./settings-4ag1jtR0.js";
10
10
  import { REGISTERED_TOOLS } from "./invariant.js";
11
11
  import { a as readFeishuCredential, d as weixinSessionIdForTrajectory, i as matchWeixinRoute, l as sanitizeFileName$1, n as extractWeixinText, o as readWeixinCredential, r as hasVoiceItem, s as readWeixinSettings, t as extractWeixinMedia, u as weixinInboundDir } from "./route-Dr0SFD8A.js";
12
12
  import { c as sendTextMessage, i as getUpdates, l as sendTyping, n as downloadMedia, o as markdownToPlainText, r as getConfig, s as sendFileMessage, t as TypingStatus, u as sniffImageExt } from "./ilink-BMk2w2KY.js";
@@ -9346,7 +9346,8 @@ async function sendToCognitiveTrajectory(ctx, root, target, message, sender) {
9346
9346
  }],
9347
9347
  source: PLUGIN_SOURCE
9348
9348
  });
9349
- if (agent.status === "idle") {
9349
+ const freshCarrier = createdNote !== "";
9350
+ if (freshCarrier || agent.status === "idle") {
9350
9351
  try {
9351
9352
  agent.followup(make());
9352
9353
  } catch (err) {
@@ -9357,7 +9358,7 @@ async function sendToCognitiveTrajectory(ctx, root, target, message, sender) {
9357
9358
  }
9358
9359
  return {
9359
9360
  ok: true,
9360
- detail: `已即时投递 ${t.dirName}(${acquired.how};目标空闲 ⇒ followup 立即起轮)${createdNote}`
9361
+ detail: `已即时投递 ${t.dirName}(${acquired.how};${freshCarrier ? "刚建的载体 ⇒ followup 排队,锚定先于任务" : "目标空闲 ⇒ followup 立即起轮"})${createdNote}`
9361
9362
  };
9362
9363
  }
9363
9364
  try {
@@ -14189,7 +14190,7 @@ function registerStatusApi(ctx, opts = {}) {
14189
14190
  });
14190
14191
  }
14191
14192
  const { saveWeixinRoutes } = await import("./route-Dr0SFD8A.js").then((n) => n.c);
14192
- const { findDirNameByCode } = await import("./profile-CiRWh2a2.js").then((n) => n.i);
14193
+ const { findDirNameByCode } = await import("./profile-DnLSb7yv.js").then((n) => n.i);
14193
14194
  for (const r of routes) if (findDirNameByCode(root, r.trajectory) === null) {
14194
14195
  sendJson$2(res, 400, { error: `unknown trajectory: ${r.trajectory} (no such trajectory code in ${root})` });
14195
14196
  return;
@@ -19228,7 +19229,7 @@ const MEDIA_MAX_BYTES = 20971520;
19228
19229
  */
19229
19230
  async function resolveCccRootByAlias(ctx, alias) {
19230
19231
  try {
19231
- const { listCccs } = await import("./ccc-roots-4LwGLCXa.js").then((n) => n.a);
19232
+ const { listCccs } = await import("./ccc-roots-VCJ3aYJA.js").then((n) => n.a);
19232
19233
  const entries = await listCccs(ctx);
19233
19234
  const byName = entries.find((e) => e.name === alias);
19234
19235
  if (byName) return byName.root;
@@ -19296,7 +19297,7 @@ async function resolveInboundTarget(ctx, input) {
19296
19297
  });
19297
19298
  return null;
19298
19299
  }
19299
- const { findDirNameByCode } = await import("./profile-CiRWh2a2.js").then((n) => n.i);
19300
+ const { findDirNameByCode } = await import("./profile-DnLSb7yv.js").then((n) => n.i);
19300
19301
  if (findDirNameByCode(root, target.role) === null) {
19301
19302
  const detail = `目标 CCC "${target.ccc}" 内没有编码为 "${target.role}" 的认知轨迹`;
19302
19303
  console.error(`[serenity-hooks] ✗ human-channel: ${detail}(account=${input.account} user=${input.user})—— 该消息**未投递**,请改订阅表里的目标编码`);
@@ -20246,7 +20247,7 @@ function syncHumanChannel(ctx) {
20246
20247
  (async () => {
20247
20248
  try {
20248
20249
  stopMachineLoops();
20249
- const { listCccs } = await import("./ccc-roots-4LwGLCXa.js").then((n) => n.a);
20250
+ const { listCccs } = await import("./ccc-roots-VCJ3aYJA.js").then((n) => n.a);
20250
20251
  for (const entry of await listCccs(ctx)) syncCccBridge(ctx, entry.root);
20251
20252
  } catch {}
20252
20253
  })();
@@ -20537,7 +20538,7 @@ function matchCcc(input, candidates) {
20537
20538
  }
20538
20539
  /** 组装候选列表(`ccc-roots.listCccs` 投影 + `.serenity` 名;动态 import 保持本模块静态依赖轻量) */
20539
20540
  async function collectCandidates(ctx) {
20540
- const { listCccs } = await import("./ccc-roots-4LwGLCXa.js").then((n) => n.a);
20541
+ const { listCccs } = await import("./ccc-roots-VCJ3aYJA.js").then((n) => n.a);
20541
20542
  const entries = await listCccs(ctx, { defaultRoot: process.cwd() });
20542
20543
  const seen = /* @__PURE__ */ new Set();
20543
20544
  const out = [];
@@ -1,6 +1,6 @@
1
- import { r as cccRootForCwd } from "./ccc-roots-4LwGLCXa.js";
1
+ import { r as cccRootForCwd } from "./ccc-roots-VCJ3aYJA.js";
2
2
  import { _ as resolveInside, g as readUtf8 } from "./ccc-CyYJL4F2.js";
3
- import { A as sessionEvents, E as parseTrajectoryCode, b as getActiveSessionInfo, j as sessionsRoot, x as getLastActiveSessionInfo } from "./profile-CiRWh2a2.js";
3
+ import { A as sessionEvents, E as parseTrajectoryCode, b as getActiveSessionInfo, j as sessionsRoot, x as getLastActiveSessionInfo } from "./profile-DnLSb7yv.js";
4
4
  import { dirname, join } from "node:path";
5
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
6
6
  import { fileURLToPath } from "node:url";
@@ -501,12 +501,16 @@ function findSession(sessionsDir, key) {
501
501
  const all = readAllSessions(sessionsDir);
502
502
  const byName = all.find((s) => s.dirName === key);
503
503
  if (byName) return byName;
504
- const byCode = all.find((s) => parseTrajectoryCode(s.dirName) === key);
504
+ const byCodeHits = all.filter((s) => parseTrajectoryCode(s.dirName) === key);
505
+ if (byCodeHits.length > 1) throw new Error(`编码「${key}」在本 CCC 有 ${byCodeHits.length} 条轨迹同时占用,无法确定要操作哪一条:\n` + byCodeHits.map((s) => ` · ${s.dirName}`).join("\n") + "\n认知轨迹的编码是**终身身份**(AXIOM 3),重码意味着历史存量有问题 —— ⛔ 不会替你任选其一。\n⇒ 改用**完整目录名**指定(上列任一)。");
506
+ const byCode = byCodeHits[0];
505
507
  if (byCode) return byCode;
506
508
  const padded = key.match(/^S(\d{1,})$/);
507
509
  if (padded) {
508
510
  const want = `S${padded[1].padStart(3, "0")}`;
509
- const byPadded = all.find((s) => parseTrajectoryCode(s.dirName) === want);
511
+ const byPaddedHits = all.filter((s) => parseTrajectoryCode(s.dirName) === want);
512
+ if (byPaddedHits.length > 1) throw new Error(`编码「${want}」(由「${key}」补零而来)有 ${byPaddedHits.length} 条轨迹同时占用,无法确定:\n` + byPaddedHits.map((s) => ` · ${s.dirName}`).join("\n") + "\n⇒ 改用**完整目录名**指定。");
513
+ const byPadded = byPaddedHits[0];
510
514
  if (byPadded) return byPadded;
511
515
  }
512
516
  const byUid = all.find((s) => readTrajectoryUid(s.path) === key);
@@ -576,7 +580,12 @@ function createSession(opts) {
576
580
  }
577
581
  if (issue) {
578
582
  if (issue.length > 100) throw new Error(`issue too long: ${issue.length} chars (max 100)`);
579
- const dirName = `${datePrefix}--${sanitizeDirName(issue)}`;
583
+ const issueCode = sanitizeDirName(issue);
584
+ if (!isValidTrajectoryCode(issueCode)) throw new Error(`issue「${issue}」会被当成本轨迹的**编码**(目录名 = 日期--<编码>),但它不是合法编码:允许 [A-Za-z0-9._-]、首字符须字母或数字、长度 ≤64,且不得含中文与 "--"。`);
585
+ const issueDup = findCodeCollision(sessionsDir, issueCode);
586
+ if (issueDup !== null) throw new Error(`issue「${issue}」会被当成本轨迹的**编码**,而它已被占用:${issueDup}\n认知轨迹的编码是**终身身份**(AXIOM 3),归档不会释放它。
587
+ ⇒ 换一个工单号,或用 \`create --desc … --id <新码>\` 显式指定。`);
588
+ const dirName = `${datePrefix}--${issueCode}`;
580
589
  const sessionPath = join(sessionsDir, dirName);
581
590
  if (!dryRun && existsSync(sessionPath)) throw new Error(`Session directory already exists: "${dirName}"`);
582
591
  if (dryRun) return {
@@ -1137,8 +1146,10 @@ function listTrajectoryConstraints(root) {
1137
1146
  * 静默投到一条相近的轨迹上——那正是最难查的一类串味。
1138
1147
  */
1139
1148
  function findDirNameByCode(root, code) {
1140
- for (const name of activeTrajectoryDirNames(root)) if (parseTrajectoryCode(name) === code) return name;
1141
- return null;
1149
+ const hits = [];
1150
+ for (const name of activeTrajectoryDirNames(root)) if (parseTrajectoryCode(name) === code) hits.push(name);
1151
+ if (hits.length > 1) throw new Error(`编码「${code}」在本 CCC 有 ${hits.length} 条轨迹同时占用,无法确定要施加到哪一条:\n` + hits.map((n) => ` · ${n}`).join("\n") + "\n编码是终身身份(AXIOM 3)⇒ 不替你任选其一。改用**完整目录名**指定。");
1152
+ return hits[0] ?? null;
1142
1153
  }
1143
1154
  /**
1144
1155
  * **会话级**判据(J2):这个 dsh 会话是不是 轨迹约束会话 —— 唯一入口。
@@ -1,8 +1,8 @@
1
- import { n as agentCwdFor, r as cccRootForCwd, s as hostAgents } from "./ccc-roots-4LwGLCXa.js";
1
+ import { n as agentCwdFor, r as cccRootForCwd, s as hostAgents } from "./ccc-roots-VCJ3aYJA.js";
2
2
  import { g as readUtf8, o as isSafeModeOn, p as readCognitiveTrajectorySkills, u as readBlacklist } from "./ccc-CyYJL4F2.js";
3
- import { B as isoLocal, D as readActiveSessionMd, a as readTrajectoryConstraintAt, c as trajectoryConstraintForSession, d as unregisterTrajectorySession$1, j as sessionsRoot, l as registerTrajectorySession$1, p as DEFAULT_SESSION_SCOPE, u as trajectoryDirNameForSession } from "./profile-CiRWh2a2.js";
3
+ import { B as isoLocal, D as readActiveSessionMd, a as readTrajectoryConstraintAt, c as trajectoryConstraintForSession, d as unregisterTrajectorySession$1, j as sessionsRoot, l as registerTrajectorySession$1, p as DEFAULT_SESSION_SCOPE, u as trajectoryDirNameForSession } from "./profile-DnLSb7yv.js";
4
4
  import { a as readGitTrack, i as localstorePath } from "./service-DDmHSglV.js";
5
- import { d as constraintCognitiveTrajectory, m as profileMsmWhitelist, n as PLUGIN_SOURCE, o as readLastBound, p as createProfilePromptReader, u as buildTrajectoryBasePrompt, v as ACC_VERSION } from "./message-source-CfqdGIi2.js";
5
+ import { d as constraintCognitiveTrajectory, m as profileMsmWhitelist, n as PLUGIN_SOURCE, o as readLastBound, p as createProfilePromptReader, u as buildTrajectoryBasePrompt, v as ACC_VERSION } from "./message-source-D7dVNDIh.js";
6
6
  import { basename, dirname, join, resolve } from "node:path";
7
7
  import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
8
8
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
@@ -1,4 +1,4 @@
1
- import { f as hostSettings } from "./ccc-roots-4LwGLCXa.js";
1
+ import { f as hostSettings } from "./ccc-roots-VCJ3aYJA.js";
2
2
  //#region src/surface/settings.ts
3
3
  /**
4
4
  * 设置面板命名空间 = **profile 条目 id**(v0.1.7 起;与旧 `settings.yaml` 段名逐字相同)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.84.0",
3
+ "version": "1.85.0",
4
4
  "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档)。",
5
5
  "license": "MIT",
6
6
  "repository": {