@shgroup/dsh-serenity-hooks 1.26.14 → 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.
Files changed (58) hide show
  1. package/dsh.plugin.json +1 -1
  2. package/lib/acp-core.d.ts +100 -0
  3. package/lib/acp-http.d.ts +29 -0
  4. package/lib/api.d.ts +47 -0
  5. package/lib/autotrajectory.d.ts +186 -0
  6. package/lib/ccc-CfDrlfA7.js +141 -0
  7. package/lib/ccc.d.ts +154 -0
  8. package/lib/config-ops.d.ts +166 -0
  9. package/lib/constants.d.ts +8 -0
  10. package/lib/fs-ops.d.ts +36 -0
  11. package/lib/gateway-auth.d.ts +89 -0
  12. package/lib/gateway-proxy.d.ts +39 -0
  13. package/lib/gateway.d.ts +80 -0
  14. package/lib/git-ops.d.ts +28 -0
  15. package/lib/handyman-ops.d.ts +68 -0
  16. package/lib/handyman-preset-inherit.d.ts +34 -0
  17. package/lib/index.d.ts +68 -0
  18. package/lib/index.js +2172 -1992
  19. package/lib/invariant.d.ts +29 -0
  20. package/lib/json.d.ts +9 -0
  21. package/lib/kit-ops.d.ts +23 -0
  22. package/lib/localstore-ops.d.ts +85 -0
  23. package/lib/msm-ops.d.ts +78 -0
  24. package/lib/output-guard-seam.d.ts +21 -0
  25. package/lib/output-guard.d.ts +68 -0
  26. package/lib/rebuild.d.ts +118 -0
  27. package/lib/seams/bootstrap.d.ts +83 -0
  28. package/lib/seams/compact.d.ts +31 -0
  29. package/lib/seams/context.d.ts +48 -0
  30. package/lib/seams/env.d.ts +16 -0
  31. package/lib/seams/guards.d.ts +72 -0
  32. package/lib/seams/keeper.d.ts +61 -0
  33. package/lib/seams/opencode-skills.d.ts +14 -0
  34. package/lib/seams/system-prompt.d.ts +113 -0
  35. package/lib/session-ops.d.ts +127 -0
  36. package/lib/settings-section.d.ts +113 -0
  37. package/lib/skiff-core.d.ts +78 -0
  38. package/lib/skiff-debug.d.ts +86 -0
  39. package/lib/skiff-registry.d.ts +25 -0
  40. package/lib/skiff-role.d.ts +50 -0
  41. package/lib/skills/opencode-scan.d.ts +27 -0
  42. package/lib/skills-discovery.d.ts +25 -0
  43. package/lib/status.d.ts +38 -0
  44. package/lib/tools/autotrajectory-exp.d.ts +24 -0
  45. package/lib/tools/cc-fs.d.ts +7 -0
  46. package/lib/tools/cce.d.ts +9 -0
  47. package/lib/tools/eap.d.ts +7 -0
  48. package/lib/tools/git.d.ts +4 -0
  49. package/lib/tools/handyman.d.ts +43 -0
  50. package/lib/tools/kit.d.ts +4 -0
  51. package/lib/tools/localstore.d.ts +8 -0
  52. package/lib/tools/msm.d.ts +4 -0
  53. package/lib/tools/neat.d.ts +5 -0
  54. package/lib/tools/rebuild.d.ts +19 -0
  55. package/lib/tools/session.d.ts +78 -0
  56. package/lib/tools/skiff-admin.d.ts +25 -0
  57. package/lib/totp.d.ts +40 -0
  58. package/package.json +6 -4
