@shgroup/dsh-serenity-hooks 1.26.15 → 1.26.16
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/acp-core.d.ts +100 -0
- package/lib/acp-http.d.ts +29 -0
- package/lib/api.d.ts +47 -0
- package/lib/autotrajectory.d.ts +186 -0
- package/lib/ccc-CfDrlfA7.js +141 -0
- package/lib/ccc.d.ts +154 -0
- package/lib/config-ops.d.ts +166 -0
- package/lib/constants.d.ts +8 -0
- package/lib/fs-ops.d.ts +36 -0
- package/lib/gateway-auth.d.ts +89 -0
- package/lib/gateway-proxy.d.ts +39 -0
- package/lib/gateway.d.ts +80 -0
- package/lib/git-ops.d.ts +28 -0
- package/lib/handyman-ops.d.ts +68 -0
- package/lib/handyman-preset-inherit.d.ts +34 -0
- package/lib/index.d.ts +68 -0
- package/lib/invariant.d.ts +29 -0
- package/lib/json.d.ts +9 -0
- package/lib/kit-ops.d.ts +23 -0
- package/lib/localstore-ops.d.ts +85 -0
- package/lib/msm-ops.d.ts +78 -0
- package/lib/output-guard-seam.d.ts +21 -0
- package/lib/output-guard.d.ts +68 -0
- package/lib/rebuild.d.ts +118 -0
- package/lib/seams/bootstrap.d.ts +83 -0
- package/lib/seams/compact.d.ts +31 -0
- package/lib/seams/context.d.ts +48 -0
- package/lib/seams/env.d.ts +16 -0
- package/lib/seams/guards.d.ts +72 -0
- package/lib/seams/keeper.d.ts +61 -0
- package/lib/seams/opencode-skills.d.ts +14 -0
- package/lib/seams/system-prompt.d.ts +113 -0
- package/lib/session-ops.d.ts +127 -0
- package/lib/settings-section.d.ts +113 -0
- package/lib/skiff-core.d.ts +78 -0
- package/lib/skiff-debug.d.ts +86 -0
- package/lib/skiff-registry.d.ts +25 -0
- package/lib/skiff-role.d.ts +50 -0
- package/lib/skills/opencode-scan.d.ts +27 -0
- package/lib/skills-discovery.d.ts +25 -0
- package/lib/status.d.ts +38 -0
- package/lib/tools/autotrajectory-exp.d.ts +24 -0
- package/lib/tools/cc-fs.d.ts +7 -0
- package/lib/tools/cce.d.ts +9 -0
- package/lib/tools/eap.d.ts +7 -0
- package/lib/tools/git.d.ts +4 -0
- package/lib/tools/handyman.d.ts +43 -0
- package/lib/tools/kit.d.ts +4 -0
- package/lib/tools/localstore.d.ts +8 -0
- package/lib/tools/msm.d.ts +4 -0
- package/lib/tools/neat.d.ts +5 -0
- package/lib/tools/rebuild.d.ts +19 -0
- package/lib/tools/session.d.ts +78 -0
- package/lib/tools/skiff-admin.d.ts +25 -0
- package/lib/totp.d.ts +40 -0
- package/package.json +6 -4
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skiff-debug.ts — Skiff 调试问答页(F4a',v1.25.x 实验性)
|
|
3
|
+
*
|
|
4
|
+
* node:http 调试端口(默认关,仅监听 127.0.0.1;启停 = 人工——设置面板「Serenity」
|
|
5
|
+
* 页 Skiff 区块开关,不随插件加载自动启动)。
|
|
6
|
+
*
|
|
7
|
+
* - GET / → 问答 HTML 页(**CCC 选择器** + 角色下拉 + 输入框 + 答案区 + 轨迹区 + WebUI 链接)
|
|
8
|
+
* - POST /ask → {ccc?, role, question} → 走会话核心(skiff-core)→ {answer, sessionId, trajectory}
|
|
9
|
+
*
|
|
10
|
+
* **多 CCC 手工切换(v1.25.4,S142 用户)**:dsh 管理多个 CCC 时,调试页顶部 CCC
|
|
11
|
+
* 下拉列出全部候选(live 会话 cwd 上溯 .serenity 去重 + 默认绑定 root 兜底),
|
|
12
|
+
* 切换后角色下拉联动(各 CCC 的 skiff.roles 实时读取),提问按所选 CCC 创建 agent。
|
|
13
|
+
*
|
|
14
|
+
* 与 ACP stdio 协议(F4c 后续)共用同一会话核心(createSkiffAgent + askSkiff),
|
|
15
|
+
* 协议层后加不返工。轨迹 = session.events 结构化返回(与 dsh WebUI 同源数据),
|
|
16
|
+
* 页面 JS 渲染成对话时间线;同时保留原生 WebUI 会话链接供完整交互。
|
|
17
|
+
*
|
|
18
|
+
* 实验性质:未开启时零资源占用(无监听、无 agent 创建)。
|
|
19
|
+
*/
|
|
20
|
+
import type { Context } from 'cordis';
|
|
21
|
+
import { type SkiffTrajectoryEntry } from './skiff-core.js';
|
|
22
|
+
export declare function skiffDebugActive(): boolean;
|
|
23
|
+
export declare function skiffDebugPort(): number | null;
|
|
24
|
+
/** 候选 CCC 条目(调试页 CCC 切换器数据) */
|
|
25
|
+
export interface SkiffCccEntry {
|
|
26
|
+
/** CCC 根(绝对路径) */
|
|
27
|
+
root: string;
|
|
28
|
+
/** 目录名(展示用) */
|
|
29
|
+
name: string;
|
|
30
|
+
/** 该 CCC 的 skiff 角色名列表(实时读取) */
|
|
31
|
+
roles: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 发现候选 CCC 列表(多 CCC 手工切换,v1.25.6):
|
|
35
|
+
* ① **dsh 工作区注册表**(workspaceRegistry.list,持久化——所有工作目录即使无 live 会话;
|
|
36
|
+
* S142 用户 2026-08-29:应直接拉 dsh 工作区,且只列具体 CCC)
|
|
37
|
+
* ② **sessionPersistence 兜底**(持久化会话 headers——必装配服务,覆盖所有历史会话工作目录;
|
|
38
|
+
* 用户实测 workspaceRegistry 拉取仍空时兜底)
|
|
39
|
+
* ③ live 会话兜底
|
|
40
|
+
* ④ 默认绑定 root 兜底(不在列表时放首位)
|
|
41
|
+
*/
|
|
42
|
+
export declare function discoverCccs(ctx: Context, defaultRoot: string): Promise<SkiffCccEntry[]>;
|
|
43
|
+
/** 问答页 HTML:CCC 切换器 + 角色下拉 + 输入 + 答案区 + 轨迹区(JS 渲染)+ WebUI 链接 */
|
|
44
|
+
export declare function skiffDebugPage(cccs: SkiffCccEntry[], defaultRoot: string, webPort: number): string;
|
|
45
|
+
/**
|
|
46
|
+
* JSC (Safari/iOS) JSON.parse 快速路径正则兼容化(v1.26.9,S142 调研定稿)。
|
|
47
|
+
*
|
|
48
|
+
* 背景:WebKit bug 200190「JavaScriptCore's Regex can't match the content」——JSC 的
|
|
49
|
+
* JSON.parse 用**内部正则**预校验字符串;内容含**原始** `\u2028`(行分隔符)/`\u2029`
|
|
50
|
+
* (段分隔符)时正则无法匹配 → 对**合法 JSON** 也抛
|
|
51
|
+
* `SyntaxError: The string did not match the expected pattern`(sentry-javascript #2487 同源)。
|
|
52
|
+
* JSON.stringify **不转义** `\u2028`/`\u2029`/`\uFEFF`(它们都是合法 JSON 字符串字符)→
|
|
53
|
+
* 在 JSON **文本层**把它们替换为 `\uXXXX` 转义序列:JSON.parse 后语义完全一致(还原原字符),
|
|
54
|
+
* 且 JSC 正则看到的是常规 ASCII 转义(与 JSON.stringify 对控制字符的输出同形态,安全)。
|
|
55
|
+
*
|
|
56
|
+
* 3100 问答页客户端 `await res.json()`(acp-http.ts)与页面内嵌 JSON(skiff-debug/acp-http)
|
|
57
|
+
* 均需此兼容层——iOS Safari 用户实测"复杂回答"触发。
|
|
58
|
+
*
|
|
59
|
+
* @param jsonText JSON.stringify 的输出文本;原地等价替换,返回 JSC 安全文本
|
|
60
|
+
*/
|
|
61
|
+
export declare function jscSafeJsonText(jsonText: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Markdown 渲染(v1.25.9,正经库 marked 服务端渲染——替代手写正则渲染器,S142 用户要求):
|
|
64
|
+
* ① 提取 `<think>…</think>` 块(v1.26.8 状态机扫描,占位符 \u0001T<idx>\u0001)
|
|
65
|
+
* ② 正文与 think 内容**先 escapeHtml 再 marked.parse**(GFM + breaks)——markdown 语法不受
|
|
66
|
+
* 转义影响,原始 HTML 注入被消除(安全);代码块内 `<` 显示为实体(可接受)
|
|
67
|
+
* ③ think 占位符:默认还原为 `<details class="think">` 折叠卡(🧠 思考过程,默认收起);
|
|
68
|
+
* **hideThink=true(v1.26.4,public 口)→ 直接移除**(思考过程对普通用户不展示)
|
|
69
|
+
* @param hideThink 为 true 时 `<think>` 内容完全不渲染(public 问答页体验)
|
|
70
|
+
*/
|
|
71
|
+
export declare function renderSkiffMarkdown(raw: string, hideThink?: boolean): string;
|
|
72
|
+
/**
|
|
73
|
+
* 启动调试问答服务(单实例;重复启动幂等返回既有实例)。
|
|
74
|
+
*
|
|
75
|
+
* **CCC 绑定(v1.25.2 用户指出)**:服务绑定一个默认 CCC root(调用方 resolveSkiffRoot
|
|
76
|
+
* 解析:live 会话中**含 skiff.roles 的 CCC 优先**);v1.25.4 起页面可**手工切换**到
|
|
77
|
+
* 其它候选 CCC(live 会话发现的全部 CCC);角色配置**每次请求实时读取**(不缓存快照)。
|
|
78
|
+
*
|
|
79
|
+
* @param root 默认绑定的 CCC 根(首次加载选中;角色配置读取 + skiff agent cwd)
|
|
80
|
+
* @param port 调试端口(仅 127.0.0.1)
|
|
81
|
+
* @param webPort 主 WebUI 端口(WebUI 链接)
|
|
82
|
+
*/
|
|
83
|
+
export declare function startSkiffDebugServer(ctx: Context, root: string, port: number, webPort: number): Promise<void>;
|
|
84
|
+
export declare function stopSkiffDebugServer(): void;
|
|
85
|
+
/** 导出类型引用(测试断言轨迹结构) */
|
|
86
|
+
export type { SkiffTrajectoryEntry };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skiff-registry.ts — Skiff 会话注册表(sessionId → {role, ccc};零 DSH 依赖,可被任何 seams 安全 import)
|
|
3
|
+
*
|
|
4
|
+
* F4b 会话映射:Skiff agent 创建时注册(skiff-core),guards/seams 按 sessionId 查角色。
|
|
5
|
+
* 独立成模块的原因:guards.ts 等拦截缝需要查角色而不引入 skiff-core 的运行时依赖
|
|
6
|
+
* (skiff-core 依赖 @deepseek-ai/dsh-llm,测试/装配级联成本高)——注册表本身纯内存 Map。
|
|
7
|
+
*
|
|
8
|
+
* 值结构 v1.25.10 扩展:role(guards/seams 依赖,向后兼容)+ ccc(会话追问时
|
|
9
|
+
* 角色/容器绑定校验——同 sessionId 复用必须同 (role, ccc),防串角色污染)。
|
|
10
|
+
*
|
|
11
|
+
* 生命周期:进程内存态;连接/页面关闭时 unregister;进程重启自然清空(skiff 会话不复存在)。
|
|
12
|
+
*/
|
|
13
|
+
/** 注册表值:会话绑定的角色 + CCC 根(追问延续校验用) */
|
|
14
|
+
export interface SkiffSessionBinding {
|
|
15
|
+
role: string;
|
|
16
|
+
ccc: string;
|
|
17
|
+
}
|
|
18
|
+
/** 查 sessionId 的 Skiff 角色名(无 → null)——向后兼容(guards/seams 依赖) */
|
|
19
|
+
export declare function skiffRoleFor(sessionId: string): string | null;
|
|
20
|
+
/** 查 sessionId 的完整绑定(role + ccc;无 → null)——v1.25.10 会话追问校验 */
|
|
21
|
+
export declare function skiffSessionInfo(sessionId: string): SkiffSessionBinding | null;
|
|
22
|
+
export declare function registerSkiffSession(sessionId: string, role: string, ccc: string): void;
|
|
23
|
+
export declare function unregisterSkiffSession(sessionId: string): void;
|
|
24
|
+
/** 测试/调试:注册表快照(sessionId → {role, ccc}) */
|
|
25
|
+
export declare function skiffSessionSnapshot(): ReadonlyMap<string, SkiffSessionBinding>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skiff-role.ts — Skiff(F4,v1.25.0 实验性)角色层纯逻辑(零 DSH 依赖,可独立单测)
|
|
3
|
+
*
|
|
4
|
+
* 概念(S142 用户拍板):Skiff = 完整宁静号 trajectory(在宁静号内全知全能)的
|
|
5
|
+
* **任意子集**——CCC 通过角色配置定义:能力面(tools 非 MSM 工具白名单 + msms
|
|
6
|
+
* MSM 白名单,双白名单独立,白名单外全隐藏)+ 轨迹纪律面(trajectory 子集)+
|
|
7
|
+
* 系统提示词(CCC 完整定义,dsp 只给基础部分)。
|
|
8
|
+
*
|
|
9
|
+
* 实验性质:未配置任何角色 → Skiff 完全零影响(无监听、无 agent 创建、guard 无规则)。
|
|
10
|
+
*/
|
|
11
|
+
import { type SkiffRoleConfig } from './ccc.js';
|
|
12
|
+
export type { SkiffRoleConfig };
|
|
13
|
+
/** Skiff agent 会话 id 前缀(agents.create 生成;seams 旁路/白名单判定用) */
|
|
14
|
+
export declare const SKIFF_SESSION_PREFIX = "skiff-";
|
|
15
|
+
/** 判定 sessionId 是否为 Skiff 会话(仿 handyman- 前缀排除模式) */
|
|
16
|
+
export declare function isSkiffSessionId(sessionId: string | undefined): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* 读取 CCC 的 Skiff 角色配置(.opencode/serenity.json skiff.roles)。
|
|
19
|
+
* @returns 名 → 角色配置 的 Map;未配置(无 skiff 段/空 roles)返回空 Map(Skiff 未启用)
|
|
20
|
+
*/
|
|
21
|
+
export declare function readSkiffRoles(root: string, paths?: string[]): Map<string, SkiffRoleConfig>;
|
|
22
|
+
/** 某角色的轨迹纪律子集(缺省全 false = 完全独立) */
|
|
23
|
+
export interface SkiffTrajectorySubset {
|
|
24
|
+
session: boolean;
|
|
25
|
+
keeper: boolean;
|
|
26
|
+
rebuild: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function trajectorySubset(role: SkiffRoleConfig | undefined): SkiffTrajectorySubset;
|
|
29
|
+
/** 角色可用工具面(白名单并集):tools + acc_msm(msms 非空时作为 MSM 通道自动可用) */
|
|
30
|
+
export declare function roleToolWhitelist(role: SkiffRoleConfig | undefined): Set<string>;
|
|
31
|
+
/** 角色允许的 MSM 白名单(acc_msm exec 校验 / msm_list 过滤用;独立于 tools 白名单) */
|
|
32
|
+
export declare function roleMsmWhitelist(role: SkiffRoleConfig | undefined): Set<string>;
|
|
33
|
+
/**
|
|
34
|
+
* 解析角色的系统提示词全文(v1.25.10,S142 用户:超长提示词 JSON 内嵌不可读):
|
|
35
|
+
* ① `systemPromptFile` 存在 → 读取文件内容(**推荐配置方法**;相对 CCC 根,
|
|
36
|
+
* 路径逃逸拒绝(resolveInside)+ BOM 剥除(readUtf8)+ 存在性校验)
|
|
37
|
+
* ② 否则 → 内嵌 `systemPrompt`(兼容旧配置)
|
|
38
|
+
* ③ 都无 → 空字符串
|
|
39
|
+
* 文件缺失/逃逸 → 抛错(调用方 catch 降级 + validate 报 issue)。
|
|
40
|
+
* 懒读取:readSkiffRoles 不读文件(guards/seams 每次工具调用查询的热路径零 IO),
|
|
41
|
+
* 仅在本函数(创建 agent / validate / list 时)读取。
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveRoleSystemPrompt(root: string, role: SkiffRoleConfig | undefined): string;
|
|
44
|
+
/** 角色系统提示词来源(validate/list 展示用) */
|
|
45
|
+
export declare function systemPromptSource(role: SkiffRoleConfig | undefined): 'file' | 'inline' | 'none';
|
|
46
|
+
/**
|
|
47
|
+
* Skiff 基础提示词(dsp 只给这部分;CCC 的 systemPrompt 段由调用方拼接):
|
|
48
|
+
* 身份 + 可用 MSM/工具清单 + 调用协议 + 边界声明。动态生成(清单来自角色白名单)。
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildSkiffBasePrompt(roleName: string, role: SkiffRoleConfig | undefined): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opencode-scan.ts — opencode skill 标准扫描(纯逻辑,零 DSH 依赖)
|
|
3
|
+
*
|
|
4
|
+
* 兼容 opencode 的 skill 标准:`.opencode/skills/<name>/SKILL.md`
|
|
5
|
+
* (frontmatter: name/description/whenToUse;结构含 references/、scripts/)。
|
|
6
|
+
*/
|
|
7
|
+
export interface OpencodeSkillMeta {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
whenToUse?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface OpencodeSkill {
|
|
13
|
+
name: string;
|
|
14
|
+
dir: string;
|
|
15
|
+
meta: OpencodeSkillMeta;
|
|
16
|
+
content: string;
|
|
17
|
+
path: string;
|
|
18
|
+
}
|
|
19
|
+
/** 解析 --- 分隔的 YAML frontmatter(只需 name/description/whenToUse) */
|
|
20
|
+
export declare function parseFrontmatter(raw: string): {
|
|
21
|
+
meta: OpencodeSkillMeta;
|
|
22
|
+
content: string;
|
|
23
|
+
};
|
|
24
|
+
/** 扫描 CCC 的 .opencode/skills(一级目录 + SKILL.md 存在性) */
|
|
25
|
+
export declare function listOpencodeSkillDirs(root: string): string[];
|
|
26
|
+
/** 加载一个 opencode skill(frontmatter 解析 + 正文);读失败(EPERM/占用等)返回 null,单目录容错 */
|
|
27
|
+
export declare function loadOpencodeSkill(skillDir: string): OpencodeSkill | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skills-discovery.ts — CCC 入口 skill 自动发现(纯逻辑,零 DSH 依赖)
|
|
3
|
+
*
|
|
4
|
+
* 发现全部入口技能(原文全量,不截断):
|
|
5
|
+
* 0. **`.serenity` 记号文件内容 = 顶层入口 skill 名**(CCC 记号文件的权威语义,
|
|
6
|
+
* tiangong-serenity 的 .serenity 内容为 `tg-serenity`)—— 最高优先
|
|
7
|
+
* 1. `.dsh/entry-skill` 指针文件(内容 = skill 名)—— 兼容旧约定
|
|
8
|
+
* 2. `.opencode/skills/*-serenity/SKILL.md` —— 自动扫描该 CCC 的顶层入口
|
|
9
|
+
* (home-serenity / tg-serenity / pangu-serenity …,命名模式 `*-serenity`)
|
|
10
|
+
* 3. `.dsh/skills/*-serenity/SKILL.md` —— 自动扫描 ACC/harness 入口(acc-serenity 等)
|
|
11
|
+
* 按名去重;顺序 = 记号文件 → 指针 → opencode 入口 → dsh 入口。
|
|
12
|
+
*
|
|
13
|
+
* 任何 CCC 都能自动注入其顶层入口 skill 全文(不硬编码名字)。
|
|
14
|
+
*/
|
|
15
|
+
export type EntrySkillSource = 'serenity-marker' | 'pointer' | 'opencode' | 'dsh';
|
|
16
|
+
export interface EntrySkill {
|
|
17
|
+
name: string;
|
|
18
|
+
content: string;
|
|
19
|
+
source: EntrySkillSource;
|
|
20
|
+
}
|
|
21
|
+
/** 发现全部入口技能(原文全量,不截断) */
|
|
22
|
+
export declare function findEntrySkills(root: string): EntrySkill[];
|
|
23
|
+
/** 兼容旧接口:第一个入口(或 null) */
|
|
24
|
+
export declare function findEntrySkill(root: string): EntrySkill | null;
|
|
25
|
+
export declare function truncateContent(content: string, maxChars: number): string;
|
package/lib/status.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* status.ts — 状态与安全模式操作(纯逻辑,零 DSH 依赖,可独立单测)
|
|
3
|
+
*
|
|
4
|
+
* WebUI 停靠栏的数据源:ACC 版本 / CCC 根 / safe-mode 状态 / 黑名单 / keeper 阈值 / handyman 模型。
|
|
5
|
+
* setSafeMode 直接读写 .serenity-safe-on 标记(守卫实时读取,写即生效)。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 读取已安装 DSH CLI 版本;读不到返回 null。
|
|
9
|
+
* 跨平台(Windows 审计问题 13):Windows npm 全局装在 %APPDATA%\npm(非 ~/.npm-global)——
|
|
10
|
+
* 依次尝试 npm_config_prefix / APPDATA\npm / ~/.npm-global。
|
|
11
|
+
*/
|
|
12
|
+
export declare function readDshVersion(): string | null;
|
|
13
|
+
export interface SerenityStatus {
|
|
14
|
+
root: string | null;
|
|
15
|
+
accVersion: string;
|
|
16
|
+
dshVersion: string | null;
|
|
17
|
+
nodeVersion: string;
|
|
18
|
+
safeModeOn: boolean;
|
|
19
|
+
/** 黑名单条目(string 或 {pattern, message},对齐 osp) */
|
|
20
|
+
blacklist: {
|
|
21
|
+
pattern: string;
|
|
22
|
+
message?: string;
|
|
23
|
+
}[];
|
|
24
|
+
threshold: number | null;
|
|
25
|
+
handymanModel: string | null;
|
|
26
|
+
restrict: {
|
|
27
|
+
lastKey: string | null;
|
|
28
|
+
lastAttemptAt: string | null;
|
|
29
|
+
lastSuccess: boolean | null;
|
|
30
|
+
lastError: string | null;
|
|
31
|
+
activeKeys: string[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export declare function getStatus(cwd: string, configPaths?: string[]): SerenityStatus;
|
|
35
|
+
/** 切换安全模式(写/删标记文件);返回实际生效状态 */
|
|
36
|
+
export declare function setSafeMode(root: string, on: boolean): {
|
|
37
|
+
on: boolean;
|
|
38
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* autotrajectory-exp.ts — 自主轨迹实验一站式管理工具(v1.26.12 实验提案,默认关)
|
|
3
|
+
*
|
|
4
|
+
* 定位:dsp **只提供工具与知识**,不向 CCC 自动安装任何东西(实验可能失败,不污染 CCC)——
|
|
5
|
+
* 实验是 CCC 的自选动作:agent 调本工具(doc/全报告)即懂实验,init/random/check 辅助,
|
|
6
|
+
* 实际执行(写配置/写偏见脚本/标记会话)由 CCC 自己决定、自己用现有工具完成。
|
|
7
|
+
*
|
|
8
|
+
* 实现:薄封装——exec 包内静态脚本(npm files 含 experiments/),脚本是单一真相源。
|
|
9
|
+
* 环境注入 SERENITY_ROOT(当前 CCC 根)供脚本定位;bun 优先(可直跑 TS)。
|
|
10
|
+
* diag-live:**进程内诊断**(v1.26.14 用户"排查访问不到")——闭包捕获 ctx,
|
|
11
|
+
* 直接读 live 会话/标题/agent(脚本 diag 看不到运行时),输出实例级诊断报告。
|
|
12
|
+
*/
|
|
13
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
14
|
+
import type { Context } from 'cordis';
|
|
15
|
+
/**
|
|
16
|
+
* 定位包内实验脚本(npm files 分发 experiments/autotrajectory/)。
|
|
17
|
+
* 布局差异:tsdown bundle 后 import.meta.url 指向 lib/index.js(lib → 包根 1 层);
|
|
18
|
+
* vitest 源码直跑时指向 src/tools/x.ts(src/tools → 包根 2 层)——逐级上溯查找,
|
|
19
|
+
* 两种布局都稳(找到 experiments/autotrajectory/scripts/autotrajectory-exp.ts 即止)。
|
|
20
|
+
*/
|
|
21
|
+
export declare function findExpScript(startDir: string): string | null;
|
|
22
|
+
export declare const AUTO_TRAJECTORY_EXP_ACTIONS: readonly ["all", "init", "random", "diag", "doc", "check", "status", "guide", "diag-live"];
|
|
23
|
+
/** 创建 autotrajectory-exp 工具(闭包捕获 ctx → diag-live 进程内诊断;v1.26.14) */
|
|
24
|
+
export declare function createAutoTrajectoryExpTool(ctx: Context): ReturnType<typeof defineTool>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cce.ts — CCE 认知连续性工程工具(渐进式披露,ACC 标准工具化)
|
|
3
|
+
*
|
|
4
|
+
* 内容:认知连续性工程(Cognitive Continuity Engineering)——在有限资源与
|
|
5
|
+
* 不可逆不确定性约束下,维持认知实体身份、可达性与演化能力的工程学科。
|
|
6
|
+
* 来源:home-serenity `.opencode/skills/cce/SKILL.md` + CCE 理论。
|
|
7
|
+
*/
|
|
8
|
+
export declare const CCE_CONTENT = "# CCE \u2014 Cognitive Continuity Engineering\n\n> **Cognitive Continuity Engineering is the engineering discipline of maintaining a cognitive entity's identity, accessibility, and capacity to evolve under the constraints of bounded resources and irreversible uncertainty.**\n> CCE does not optimize cognition. It preserves the conditions under which cognition can continue. \u2014 Persistence Engineering, not performance engineering\n\n## Core Propositions\n- **Continuity belongs to the container, not to any individual participant** \u2014 agents come and go, but the CCC's cognitive trajectory persists\n- **Organization must at minimum keep pace with accumulation** \u2014 otherwise operational cognitive entropy (H_op) grows unboundedly and accessibility is lost\n- **Reconstruction over preservation** \u2014 an artifact's value is determined by its ability to let future agents rebuild the original reasoning\n\n## Cognitive Container\nA bounded cognitive space in which cognition can accumulate, reorganize, and evolve. 5 defining properties:\n| Property | Function |\n|----------|----------|\n| Identity | Distinguishes this cognitive system from others |\n| Boundaries | Define what is inside/outside the cognitive space |\n| Persistent Memory | Retains accumulated cognition across time |\n| Operational Constraints | Define which operations are allowed inside the container |\n| Evolutionary History | Records the trajectory of cognitive change, making reconstruction possible |\n\n## Operational Cognitive Entropy (H_op)\nDoes not measure total entropy (not operational); it measures only the **excess cognitive cost** for agents to complete tasks inside the container:\n> H_op(C, t) = cost(task | C, t) \u2212 cost(task | ideal)\nContinuity condition: **H_op(C, t) \u2264 H_critical** \u2014 agents can still complete tasks at reasonable cost\n\n## Continuity Maintenance Condition\n> **\u0394H_org \u2265 \u0394H_in** \u2014 organization must at minimum keep pace with accumulation\n\n## Six-Phase Lifecycle\nExperience \u2192 Accumulation \u2192 Organization \u2192 Abstraction \u2192 Reconstruction \u2192 Evolution \u2192\uFF08loop\uFF09\n| Phase | Engineering Concern |\n|-------|---------------------|\n| Experience | Does input carry enough structure |\n| Accumulation | Is information stored losslessly |\n| Organization | Entropy management \u2014 \u0394H_org offsets \u0394H_in |\n| Abstraction | Is abstraction explicitly encoded |\n| Reconstruction | Can reasoning structure be recovered from artifacts |\n| Evolution | Does evolution stay coherent or introduce drift |\n\n## Relationship with EAP\nEAP answers \"how a piece of knowledge should be structured\" (explicitness E\u2191 / reconstructability R\u2193 / stability S\u2191);\nCCE answers \"how structured knowledge should keep evolving across time without losing coherence\". They complement each other: EAP is static quality, CCE is dynamic persistence.\n\n## Relationship with Serenity\nSerenity's session system, session tracking, and entropy management mechanisms (SQC quality loop) are all engineering implementations of CCE;\nthe behavioral constraints embedded in CCC system prompts come from CCE.";
|
|
9
|
+
export declare const cceTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eap.ts — EAP 认知质量框架工具(渐进式披露,ACC 标准工具化)
|
|
3
|
+
*
|
|
4
|
+
* 内嵌框架内容(自包含,不依赖已安装技能);可选 section 参数聚焦某原则。
|
|
5
|
+
*/
|
|
6
|
+
export declare const EAP_CONTENT = "# EAP Cognitive Quality Framework (Explicit Abstraction Principle)\n\n> \"The functional value of a thought is proportional to its external reconstructability.\"\n\n## Three Variables\n| Variable | Meaning | How to improve |\n|----------|---------|----------------|\n| E\u2191 Explicitness | Degree to which variables/entities/relations are clearly defined | Define variables, state relationship direction & cardinality, draw boundaries |\n| R\u2193 Reconstructability | Cost of rebuilding the original reasoning later | Record decision rationale, context, constraints, alternatives |\n| S\u2191 Stability | Degree to which the same input repeatedly produces consistent output | Fix structures, protocolize, avoid relying on implicit context |\n\n## Pre-Output Self-Check Checklist\n- [ ] Variables/entities clearly defined (E\u2191)\n- [ ] Relationships state direction/cardinality (E\u2191)\n- [ ] Boundaries drawn \u2014 what is in scope / what is not (E\u2191)\n- [ ] No ambiguous words: \"handle\" \"optimize\" \"problem\" \u2192 be specific (E\u2191)\n- [ ] Key decisions record rationale and alternatives (R\u2193)\n- [ ] No level-skipping \u2014 align the upper layer before descending (R\u2193)\n- [ ] Structures can be regenerated repeatably (S\u2191)\n\n## Relationship with ACC\nACC (plugin/template) encodes structure as code (E\u2191); generating a CCC from ACC is deterministic (R\u2193); consistent across multiple CCCs (S\u2191).\nCCC (home-serenity etc.) encodes cognitive content as skills/SESSIONs/design docs. Use this checklist to self-check outputs.\n\n## Reference\nhttps://github.com/tellmewhattodo/theory-eap";
|
|
7
|
+
export declare const eapTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* handyman.ts — handyman(杂工)真实 DSH 工具(v1.24.0:loop 牛马 → handyman 杂工)
|
|
3
|
+
*
|
|
4
|
+
* 用户需求(S142 拍板):
|
|
5
|
+
* - **同步**(用户明确:这个事一般不会异步——工具阻塞到完成)
|
|
6
|
+
* - **指定模型**(CCC 白名单内——handyman.models,未配置报错)
|
|
7
|
+
* - **自主循环到完成**(stop-token 唯一完成判据,对齐 osp loop)
|
|
8
|
+
* - **内部递归同样低能 subagent**(worker 工具面含 subagent,DSH 原生模型继承)
|
|
9
|
+
* - **workflow 能力**(jobs 编排:主 agent 一次并行多个杂工,maxParallel 默认 10)
|
|
10
|
+
* - **worker 不含 handyman 本身**(递归编排归主 agent,防无限嵌套)
|
|
11
|
+
* - **不兼容旧 loop 进度文件**(仅 handyman- 前缀)
|
|
12
|
+
*
|
|
13
|
+
* 机制:ctx.agents.create()(带 setup 钩子)创建专用 agent(进程内),
|
|
14
|
+
* 每轮 followup → agent/status idle → 读 session.events 响应 → 写进度 → stop token 检查 →
|
|
15
|
+
* 未完成继续下一轮;followup/waitIdle 抛错(非正常停止)→ dispose 并重新 create agent
|
|
16
|
+
* (重启计数,≤100),同一轮重试。工厂模式:apply 时闭包捕获插件 ctx(工具 execute 无 ctx 参数)。
|
|
17
|
+
*
|
|
18
|
+
* preset 继承 + 工具收窄:setup 钩子里对子 agent 执行 agentPresets.composeFrom(对齐
|
|
19
|
+
* subagent 先例)+ tools.restrict deny handyman(worker 内部看不到 handyman 工具)。
|
|
20
|
+
*/
|
|
21
|
+
import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
|
|
22
|
+
import type { Context } from 'cordis';
|
|
23
|
+
/** 非正常停止时重启 agent 的次数上限(防死循环保险阀):对话轮次有上限,重启有上限 */
|
|
24
|
+
export declare const HANDYMAN_MAX_RESTARTS = 100;
|
|
25
|
+
/** 对话轮次上限(对齐 osp loop-runner 的 round>=100 强制 done 保险阀) */
|
|
26
|
+
export declare const HANDYMAN_MAX_ROUNDS = 100;
|
|
27
|
+
export interface HandymanJob {
|
|
28
|
+
task: string;
|
|
29
|
+
label: string;
|
|
30
|
+
model?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface HandymanJobResult {
|
|
33
|
+
label: string;
|
|
34
|
+
done: boolean;
|
|
35
|
+
rounds: number;
|
|
36
|
+
finishReason: 'done' | 'max_rounds' | 'restart_exceeded';
|
|
37
|
+
restarts: number;
|
|
38
|
+
model: string;
|
|
39
|
+
lastResponse: string;
|
|
40
|
+
progressFile: string;
|
|
41
|
+
}
|
|
42
|
+
/** 创建 handyman 工具(闭包捕获插件 ctx → 可访问 ctx.agents) */
|
|
43
|
+
export declare function createHandymanTool(ctx: Context): ToolDefinition;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* localstore.ts — localstore 真实 DSH 工具定义(defineTool)
|
|
3
|
+
*
|
|
4
|
+
* ACC 标准本地凭据/配置存储(S133 设计,S134 重设计:CCC 根 localstore.json)。
|
|
5
|
+
* 进程内注册,零 DSH 依赖逻辑在 localstore-ops.ts(可单测)。
|
|
6
|
+
* doc 子命令输出存储规范,agent 可直接用 fs 工具(read/write)自己读写。
|
|
7
|
+
*/
|
|
8
|
+
export declare const localstoreTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* neat.ts — Neat 设计协作协议工具(渐进式披露,ACC 标准工具化)
|
|
3
|
+
*/
|
|
4
|
+
export declare const NEAT_CONTENT = "# Neat Design Collaboration Protocol\n\n> Complex design is not thought up at once \u2014 it is walked out in small aligned steps.\n\n## Four Iron Rules\n| Rule | Meaning | Anti-example |\n|------|---------|--------------|\n| Small-step alignment | Advance one decision at a time; confirm before the next step | Presenting 10 options at once |\n| Explicit decisions | Every choice records rationale and alternatives | \"I feel this is good\" (no rationale) |\n| Document-driven | Conclusions land in named files (<subject>-<scope>-<type>.md) | Conclusions exist only in conversation |\n| No level-skipping | Advance strictly through the layers | Writing implementation before requirements are aligned |\n\n## Five-Layer Progression (no skipping)\nRequirements \u2192 Scope \u2192 Solution \u2192 Interface \u2192 Implementation\n| Layer | Artifact | Question |\n|-------|----------|----------|\n| Requirements | Requirements description | \"What problem are we solving?\" |\n| Scope | Scope list (in/out) | \"What is in, explicitly what is out?\" |\n| Solution | Solution comparison + selection | \"How? Which one? Why?\" |\n| Interface | Interface/protocol definition | \"How do the boundaries interact?\" |\n| Implementation | Code/docs | \"Land it layer by layer\" |\n\n## Collaboration Rhythm\n1. Raise one decision point of the current layer (with context + suggestion + rationale)\n2. Wait for confirmation or correction (small step)\n3. After confirmation, record the decision (into session SESSION.md or a design doc)\n4. Move to the next decision point";
|
|
5
|
+
export declare const neatTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rebuild.ts — session_rebuild 工具定义(轨迹跟踪器,v1.22.4 定稿:复用旧会话 + 完全清空重来)
|
|
3
|
+
*
|
|
4
|
+
* LLM 主动触发清空重建(用户决策:keeper 超阈值提示 [TRAJECTORY],不自动执行——防误清空)。
|
|
5
|
+
* v1.22.4 定稿语义(用户明确):**复用当前 dsh 会话(同一 id),turn 结束时 surface
|
|
6
|
+
* 完全清空重建**——锚点消息「继续 {宁静号 SESSION 名} 的工作」;SESSION.md 是持久轨迹
|
|
7
|
+
* 永远原位,身份从 SESSION.md 自动延续。同一会话 id → 同工作区天然满足、无新/旧会话
|
|
8
|
+
* 之分、无需销毁/切换/归档。
|
|
9
|
+
* v1.22.5 增强(S142 用户需求):① turn-stopping 执行 replace 后 **steer 自动继续**
|
|
10
|
+
* (无需用户手工输入,模型自动读 SESSION.md 接续);② 锚点消息**保留 first-anchor
|
|
11
|
+
* 协议正文**(ACC 身份/EAP/协作协议,去 acknowledge 尾句——重建后直接干活)。
|
|
12
|
+
* 执行时机:工具只排队(queueRebuild),`agent/turn-stopping` 钩子执行真正 replace
|
|
13
|
+
* (turn 结束前所有 tool/result 已 append → 无孤儿;S141 INVALID_REQUEST 根治)。
|
|
14
|
+
* 服务端逻辑在 ../rebuild.ts(queueRebuild/performRebuild/registerRebuildTurnHook)。
|
|
15
|
+
*/
|
|
16
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
17
|
+
import type { Context } from 'cordis';
|
|
18
|
+
/** 创建 session_rebuild 工具(闭包捕获 ctx → 排队清空重建,turn 结束时同一会话原地重来并自动继续) */
|
|
19
|
+
export declare function createRebuildTool(ctx: Context): ReturnType<typeof defineTool>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session.ts — session 真实 DSH 工具定义(defineTool)
|
|
3
|
+
*
|
|
4
|
+
* AGENT_SESSIONS/ 全周期管理:list/show/create/use/close/health/qa/archive/summary。
|
|
5
|
+
* 行为对齐 osp(opencode-serenity-plugin/src/session/session-tool.ts)——osp 是 ACC 工具 spec:
|
|
6
|
+
* - create:--desc <desc> [--goal <goal>] 或 --issue <id>(二选一)
|
|
7
|
+
* - close:需 --confirm 防误关
|
|
8
|
+
* - archive:name 可缺省(批量归档)
|
|
9
|
+
* - hook-develop-guide 子命令 + CCC session-tool MSM 扩展提示(extHint)
|
|
10
|
+
* CCC 扩展采用 osp 的"钩子后处理"模型(create-transform),而非整命令委派。
|
|
11
|
+
* 活跃会话跟踪:写内存 Map(.dsh/active-sessions/<scope> 语义)+ events 恢复(S134)。
|
|
12
|
+
*
|
|
13
|
+
* v1.21 F3(用户逻辑修正):SESSION 是对话过程中创建的——**use 激活宁静号会话时,
|
|
14
|
+
* 同步把当前 dsh 会话重命名为该 SESSION 目录名**(sessionTitle.rename,user source
|
|
15
|
+
* pin 住标题)。非创建时预命名。
|
|
16
|
+
*/
|
|
17
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
18
|
+
import type { Context } from 'cordis';
|
|
19
|
+
import { type ActiveSessionInfo, type CreateSessionResult } from '../session-ops.js';
|
|
20
|
+
export interface RenameOnUseDeps {
|
|
21
|
+
/** naming.enabled 简单配置(DSH settings) */
|
|
22
|
+
namingEnabled: boolean;
|
|
23
|
+
/** sessionTitle 服务可用性 */
|
|
24
|
+
sessionTitleAvailable: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 从激活会话派生命名标题(v1.22.9 格式修正):
|
|
28
|
+
* F3 原始需求是 **`S###-日期`**(如 `S143-2026-08-26`)——从 `sessionId` 派生,
|
|
29
|
+
* 而非完整目录名(`2026-08-24--S142--...` 超长 + 中文,不符合用户拍板格式)。
|
|
30
|
+
* 无 S### 编号(issue 会话等)→ 回退目录名。
|
|
31
|
+
* @returns `S143-2026-08-26` 或原目录名
|
|
32
|
+
*/
|
|
33
|
+
export declare function namingTitleFor(active: ActiveSessionInfo): string;
|
|
34
|
+
/**
|
|
35
|
+
* use 激活宁静号会话后,把当前 dsh 会话重命名为命名标题(`S###-日期`)。
|
|
36
|
+
* 门控:naming.enabled + sessionTitle 服务存在;失败不静默——返回结果对象
|
|
37
|
+
* 而非 null(v1.22.9),调用方决定可见性。
|
|
38
|
+
*
|
|
39
|
+
* v1.23.2 修复(this 绑定):第三参从**解构的裸 rename 函数**改为**整个
|
|
40
|
+
* sessionTitle 服务对象**——内部以 `titles.rename(session, title)` **方法调用**
|
|
41
|
+
* (this = titles 服务实例)。旧实现调用点 `const rename = titles.rename` 解构
|
|
42
|
+
* 后传入,方法内部读 `this.assertServiceActive` → this=undefined 抛错
|
|
43
|
+
* (日志实证:`Cannot read properties of undefined (reading 'assertServiceActive')`;
|
|
44
|
+
* 与 v1.20.2/1.20.3 图片落盘同款解构丢 this bug)。
|
|
45
|
+
* @returns { title, ok } 或 { ok:false, reason }(未执行/失败均返回对象)
|
|
46
|
+
*/
|
|
47
|
+
export declare function renameDshSessionOnUse(deps: RenameOnUseDeps, session: unknown, titles: {
|
|
48
|
+
rename: (session: unknown, title: string) => unknown;
|
|
49
|
+
} | undefined, active: ActiveSessionInfo): {
|
|
50
|
+
ok: true;
|
|
51
|
+
title: string;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
reason: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* 从 create 结果构造命名用 ActiveSessionInfo(v1.25.11,S142 用户:create 也要命名):
|
|
58
|
+
* createSession 返回的 result 已含 sessionId(S###/issue)与 dirName——无需等待 use 激活,
|
|
59
|
+
* 直接构造(mdPath = sessionPath/SESSION.md,与 use 时一致)即可驱动 renameDshSessionOnUse。
|
|
60
|
+
*/
|
|
61
|
+
export declare function activeInfoFromCreate(result: CreateSessionResult): ActiveSessionInfo;
|
|
62
|
+
/**
|
|
63
|
+
* 把当前 dsh 会话重命名为指定 SESSION 的命名标题(use/create 共用;v1.25.11)。
|
|
64
|
+
* 门控/失败可见性与 renameDshSessionOnUse 一致(不静默:成功 log / 失败 warn)。
|
|
65
|
+
* 调用点(use 分支原内联逻辑提取,create 分支复用):
|
|
66
|
+
* - use:激活后从 activeStore 取 info
|
|
67
|
+
* - create:createSession 结果经 activeInfoFromCreate 构造 info
|
|
68
|
+
*/
|
|
69
|
+
export declare function renameDshSessionForActive(ctx: Context, exec: {
|
|
70
|
+
agent?: {
|
|
71
|
+
session?: unknown;
|
|
72
|
+
};
|
|
73
|
+
}, info: ActiveSessionInfo): void;
|
|
74
|
+
/**
|
|
75
|
+
* 创建 session 工具(闭包捕获插件 ctx → use 后可调 ctx.sessionTitle.rename)。
|
|
76
|
+
* v1.21 F3:use 激活宁静号会话 → 当前 dsh 会话重命名为该 SESSION 目录名。
|
|
77
|
+
*/
|
|
78
|
+
export declare function createSessionTool(ctx: Context): ReturnType<typeof defineTool>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skiff-admin.ts — skiff_admin ACC 工具(F4a',v1.25.0 实验性,第 12 个工具)
|
|
3
|
+
*
|
|
4
|
+
* 教 CCC 如何定义 Skiff 角色(仿 session 工具 hook-develop-guide 的 SEP 教学模式,
|
|
5
|
+
* 用户拍板 2026-08-28:guide 定义教程 / validate 配置校验 / list 角色摘要)。
|
|
6
|
+
*
|
|
7
|
+
* 归属:ACC 机制工具(教会 + 校验),角色内容仍归 CCC 配置(.opencode/serenity.json skiff.roles)。
|
|
8
|
+
*/
|
|
9
|
+
import type { JsonValue } from '../json.js';
|
|
10
|
+
/** Skiff 定义教程(核心):概念 / schema / 认知 MSM 写法 / 双白名单 / 轨迹纪律 / 示例角色 */
|
|
11
|
+
export declare const SKIFF_GUIDE = "\u2550\u2550\u2550 Skiff Definition Guide (F4, experimental) \u2550\u2550\u2550\n\nSkiff = \u5B81\u9759\u53F7\u653E\u51FA\u7684\u72EC\u7ACB\u5C0F\u8247\u2014\u2014\u5B8C\u6574 trajectory\uFF08\u5728\u5B81\u9759\u53F7\u5185\u5168\u77E5\u5168\u80FD\uFF09\u7684**\u4EFB\u610F\u5B50\u96C6\u89D2\u8272**\u3002\n\u7531\u672C CCC\uFF08.opencode/serenity.json skiff.roles\uFF09\u5B9A\u4E49\uFF1A\u80FD\u529B\u9762\uFF08\u53CC\u767D\u540D\u5355\uFF09+ \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6 + \u7CFB\u7EDF\u63D0\u793A\u8BCD\u3002\ndsp \u53EA\u63D0\u4F9B\u673A\u5236\uFF08\u53CC\u767D\u540D\u5355\u5F3A\u5236 + \u57FA\u7840\u63D0\u793A\u8BCD + \u8C03\u8BD5\u95EE\u7B54\u9875\uFF09\uFF1B\u89D2\u8272\u5185\u5BB9\u5B8C\u5168\u7531 CCC \u53D1\u6325\u3002\n\n\u2500\u2500 \u89D2\u8272\u914D\u7F6E schema \u2500\u2500\n { \"skiff\": { \"roles\": {\n \"<role-name>\": {\n \"model\": \"provider/model\", // \u89D2\u8272\u6A21\u578B\uFF08CCC \u76F4\u63A5\u6307\u5B9A\uFF0C\u65E0\u767D\u540D\u5355\u6821\u9A8C\uFF1B\u7F3A\u7701\u56DE\u9000 handyman.defaultModel\uFF09\n \"msms\": [\"msm-a\", \"msm-b\"], // MSM \u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1Aacc_msm exec \u53EA\u80FD\u8DD1\u8FD9\u4E9B\uFF1Bregister/deregister \u5FC5\u62D2\uFF1Blist \u53EA\u663E\u793A\u8FD9\u4E9B\n \"tools\": [\"read\",\"grep\",\"glob\",...], // \u975E MSM \u5DE5\u5177\u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1A\u767D\u540D\u5355\u5916\u5DE5\u5177\u4E00\u5F8B\u4E0D\u53EF\u7528\uFF08guard \u5F3A\u5236\uFF09\n \"trajectory\": { \"session\": false, \"keeper\": false, \"rebuild\": false }, // \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08\u7F3A\u7701\u5168\u5173 = \u5B8C\u5168\u72EC\u7ACB\uFF09\n // \u89D2\u8272\u4EBA\u683C/\u8BA4\u77E5\u8FB9\u754C/\u98CE\u683C\uFF08CCC \u5B8C\u6574\u5B9A\u4E49\uFF1Bdsp \u53EA\u7ED9\u57FA\u7840\u63D0\u793A\u8BCD\uFF09\n \"systemPromptFile\": \".opencode/skiff/<role>.md\" // \u2605 \u63A8\u8350\uFF1A\u5F15\u7528 md \u6587\u4EF6\uFF08\u76F8\u5BF9 CCC \u6839\uFF1B\u8D85\u957F\u63D0\u793A\u8BCD\u5728 JSON \u5185\u5D4C\u4E0D\u53EF\u8BFB\uFF09\n // \"systemPrompt\": \"...\" // \u517C\u5BB9\uFF1A\u5185\u5D4C\u5B57\u7B26\u4E32\u4ECD\u53EF\u7528\uFF1B\u4E24\u8005\u90FD\u8BBE\u65F6 systemPromptFile \u4F18\u5148\n }\n } } }\n\n\u2500\u2500 \u53CC\u767D\u540D\u5355\u8BED\u4E49\uFF08\u5168\u6309\u767D\u540D\u5355\u66B4\u9732\uFF0C\u767D\u540D\u5355\u5916\u5168\u9690\u85CF\uFF09\u2500\u2500\n - tools \u7A7A + msms \u975E\u7A7A = \u7EAF MSM \u89D2\u8272\uFF08\u8BA4\u77E5\u95EE\u7B54\u5178\u578B\u5F62\u6001\uFF09\n - msms \u975E\u7A7A \u2192 acc_msm \u5DE5\u5177\u81EA\u52A8\u53EF\u7528\uFF08MSM \u901A\u9053\uFF09\n - \u767D\u540D\u5355\u5916\u5DE5\u5177\u5373\u4F7F DSH \u672A\u6765\u65B0\u589E\u4E5F\u81EA\u52A8\u88AB\u6321\uFF08guard \u6309\u89D2\u8272\u5224\u5B9A\uFF0C\u4E0D\u679A\u4E3E\u5DE5\u5177\u540D\u2014\u2014\u5B8C\u5907\u6027\uFF09\n\n\u2500\u2500 \u8BA4\u77E5 MSM \u5199\u6CD5\uFF08\u8BFB\u77E5\u8BC6 / \u64CD\u4F5C\u80FD\u529B\uFF09\u2500\u2500\n - \u8BFB\u77E5\u8BC6\uFF1A\u811A\u672C\u8BFB CCC \u5185\u6587\u4EF6\uFF08SERENITY_ROOT env \u6CE8\u5165\uFF09\u2192 \u8F93\u51FA\u7B54\u6848/\u6458\u8981\uFF08\u5982 cognitive-qa\uFF09\n - \u64CD\u4F5C\u80FD\u529B\uFF1A\u811A\u672C\u8C03\u7528\u65E2\u6709\u5BB6\u5EAD\u5DE5\u5177/\u670D\u52A1\uFF08SSH/API/\u6587\u4EF6\u64CD\u4F5C\uFF09\u2014\u2014\u89D2\u8272\u80FD\u529B\u4E0A\u9650 = \u767D\u540D\u5355 MSM \u7684\u5B9E\u9645\u884C\u4E3A\n - \u4F8B\uFF1Acognitive-qa\uFF08\u8BFB docs/references \u56DE\u7B54\uFF09\u3001review-scan\uFF08\u8BFB\u4EE3\u7801\u51FA\u5BA1\u67E5\u610F\u89C1\uFF09\u3001review-fix\uFF08\u5199\u4FEE\u590D\uFF09\n - \u6CE8\u610F\uFF1AMSM \u5728\u811A\u672C\u5C42\u6267\u884C\uFF08bun\uFF09\uFF0C\u6587\u4EF6\u8BBF\u95EE\u4E0D\u53D7 agent \u5DE5\u5177\u9762\u7EA6\u675F\u2014\u2014\"\u53EA\u8BFB\"\u8BED\u4E49\u9760 CCC \u81EA\u5199 MSM \u81EA\u89C9\n\n\u2500\u2500 \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08trajectory\uFF09\u2500\u2500\n - session/keeper/rebuild \u9ED8\u8BA4 false\uFF1ASkiff \u5B8C\u5168\u72EC\u7ACB\uFF08\u4E0D\u5EFA SESSION.md\u3001\u65E0 keeper \u63D0\u9192\u3001\u65E0 rebuild \u538B\u529B\u68C0\u6D4B\uFF09\n - \u5F00\u542F\u67D0\u9879 = \u8BE5\u89D2\u8272\u53C2\u4E0E\u5BF9\u5E94\u8F68\u8FF9\u673A\u5236\uFF08\u5982 keeper=true \u8BA1\u5206\u63D0\u9192\u6309\u89D2\u8272\u751F\u6548\uFF09\n\n\u2500\u2500 \u793A\u4F8B\u89D2\u8272 \u2500\u2500\n qa-readonly: { \"msms\": [\"cognitive-qa\"], \"tools\": [], \"trajectory\": {} }\n \u2192 \u8BA4\u77E5\u95EE\u7B54\uFF08\u4EC5 MSM \u901A\u9053\uFF0C\u65E0\u76F4\u63A5\u5DE5\u5177\uFF0C\u5B8C\u5168\u72EC\u7ACB\uFF09\n code-review: { \"msms\": [\"review-scan\",\"review-fix\"], \"tools\": [\"read\",\"grep\",\"glob\",\"write\",\"edit\"], \"trajectory\": { \"keeper\": true } }\n \u2192 \u6709\u64CD\u4F5C\u80FD\u529B\uFF08\u53EF\u5199\u4FEE\u590D\uFF09\uFF0C\u53C2\u4E0E keeper \u8F68\u8FF9\u673A\u5236\n\n\u2500\u2500 \u8FD0\u884C \u2500\u2500\n \u8C03\u8BD5\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CSerenity\u300D\u9875 Skiff \u533A\u5757\u5F00\u542F \u2192 http://127.0.0.1:<debugPort> \u95EE\u7B54\u9875\u5B9E\u6D4B\n ACP \u7A0B\u5E8F\u5316\u9762\uFF08v1.26.0\uFF09\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CACP\u300D\u533A\u5757\u5F00\u542F \u2192 HTTP JSON-RPC \u7AEF\u70B9\uFF08\u9ED8\u8BA4 3100\uFF09\u2014\u2014\n POST / {jsonrpc, id, method, params}\n session/new {ccc, role, sessionId?} \u2192 \u521B\u5EFA/\u5EF6\u7EED\u4F1A\u8BDD\uFF08sessionId \u53EF\u9009=\u8FDB\u7A0B\u5185\u8FFD\u95EE\uFF09\n session/prompt {sessionId, question} \u2192 {answer, trajectory}\n session/cancel / session/close / session/list / request_permission\uFF08\u6052 allow\uFF09\n \u542F\u505C = \u4EBA\u5DE5\uFF08\u8BBE\u7F6E\u9762\u677F\u5F00\u5173\uFF0C\u4E0D\u968F\u63D2\u4EF6\u52A0\u8F7D\u81EA\u52A8\u542F\u52A8\uFF09\uFF1B\u672A\u5F00\u542F\u96F6\u8D44\u6E90\u5360\u7528\n \u751F\u6548\u673A\u5236\uFF1A\u89D2\u8272\u914D\u7F6E**\u5B9E\u65F6\u8BFB\u53D6**\uFF08\u6539 .opencode/serenity.json \u2192 \u5237\u65B0\u8C03\u8BD5\u9875\u5373\u751F\u6548\uFF09\uFF1B\n \u6539\u914D\u7F6E\u540E\u7528 skiff_admin apply \u505A\u663E\u5F0F\u6821\u9A8C + \u5E94\u7528\u786E\u8BA4\uFF08\u7ED1\u5B9A CCC + \u89D2\u8272\u6E05\u5355\uFF09\n \u4F1A\u8BDD\u8FFD\u95EE\uFF08v1.25.10\uFF09\uFF1A\u8C03\u8BD5\u9875\u6301\u6709\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8FFD\u95EE\u81EA\u52A8\u7EED\u63A5\uFF08\u540C\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u5EF6\u7EED\uFF09\uFF1B\n \u300C\u65B0\u5BF9\u8BDD\u300D\u6309\u94AE\u5F00\u65B0\u4F1A\u8BDD\uFF1B\u8FDB\u7A0B\u91CD\u542F\u540E\u65E7\u4F1A\u8BDD\u4E0D\u53EF\u7EED\uFF08WebUI \u4ECD\u53EF\u89C1\u5386\u53F2\uFF09\n \u6CE8\u610F\uFF1Askill \u52A0\u8F7D\u5BF9 skiff **\u6052\u53EF\u7528**\uFF08\u4E0D\u8BBE\u767D\u540D\u5355\u2014\u2014\u8BFB\u77E5\u8BC6\u9762\uFF0C\u65E0\u5199\u80FD\u529B\uFF09";
|
|
12
|
+
/** 校验当前 CCC 的 skiff 配置:roles schema 合法 / msms 均已注册 / model ∈ handyman.models / systemPrompt 非空 */
|
|
13
|
+
export declare function validateSkiffConfig(root: string): JsonValue;
|
|
14
|
+
/** 列出当前 CCC 已定义角色(名 / 模型 / msms / tools / 轨迹纪律摘要) */
|
|
15
|
+
export declare function listSkiffRoles(root: string): JsonValue;
|
|
16
|
+
/**
|
|
17
|
+
* 应用当前 skiff 配置(v1.25.3,S142 用户:改了 json 应该有个生效机制)。
|
|
18
|
+
*
|
|
19
|
+
* 语义:配置是**每次请求实时读取**的(v1.25.2)——apply 不是"推送",而是**显式校验 + 应用确认**:
|
|
20
|
+
* ① 校验配置合法(复用 validate:msms 注册 / model 白名单 / systemPrompt 非空)
|
|
21
|
+
* ② 非法 → 报告问题清单,不应用(提示修复后重跑 apply)
|
|
22
|
+
* ③ 合法 → 应用确认:绑定 CCC + 角色清单 + 说明(调试页刷新即生效)
|
|
23
|
+
*/
|
|
24
|
+
export declare function applySkiffConfig(root: string): JsonValue;
|
|
25
|
+
export declare const skiffAdminTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
package/lib/totp.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* totp.ts — TOTP 第二因素(RFC 6238,零依赖,v1.22.4)
|
|
3
|
+
*
|
|
4
|
+
* 背景(S142 安全审计 S1):公网暴露密码登录不足 → 可选 Authenticator 第二因素。
|
|
5
|
+
* 实现:HMAC-SHA1 TOTP(与 Google Authenticator / 1Password / Aegis 等兼容),
|
|
6
|
+
* base32 secret(RFC 4648 无填充),30s 时步,6 位码,允许 ±1 时步漂移。
|
|
7
|
+
* 零依赖(node:crypto HMAC),可单测。
|
|
8
|
+
*
|
|
9
|
+
* 边界:本模块只做纯算法(生成/校验/URI),secret 的存储/绑定由 config-ops +
|
|
10
|
+
* gateway 登录流负责(wire 层永不返回 secret,只返回 hasTotp 布尔)。
|
|
11
|
+
*/
|
|
12
|
+
/** 时步(秒)——RFC 6238 默认 30 */
|
|
13
|
+
export declare const TOTP_STEP_SECONDS = 30;
|
|
14
|
+
/** 验证窗口:当前时步 ± 1(容忍时钟漂移/生成延迟) */
|
|
15
|
+
export declare const TOTP_WINDOW = 1;
|
|
16
|
+
/** 输出位数(标准 6 位) */
|
|
17
|
+
export declare const TOTP_DIGITS = 6;
|
|
18
|
+
/** 字节 → base32(无填充)。secret 显示/otpauth URI 用。 */
|
|
19
|
+
export declare function base32Encode(bytes: Uint8Array): string;
|
|
20
|
+
/** base32(无填充,大小写不敏感)→ 字节;非法字符抛错。 */
|
|
21
|
+
export declare function base32Decode(input: string): Uint8Array;
|
|
22
|
+
/** 生成新 TOTP secret(20 字节 = 160-bit,RFC 4226 推荐 ≥128-bit;返回 base32) */
|
|
23
|
+
export declare function generateTotpSecret(): string;
|
|
24
|
+
/** 一个时步的 TOTP code(6 位,前导零保留)。counter = floor(epochSeconds / step) */
|
|
25
|
+
export declare function totpCode(secretBase32: string, counter: number): string;
|
|
26
|
+
/** 当前 epoch 秒 */
|
|
27
|
+
export declare function nowEpochSeconds(): number;
|
|
28
|
+
/**
|
|
29
|
+
* 校验用户输入的 code(允许 ±TOTP_WINDOW 时步漂移,防重放窗口内同 code 复用由
|
|
30
|
+
* 调用方按账号记录最近成功 counter 实现——本函数只做纯算法校验)。
|
|
31
|
+
* @returns 命中的 counter(用于防重放);不匹配返回 null。
|
|
32
|
+
*/
|
|
33
|
+
export declare function verifyTotpCode(secretBase32: string, code: string, nowSeconds?: number): number | null;
|
|
34
|
+
/**
|
|
35
|
+
* 生成 otpauth://totp URI(标准格式,主流 Authenticator 兼容)。
|
|
36
|
+
* @param secretBase32 - base32 secret
|
|
37
|
+
* @param label - 账号标识(如 "yh@serenity-home")
|
|
38
|
+
* @param issuer - 发行方(如 "Serenity Home")
|
|
39
|
+
*/
|
|
40
|
+
export declare function otpauthUri(secretBase32: string, label: string, issuer: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.16",
|
|
4
4
|
"description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"lib/index.js",
|
|
26
26
|
"lib/client.js",
|
|
27
27
|
"lib/invariant.js",
|
|
28
|
-
"lib
|
|
28
|
+
"lib/*.js",
|
|
29
|
+
"lib/*.d.ts",
|
|
30
|
+
"lib/**/*.d.ts",
|
|
29
31
|
"cordis.patch.yml",
|
|
30
32
|
"dsh.plugin.json",
|
|
31
33
|
"README.md",
|
|
@@ -35,8 +37,8 @@
|
|
|
35
37
|
"scripts": {
|
|
36
38
|
"typecheck": "tsc --noEmit",
|
|
37
39
|
"test": "vitest run",
|
|
38
|
-
"build": "
|
|
39
|
-
"prepare": "tsdown --config tsdown.prepare.config.ts"
|
|
40
|
+
"build": "tsdown -c tsdown.config.ts && tsc -p tsconfig.json --emitDeclarationOnly",
|
|
41
|
+
"prepare": "tsdown --config tsdown.prepare.config.ts && tsc -p tsconfig.json --emitDeclarationOnly"
|
|
40
42
|
},
|
|
41
43
|
"dsh": {
|
|
42
44
|
"bundle": {
|