@shgroup/dsh-serenity-hooks 1.71.0 → 1.73.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 +2 -2
- package/lib/{ccc-Dkoa2oW3.js → ccc-CZUOq3NY.js} +1 -1
- package/lib/{ccc-roots-jZYR2GVE.js → ccc-roots-BhoA7G-0.js} +3 -3
- package/lib/client.js +50 -58
- package/lib/{wake/cro.d.ts → cro/core.d.ts} +2 -2
- package/lib/{wake/cro-guide.d.ts → cro/guide.d.ts} +3 -3
- package/lib/{wake/cro-log.d.ts → cro/log.d.ts} +2 -2
- package/lib/{wake/cro-turns.d.ts → cro/turns.d.ts} +2 -2
- package/lib/guard/seam.d.ts +1 -1
- package/lib/{ilink-DEpmE3yi.js → ilink-BMk2w2KY.js} +1 -1
- package/lib/im/accounts.d.ts +105 -0
- package/lib/im/bridge.d.ts +33 -62
- package/lib/im/endpoint.d.ts +1 -1
- package/lib/im/feishu-account.d.ts +92 -0
- package/lib/im/inbound-event.d.ts +162 -0
- package/lib/im/route.d.ts +37 -2
- package/lib/im/weixin-account.d.ts +45 -0
- package/lib/index.d.ts +0 -22
- package/lib/index.js +1070 -996
- package/lib/kernel/ccc.d.ts +78 -2
- package/lib/kernel/ports.d.ts +2 -4
- package/lib/lib-TxscFKeo.js +119355 -0
- package/lib/{message-source-kVoNK0C5.js → message-source-ChyVfev9.js} +2 -2
- package/lib/{profile-DyMJ_bfr.js → profile-BIQ2widI.js} +14 -11
- package/lib/rolldown-runtime-B4iAMlE-.js +35 -0
- package/lib/{route-CPneN5iv.js → route-ItCgAsnz.js} +96 -35
- package/lib/seams/guards.d.ts +1 -1
- package/lib/seams/system-prompt.d.ts +3 -1
- package/lib/{settings-lt1i3OZv.js → settings-UcwIPJhM.js} +13 -62
- package/lib/skills/resource-index.d.ts +1 -1
- package/lib/surface/settings.d.ts +0 -6
- package/lib/surface/text.d.ts +72 -0
- package/lib/surface/usage.d.ts +2 -2
- package/lib/{role/worker/idle.d.ts → trajectory/carrier.d.ts} +12 -2
- package/lib/{role/worker → trajectory/delegate}/core.d.ts +7 -1
- package/lib/{role/worker → trajectory/delegate}/preset.d.ts +9 -2
- package/lib/{role/skiff → trajectory/policy}/profile.d.ts +9 -2
- package/lib/{role/skiff/config.d.ts → trajectory/policy/rules.d.ts} +9 -3
- package/lib/{role/skiff/registry.d.ts → trajectory/policy/window.d.ts} +7 -1
- package/lib/trajectory/prompt.d.ts +101 -0
- package/lib/{role/skiff/core.d.ts → trajectory/session.d.ts} +13 -4
- package/package.json +3 -2
- package/lib/role/skiff/debug.d.ts +0 -88
- package/lib/rolldown-runtime-8H4AJuhK.js +0 -14
package/dsh.plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.73.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
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 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/微信桥/认知轨迹唤醒注册表。skiff = 目录下有 skiff.json
|
|
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 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/微信桥/认知轨迹唤醒注册表。skiff = 目录下有 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": {
|
|
7
7
|
"dsh": ">=0.1.7-rc.1"
|
|
8
8
|
},
|
|
@@ -80,7 +80,7 @@ function readCccName(root) {
|
|
|
80
80
|
* 🔴 **`SkiffRoleConfig` 已于 2026-10-19 退役**(owner 重做令)。
|
|
81
81
|
*
|
|
82
82
|
* 它的语义整体搬进**轨迹目录下的 `skiff.json`**,类型现在是
|
|
83
|
-
* `
|
|
83
|
+
* `trajectory/policy/profile.ts` 的 `SkiffProfile`(在那里还多了 `code`/`dirName`/`path`
|
|
84
84
|
* 三个与轨迹身份相关的字段)。
|
|
85
85
|
*
|
|
86
86
|
* 退役理由(一句话):skiff 的约束面是**某一条轨迹的属性**,不是容器级配置表里的一个 entry。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as findSerenityRoot } from "./ccc-
|
|
1
|
+
import { n as __exportAll } from "./rolldown-runtime-B4iAMlE-.js";
|
|
2
|
+
import { a as findSerenityRoot } from "./ccc-CZUOq3NY.js";
|
|
3
3
|
import { basename } from "node:path";
|
|
4
4
|
//#region src/host/access.ts
|
|
5
5
|
/**
|
|
@@ -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 { listSkiffProfiles } = await import("./profile-
|
|
230
|
+
const { listSkiffProfiles } = await import("./profile-BIQ2widI.js").then((n) => n.i);
|
|
231
231
|
rolesOf = (root) => {
|
|
232
232
|
try {
|
|
233
233
|
return listSkiffProfiles(root).map((p) => p.code);
|
package/lib/client.js
CHANGED
|
@@ -3751,16 +3751,26 @@ Instruction-following style:
|
|
|
3751
3751
|
});
|
|
3752
3752
|
}
|
|
3753
3753
|
//#endregion
|
|
3754
|
-
//#region src/client/
|
|
3754
|
+
//#region src/client/ImBridgeEditor.tsx
|
|
3755
3755
|
/**
|
|
3756
|
-
*
|
|
3756
|
+
* ImBridgeEditor.tsx — 「IM 桥」配置区块(原 `WeixinBridgeEditor`,2026-10-19 泛化)
|
|
3757
3757
|
*
|
|
3758
|
-
*
|
|
3758
|
+
* ## 为什么改名 + 泛化(R↓,这不是"改个标题")
|
|
3759
|
+
*
|
|
3760
|
+
* P2 起「微信」与「飞书」是**并列的账号实现**:装配处只认 `account.channel`
|
|
3761
|
+
* (`im/accounts.ts` 的派发表),而账号、路由、会话**全部与渠道无关**。
|
|
3762
|
+
* ⇒ 面板属于"设定账号"这一层,标题若仍叫「微信桥」,第二家 IM 一接上就开始说谎
|
|
3763
|
+
* (**正是 D151 记过的那类失效:引用与口径随别的功能演进失效,且零机械信号**)。
|
|
3764
|
+
*
|
|
3765
|
+
* ⚠️ **扫码绑定是微信独有形态**;飞书走**凭据表单**(appId/appSecret)。
|
|
3766
|
+
* 二者在同一个「IM 桥」块里按账号行的 `channel` 分列。
|
|
3767
|
+
* 判据:**面板不是判据**(施工图 P4 原文),它只负责把统一配置显示出来并可写。
|
|
3768
|
+
*
|
|
3769
|
+
* **CCC 级配置**(S142 用户拍板:dsh 一个进程含多个 CCC,每个 CCC 独立对接 IM 桥):
|
|
3759
3770
|
* - 顶部 **CCC 选择器**(数据源 /serenity/cccs——listCccs 复用)——显式选择配置目标,
|
|
3760
|
-
* 不隐式依赖"当前活跃会话"(WebUI
|
|
3761
|
-
* - 选中 CCC 后:总开关 /
|
|
3762
|
-
* -
|
|
3763
|
-
* → 轮询 /serenity/weixin/login → confirmed 自动写凭据 + 账号元信息
|
|
3771
|
+
* 不隐式依赖"当前活跃会话"(WebUI 顶层全局,IM 桥是配置写入必须显式)
|
|
3772
|
+
* - 选中 CCC 后:总开关 / 账号列表 / 路由表(user → 轨迹编码)
|
|
3773
|
+
* - 扫码绑定(**微信专用**):POST login-start → qrcode-generator 生成二维码 SVG
|
|
3764
3774
|
*
|
|
3765
3775
|
* 全部端点带显式 ccc 参数 + x-serenity-ui 头(服务端校验)。
|
|
3766
3776
|
*/
|
|
@@ -3775,9 +3785,16 @@ Instruction-following style:
|
|
|
3775
3785
|
scalable: true
|
|
3776
3786
|
});
|
|
3777
3787
|
}
|
|
3788
|
+
/** 账号渠道的显示名(未登记的新渠道原样显示,不猜) */
|
|
3789
|
+
function channelLabel(channel) {
|
|
3790
|
+
const c = (channel ?? "weixin").trim() || "weixin";
|
|
3791
|
+
if (c === "weixin") return "微信";
|
|
3792
|
+
if (c === "feishu") return "飞书";
|
|
3793
|
+
return c;
|
|
3794
|
+
}
|
|
3778
3795
|
/** 当前工作区 CCC(默认选择器初值:settings 面板无 workspace 参数——服务端 /serenity/weixin 显式 ccc;
|
|
3779
3796
|
* 选择器默认选第一个;用户手选) */
|
|
3780
|
-
function
|
|
3797
|
+
function ImBridgeEditor() {
|
|
3781
3798
|
const [cccs, setCccs] = (0, react.useState)([]);
|
|
3782
3799
|
const [selectedRoot, setSelectedRoot] = (0, react.useState)("");
|
|
3783
3800
|
const [status, setStatus] = (0, react.useState)(null);
|
|
@@ -4018,7 +4035,7 @@ Instruction-following style:
|
|
|
4018
4035
|
}),
|
|
4019
4036
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4020
4037
|
className: "ss-rowDesc",
|
|
4021
|
-
children: "
|
|
4038
|
+
children: "选择要配置 IM 桥的认知容器"
|
|
4022
4039
|
}),
|
|
4023
4040
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4024
4041
|
className: "ss-help",
|
|
@@ -4029,7 +4046,7 @@ Instruction-following style:
|
|
|
4029
4046
|
children: "?"
|
|
4030
4047
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4031
4048
|
className: "ss-helpTip",
|
|
4032
|
-
children: "
|
|
4049
|
+
children: "IM 桥是 CCC 级配置。\n· 一个 dsh 进程可挂多个 CCC,各自独立对接 IM\n· 在这里显式选择目标,不跟随当前会话\n· 各 CCC 的账号、路由、开关互不影响\n· 切换后自动加载该 CCC 的配置"
|
|
4033
4050
|
})]
|
|
4034
4051
|
})
|
|
4035
4052
|
]
|
|
@@ -4078,18 +4095,18 @@ Instruction-following style:
|
|
|
4078
4095
|
}),
|
|
4079
4096
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4080
4097
|
className: "ss-rowDesc",
|
|
4081
|
-
children: status.accounts.length === 0 ? "
|
|
4098
|
+
children: status.accounts.length === 0 ? "未绑定账号——微信可扫码绑定,飞书填凭据" : status.accounts.map((a) => `${channelLabel(a.channel)}·${a.accountId}${a.bound ? "✓" : "✗"}`).join(" ")
|
|
4082
4099
|
}),
|
|
4083
4100
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4084
4101
|
className: "ss-help",
|
|
4085
4102
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4086
4103
|
type: "button",
|
|
4087
4104
|
className: "ss-helpMark",
|
|
4088
|
-
"aria-label": "
|
|
4105
|
+
"aria-label": "IM 桥总开关帮助",
|
|
4089
4106
|
children: "?"
|
|
4090
4107
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4091
4108
|
className: "ss-helpTip",
|
|
4092
|
-
children: "
|
|
4109
|
+
children: "IM 桥总开关。\n· 开启后该 CCC 开始收消息(每个账号各自一条连接)\n· 前置:至少一个已绑定凭据的账号\n· 每账号独立连接;✓ = 已绑定凭据,✗ = 未绑定\n· 关闭 = 停止全部连接,零资源占用"
|
|
4093
4110
|
})]
|
|
4094
4111
|
})
|
|
4095
4112
|
]
|
|
@@ -4111,7 +4128,14 @@ Instruction-following style:
|
|
|
4111
4128
|
className: "ss-rowText",
|
|
4112
4129
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4113
4130
|
className: "ss-rowName",
|
|
4114
|
-
children: [
|
|
4131
|
+
children: [
|
|
4132
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4133
|
+
className: "ss-channelTag",
|
|
4134
|
+
children: channelLabel(a.channel)
|
|
4135
|
+
}),
|
|
4136
|
+
a.accountId,
|
|
4137
|
+
a.name ? ` · ${a.name}` : ""
|
|
4138
|
+
]
|
|
4115
4139
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4116
4140
|
className: "ss-rowDesc",
|
|
4117
4141
|
children: [
|
|
@@ -4198,7 +4222,7 @@ Instruction-following style:
|
|
|
4198
4222
|
}),
|
|
4199
4223
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4200
4224
|
className: "ss-rowDesc",
|
|
4201
|
-
children: "
|
|
4225
|
+
children: "IM 用户 → 认知轨迹编码(`*` 通配兜底)"
|
|
4202
4226
|
}),
|
|
4203
4227
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4204
4228
|
className: "ss-help",
|
|
@@ -4209,7 +4233,7 @@ Instruction-following style:
|
|
|
4209
4233
|
children: "?"
|
|
4210
4234
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4211
4235
|
className: "ss-helpTip",
|
|
4212
|
-
children: "
|
|
4236
|
+
children: "路由表:IM 用户 → 认知轨迹编码映射。\n· 格式:[{\"user\": \"xxx@im.wechat\", \"trajectory\": \"my-code\"}, ...]\n· user = 该渠道的用户 ID(微信 from_user_id / 飞书 open_id);`*` = 通配兜底\n· trajectory = 该 CCC 里某条认知轨迹的**编码**(目录名里 `YYYY-MM-DD--<编码>` 那一段)\n· 未命中路由的用户不回复(不暴露机器人)"
|
|
4213
4237
|
})]
|
|
4214
4238
|
})
|
|
4215
4239
|
]
|
|
@@ -4238,7 +4262,7 @@ Instruction-following style:
|
|
|
4238
4262
|
children: "加载中…"
|
|
4239
4263
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4240
4264
|
className: "ss-rowDesc",
|
|
4241
|
-
children: "读取所选 CCC
|
|
4265
|
+
children: "读取所选 CCC 的 IM 桥配置"
|
|
4242
4266
|
})]
|
|
4243
4267
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "ss-rowControl" })]
|
|
4244
4268
|
}) })
|
|
@@ -4247,7 +4271,7 @@ Instruction-following style:
|
|
|
4247
4271
|
}
|
|
4248
4272
|
//#endregion
|
|
4249
4273
|
//#region \0sp-css:src/client/SettingsSection
|
|
4250
|
-
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/* 行卡说明(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/* 路由表 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";
|
|
4274
|
+
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/* 路由表 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";
|
|
4251
4275
|
if (typeof document !== "undefined" && document.querySelector("style[data-sp-css=\"SettingsSection\"]") === null) {
|
|
4252
4276
|
const tag = document.createElement("style");
|
|
4253
4277
|
tag.setAttribute("data-sp-css", "SettingsSection");
|
|
@@ -4382,18 +4406,12 @@ Instruction-following style:
|
|
|
4382
4406
|
const setThreshold = (v) => {
|
|
4383
4407
|
set("rebuildThresholdK", Math.min(4e3, Math.max(50, Math.round(v))));
|
|
4384
4408
|
};
|
|
4385
|
-
const setSkiffPort = (v) => {
|
|
4386
|
-
set("skiffDebugPort", Math.min(65535, Math.max(1024, Math.round(v))));
|
|
4387
|
-
};
|
|
4388
4409
|
const gatewayOn = value?.gatewayEnabled ?? false;
|
|
4389
4410
|
const thresholdK = value?.rebuildThresholdK ?? 400;
|
|
4390
|
-
const skiffOn = value?.skiffEnabled ?? false;
|
|
4391
|
-
const skiffPort = value?.skiffDebugPort ?? 3099;
|
|
4392
4411
|
const croOn = value?.croEnabled ?? true;
|
|
4393
4412
|
const diagramOn = value?.diagramEnabled ?? false;
|
|
4394
4413
|
const [openGateway, setOpenGateway] = (0, react.useState)(false);
|
|
4395
4414
|
const [openRebuild, setOpenRebuild] = (0, react.useState)(false);
|
|
4396
|
-
const [openSkiff, setOpenSkiff] = (0, react.useState)(false);
|
|
4397
4415
|
const [openCro, setOpenCro] = (0, react.useState)(false);
|
|
4398
4416
|
const [openDiagram, setOpenDiagram] = (0, react.useState)(false);
|
|
4399
4417
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -4432,7 +4450,7 @@ Instruction-following style:
|
|
|
4432
4450
|
title: "上下文",
|
|
4433
4451
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
4434
4452
|
title: "超限重建",
|
|
4435
|
-
desc: "上下文接近上限时提示调用
|
|
4453
|
+
desc: "上下文接近上限时提示调用 cognitive_trajectory rebuild 清空重建",
|
|
4436
4454
|
expandable: true,
|
|
4437
4455
|
open: openRebuild,
|
|
4438
4456
|
onToggle: setOpenRebuild,
|
|
@@ -4440,7 +4458,7 @@ Instruction-following style:
|
|
|
4440
4458
|
className: "ss-detailStack",
|
|
4441
4459
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4442
4460
|
className: "ss-detailIntro",
|
|
4443
|
-
children: "上下文占用到阈值时,由模型调用
|
|
4461
|
+
children: "上下文占用到阈值时,由模型调用 cognitive_trajectory rebuild 原地清空重建。\n· 语义:丢弃当前会话 → 新建 → 注入「继续原 SESSION 的工作」\n· SESSION.md 原位不动,轨迹延续,上下文归零\n· 恒开、无总闸;要调敏感度只改下面的阈值"
|
|
4444
4462
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
4445
4463
|
title: "重建阈值",
|
|
4446
4464
|
desc: "上下文占用到该值(K token,默认 400)时提示重建",
|
|
@@ -4459,35 +4477,9 @@ Instruction-following style:
|
|
|
4459
4477
|
})
|
|
4460
4478
|
}) })
|
|
4461
4479
|
}),
|
|
4462
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
4480
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Group, {
|
|
4463
4481
|
title: "外部能力",
|
|
4464
|
-
children:
|
|
4465
|
-
title: "Skiff 调试",
|
|
4466
|
-
desc: "Skiff 认知子集问答页(默认 3099,仅本机,实验性)",
|
|
4467
|
-
expandable: true,
|
|
4468
|
-
open: openSkiff,
|
|
4469
|
-
onToggle: setOpenSkiff,
|
|
4470
|
-
control: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4471
|
-
className: "ss-switchRow",
|
|
4472
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toggle, {
|
|
4473
|
-
checked: skiffOn,
|
|
4474
|
-
onChange: (on) => toggle("skiffEnabled", on)
|
|
4475
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4476
|
-
className: "ss-portInput",
|
|
4477
|
-
type: "number",
|
|
4478
|
-
min: 1024,
|
|
4479
|
-
max: 65535,
|
|
4480
|
-
value: skiffPort,
|
|
4481
|
-
disabled: !skiffOn,
|
|
4482
|
-
title: "Skiff 调试端口(默认 3099)",
|
|
4483
|
-
onChange: (e) => setSkiffPort(Number(e.target.value))
|
|
4484
|
-
})]
|
|
4485
|
-
}),
|
|
4486
|
-
detail: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4487
|
-
className: "ss-detailIntro",
|
|
4488
|
-
children: "Skiff 认知子集角色的问答页,仅监听 127.0.0.1。\n· Skiff = 完整轨迹的任意子集(认知子集角色)\n· 先在 CCC 的 skiff.roles 里配角色,再用此页以角色身份问答\n· 实验性,人工启停,默认关"
|
|
4489
|
-
})
|
|
4490
|
-
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
4482
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
4491
4483
|
title: "CRO(轨迹自编程唤起)",
|
|
4492
4484
|
desc: "让轨迹用自己的一段程序决定何时唤起(全局开关,默认开)",
|
|
4493
4485
|
expandable: true,
|
|
@@ -4504,7 +4496,7 @@ Instruction-following style:
|
|
|
4504
4496
|
children: "轨迹目录下放一个 continuous-re-occurrence.ts,调度器每 5 分钟跑它一次,由这段程序决定要不要唤、何时唤、唤的时候说什么。\n· 程序文件在即启用,不必在此配置;本开关只是总闸\n· 关掉只停 CRO 阶段:定时唤醒(send-later)、即时投递(send-now)与唤醒表投递照常\n· 没有程序文件的轨迹本来就不参与"
|
|
4505
4497
|
})
|
|
4506
4498
|
})
|
|
4507
|
-
}) })
|
|
4499
|
+
}) })
|
|
4508
4500
|
}),
|
|
4509
4501
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Group, {
|
|
4510
4502
|
title: "工具",
|
|
@@ -4533,9 +4525,9 @@ Instruction-following style:
|
|
|
4533
4525
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PersonaEditor, {})
|
|
4534
4526
|
}),
|
|
4535
4527
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapse, {
|
|
4536
|
-
title: "
|
|
4537
|
-
desc: "
|
|
4538
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4528
|
+
title: "IM 桥",
|
|
4529
|
+
desc: "绑定即时通讯账号 · 路由到认知轨迹(CCC 级配置)",
|
|
4530
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImBridgeEditor, {})
|
|
4539
4531
|
}),
|
|
4540
4532
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapse, {
|
|
4541
4533
|
title: "会话清理",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* cro/core.ts — CRO(Continuous Re-Occurrence · 持续再发生)机制层(S142 §7.8,2026-09-19)
|
|
3
3
|
*
|
|
4
4
|
* ## 这东西用来干什么(白话)
|
|
5
5
|
*
|
|
@@ -104,7 +104,7 @@ export interface CroSnapshot {
|
|
|
104
104
|
/**
|
|
105
105
|
* 🔴 其中**正在跑轮次**的(设计 §3.2 —— 本机制**唯一需要 ACC 新增的状态**)。
|
|
106
106
|
* ⚠️ `live ≠ 在跑`:一条会话可以 live 而空闲。
|
|
107
|
-
* 宿主没有现成的 turn 运行标志 ⇒ 由 `
|
|
107
|
+
* 宿主没有现成的 turn 运行标志 ⇒ 由 `cro/turns.ts` 用 `agent/session-start` +
|
|
108
108
|
* `agent/turn-stopping` 两个**既有契约事件**夹出来。
|
|
109
109
|
*/
|
|
110
110
|
runningSessionIds: string[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* cro/guide.ts — CRO 编写指南(**ACC 内置**,S142 §7.8,2026-09-19)
|
|
3
3
|
*
|
|
4
4
|
* ## 为什么指南在 ACC 而不在 CCC(所有者令)
|
|
5
5
|
*
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* 1. 🔴 **必须备注:CRO 程序是可自测的;测试通过再把文件名改成正式名**;
|
|
20
20
|
* 2. 🔴 **要一并给出测试用的参数**。
|
|
21
21
|
*/
|
|
22
|
-
import { type CroSnapshotInput } from './
|
|
22
|
+
import { type CroSnapshotInput } from './core.js';
|
|
23
23
|
/**
|
|
24
24
|
* 样例快照输入 —— **代表性数据**(不是真实某条轨迹的现状)。
|
|
25
25
|
*
|
|
@@ -36,7 +36,7 @@ export declare const CRO_SAMPLE_SNAPSHOT_INPUT: CroSnapshotInput;
|
|
|
36
36
|
*/
|
|
37
37
|
export declare function renderCroSampleSnapshot(): string;
|
|
38
38
|
/** 正式入口文件名(写死于此,供指南与实现共用同一常量来源) */
|
|
39
|
-
export { CRO_FILENAME, CRO_TIMEOUT_MS } from './
|
|
39
|
+
export { CRO_FILENAME, CRO_TIMEOUT_MS } from './core.js';
|
|
40
40
|
/**
|
|
41
41
|
* CRO 编写指南正文(ACC 内置手册;由工具的 guide 动作输出)。
|
|
42
42
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* cro/log.ts — CRO 唤起日志(**ACC 侧**,每轨迹一份固定名文件,2026-09-20 S142 §7.16)
|
|
3
3
|
*
|
|
4
4
|
* ## 所有者令(本模块的存在理由)
|
|
5
5
|
*
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* ⇒ 清理与写入**是同一笔操作** ⇒ **结构上不存在"忘了清"的可能**(比"另设一个每 tick 的清理步"更硬:
|
|
36
36
|
* 那多一个"可能忘了跑"的面)。窗宽是**常量**,**无配置键、无人工清理动作**。
|
|
37
37
|
*
|
|
38
|
-
* ## 🔴 铁律(与 `
|
|
38
|
+
* ## 🔴 铁律(与 `cro/core.ts` 同族)
|
|
39
39
|
*
|
|
40
40
|
* **本模块的每个导出函数都不抛错**:写盘 / 裁剪 / 解析失败一律返回结构化失败,
|
|
41
41
|
* 由调用方只记一行 tick 日志 ⇒ **CRO 流水的问题绝不影响投递与既有链路**(设计 §5)。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* cro/turns.ts — 「这条轨迹是否正在跑轮次」的追踪(设计 §3.2,2026-09-19 S142)
|
|
3
3
|
*
|
|
4
4
|
* ## 为什么需要这个模块(CRO 唯一需要 ACC 新增的状态)
|
|
5
5
|
*
|
|
@@ -94,7 +94,7 @@ export declare function __resetCroTurnsForTest(): void;
|
|
|
94
94
|
* 🔴 **本处顺带更正 §2.7 的一处分档**:本文件原被列在"剩余 3 个属**真依赖**档"里,
|
|
95
95
|
* 但**逐符号查证后与那个判断不符** ——
|
|
96
96
|
* · `Context`:`ctx` 只被**结构化访问**(原码本就写着 `ctx as unknown as { on: … }`)
|
|
97
|
-
* ⇒ 该注解未提供任何类型保证(与 `
|
|
97
|
+
* ⇒ 该注解未提供任何类型保证(与 `trajectory/carrier.ts` 同档)。
|
|
98
98
|
* · `Agent`:**导入后从未使用** —— 事件 payload 一律按 `{ agent?: unknown }` 解构,
|
|
99
99
|
* 再交给 `sessionIdOf(...)`(它收 `unknown`)。⇒ **纯粹是死 import**。
|
|
100
100
|
* ⇒ **判据(本件再证一次,且比上一件更硬)**:分档**必须逐符号看"它有没有参与类型检查"**,
|
package/lib/guard/seam.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* 🔴 **2026-10-15 补注(面 E 退役)**:`acp-` 前缀分支**已成孤儿,但本批不动**。
|
|
14
14
|
* 判据(两条,实测):① **该前缀从来没有生产者** —— 历史 `acp-core.ts` 建会话走的是
|
|
15
|
-
* `createSkiffAgent`,其 id = `` `skiff-${role}-${uuid}` ``(`
|
|
15
|
+
* `createSkiffAgent`,其 id = `` `skiff-${role}-${uuid}` ``(`trajectory/session.ts`)⇒ `acp-` **从不出现**;
|
|
16
16
|
* ② 面 E 退役后连"本可能产生它的模块"也不在了。⇒ 该分支是**恒 false 的死判据**。
|
|
17
17
|
* ⚠️ **仍不擅自删**:这是**运行时字符串比较**,删它属**行为变更**(不是纯清理),
|
|
18
18
|
* 依本轨既有先例(`cheap-worker-` 四处置孤儿,同族、同判据)⇒ **登记待裁**(见 S142 §当前状态「观察」)。
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* im/accounts.ts — **账号实现派发表**(P2,2026-10-19)
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么是"账号"这一层(owner 定向,逐字)
|
|
5
|
+
*
|
|
6
|
+
* > 「飞书继承可以很方便的加到当前的体系里,**和微信一样,只不过是 account 方实现不同**。
|
|
7
|
+
* > **要整合到统一的配置中**。」
|
|
8
|
+
*
|
|
9
|
+
* 微信与飞书的差别**只在账号侧**:怎么连、怎么收、怎么发。而它们的**身份、路由、会话**
|
|
10
|
+
* 从来就是通道无关的:
|
|
11
|
+
* - 路由表 = `user → 轨迹编码`(不认渠道)
|
|
12
|
+
* - 会话 id = `skiff-weixin-<轨迹编码>`(由轨迹决定,不认渠道)
|
|
13
|
+
* - 一账号一 poller 的归属判据 = `(root, accountId, identity)`(不含渠道概念)
|
|
14
|
+
*
|
|
15
|
+
* ⇒ 抽象点是 `account.channel`,**不是**新造一个平行的"通道接口"。
|
|
16
|
+
* 本文件的全部职责:**channel 字符串 → 那个实现**。
|
|
17
|
+
*
|
|
18
|
+
* ## 这不是新设计(源码里早就留了口)
|
|
19
|
+
*
|
|
20
|
+
* `bridge.ts` 的机器级装配处原本写着:
|
|
21
|
+
* *「只有已实现的渠道能起 poller(**P2 才加第二个实现**)⇒ 未实现的出声但不静默跳过」*
|
|
22
|
+
* 且账号行 `HumanChannelAccountSettings` **本来就有 `channel` 字段**。
|
|
23
|
+
* ⇒ 本文件就是把那个"P2 预留位"填上。
|
|
24
|
+
*
|
|
25
|
+
* ## 为什么用「注册表 + 未命中响亮」而不是 switch
|
|
26
|
+
*
|
|
27
|
+
* switch 会把"支持哪些渠道"写死在装配逻辑里;注册表让**新增一个渠道实现 = 新增一个文件
|
|
28
|
+
* + 一次 register**,装配处一行不改(R3 家族式扩展)。而未命中**必须出声**——
|
|
29
|
+
* 静默跳过会表现成"某个账号莫名其妙不工作",那是本轨反复踩过的一类最难查的故障。
|
|
30
|
+
*/
|
|
31
|
+
/** 一条账号的运行期凭据(各实现自解释;`weixin` 用 token/baseUrl/userId) */
|
|
32
|
+
export interface ImAccountCredential {
|
|
33
|
+
token?: string;
|
|
34
|
+
baseUrl?: string;
|
|
35
|
+
userId?: string;
|
|
36
|
+
/** 飞书等:appId(凭据本体仍在 localstore) */
|
|
37
|
+
appId?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 账号实现的**最小面**(只放装配处真正需要的东西)。
|
|
41
|
+
*
|
|
42
|
+
* 🔴 刻意**不**把"收消息"放进来:接收循环的形状(长轮询 vs WebSocket 回调)
|
|
43
|
+
* 两家根本不同,硬塞进一个签名只会让两边都别扭。装配处需要的是:
|
|
44
|
+
* ① 这个账号该不该起(凭据齐不齐)② 起起来 ③ 停 ④ 健康快照。
|
|
45
|
+
*/
|
|
46
|
+
export interface ImAccountImpl {
|
|
47
|
+
/** 实现名(= `account.channel` 的取值,如 `weixin`) */
|
|
48
|
+
readonly channel: string;
|
|
49
|
+
/**
|
|
50
|
+
* 凭据是否齐全到**可以起**(缺失 ⇒ 装配处跳过并出声,**不静默**)。
|
|
51
|
+
* @param cred 已从 localstore 读好的凭据(实现自己判断哪个字段必需)
|
|
52
|
+
*/
|
|
53
|
+
isReady(cred: ImAccountCredential): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* 凭据不全时**给人看的原因**(装配处的告警文案,可含 CC 特定措辞)。
|
|
56
|
+
* 缺省 ⇒ 装配处用通用文案。存在的理由:微信的文案是「无 token(未绑定)」,
|
|
57
|
+
* 那是有既有判据钉住的措辞(测试与排查手册都按它找),不该被本层统一措辞冲掉。
|
|
58
|
+
*/
|
|
59
|
+
notReadyReason?(cred: ImAccountCredential): string;
|
|
60
|
+
/**
|
|
61
|
+
* 起这条账号的接收循环(fire-and-forget:实现内部自行循环,不得阻塞装配)。
|
|
62
|
+
* @returns 该账号的循环控制对象(装配处用它做停止与快照)
|
|
63
|
+
*/
|
|
64
|
+
startLoop(input: ImAccountLoopInput): ImAccountLoop;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 起循环的输入。
|
|
68
|
+
*
|
|
69
|
+
* ⚠️ `root` 在**机器级模式**下是 `MACHINE_SCOPE` 哨兵(不是一个目录)——
|
|
70
|
+
* 这与既有语义一致(投到哪个 CCC 由**每条消息**的订阅表决定,不由账号决定)。
|
|
71
|
+
*/
|
|
72
|
+
export interface ImAccountLoopInput {
|
|
73
|
+
ctx: unknown;
|
|
74
|
+
root: string;
|
|
75
|
+
accountId: string;
|
|
76
|
+
cred: ImAccountCredential;
|
|
77
|
+
/** 真 = 机器级 poller(目标由订阅表逐条决定) */
|
|
78
|
+
machine: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 循环控制(装配处持有;`weixinBridgeStatus` 读它出健康快照)。
|
|
82
|
+
*
|
|
83
|
+
* 🔴 `lastPollAt` / `lastError` 是**面板读数面**的既有字段,名字不能改
|
|
84
|
+
* (`im-bridge status` 与设置面板都按这个形状读)。
|
|
85
|
+
*/
|
|
86
|
+
export interface ImAccountLoop {
|
|
87
|
+
stopped: boolean;
|
|
88
|
+
lastPollAt: number;
|
|
89
|
+
lastError?: string;
|
|
90
|
+
}
|
|
91
|
+
/** 注册账号实现(`index.ts` 装配时调用;重复 channel 覆盖——测试与热重载友好) */
|
|
92
|
+
export declare function registerImAccountImpl(impl: ImAccountImpl): void;
|
|
93
|
+
/** 取实现(未注册 ⇒ `null`,由调用方**响亮出声**,不要静默跳过) */
|
|
94
|
+
export declare function getImAccountImpl(channel: string): ImAccountImpl | null;
|
|
95
|
+
/** 已注册的实现名(诊断与错误文案用;顺序 = 注册顺序) */
|
|
96
|
+
export declare function imAccountChannels(): string[];
|
|
97
|
+
/** 测试辅助:清空派发表(生产零调用) */
|
|
98
|
+
export declare function __resetImAccountImplsForTest(): void;
|
|
99
|
+
/**
|
|
100
|
+
* 账号行的渠道归一(**单一处**)。
|
|
101
|
+
*
|
|
102
|
+
* 缺省 `weixin`:老配置平移到 `im` 段时不必补这个字段——owner 的"统一配置"
|
|
103
|
+
* 要能直接吃旧数据(与 `route.ts` 的 `normalizeImSection` 保持同一口径)。
|
|
104
|
+
*/
|
|
105
|
+
export declare function normalizeAccountChannel(channel: string | undefined): string;
|