@@ -0,0 +1,29 @@
1
+ /**
2
+ * invariant.ts — 包级不变量伴生(dsh-my-rsi creating-a-plugin 规范)
3
+ *
4
+ * 检查:dsh.plugin.json 的 contributes.tools 与代码实际注册的工具一致。
5
+ * 挂载时 plugin-local 会校验清单;本不变量让仓库内 `verify-package-invariants`
6
+ * 类门禁也可直接调用。
7
+ */
8
+ export interface PluginManifest {
9
+ id: string;
10
+ version?: string;
11
+ main?: string;
12
+ description?: string;
13
+ engines?: {
14
+ dsh?: string;
15
+ };
16
+ contributes?: {
17
+ tools?: string[];
18
+ skills?: string[];
19
+ };
20
+ }
21
+ /** 读取插件清单;缺失/非法返回 null */
22
+ export declare function readPluginManifest(manifestPath: string): PluginManifest | null;
23
+ /**
24
+ * 校验清单声明的工具与代码注册的工具一致。
25
+ * 返回不一致项列表(空 = 通过)。
26
+ */
27
+ export declare function verifyToolConsistency(manifestPath: string, registeredTools: readonly string[]): string[];
28
+ /** 包级不变量:本插件注册的工具集合(与 dsh.plugin.json contributes.tools 一致) */
29
+ export declare const REGISTERED_TOOLS: readonly ["cc_fs", "session", "acc_kit", "cc_git", "acc_msm", "eap", "neat", "cce", "handyman", "session_rebuild", "localstore", "skiff_admin"];
package/lib/json.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * json.ts — 本地 JsonValue 类型(与 DSH 的 JsonValue 同构)
3
+ *
4
+ * 纯层(fs-ops/session-ops)保持零 DSH 运行时依赖:仅用本地类型标注,
5
+ * 工具层(defineTool)要求 execute 返回 DSH JsonValue,二者结构等价。
6
+ */
7
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
8
+ [key: string]: JsonValue;
9
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * kit-ops.ts — acc_kit 纯操作层(零 DSH 依赖)
3
+ *
4
+ * 行为对齐 osp(opencode-serenity-plugin/src/acc-kit.ts)——osp 是 ACC 工具 spec:
5
+ * - health:{ccc, root, version, status: healthy|degraded, principles: {P1_rooted, P2_git_managed, P3_binary_permissions}}
6
+ * - time:{now_iso, now_local, epoch_ms}
7
+ * - wait:缺省 1s(正整数秒),返回 'waited Ns' 文本
8
+ * 平台适配:P3 在 osp 检查 opencode.json,DSH 无 opencode.json → 检查 DSH/opencode 配置路径
9
+ * (.opencode/serenity.json / .dsh/serenity.json 等,见 DEFAULT_SERENITY_CONFIG_PATHS)。
10
+ * CCC 缺失时返回 degraded 报告而非抛错(对齐 osp 未激活语义)。
11
+ * 保留 dsp 增强:accVersion/dshVersion 版本自省字段。
12
+ * wait 用纯 Node setTimeout——不依赖外部 sleep 可执行文件(Windows 无 GNU coreutils sleep)。
13
+ */
14
+ import { loadSerenityConfig } from './ccc.js';
15
+ import type { JsonValue } from './json.js';
16
+ export type KitAction = 'health' | 'time' | 'wait';
17
+ export declare const KIT_ACTIONS: readonly KitAction[];
18
+ export interface KitArgs {
19
+ action: KitAction;
20
+ seconds?: number;
21
+ }
22
+ export declare function runKit(root: string | null, args: KitArgs): Promise<JsonValue>;
23
+ export { loadSerenityConfig };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * localstore-ops.ts — localstore 纯逻辑层(零 DSH 依赖,可独立单测)
3
+ *
4
+ * S134 重设计(v1.16.7):存储从 ~/.serenity/ 迁到 **CCC 根根目录 localstore.json**
5
+ * (JSON 格式——方便 MSM 直接 read + JSON.parse 读取,零解析依赖)。
6
+ *
7
+ * git 提交策略(可靠机制 × 用户自由):
8
+ * - 配置:.opencode/serenity.json `localstore.gitTrack`: "allow"(可提交)| "deny"(禁提交)
9
+ * - **缺省 deny(没配就是不提交)**;且 deny 的保证**不依赖 dsh 运行**——
10
+ * 写入时自动确保 .gitignore 含 localstore.json(物理保证:即使 dsh 不在、
11
+ * 用户手动 git commit 也不会误提交),cc_git 检查为第二道防线(拒绝 + 提示)
12
+ * - allow:放行(文件可提交,用户自行管理 .gitignore)
13
+ *
14
+ * 存储结构(JSON 顶层分节):
15
+ * { "credentials": { "HOME_GITLAB_TOKEN": "xxx" }, "<config节>": { "<key>": "v" } }
16
+ * credentials 为保留节(credential 命名空间,key 大写蛇形);其余节归 config 命名空间
17
+ * (path = section.key,如 handyman.models)。
18
+ */
19
+ import type { JsonValue } from './json.js';
20
+ /** 命名空间:credential(凭据)| config(配置) */
21
+ export type LocalStoreScope = 'credential' | 'config';
22
+ export declare const LOCALSTORE_SCOPES: readonly LocalStoreScope[];
23
+ /** 存储文件名(CCC 根根目录) */
24
+ export declare const LOCALSTORE_FILENAME = "localstore.json";
25
+ /** 凭据保留节名(JSON 顶层) */
26
+ export declare const CREDENTIALS_SECTION = "credentials";
27
+ /** 凭据 key 规范:大写蛇形,如 HOME_GITLAB_TOKEN */
28
+ export declare const CREDENTIAL_KEY_RE: RegExp;
29
+ /** 配置节名规范:小写字母数字连字符 */
30
+ export declare const CONFIG_SECTION_RE: RegExp;
31
+ /** 配置 key 规范(节内):小驼峰,如 defaultModel */
32
+ export declare const CONFIG_KEY_RE: RegExp;
33
+ /** git 提交策略 */
34
+ export type GitTrack = 'allow' | 'deny';
35
+ /** 存储文件绝对路径(CCC 根根目录) */
36
+ export declare function localstorePath(root: string): string;
37
+ /** git 策略:serenity.json localstore.gitTrack,缺省 deny(不提交) */
38
+ export declare function readGitTrack(root: string, paths?: string[]): GitTrack;
39
+ /** .gitignore 是否已覆盖 localstore 文件(非空非注释行含文件名即算) */
40
+ export declare function isLocalstoreGitignored(root: string): boolean;
41
+ /**
42
+ * 确保 .gitignore 含 localstore 文件(deny 时的物理保证,不依赖 dsh 运行):
43
+ * 写入 localstore 时调用——deny(含缺省)且 .gitignore 未覆盖 → 自动追加一行。
44
+ * allow → 不写入(放行,文件可提交)。
45
+ */
46
+ export declare function ensureLocalstoreGitignored(root: string): {
47
+ status: 'allow' | 'ignored' | 'appended';
48
+ };
49
+ /**
50
+ * cc_git 联动检查(第二道防线):文件存在 && deny && .gitignore 未覆盖 → 不通过。
51
+ * 调用方(cc_git commit)据此拒绝提交;status 可输出 warning。
52
+ */
53
+ export declare function checkLocalstoreGitCompliance(root: string): {
54
+ ok: boolean;
55
+ reason?: string;
56
+ };
57
+ /** 读取命名空间全部条目:credential → 扁平;config → 分节(剔除 credentials 保留节) */
58
+ export declare function readStore(root: string, scope: LocalStoreScope): Record<string, string> | Record<string, Record<string, string>>;
59
+ /** 校验凭据 key 合法(大写蛇形);不合法抛错 */
60
+ export declare function assertCredentialKey(key: string): void;
61
+ /** 校验 config 路径(节.key);不合法抛错 */
62
+ export declare function assertConfigPath(path: string): {
63
+ section: string;
64
+ key: string;
65
+ };
66
+ /** 写入单个条目(自动建文件;deny 默认时同步确保 .gitignore 物理保证) */
67
+ export declare function writeEntry(root: string, scope: LocalStoreScope, name: string, value: string): void;
68
+ /** 删除单个条目(不存在返回 false);空节自动移除 */
69
+ export declare function unsetEntry(root: string, scope: LocalStoreScope, name: string): boolean;
70
+ /** 读取单个条目值;不存在返回 null */
71
+ export declare function getEntry(root: string, scope: LocalStoreScope, name: string): string | null;
72
+ /** 列出 key(凭据只返回 key 名,不返回值) */
73
+ export declare function listKeys(root: string, scope: LocalStoreScope): string[];
74
+ /**
75
+ * doc 说明文本:输出存储位置/格式/key 规范/git 策略/读写方法。
76
+ * agent 据此可直接用 fs 工具(read/write)自己读写凭据/配置。
77
+ */
78
+ export declare function docText(root: string): string;
79
+ /** 运行 localstore 操作(纯逻辑;返回 JSON 值供工具 render) */
80
+ export declare function runLocalStore(root: string, args: {
81
+ action: string;
82
+ name?: string;
83
+ value?: string;
84
+ scope?: string;
85
+ }): JsonValue;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * msm-ops.ts — acc_msm 纯操作层(零 DSH 依赖)
3
+ *
4
+ * MSM(Mech & Semi-Mech)框架:list / exec / admin(register|deregister|check)。
5
+ * 复用 CCC 的 mech-registry.json(v1 或数组格式)。cwd 钉在 CCC 根。
6
+ */
7
+ import type { JsonValue } from './json.js';
8
+ export declare const MSM_TIMEOUT_MS = 600000;
9
+ /** CCC 名:从 .serenity 首行解析(对齐 osp readSerenityCccName) */
10
+ export declare function readCccName(root: string): string | null;
11
+ export type MsmAction = 'list' | 'exec' | 'register' | 'deregister' | 'check' | 'guide' | 'ccc-config';
12
+ export declare const MSM_ACTIONS: readonly MsmAction[];
13
+ export declare const MSM_GUIDE = "MSM Development Manual (Mech & Semi-Mech framework)\n\n## What it is\nMSM = the executable-unit layer. Mech is pure TS with zero LLM reasoning; Semi-Mech is a TS framework + LLM decision points.\nMSM is ACC's deterministic executable-unit layer \u2014 all shell/exec operations go through MSM and cannot be bypassed.\n\n## Registering a new MSM (acc_msm register)\n1. Write the script under <skill>/scripts/ (runnable via tsx; must include a main() CLI guard with an import.meta.url check)\n2. acc_msm register <name> --skill <s> --path <script path relative to root> --category <mech|semi-mech> --description <desc>\n3. Auto-writes mech-registry.json (preserving the original format) + git commit (commits only the registry file)\n4. Validation: path must be inside root, script must exist, name must be globally unique\n\n## flag schema (v1)\nflags is a new-style object array for parameter validation and path-escape guarding:\n [{\"name\":\"output\",\"type\":\"string\",\"description\":\"output path\"},\n {\"name\":\"target\",\"type\":\"path\",\"description\":\"operation target (type:path enables in-root validation + symlink defense)\"},\n {\"name\":\"force\",\"type\":\"boolean\",\"description\":\"force mode\",\"default\":false}]\n- {name, type} format \u2014 new style, type:\"path\" enables the path-escape guard\n- {flag, description} format \u2014 old style, CLI flag description string\n- On registration, flags are passed via acc_msm register --flags '<json>' (the tool currently parses the name style)\n\n## Script conventions\n- Top-of-file documentation: purpose / usage / exit codes\n- Exit codes: 0 success / 1 user / 2 system / 3 operator (per ACC protocol classification)\n- main() CLI guard (DC-M2): the script must start with\n if (import.meta.url === `file://${process.argv[1]}`) { main() }\n or an equivalent isMain / require.main === check \u2014 so vitest imports never trigger top-level code\n- A paired .test.ts or .spec.ts (DC-M1, vitest)\n- Business subprocess environment: SERENITY_ROOT / SERENITY_CCC / SERENITY_VERSION injected\n\n## Interaction & confirmation conventions (no blocking confirmation)\n- MSMs run in **user-less subprocesses** (spawn/execFile, 600s timeout) \u2014 **never** use\n readline / prompt / process.stdin etc. to block waiting for user input (it would hang until killed by the timeout)\n- When a second confirmation is needed: **directly return the confirmation request** (list the operation to perform and its impact + how to retry with the confirmation flag),\n returning a non-zero exit code (or an explicit hint)\n- After the agent confirms, **re-invoke the MSM with the confirmation flag** (e.g. --confirm / --yes / --force) to retry\n- Standard mode (two-phase):\n 1. First call: destructive/confirmation-requiring operation detected and no confirmation flag present \u2192 output the confirmation request (list operation/impact/rollback),\n exit non-zero (e.g. 1 user), **perform no changes**\n 2. After the agent evaluates, re-invoke: with the confirmation flag \u2192 execute and output the result\n- Applies to: delete/overwrite/push/batch operations and other irreversible or wide-impact operations\n- Anti-example (forbidden): readline waiting for user input, process.stdin.on('data') blocking waits\n (MSMs have no stdin interaction channel \u2014 they hang until the 600s timeout)\n\n## Quality checks (acc_msm check, DC-M1~M4)\nDC-M1 has .test.ts/.spec.ts; DC-M2 has a main() guard (function main( / isMain / require.main === / import.meta.url);\nDC-M3 bidirectional: scripts unregistered + registry references missing scripts; DC-M4 path-type flags marked type:\"path\"\n\n## Self-description (protocol flags, first argument only)\nacc_msm exec <name> --list \u2014 list all MSMs\nacc_msm exec <name> --schema <n> \u2014 view a specific MSM's parameter schema\nacc_msm exec <name> --format=json \u2014 JSON output mode (remaining args passed through losslessly)\n";
14
+ /** CCC 配置参考(对齐 osp ccc-config action) */
15
+ export declare const CCC_CONFIG_REFERENCE = "\u2550\u2550\u2550 CCC Configuration Reference \u2550\u2550\u2550\n\nCCC-level features are configured in .opencode/serenity.json.\nBelow are all available configuration sections.\n\n\u2500\u2500 1. handyman.models \u2500\u2500\nhandyman\uFF08\u6742\u5DE5\uFF09\u5DE5\u5177\u53EF\u7528\u6A21\u578B\u767D\u540D\u5355\uFF08provider/model \u5217\u8868\uFF09\uFF1B\u672A\u914D\u7F6E\u65F6 handyman \u62A5\u9519\u8981\u6C42\u914D\u7F6E\u3002\n\u7F3A\u7701\u6A21\u578B = models[0]\uFF08\u53EF\u7528 handyman.defaultModel \u6307\u5B9A\uFF0C\u5FC5\u987B \u2208 models\uFF09\u3002\n\n Config:\n { \"handyman\": { \"models\": [\"provider/model-name\"] } }\n\n Example:\n { \"handyman\": { \"models\": [\"minimax-cn-coding-plan/MiniMax-M3\"], \"defaultModel\": \"minimax-cn-coding-plan/MiniMax-M3\", \"maxRounds\": 100, \"maxParallel\": 10 } }\n\n\u2500\u2500 2. sessionKeeper.threshold \u2500\u2500\nSESSION-KEEPER \u63D0\u9192\u673A\u5236\u7684\u79EF\u5206\u9608\u503C\uFF08\u975E headless \u4E3B agent\uFF09\u3002\n\u6309\u5DE5\u5177\u8C03\u7528\u52A0\u6743 + \u8017\u65F6\u8BA1\u5206\uFF1B\u8FBE\u5230\u9608\u503C\u6CE8\u5165\u63D0\u9192\uFF0C\u8981\u6C42\u6A21\u578B\u56DE\u590D ACK \u7801\u3002\n\n Config:\n { \"sessionKeeper\": { \"threshold\": 150 } }\n\n \u8BA1\u5206\uFF1Awrite/edit = 3\uFF0Ctask = 10\uFF0Cread/grep/glob/msm \u7B49 = 1\uFF0C\u65F6\u95F4 = 1/\u5206\u949F\n \u9ED8\u8BA4\uFF1A150\n\n\u2500\u2500 3. localstore.gitTrack \u2500\u2500\nlocalstore.json \u7684 git \u7B56\u7565\uFF1Aallow \u53EF\u63D0\u4EA4 / deny \u7981\u63D0\u4EA4\uFF08\u9ED8\u8BA4 deny\uFF09\u3002\ndeny \u65F6\u5199\u5165\u81EA\u52A8\u786E\u4FDD .gitignore \u542B\u8BE5\u6587\u4EF6\uFF08\u7269\u7406\u4FDD\u8BC1\uFF09\uFF0Ccc_git commit \u4F1A\u68C0\u67E5\u62D2\u7EDD\u3002\n\n Config:\n { \"localstore\": { \"gitTrack\": \"allow\" } }\n\n\u2500\u2500 4. hooks.autoRestoreSession \u2500\u2500\n\u4F1A\u8BDD\u81EA\u52A8\u6062\u590D\uFF08\u9ED8\u8BA4 true\uFF1B\u53D7 events \u95E8\u63A7\u2014\u2014\u4EC5\u6839\u4F1A\u8BDD + \u5DF2\u6709\u5BF9\u8BDD\u5386\u53F2\u624D\u6062\u590D\uFF09\u3002\n\n Config:\n { \"hooks\": { \"autoRestoreSession\": false } }\n\n\u2500\u2500 5. safeMode / blacklist \u2500\u2500\nsafe-mode \u7531 WebUI \u5F00\u5173\u63A7\u5236\uFF08\u5199 .serenity-safe-on \u6807\u8BB0\uFF09\uFF1B\u9ED1\u540D\u5355\u8DEF\u5F84\u53D7 guards seam \u62E6\u622A\u3002\n\n Config:\n { \"safeMode\": { \"blacklist\": [\".secrets/\"] } }\n";
16
+ export interface MsmFlag {
17
+ name: string;
18
+ type?: string;
19
+ description?: string;
20
+ required?: boolean;
21
+ default?: unknown;
22
+ }
23
+ export interface MsmEntry {
24
+ name: string;
25
+ path: string;
26
+ skill?: string;
27
+ category?: string;
28
+ description?: string;
29
+ usage?: string;
30
+ flags?: MsmFlag[];
31
+ }
32
+ export interface MsmArgs {
33
+ action: MsmAction;
34
+ name?: string;
35
+ args?: string[];
36
+ skill?: string;
37
+ path?: string;
38
+ category?: string;
39
+ description?: string;
40
+ /** register: flags JSON 字符串(对齐 osp --flags 入参;如 '[{"name":"hook","type":"string",...}]') */
41
+ flags?: string;
42
+ /** register: 自定义 usage(缺省 'acc_msm exec <name> [args...]') */
43
+ usage?: string;
44
+ }
45
+ export declare function parseRegistry(raw: string): MsmEntry[];
46
+ export declare function findRegistries(root: string): string[];
47
+ export declare function loadMsmEntries(root: string): MsmEntry[];
48
+ export declare function findEntry(root: string, name: string): MsmEntry | null;
49
+ /** 扫描各 skill scripts/ 下的非测试脚本(DC-M3 正向基准,对齐 osp) */
50
+ export declare function scanSkillScripts(root: string): string[];
51
+ export declare function runMsm(root: string, args: MsmArgs): JsonValue;
52
+ /** 解析并校验 exec 参数:返回可执行条目 + 业务参数(list/schema 协议 flag 已分流) */
53
+ export interface PreparedExec {
54
+ entry: MsmEntry;
55
+ businessArgs: string[];
56
+ fmtJson: boolean;
57
+ /** 业务参数是否含 --help/-h(exit≠0 时不追加 TIP,对齐 osp) */
58
+ hasHelp: boolean;
59
+ /** 协议结果(--list / --schema);非协议执行时为 undefined */
60
+ protocol?: {
61
+ list: {
62
+ name: string;
63
+ category: string | null;
64
+ }[];
65
+ } | {
66
+ schema: {
67
+ name: string;
68
+ path: string;
69
+ flags: {
70
+ name: string;
71
+ type: string | null;
72
+ description: string | null;
73
+ }[];
74
+ };
75
+ };
76
+ }
77
+ export declare function prepareExec(root: string, args: MsmArgs): PreparedExec;
78
+ export declare function runMsmAsync(root: string, args: MsmArgs): Promise<JsonValue>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * output-guard-seam.ts — 输出守卫拦截缝(v1.26.3,S142 用户需求)
3
+ *
4
+ * `agent/turn-stopping`(serial)时:取该 turn 最后 assistant 文本 → 敏感词表检测 →
5
+ * 命中 → `agent.steer(buildRebuke(hits))` 打回重生成(turn 不关闭,模型同轮重答)。
6
+ * 连续命中达 REBUKE_MAX_ROUNDS → 放弃打回(防死循环),输出保留 + 审计日志。
7
+ *
8
+ * 作用范围(v1.26.3 用户拍板):**仅外部面**——skiff/ACP/问答页等对外输出会话
9
+ * (session id `skiff-`/`acp-`/`rebuild-` 前缀;v1.22.4 rebuild 新建会话同面)。
10
+ * **本地维护会话(普通 dsh 会话)不检测**——维护会话必然提及机制词
11
+ * (dsh-serenity-hooks/session_rebuild/mech-registry),打回会瘫痪自身工作。
12
+ */
13
+ import type { Context } from 'cordis';
14
+ /** 外部面会话判定(v1.26.3 用户拍板:仅外部面检测,本地维护会话豁免):
15
+ * skiff-(F4 问答)/ acp-(F4c 程序化)/ rebuild-(v1.22.4 重建会话)前缀 */
16
+ export declare function isExternalFaceSession(sessionId: string | undefined): boolean;
17
+ /**
18
+ * 注册输出守卫(index.ts apply 调用):
19
+ * turn-stopping 时检测最终输出,命中敏感词 → steer 打回重生成(官方机制,零改 DSH)。
20
+ */
21
+ export declare function registerOutputGuardHook(ctx: Context): void;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * output-guard.ts — 最终输出敏感词检测 + 打回重生成(v1.26.3,S142 用户需求)
3
+ *
4
+ * 认知容器对外提供认知结果时,**支撑宁静号自身的凭据与机制**不应透露给用户。
5
+ * 用户拍板方案(讨论稿定稿):不做工具结果 redaction(那是模型工作内存),
6
+ * 改为**卡最终输出**——`agent/turn-stopping`(serial)时取 turn 最后 assistant 文本,
7
+ * 命中敏感词表 → `agent.steer()` 打回重生成,直到合规或达上限。
8
+ *
9
+ * 敏感词表(有限,ACC 立场,用户确认"这样比较全面了"):
10
+ * ① 凭据词 — localstore.json credentials 条目名 + 值精确匹配(运行时读)
11
+ * ② 机制词 — 内部结构静态词(插件名/配置路径/端口/内部实现词)
12
+ * ③ MSM 词 — mech-registry.json 注册的工具名(用户补充:msm_list 里的工具名)
13
+ * **不含** 公开概念(宁静号/Serenity/认知容器/EAP/CCE/Neat——正常交流词,误伤灾难)
14
+ *
15
+ * 机制依据(DSH 官方):agent/turn-stopping 注释 "a listener that objects steers and
16
+ * the machine re-reads its inbox: fresh steering runs another step, none closes the
17
+ * turn"——steer 打回是官方支持的"重生成"通道(v1.22.5 rebuild 自动继续同款先例)。
18
+ */
19
+ /** 敏感词分类(v1.26.11:打回消息按类给规避指引——裸词不够,模型要知道词是什么/怎么规避) */
20
+ export type SensitiveCategory = 'credential' | 'mechanism' | 'port' | 'msm';
21
+ /** 一次命中(词 + 分类) */
22
+ export interface SensitiveHit {
23
+ word: string;
24
+ category: SensitiveCategory;
25
+ }
26
+ export interface SensitiveWordTable {
27
+ /** 精确匹配词(条目名/值/工具名——命中即敏感) */
28
+ exact: Set<string>;
29
+ /** 子串匹配词(机制词——命中即敏感) */
30
+ substring: string[];
31
+ /** v1.26.11:分类词表(打回消息按类给规避指引;exact/substring 为聚合视图) */
32
+ credentialWords: string[];
33
+ mechanismWords: string[];
34
+ portWords: string[];
35
+ msmWords: string[];
36
+ /** 归一化后的全部精确词(供审计展示) */
37
+ sources: {
38
+ exact: string[];
39
+ substring: string[];
40
+ };
41
+ }
42
+ /**
43
+ * 构建敏感词表(每次调用实时构建——词源文件小,开销可接受):
44
+ * ① localstore.json credentials:条目名(UPPER_SNAKE)+ 值(精确匹配)
45
+ * ② 静态机制词 + 端口
46
+ * ③ mech-registry 注册的 MSM 工具名(loadMsmEntries 全注册表去重)
47
+ * @param root CCC 根(localstore.json / mech-registry 所在)
48
+ */
49
+ export declare function buildSensitiveTable(root: string): SensitiveWordTable;
50
+ /**
51
+ * 检测文本中命中的敏感词(v1.26.11:返回带分类的命中——credential/mechanism/port/msm,
52
+ * 打回消息据此给语义化规避指引;未命中返回空数组)
53
+ */
54
+ export declare function detectSensitive(text: string, table: SensitiveWordTable): SensitiveHit[];
55
+ /**
56
+ * 打回消息(steer 内容):**逐词告知命中词 + 分类规避指引**(v1.26.11 用户调整——
57
+ * v1.26.10 只列裸词(如 "3080")模型仍不知道是什么/怎么规避;现在按类说明:
58
+ * "3080" → 内部服务端口,不要提及内部端口/地址/端点)。
59
+ * R↓ 安全性:命中词本就已在被拦截回复中进入会话(已暴露面),打回重复一次不扩大暴露;
60
+ * steer 是 plugin source 消息不回显给用户(3100 对外响应已不含 trajectory → 打回文本不达外部用户)。
61
+ */
62
+ export declare function buildRebuke(hits: SensitiveHit[]): string;
63
+ /** 连续打回上限(防死循环;达到后放弃打回,最终输出替换为合规占位 + 审计) */
64
+ export declare const REBUKE_MAX_ROUNDS = 3;
65
+ /** 打回状态(按 agent 会话跟踪连续命中轮数) */
66
+ export declare const rebukeStates: Map<string, {
67
+ consecutive: number;
68
+ }>;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * rebuild.ts — 轨迹跟踪器(Trajectory Tracker)超限重建:session_rebuild
3
+ *
4
+ * 概念(S142 用户拍板命名,v1.22.1 语义修正;v1.22.4 定稿语义):
5
+ * **SESSION.md = 持久 agent(轨迹)**——身份/决策/进度/未解决问题的本体,
6
+ * 永远留在 AGENT_SESSIONS/ 原位,**不归档、不移动**。
7
+ * **自身 dsh 会话 = 临时可重建(工作副本)**——上下文超阈值时**完全清空重来**,
8
+ * 身份从 SESSION.md 自动延续。
9
+ *
10
+ * v1.22.4 定稿语义(用户明确:**复用旧会话 + 完全清空重来**,不要新建会话):
11
+ * ① rebuild 工具执行时**只排队**(pending map:sessionId → 锚点文本),不立即改 surface
12
+ * ② `agent/turn-stopping`(turn 结束前 serial 触发)时真正执行:
13
+ * surface replace 全部节点 → 锚点 user/message(「继续 {SESSION 名} 的工作」)
14
+ * ③ 同一会话 id 不变 → 同工作区天然满足、无新/旧会话之分、无需销毁/切换/归档
15
+ *
16
+ * 为何不在工具执行时立即 replace(v1.22.2 方案废弃):
17
+ * S141 实测崩溃——rebuild 工具在 turn 中途执行 surface replace,把**当前 turn
18
+ * 的 assistant tool-call 节点**也 shadow 掉;工具返回后 agent-loop append
19
+ * tool/result(sourceEventSeqs 引用被 shadow 的 callSeq),deriveMessages 折叠出
20
+ * 孤儿 tool 消息 → LLM API 报 "Messages with role 'tool' must be a response to
21
+ * a preceding message with 'tool_calls'"(INVALID_REQUEST)。
22
+ * **延迟到 turn 结束清空**:届时当前 turn 所有 tool/result 已完整 append,replace
23
+ * 一并 shadow,无孤儿。
24
+ *
25
+ * v1.22.5 增强(S142 用户需求):
26
+ * ① **自动继续**:turn-stopping 执行 replace 后 `agent.steer()` 注入自动继续指令
27
+ * (DSH 官方先例:hooks-claude-code Stop hook 在 turn-stopping 里 steer 强制
28
+ * 再执行一步)——next-step 队列非空 → turn 循环不 break → 模型自动读取
29
+ * SESSION.md 继续工作,无需用户手工输入。
30
+ * ② **保留 first-anchor**:锚点消息并入 DEFAULT_ANCHOR_MESSAGES 正文(ACC 身份/
31
+ * EAP/协作协议),去掉 acknowledge 尾句(重建后直接干活,不重走确认轮)——
32
+ * 系统提示词层身份未丢(每轮注入),bootstrap 晋升状态不受影响(surface
33
+ * replace 不改 events,promoted 保持完整工具目录)。
34
+ *
35
+ * 触发:LLM 主动调用(keeper 超阈值后提示 [TRAJECTORY],不自动执行——防误清空)。
36
+ * 门控:仅 CCC 内 + 简单配置 rebuild.enabled。
37
+ */
38
+ import type { Context } from 'cordis';
39
+ import type { Session } from '@deepseek-ai/dsh-session';
40
+ import type { Message } from '@deepseek-ai/dsh-llm';
41
+ /**
42
+ * 剥离 first-anchor 消息的 acknowledge 尾句(rebuild 锚点保留协议正文但不要求确认回复)。
43
+ */
44
+ export declare function stripAckSuffix(text: string): string;
45
+ /**
46
+ * 构建重建锚点消息(v1.22.4 定稿语义 + v1.22.5 保留 first-anchor 正文):
47
+ * 「[TRAJECTORY-REBUILD] + first-anchor 协议正文(去 acknowledge 尾句)+ 继续 {SESSION 名} 的工作」。
48
+ * @param root - CCC 根
49
+ * @param sessionName - 当前 use 的宁静号 SESSION 名(如 S142);无激活则通用指令
50
+ * @param activeMdPath - 持久轨迹 SESSION.md 绝对路径(保持原位)
51
+ * @param anchorMessages - first-anchor 协议消息序列(缺省 DEFAULT_ANCHOR_MESSAGES;可注入测试)
52
+ */
53
+ export declare function buildRebuildAnchor(root: string, sessionName: string, activeMdPath: string, anchorMessages?: string[]): string;
54
+ export interface RebuildResult {
55
+ /** 是否成功排队(turn 结束时执行清空重建) */
56
+ queued: boolean;
57
+ /** 锚点消息文本(将在 turn 结束时注入) */
58
+ anchor: string;
59
+ /** 宁静号 SESSION.md(持久轨迹,保持原位) */
60
+ sessionMdPath: string | null;
61
+ }
62
+ /**
63
+ * 稳固的 SESSION.md 定位(多层候选 + 存在性校验,**绝不输出虚假路径**):
64
+ * ① 内存活跃会话(本会话显式 use 过)→ ② events 恢复(use 标记 + 重建锚点规范行,进程重启后)
65
+ * → ③ surface 首条锚点(events 异常时兜底)→ ④ AGENT_SESSIONS 约定回退(最新未完成活动目录)。
66
+ * 每候选 resolve 后 existsSync 校验(相对路径按 root 解析);全部失败返回 null → 调用方报错引导。
67
+ */
68
+ export declare function resolveSessionMdPath(root: string, scope: string, session: Session): string | null;
69
+ interface PendingRebuild {
70
+ /** 锚点消息文本 */
71
+ anchor: string;
72
+ /** 排队时间(防陈旧队列误清空——超时丢弃) */
73
+ queuedAt: number;
74
+ }
75
+ /** 测试/调试:查看 pending 队列内容 */
76
+ export declare function pendingRebuildSnapshot(): ReadonlyMap<string, PendingRebuild>;
77
+ /**
78
+ * 排队一次重建(v1.22.4 定稿语义第一步):
79
+ * ① 门控校验(rebuild.enabled + 会话定位)
80
+ * ② 构建锚点(激活会话名 + 持久轨迹路径)
81
+ * ③ 写入 pending 队列——**不立即改 surface**(等 turn-stopping 执行)
82
+ * @returns 排队结果;rebuild.enabled=false 或非 CCC 抛错
83
+ */
84
+ export declare function queueRebuild(ctx: Context, opts: {
85
+ root: string;
86
+ note?: string;
87
+ agentCwd: string;
88
+ dshSessionId: string;
89
+ }): Promise<RebuildResult>;
90
+ /**
91
+ * 执行真正的 surface replace(v1.22.4 定稿语义第二步,turn-stopping 时调用):
92
+ * 当前 turn 已完整结束(所有 tool/result 已 append)→ 全部节点替换为锚点消息。
93
+ * 同一会话 id 原地重建——同工作区天然满足,无新/旧会话之分。
94
+ *
95
+ * **shadow-price 协议(v1.23.5 修复,S142 用户问询)**:DSH token-meter 的
96
+ * `foldSurfaceProjection` 对 surface `replace` 要求**紧邻其前的 metering 事件**
97
+ * (`compaction/summary` 或 `compaction/prune`)声明被替换范围的启发式 token 价,
98
+ * 否则 claim 缺失 → `deltaTokens=0` → `contextBreakdown.messageTokens` 永不扣减
99
+ * → UI「对话消息」虚高累计、往复 rebuild 计量爆炸(用户截图实证:总 15% 但
100
+ * 对话消息 ~1M)。官方先例 = `compaction-tool-result-pruner`(append
101
+ * `compaction/prune` → 紧接 replace)。此处同款:先 append `compaction/prune`
102
+ * (定价全部被替换节点,经 ctx.tokenMeter.estimateMessage 逐节点累加),再
103
+ * append 锚点 replace——meter 不可用时退化(无 claim,仅计量漂移,会话功能不受影响)。
104
+ *
105
+ * @returns 是否执行了 replace(false = 无 pending 或 surface 空)
106
+ */
107
+ export declare function performRebuild(session: Session, pending: PendingRebuild, meter?: {
108
+ estimateMessage(message: Message): number;
109
+ }): boolean;
110
+ /**
111
+ * 注册 turn-stopping 钩子(index.ts apply 调用):
112
+ * agent 每轮 turn 结束前(serial)检查 pending 队列——有该会话的重建请求 → 执行清空
113
+ * 并 **steer 自动继续**(v1.22.5:next-step 非空 → turn 不 break → 模型自动读取
114
+ * SESSION.md 继续,无需用户手工输入;DSH 官方先例 hooks-claude-code Stop hook)。
115
+ * 陈旧队列(超 TTL)丢弃防误清空;无 pending 零开销。
116
+ */
117
+ export declare function registerRebuildTurnHook(ctx: Context): void;
118
+ export {};
@@ -0,0 +1,83 @@
1
+ /**
2
+ * bootstrap.ts — Anchored Standard 两阶段工具目录(S137)
3
+ *
4
+ * 移植自 xiaobright/dsh-anchored-standard(preset/tool-bootstrap.mjs + compaction-epoch.mjs):
5
+ * 首请求暴露最小工具集(锚定轨迹——V4 Pro 强依赖 API 可见工具目录选轨迹),
6
+ * 会话出现首次持久晋升信号(tool/call 或 assistant/message,先到者为准)后开放完整工具。
7
+ *
8
+ * 严格对齐 anchored 语义:
9
+ * - 阶段从持久 session events 推导(resume/reload 不丢状态)
10
+ * - epoch 感知:compaction/end 后回落受控阶段(bootstrap 集 + compactionTools),
11
+ * 需新的晋升信号才重新晋升(压缩后首请求 = "第二次首请求")
12
+ * - 子 agent(delegationDepth > 0)恒为 promoted(完整目录)
13
+ * - bootstrap 阶段剥离自动注入上下文(suppressedContextSources,默认
14
+ * skill-catalog + agent-instructions——即 Standard 比 Minimal 多出的两类注入)
15
+ * - 降级:过滤器出错绝不吞上下文(pre-step 保留全部)/ 工具缺失降级完整目录 + 一次性告警
16
+ *
17
+ * 协议固有(用户原则 2026-08-24,S142):first-anchor 属 ACC 协议层——任何 CCC
18
+ * 在抽象层都是宁静号/ACC,机制与内容均不可配置(零配置面)。旧版 serenity.json
19
+ * bootstrap 段(S137 引入的调参入口)已移除,遗留字段静默忽略。
20
+ */
21
+ import type { Context } from 'cordis';
22
+ import type { Agent } from '@deepseek-ai/dsh-agent';
23
+ export interface BootstrapSettings {
24
+ /** 首请求(bootstrap 阶段)工具集(缺省 dsp 核心;zeroTools 时忽略——0 工具) */
25
+ bootstrapTools: string[];
26
+ /** 晋升信号类型集合 */
27
+ promoteEvents: Set<'tool/call' | 'assistant/message'>;
28
+ /** 晋升所需信号数(boundary 后累计;多轮锚定时 = 锚定轮数) */
29
+ requiredSignals: number;
30
+ /** bootstrap 阶段剥离的注入源 */
31
+ suppressedSources: Set<string>;
32
+ /** compaction 后(重新晋升前)额外保留的工具集 */
33
+ compactionTools: string[];
34
+ /** 锚定消息序列(v4 两轮递进:按序 prepend 到 next-turn 队列,每条一轮 0 工具回复) */
35
+ anchorMessages: string[];
36
+ /** Zero-Anchored 变体:首请求 0 工具(晋升信号仅 assistant/message,对齐 zero-anchored-standard) */
37
+ zeroTools: boolean;
38
+ }
39
+ /** 默认首请求工具集:dsp 平台 Minimal 等价核心(anchored 是 bash+str_replace_editor) */
40
+ export declare const DEFAULT_BOOTSTRAP_TOOLS: string[];
41
+ /** 默认剥离的自动注入源(anchored 默认:可用技能目录提醒 + 工作区指令摘要) */
42
+ export declare const DEFAULT_SUPPRESSED_SOURCES: string[];
43
+ /** 默认 compaction 恢复工作集(anchored 默认 read/write/edit/glob/grep/todo_write/ask_user_question) */
44
+ export declare const DEFAULT_COMPACTION_TOOLS: string[];
45
+ /**
46
+ * 协议级锚定消息序列(用户确认固化,2026-08-24 S142):任何 CCC 在抽象层都是
47
+ * 宁静号/ACC——首轮锚定话语统一,无 CCC 配置面。两轮递进:
48
+ * ① ACC 身份 + EAP 原则 + we/us 人称 + 先锚定后行动
49
+ * ② 协作协议 5 条 + acknowledge 要求(只回确认,不做事)
50
+ * 文本 = 原 home-serenity CCC 配置(anchorMessages),随零配置化固化进代码。
51
+ */
52
+ export declare const DEFAULT_ANCHOR_MESSAGES: string[];
53
+ export interface PromotionStatus {
54
+ /** 最后一次 compaction/end 的 seq(-1 = 未压缩过) */
55
+ boundary: number;
56
+ /** 边界后是否存在持久晋升信号 */
57
+ promoted: boolean;
58
+ }
59
+ export interface PromotionTracker {
60
+ status(agent: Agent | undefined): PromotionStatus;
61
+ observe(session: unknown, event: unknown): void;
62
+ }
63
+ /**
64
+ * 构建一个 epoch 感知晋升跟踪器(纯逻辑,可单测)。
65
+ * requiredSignals:晋升所需信号数(boundary 后累计;默认 1)。
66
+ * 多轮锚定(v4):两轮递进锚定时 requiredSignals = 锚定轮数——
67
+ * 每条锚定回复(assistant/message)计一次,最后一条回复后晋升。
68
+ *
69
+ * maxRoundsFallback:**轮次兜底**(v1.19.3 修复 responses API 兼容)。
70
+ * 某些模型/协议(如 opencode-go-responses)的会话可能不产生标准
71
+ * `assistant/message` 晋升信号 → 永不晋升 → bootstrap 阶段工具被裁空
72
+ * (zeroTools 首请求 0 工具,ACC 工具不可见)。兜底:无论晋升信号是否
73
+ * 到达,观察到的模型 step 数(`step/start` 事件计数,平台稳定事件,
74
+ * responses/completions 都触发,独立于 promoteEvents)达到 maxRoundsFallback
75
+ * 即强制 promoted(开放完整工具)。正常模型锚定轮数(requiredSignals)
76
+ * 通常 ≤ 2 < 默认兜底 3,不受影响。
77
+ */
78
+ export declare function createEpochPromotion(promoteEvents: Set<'tool/call' | 'assistant/message'>, requiredSignals?: number, maxRoundsFallback?: number): PromotionTracker;
79
+ /** 协议固有 bootstrap 设置:zeroTools=true(首请求 0 工具纯文字锚定轮)、
80
+ * 晋升信号仅 assistant/message(对齐 zero-anchored-standard)、
81
+ * requiredSignals = 锚定轮数(2 条消息 → 2 条回复后晋升)。无参——零配置面。 */
82
+ export declare function resolveBootstrapSettings(): BootstrapSettings;
83
+ export declare function registerBootstrap(ctx: Context): void;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * compact.ts — 拦截缝:压缩保留(P2,osp session.compacting 的 DSH 等价)
3
+ *
4
+ * 问题(历史):ACC 身份消息是早期注入的历史消息;上下文压缩会折叠它们,
5
+ * 模型上下文丢失 ACC 身份 → 后续行为偏离 CCC 约束。
6
+ *
7
+ * 现状(S134 去重):完整身份由**系统提示词层**(systemPrompt.section)每轮自动注入,
8
+ * 不在对话历史里、不随压缩折叠 → 压缩无需恢复完整身份。压缩重注入改为
9
+ * 简短身份锚点([ACC] 头,与 context.ts 共用 accMessage)——压缩后对话流
10
+ * 仍保留可追溯的身份标记(R↓),token 开销极小。
11
+ *
12
+ * session → agent 关联:session.id 即 agent id(goal-session 用 ctx.agents.get(session.id))。
13
+ *
14
+ * 时机依据(DSH 公开版 compaction 类型,事件名 compact/* → compaction/*):
15
+ * - `compaction/start`: { compactionId, sourceCommandId?, turn: number | null } — 压缩开始(log-only,持锁)
16
+ * - `compaction/summary`: { compactionId, summary, ... } — 摘要完成(log-only)
17
+ * - `compaction/end`: { compactionId, sourceCommandId?, turn, error? } — 压缩结束,error 记录失败
18
+ * 成功判定:compaction/end 无 error。
19
+ */
20
+ import type { Context } from 'cordis';
21
+ export interface CompactRegistration {
22
+ /** CCC 配置相对路径;缺省用 DEFAULT_SERENITY_CONFIG_PATHS */
23
+ configPaths?: string[];
24
+ /** 入口 skill 内容注入上限(与 context.ts 对齐) */
25
+ entrySkillMaxChars?: number;
26
+ }
27
+ /**
28
+ * 注册压缩保留:compact/end(成功)后重注入 ACC 身份。
29
+ * 仅当 agent 工作目录在 CCC 内时生效(激活门控)。
30
+ */
31
+ export declare function registerCompactRetention(ctx: Context, opts?: CompactRegistration): void;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * context.ts — 拦截缝:ACC 上下文注入(agent/session-start + agent/prompt-submit)
3
+ *
4
+ * 对应 opencode-serenity-plugin 的 system.transform(ACC 身份/约束注入)+ Phase 2 访谈提示。
5
+ *
6
+ * 设计:
7
+ * - session-start(emit):CCC 内新会话一次性播种 ACC 身份(agent.inject)
8
+ * - prompt-submit(waterfall):每 agent 首次进入 CCC 时附加紧凑身份提示;
9
+ * 只注入一次(Set 跟踪),避免每轮 token 膨胀;context-only 必须 next() 委托
10
+ * (短路会跳过后续策略监听器,interception-seams 笔记明确警告)。
11
+ */
12
+ import type { Context } from 'cordis';
13
+ import type { Agent } from '@deepseek-ai/dsh-agent';
14
+ import type { UserMessage } from '@deepseek-ai/dsh-session';
15
+ export declare const DEFAULT_ENTRY_SKILL_MAX_CHARS = 30000;
16
+ export declare function accIdentityText(root: string, configPaths?: string[], entrySkillMaxChars?: number): string;
17
+ /**
18
+ * ACC 注入消息(S134 去重):**只含简短身份锚点**([ACC] 已激活 + CCC 根 + 约束 + handyman 模型 + Phase 2)。
19
+ * 完整身份(ACC 5 块 + CCE + Constraints + EAP + SKILL 全文 + Session 块)由**系统提示词层**
20
+ * (systemPrompt.section,每轮 prompt 装配自动注入,含 subagent)承担——对话消息流/压缩重注入
21
+ * 不再重复注入同一内容(token 双倍浪费,见 S134 注入方案梳理)。
22
+ */
23
+ export declare function accMessage(root: string, configPaths: string[], entrySkillMaxChars: number): UserMessage;
24
+ /**
25
+ * 重启恢复的根会话判定(S134 需求):
26
+ * 只有"conversation 根会话"才自动恢复最近激活的宁静号会话——
27
+ * - subagent:session header `origin === 'subagent'`(DSH 路由语义,agent-lookup.ts)
28
+ * - 派生会话:`parentSession` 存在(任何子会话)
29
+ * - handyman 杂工:sessionId 固定 `handyman-` 前缀(tools/handyman.ts 生成)
30
+ * 三者都不恢复(避免把主会话激活注入子上下文,违背 v1.16.2 scope 隔离)。
31
+ */
32
+ export declare function shouldAutoRestore(agent: Agent): boolean;
33
+ /**
34
+ * 恢复触发判定(S134 泄漏修复 v1.16.13):根会话 **且已有对话历史**(续跑/恢复的会话)
35
+ * 才自动恢复上次激活的宁静号会话——全新会话(新任务,如 apaas-26116)无历史 → 不恢复,
36
+ * 避免把过去的 SESSION 上下文注入新任务(跨任务污染)。
37
+ */
38
+ export declare function shouldRestoreActive(agent: Agent): boolean;
39
+ export interface ContextRegistration {
40
+ configPaths?: string[];
41
+ /** session-start 播种 */
42
+ seedOnStart?: boolean;
43
+ /** prompt-submit 兜底注入 */
44
+ injectOnPrompt?: boolean;
45
+ /** 入口 skill 内容注入上限(字符);0 = 不注入 skill 内容 */
46
+ entrySkillMaxChars?: number;
47
+ }
48
+ export declare function registerContext(ctx: Context, opts?: ContextRegistration): void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * env.ts — shell.env 环境变量注入(ACC 标准)
3
+ *
4
+ * 经 ctx.shellEnv(DSH shell-env 缝,公开版由 bash-env 改名)注册 DSH_* 事实:
5
+ * DSH_SERENITY_ROOT — CCC 根目录(agent 会话 cwd 上溯 .serenity)
6
+ * DSH_SERENITY_CCC — CCC 名称(根目录 basename)
7
+ * DSH_SERENITY_VERSION — ACC 版本
8
+ *
9
+ * 每次模型 shell 调用都会重建 DSH_* 命名空间并注入(按当前执行解析)。
10
+ */
11
+ import type { Context } from 'cordis';
12
+ import type { DshEnvironmentKey } from '@deepseek-ai/dsh-shell';
13
+ export type SerenityEnvFacts = Partial<Record<DshEnvironmentKey, string>>;
14
+ /** 纯解析:给定 cwd,返回可注入的 DSH_SERENITY_* 事实(非 CCC 返回空) */
15
+ export declare function resolveSerenityEnv(cwd: string): SerenityEnvFacts;
16
+ export declare function registerEnv(ctx: Context): void;