dsh-plugin-tool-management 0.12.0 → 0.12.1

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/CHANGELOG.md CHANGED
@@ -10,6 +10,19 @@
10
10
 
11
11
  ---
12
12
 
13
+ ## [0.12.1] - 2026-09-22
14
+
15
+ ### 修复
16
+
17
+ - **子智能体页的人设名不再被挤成两三个字符**:以前名字和描述挤在同一横排里、右边还压着开关和两颗按钮,长名字显示成 `co...`。现在分成两行,名字独占一行、装不下才按省略号截断(悬停看全名)。
18
+
19
+ ### 变更
20
+
21
+ - **客户端类型检查进了门禁**:`typecheck:client` 此前没有任何地方调用,而且是红的。修掉那处错误后并入 `test` 与 `prepublishOnly`。
22
+ - **四个注入上限抬高**:记忆段预算 64 KiB → **256 KiB**;技能目录 50 条 → **60 条**;子智能体 40 条 → **60 条**;MCP 50 条 → **60 条**。描述截断窗口不动(技能与子智能体仍 500 字、MCP 备注仍 200 字)—— 技能这项与官方 `dsh-tool-skill` 的默认值同源,抬成两套会让同一技能在不同预设下长度不一致。提示词域未动。
23
+
24
+ ---
25
+
13
26
  ## [0.12.0] - 2026-09-20
14
27
 
15
28
  ### 新增
package/README.md CHANGED
@@ -89,7 +89,7 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
89
89
  - **「进/出模式」与「启用场景」是两个独立状态轴**:界面开关是唯一入口(两轴齐动)。绕过界面直接调 HTTP API 时要注意:`scene-mode-set{scene:null}` 只退运行时快照,**不清空启用集** —— 记忆与提示词仍按该场景注入;要彻底退出还需 `rules-set-active{scenes:[]}`。
90
90
  - **导入**:`.md` / `.zip`(目录名 = 场景,bundle 带附件),同名跳过绝不覆盖,超限逐条回报。
91
91
  - **导出**:勾选记忆打包成 zip,保留「场景/名称」层级;bundle 型连目录里的附件一起打进去。只读源文件。
92
- - **注入预算**:默认 64 KiB,放不下的跳过并列出清单。删除进回收站。
92
+ - **注入预算**:默认 256 KiB,放不下的跳过并列出清单。删除进回收站。
93
93
  - **子代理会话不注入记忆**:记忆只在**顶层会话**注入 —— 它是"父会话的现场",不是子代理完成任务所需的事实;子代理的上下文只留「角色 + 任务」,要记忆可用 `memory_manager_list/read` 自己取,相关事实应由父代理写进 `task`。其余域不受影响(MCP / 技能 / 提示词照常注入,人设目录按各自的 `catalogDepth`)。
94
94
  - **场景锁定**:锁定后 MCP / 技能 / 子智能体 / 记忆 / 提示词五个域的**增删改**整体只读,界面禁用 + 服务端守卫双侧拦截;未启动不能上锁,锁定中不能关闭,先解锁再改。**冻结的是"内容",不是"场景本身"** —— 场景的新建 / 删除 / 改名 / 提示词绑定 / 启用切换 / 回收站的恢复与永久删除、MCP 重启、导出、注入设置与令牌设置都不在冻结清单内(它们不是"场景档案里的内容")。其中「启用切换」在锁定场景正在生效时会被拒绝 —— 清空启用集合会让模型侧的写门禁失去判据(运行时却还是那个场景的档案态)。
95
95
  - **删除场景 = 连记忆一起删**:场景记录、档案与全部记忆进同一条回收站条目,恢复按原路径整条放回;使用中的场景拒绝删除。场景名可改(连带目录与档案,记忆正文不动)。
