@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 +1 -1
- package/lib/{ccc-roots-4LwGLCXa.js → ccc-roots-VCJ3aYJA.js} +1 -1
- package/lib/client.js +150 -95
- package/lib/index.js +13 -12
- package/lib/{message-source-CfqdGIi2.js → message-source-D7dVNDIh.js} +2 -2
- package/lib/{profile-CiRWh2a2.js → profile-DnLSb7yv.js} +16 -5
- package/lib/{session-BF4C3hJL.js → session-I6SM2GT6.js} +3 -3
- package/lib/{settings-Dj4_ppTC.js → settings-4ag1jtR0.js} +1 -1
- package/package.json +1 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
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-
|
|
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.
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
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)("
|
|
4231
|
-
className: "ss-
|
|
4232
|
-
children: [
|
|
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-
|
|
4235
|
-
"
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
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
|
-
})
|
|
4244
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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}
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
1141
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
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": {
|