package/README_EN.md CHANGED
@@ -89,7 +89,7 @@ The model can manage everything above via 14 tools (`mcp_manager_*` / `skill_man
89
89
  - **"Entering/leaving the mode" and "enabling a scene" are two independent state axes**: the UI toggle is the only entry point (it moves both axes at once). If you bypass the UI and call the HTTP API directly, note that `scene-mode-set{scene:null}` only drops the runtime snapshot and does **not clear the enabled set** — memories and the prompt keep being injected for that scene; a full exit also needs `rules-set-active{scenes:[]}`.
90
90
  - **Import**: `.md` / `.zip` (dir name = scene, bundles carry attachments), same names skipped never overwritten, over-limit items reported.
91
91
  - **Export**: pick memories and zip them, keeping the `scene/name` layout; bundle memories bring their attachments along. Sources are read-only.
92
- - **Injection budget**: default 64 KiB, oversized memories skipped with a list. Deletes go to recycle bin.
92
+ - **Injection budget**: default 256 KiB, oversized memories skipped with a list. Deletes go to recycle bin.
93
93
  - **Subagent sessions do not receive memories**: memories are injected into the **top-level session only** — they are the parent's situation, not the facts a child needs; a child's context stays "persona + task", it can read memories on demand with `memory_manager_list/read`, and relevant facts belong in the `task`. Other domains are unaffected (MCP / skills / prompts still inject; the persona catalog follows each persona's `catalogDepth`).
94
94
  - **Scene lock**: once locked, create/update/delete across MCP / skills / subagents / memories / prompts is read-only — UI disabled plus a server-side guard; a scene must be running to lock, and a locked scene can't be closed until unlocked. **What freezes is the content, not the scene itself**: creating/deleting/renaming a scene, rebinding its prompt, switching the active set, recycle-bin restore and purge, MCP restart, export, injection settings and token settings are all outside the frozen list (they are not "content of the scene profile"). Switching the active set *is* refused while a locked scene is in effect — clearing it would leave the model-side write guard with nothing to check while the runtime still runs that scene's profile.
95
95
  - **Deleting a scene deletes its memories too**: the scene record, profile and every memory go into one recycle-bin entry, restored as a whole; a running scene refuses deletion. Scene names are renameable (dir and profile follow, memory bodies untouched).
package/docs/update.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  | 版本 | 发布 | 主题 |
6
6
  | ---------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | [0.12.1](#0121---2026-09-22) | 2026-09-22 | 子智能体列表行:人设名与描述分行 + 客户端类型检查进门禁 + 四个注入上限抬高 |
7
8
  | [0.12.0](#0120---2026-09-20) | 2026-09-20 | 兼容页「功能总览」+ 停用工具真的从模型工具表消失 + 补丁写入前做解析校验(拦"写坏 DSH")+ doctor 三项新检查(挂载心跳 / 裸模块名 / 版本栅栏)+ 删除入口先不切换 + 投影缓存屏障与删除前置检查加固 + 关域拦截顺序钉死 |
8
9
  | [0.11.0](#0110---2026-09-20) | 2026-09-20 | 访问令牌卡片重构(可设置 / 关闭 / 修改 / 删除)+ 没解锁时锁住输入框 + 令牌安全修复 + 批量启停可撤销 + 兼容页清理旧备份 + 两页可搜索 + 体检改为真调 + 一批凭据与数据损坏修复 + 搜索与列表提速 |
9
10
  | [0.10.0](#0100---2026-09-18) | 2026-09-18 | 注入框架改 markdown(动作句加粗前置)+ 注入采纳统计 + 人设角色框 / inherit / catalogDepth + 场景锁定补齐模型侧 + 记忆删除全走回收站 + 错误码全量双语 |
@@ -19,6 +20,16 @@
19
20
 
20
21
  ---
21
22
 
23
+ ## 0.12.1 - 2026-09-22
24
+
25
+ - **子智能体页的列表行改了版式**:人设名与描述分成两行。以前名字和描述挤在同一横排里、右边还压着开关和两颗按钮,名字只剩两三个字符宽(显示成 `co...`);现在名字独占一行、装不下才按省略号截断(悬停看全名)。
26
+
27
+ - **客户端的类型检查进了门禁**:`typecheck:client` 以前只是定义在那里、没有任何地方调用,而且是红的。修掉后并进了 `npm test` 与发布前置 —— 客户端改动不再只有语法检查这一道网。
28
+
29
+ - **四个注入上限抬高了**:记忆段预算 64 KiB → 256 KiB;技能目录 50 条 → 60 条;子智能体 40 条 → 60 条;MCP 50 条 → 60 条。描述截断窗口没动(技能与官方同源,抬成两套会让同一技能在不同预设下长度不一致)。提示词域也没动。
30
+
31
+ ---
32
+
22
33
  ## 0.12.0 - 2026-09-20
23
34
 
24
35
  - **兼容页多了一块「功能总览」**:一行一个功能点,第一行就是「插件是否完整挂载」;状态是装配层 + 宿主能力层 + 你当前配置的合成结果(正常 / 降级 / 未启用 / 受令牌限制 / 部分生效 / 不可用),点一行跳到对应页签。它回答的是"现在到底哪一项能用、为什么不能用"。
package/lib/client.js CHANGED
@@ -89,6 +89,16 @@ button.dsm-tag:disabled{cursor:default;opacity:.6}
89
89
  .dsm-summary{display:grid;grid-template-columns:repeat(var(--dsm-stat-cols,3),minmax(0,1fr));overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2)}.dsm-stat{padding:12px 14px;border-right:1px solid var(--dsw-alias-border-l1);font-size:13px;color:var(--dsw-alias-label-secondary)}.dsm-stat:last-child{border-right:0}.dsm-stat strong,.dsm-stat-num{margin-right:5px;color:var(--dsw-alias-label-primary);font-size:17px;font-weight:680}.dsm-filters{display:flex;gap:9px}.dsm-search{flex:1}.dsm-source-filter{width:210px;flex:none}
90
90
  .dsm-control,.dsm-select-trigger{box-sizing:border-box;width:100%;min-height:34px;padding:0 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}.dsm-control::placeholder{color:var(--dsw-alias-label-tertiary)}textarea.dsm-control{min-height:160px;padding-top:9px;resize:vertical;line-height:20px}.dsm-select{position:relative}.dsm-select-trigger{display:flex;align-items:center;justify-content:space-between;text-align:left;cursor:pointer}.dsm-select-menu{position:absolute;z-index:40;top:calc(100% + 5px);right:0;left:0;display:flex;max-height:260px;padding:5px;overflow:auto;flex-direction:column;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-bg-layer-3);box-shadow:var(--dsw-shadow-lv2)}.dsm-option{padding:8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;text-align:left;cursor:pointer}.dsm-option:hover,.dsm-option[aria-selected=true]{background:var(--dsw-alias-interactive-bg-hover)}
91
91
  .dsm-sources{display:flex;flex-direction:column;gap:9px}.dsm-source{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2)}.dsm-source-head{box-sizing:border-box;display:flex;width:100%;min-height:48px;align-items:center;padding:0 13px}.dsm-source-head-main{display:flex;min-width:0;min-height:48px;flex:1;align-items:center;gap:10px;padding:0;border:0;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}.dsm-source-head:hover,.dsm-row:hover,.dsm-trash-row:hover,.dsm-hist-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsm-source-title{font-size:14px;font-weight:650;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsm-count{color:var(--dsw-alias-label-tertiary);font-size:12px;flex:none}.dsm-path{min-width:0;margin-left:auto;overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:11px;text-overflow:ellipsis;white-space:nowrap}.dsm-source-actions{display:flex;align-items:center;gap:6px;margin-left:8px}.dsm-source-body{border-top:1px solid var(--dsw-alias-border-l1)}.dsm-source-note{padding:9px 13px;border-bottom:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:17px}
92
+ /* ── 子智能体行:人设名与描述分行(用户 2026-09-22 报)──────────────────────────
93
+ 原来名字与描述同在 .dsm-source-head-main 那一条**横向** flex 里、各自单行省略,
94
+ 右侧还压着开关和两颗按钮 —— 名字被挤到只剩几个字符(截图里显示成 "co...")。
95
+ 改成纵向两行:**名字独占一行、仍单行省略**(全名靠 title),描述另起一行、单行省略。
96
+ 只作用于本页:.dsm-source-head-main 还被技能 / 记忆 / MCP / 会话四页的分组头共用,
97
+ 那些行没有描述,不动。同权重靠书写顺序取胜,所以必须排在上面那条 .dsm-source 规则之后。 */
98
+ .dsm-persona-main{box-sizing:border-box;min-height:48px;padding:6px 0;flex-direction:column;align-items:flex-start;justify-content:center;gap:0}
99
+ .dsm-persona-name-row{display:flex;width:100%;min-width:0;align-items:center;gap:7px}
100
+ .dsm-persona-name-row .dsm-tag{flex:none}
101
+ .dsm-persona-desc{width:100%;margin-top:1px;color:var(--dsw-alias-label-secondary);font-size:11px;line-height:17px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
92
102
  .dsm-table-head,.dsm-row{display:grid;grid-template-columns:minmax(180px,1fr) 120px 90px max-content;align-items:center;column-gap:12px;padding:0 13px}.dsm-table-head{min-height:32px;border-bottom:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);font-size:11px}.dsm-row{min-height:58px;border-bottom:1px solid var(--dsw-alias-border-l1)}.dsm-row:last-child{border-bottom:0}.dsm-main{min-width:0}.dsm-name{overflow:hidden;font-size:13px;font-weight:570;text-overflow:ellipsis;white-space:nowrap}.dsm-note{overflow:hidden;margin-top:2px;color:var(--dsw-alias-label-secondary);font-size:11px;line-height:17px;text-overflow:ellipsis;white-space:nowrap}.dsm-tags{display:flex;align-items:center;gap:5px;flex-wrap:wrap}.dsm-tag{display:inline-flex;min-height:19px;align-items:center;padding:0 6px;border:1px solid var(--dsw-alias-border-l3);border-radius:4px;color:var(--dsw-alias-label-secondary);font-size:10px;white-space:nowrap}.dsm-tag-on{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary)}.dsm-tag-off{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.dsm-enabled{color:var(--dsw-alias-state-success-primary);font-size:12px;white-space:nowrap}.dsm-disabled{color:var(--dsm-warn);font-size:12px;white-space:nowrap}.dsm-shadowed{color:var(--dsw-alias-label-tertiary);font-size:12px;white-space:nowrap}.dsm-row-actions{display:flex;align-items:center;justify-content:flex-end;gap:7px}
93
103
  .dsm-switch{position:relative;width:34px;height:20px;flex:none;padding:0;border:0;border-radius:999px;background:var(--dsw-alias-border-l3);cursor:pointer}.dsm-switch:after{position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;content:"";transition:transform 160ms ease}.dsm-switch-on{background:var(--dsw-alias-state-success-primary)}.dsm-switch-on:after{transform:translateX(14px)}.dsm-switch:disabled{opacity:.45;cursor:default}.dsm-trash-row{display:flex;min-height:48px;align-items:center;padding:0 13px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2);color:inherit;font:inherit;font-size:13px;cursor:pointer}.dsm-trash-count{margin-left:auto;padding:2px 7px;border-radius:99px;background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);font-size:11px}.dsm-empty{padding:25px 14px;color:var(--dsw-alias-label-tertiary);font-size:12px;text-align:center}.dsm-feedback{padding:9px 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-secondary);font-size:12px}.dsm-undo{display:flex;align-items:center;gap:10px}.dsm-undo-text{min-width:0;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dsm-undo-close{padding:0;border:0;background:transparent;font:inherit;font-size:18px;cursor:pointer;width:24px;height:24px;color:var(--dsw-alias-label-secondary)}.dsm-undo-close:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dsm-undo.dsm-warning{background:var(--dsm-warn-bg)}.dsm-undo.dsm-warning .dsm-undo-text{font-weight:570}.dsm-undo.dsm-warning .dsm-undo-close{color:var(--dsm-warn)}.dsm-warning{border-color:var(--dsm-warn);color:var(--dsm-warn)}.dsm-error{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}
94
104
  .dsm-mask{position:fixed;z-index:1100;inset:0;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(0,0,0,.62)}.dsm-modal{box-sizing:border-box;display:flex;width:min(560px,100%)!important;max-height:min(760px,calc(100vh - 48px));min-width:0;flex-direction:column;gap:16px;padding:22px;overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-shadow-lv3)}.dsm-modal-sm,.dsm-modal-import{width:min(480px,100%)!important}.dsm-modal-md{width:min(560px,100%)!important}.dsm-modal-lg,.dsm-modal-wide{width:min(720px,100%)!important}.dsm-modal-list{width:min(560px,100%)!important;height:min(640px,calc(100vh - 48px))!important;max-height:none!important;overflow:hidden}.dsm-modal-body{display:flex;min-height:0;flex-direction:column;gap:10px}.dsm-modal-list .dsm-modal-body{flex:1;overflow:auto;overscroll-behavior:contain}.dsm-modal-import{padding:24px}.dsm-modal-head{display:flex;align-items:flex-start;gap:12px}
@@ -2958,6 +2968,9 @@ html,body{scrollbar-gutter:stable}.dsm-settings-scroll-host{overflow-y:scroll!im
2958
2968
  * 令牌没验过照样打得开(见 request-gate.ts 的白名单)。
2959
2969
  */
2960
2970
  let tokenBanner = null
2971
+ // 文本节点单独用闭包变量持有,不挂在 DOM 节点上(`tokenBanner._text` 是把节点当
2972
+ // 储物格,客户端唯一的类型检查会报 TS2339)。横幅只创建一次、从不复位,两者同生命周期。
2973
+ let tokenBannerText = null
2961
2974
  // 手动关闭标记:横幅固定在视口顶部,会盖在宿主设置窗口的标题区上 —— 给一个出口,
2962
2975
  // 关掉后本次锁态期间不再出现;解锁(locked 变 false)即重置,下次再锁照常出现。
2963
2976
  // 输入框上的锁与行内说明不受影响,信息不丢。
@@ -2976,10 +2989,9 @@ html,body{scrollbar-gutter:stable}.dsm-settings-scroll-host{overflow-y:scroll!im
2976
2989
  tokenBanner.setAttribute('role', 'status')
2977
2990
  // 文案与关闭键分开挂:下面语言切换是往文本节点整体覆写,textContent 写在
2978
2991
  // 根节点上会把关闭键抹掉。
2979
- const bannerText = document.createElement('span')
2980
- bannerText.className = 'dsm-token-banner-text'
2981
- tokenBanner.appendChild(bannerText)
2982
- tokenBanner._text = bannerText
2992
+ tokenBannerText = document.createElement('span')
2993
+ tokenBannerText.className = 'dsm-token-banner-text'
2994
+ tokenBanner.appendChild(tokenBannerText)
2983
2995
  const bannerClose = document.createElement('button')
2984
2996
  bannerClose.type = 'button'
2985
2997
  bannerClose.className = 'dsm-token-banner-close'
@@ -2993,7 +3005,7 @@ html,body{scrollbar-gutter:stable}.dsm-settings-scroll-host{overflow-y:scroll!im
2993
3005
  document.body.appendChild(tokenBanner)
2994
3006
  }
2995
3007
  // 语言切换后文案要跟着变(锁态没变、setTokenLock 不会通知,见下面的 locale 订阅)。
2996
- tokenBanner._text.textContent = t('compat.token.banner')
3008
+ tokenBannerText.textContent = t('compat.token.banner')
2997
3009
  tokenBanner.style.display = tokenBannerDismissed ? 'none' : ''
2998
3010
  } catch (e) { /* DOM 不可用 → 只是少一条说明,不影响门禁本身 */ }
2999
3011
  }
@@ -7551,10 +7563,12 @@ function enabledMemoryCount(rules) {
7551
7563
  : React.createElement('div', { className: 'dsm-sources', ref: flipRef }, orderedSubagents.map(function (p) {
7552
7564
  return React.createElement('div', { key: p.name, className: 'dsm-source', 'data-flip-key': p.name, 'data-flip-on': p.enabled !== false ? '1' : '0' },
7553
7565
  React.createElement('div', { className: 'dsm-source-head' },
7554
- React.createElement('div', { className: 'dsm-source-head-main' },
7555
- React.createElement('span', { className: 'dsm-source-title', title: p.name }, p.name),
7556
- React.createElement('span', { className: 'dsm-note' }, p.description || ''),
7557
- p.enabled === false ? React.createElement('span', { className: 'dsm-tag', title: t('subagents.disabled.hint') }, t('subagents.disabled')) : null),
7566
+ React.createElement('div', { className: 'dsm-source-head-main dsm-persona-main' },
7567
+ React.createElement('div', { className: 'dsm-persona-name-row' },
7568
+ React.createElement('span', { className: 'dsm-source-title', title: p.name }, p.name),
7569
+ p.enabled === false ? React.createElement('span', { className: 'dsm-tag', title: t('subagents.disabled.hint') }, t('subagents.disabled')) : null),
7570
+ // 没有描述就不渲染这一行:空 div 仍占一行行高,行会变成一条无内容的空隙。
7571
+ p.description ? React.createElement('div', { className: 'dsm-persona-desc', title: p.description }, p.description) : null),
7558
7572
  React.createElement('div', { className: 'dsm-source-actions' },
7559
7573
  React.createElement(Switch, { on: p.enabled !== false, disabled: busy || anyLocked, label: t('subagents.toggle') + ' ' + p.name, onClick: function () { togglePersona(p) } }),
7560
7574
  React.createElement('button', { type: 'button', className: 'dsm-btn dsm-btn-quiet', disabled: busy || anyLocked, onClick: function () { openEditor(p.name) } }, t('memory.edit')),
@@ -40,7 +40,7 @@
40
40
  // 同步性:`text()` 必须同步返回(renderPrompt 不接受 Promise),而 MCP 清单是异步读盘 →
41
41
  // 与子智能体目录同构的 stale-while-revalidate(见 src/subagents/catalog.ts)。
42
42
  /** 段里最多列几台 server;超出部分只报数量。 */
43
- export const DEFAULT_MCP_MAX_ENTRIES = 50;
43
+ export const DEFAULT_MCP_MAX_ENTRIES = 60;
44
44
  /** 备注截断长度。备注是自由文本,界面侧另有 maxLength(500) 兜底,段侧再截一刀。 */
45
45
  export const DEFAULT_MCP_NOTE_MAX_LENGTH = 200;
46
46
  /**
@@ -17,7 +17,7 @@ export const MAX_RULE_BYTES = 1 << 18; // 正文上限 256 KiB
17
17
  export const DEFAULT_ORDER = 1000; // 默认投影 order(索引无记录时)
18
18
  export const DEFAULT_GROUP_ORDER = 1000; // 新场景默认 order
19
19
  export const SNAPSHOT_TTL_MS = 1000; // 读路径短 TTL 缓存,吸收 UI 密集轮询
20
- export const DEFAULT_MAX_BYTES = 65536; // 场景记忆段预算上限(字节)
20
+ export const DEFAULT_MAX_BYTES = 1 << 18; // 场景记忆段预算上限(字节)
21
21
  // ── 保留场景名 ─────────────────────────────────────────────────────────────
22
22
  /** 保留场景名:界面显示「全局」,恒定存在、不可删除,其记忆注入任何对话。 */
23
23
  export const GLOBAL_SCENE = 'global';
@@ -21,7 +21,7 @@
21
21
  /** 描述截断长度(与官方目录的 `catalogDescriptionMaxLength` 默认值一致)。 */
22
22
  export const SKILL_CATALOG_DESCRIPTION_MAX_LENGTH = 500;
23
23
  /** 目录最多列几条;超出只报数量(让模型去调 `skill_manager_list`)。 */
24
- export const SKILL_CATALOG_MAX_ENTRIES = 50;
24
+ export const SKILL_CATALOG_MAX_ENTRIES = 60;
25
25
  /** 描述归一化 + 截断(与官方 `catalogDescription` 同款:折叠空白、超出补省略号)。 */
26
26
  function catalogDescription(value, maxLength) {
27
27
  const normalized = String(value ?? '').replaceAll(/\s+/g, ' ').trim();
@@ -11,7 +11,7 @@ import { filterBySceneBinding } from './tools.js';
11
11
  */
12
12
  export const DEFAULT_CATALOG_DESCRIPTION_MAX_LENGTH = 500;
13
13
  /** 段里最多列几个人设;超出部分只报数量,让模型自己去调 subagent_manager_list。 */
14
- export const DEFAULT_CATALOG_MAX_ENTRIES = 40;
14
+ export const DEFAULT_CATALOG_MAX_ENTRIES = 60;
15
15
  /** 无描述时的占位,与 `subagent_manager_list` 工具的输出保持同一口径。 */
16
16
  const NO_DESCRIPTION = '(无描述)';
17
17
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-tool-management",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "DSH plugin: one settings panel for MCP servers, skills, scenes, memories, subagents, AGENTS.md presets and archived sessions — scene memory injects into the system prompt, scene lock freezes all five domains, deleted workspaces re-register with one click. Settings UI + HTTP API + 14 model tools (mcp_manager_*, skill_manager_*, prompt_manager_*, memory_manager_*, subagent_*). Install with one command: dsh plugin --profile web add dsh-plugin-tool-management@latest",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,14 +33,14 @@
33
33
  },
34
34
  "scripts": {
35
35
  "build": "tsc -p tsconfig.json && node scripts/sync-client.mjs && node scripts/sync-profile.mjs",
36
- "prepublishOnly": "npm run build && npm run lint && node --test test/client-exports.test.mjs",
36
+ "prepublishOnly": "npm run build && npm run lint && npm run typecheck:client && node --test test/client-exports.test.mjs",
37
37
  "lint": "node --check lib/client.js && node --check lib/index.js",
38
38
  "typecheck:client": "node scripts/sync-client.mjs && tsc -p tsconfig.client.json",
39
39
  "check:i18n": "node scripts/check-i18n.mjs lib/client.js",
40
40
  "check:host": "node scripts/host-deps.mjs && node scripts/doctor.mjs",
41
41
  "host-deps": "node scripts/host-deps.mjs --fix",
42
42
  "doctor": "node scripts/doctor.mjs",
43
- "test": "npm run build && npm run check:i18n && node --test test/contracts.test.mjs test/client-exports.test.mjs",
43
+ "test": "npm run build && npm run check:i18n && npm run typecheck:client && node --test test/contracts.test.mjs test/client-exports.test.mjs",
44
44
  "sync:profile": "node scripts/sync-profile.mjs"
45
45
  },
46
46
  "keywords": [