@kiturone/kapibala 0.0.6 → 0.0.8

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/dist/index.d.cts CHANGED
@@ -437,6 +437,15 @@ interface Usage {
437
437
  }
438
438
  /** canonical 消息角色;'tool' 仅用于工具结果消息,wire 角色转换只发生在请求投影阶段。 */
439
439
  type MessageRole = 'user' | 'assistant' | 'system' | 'tool';
440
+ /** 子代理通知背景消息的来源元数据;仅用于去重与审计,不发送到 Provider wire。 */
441
+ interface SubagentSourceMetadata {
442
+ readonly eventId: string;
443
+ readonly agentId: string;
444
+ readonly rootTaskId: string;
445
+ readonly role: string;
446
+ readonly status: string;
447
+ readonly originBranchId: string;
448
+ }
440
449
  /**
441
450
  * 协议无关的历史真源;wire 格式只在请求投影时出现。
442
451
  * 不变量:assistant 消息中的 tool_use 进入历史后,对应 tool_result 消息必须紧跟其后。
@@ -455,6 +464,8 @@ interface CanonicalMessage {
455
464
  role: MessageRole;
456
465
  content: ContentBlock[];
457
466
  timestamp?: number;
467
+ /** 子代理通知背景消息来源元数据(仅用于审计与收件箱幂等去重)。 */
468
+ subagentSource?: SubagentSourceMetadata;
458
469
  }
459
470
  /** 判别并收窄为文本块。 */
460
471
  declare function isTextBlock(block: ContentBlock): block is TextBlock;
@@ -799,10 +810,24 @@ interface MessageStore {
799
810
  clear(): Promise<void>;
800
811
  }
801
812
 
802
- /** 会话正文 schema 版本;读取时不匹配即拒绝恢复,不做跨版本猜测。 */
803
- declare const SESSION_SCHEMA_VERSION = 1;
804
- /** 会话记录类型:header 只出现一次,message 承载正文,其余为状态记录。 */
805
- type SessionRecordType = 'header' | 'message' | 'run_started' | 'run_finished' | 'message_state' | 'history_repair' | 'usage' | 'checkpoint' | 'context_pruned' | 'compaction_state' | 'title' | 'reset' | 'legacy_import';
813
+ /** 会话正文 schema v1 版本常量(只读兼容)。 */
814
+ declare const SESSION_SCHEMA_VERSION_V1 = 1;
815
+ /** 会话正文 schema v2 版本常量(当前规范)。 */
816
+ declare const SESSION_SCHEMA_VERSION_V2 = 2;
817
+ /** 当前会话正文默认创建与支持的 schema 版本。 */
818
+ declare const SESSION_SCHEMA_VERSION = 2;
819
+ /** 默认主分支标识。 */
820
+ declare const MAIN_BRANCH_ID = "main";
821
+ /** 会话记录类型:header 只出现一次,message 承载正文,其余为分支或全局控制记录。 */
822
+ type SessionRecordType = 'header' | 'message' | 'run_started' | 'run_finished' | 'message_state' | 'history_repair' | 'usage' | 'checkpoint' | 'context_pruned' | 'compaction_state' | 'title' | 'reset' | 'legacy_import' | 'branch_created' | 'branch_selected' | 'branch_summary' | 'archive_state';
823
+ /**
824
+ * 判断指定记录类型是否属于全局控制记录。
825
+ *
826
+ * 保证:
827
+ * - 全局控制记录的 parentId 为 null,不推进分支上下文叶子;
828
+ * - 其余记录为分支记录,必须有合法的前驱因果 parentId 并推进对应分支的叶子。
829
+ */
830
+ declare function isGlobalControlRecordType(type: SessionRecordType): boolean;
806
831
  /** 会话文件首条记录:身份与创建环境快照;conversationId 与文件名强绑定。 */
807
832
  interface SessionHeader {
808
833
  conversationId: string;
@@ -812,14 +837,26 @@ interface SessionHeader {
812
837
  gitBranch?: string;
813
838
  /** 旧历史导入的幂等身份;存在时同一来源只导入一次。 */
814
839
  importIdentity?: string;
840
+ /** v1 副本升级的幂等来源身份(来源路径 + 源 conversationId + 源内容哈希)。 */
841
+ upgradeIdentity?: string;
842
+ /** 派生或 Fork 来源会话与切点记录 ID。 */
843
+ parentSessionId?: string;
844
+ forkPointRecordId?: string;
815
845
  }
816
- /** 单条 JSONL 记录封装;parentId 链接前驱,恢复时校验追加次序。 */
846
+ /** 单条 JSONL 记录封装;v2 引入连续物理 seq 与 prevRecordId,因果 parentId 与 branchId 独立。 */
817
847
  interface SessionRecord {
818
848
  schemaVersion: number;
819
849
  type: SessionRecordType;
820
850
  recordId: string;
821
851
  timestamp: number;
852
+ /** 物理连续序号(v2,从 0 开始自增;v1 为 undefined)。 */
853
+ seq?: number;
854
+ /** 物理前驱记录 ID(v2 为上一条物理记录 ID,首条记录为 null;v1 为 undefined)。 */
855
+ prevRecordId?: string | null;
856
+ /** 上下文因果父节点记录 ID(分支记录必须有合法更早的父节点;全局控制记录为 null)。 */
822
857
  parentId: string | null;
858
+ /** 分支归属标识(v2 分支记录归属;全局控制记录为 null 或 undefined;v1 为 undefined)。 */
859
+ branchId?: string | null;
823
860
  payload: Record<string, unknown>;
824
861
  }
825
862
  /** loadState 返回的版本化状态视图;记录自最近 reset 起有效。 */
@@ -829,14 +866,59 @@ interface SessionState {
829
866
  records: SessionRecord[];
830
867
  /** 只随正文、修复与 reset 改变,不因 usage 或缓存写入失效。 */
831
868
  contentRevision: string;
869
+ /** 物理末记录 ID。 */
870
+ logRevision: string;
871
+ /** 当前活动分支 ID(默认 'main')。 */
872
+ activeBranchId: string;
873
+ /** 当前活动分支叶子记录 ID。 */
874
+ activeLeafId: string | null;
875
+ /** 所有分支的叶子节点映射表。 */
876
+ branchLeaves: ReadonlyMap<string, string>;
877
+ /** 会话文件 schema 版本。 */
878
+ schemaVersion: number;
879
+ }
880
+ /** 会话分支元数据信息。 */
881
+ interface BranchInfo {
882
+ /** 分支唯一标识。 */
883
+ branchId: string;
884
+ /** 分支切点记录 ID(主分支 main 为根节点 ID)。 */
885
+ baseRecordId: string;
886
+ /** 分支当前最新叶子节点 ID。 */
887
+ leafRecordId: string;
888
+ /** 分支创建时间(若无记录则为首条记录时间)。 */
889
+ createdAt: number;
890
+ /** 是否为当前活动分支。 */
891
+ isActive: boolean;
892
+ /** 沿该分支因果链回溯的总消息数。 */
893
+ messageCount: number;
832
894
  }
833
895
  /** MessageStore 的可选状态能力;旧 SDK Store 不需要实现,宿主据此降级持久压缩。 */
834
896
  interface StatefulMessageStore extends MessageStore {
835
- appendRecord(type: Exclude<SessionRecordType, 'header' | 'message'>, payload: Record<string, unknown>): Promise<SessionRecord>;
836
- loadState(): Promise<SessionState>;
897
+ appendRecord(type: Exclude<SessionRecordType, 'header' | 'message'>, payload: Record<string, unknown>, options?: {
898
+ branchId?: string;
899
+ parentId?: string;
900
+ }): Promise<SessionRecord>;
901
+ loadState(options?: {
902
+ branchId?: string;
903
+ }): Promise<SessionState>;
837
904
  }
838
905
  /** 判断 Store 是否支持版本化状态;不读取数据或改变旧 Store。 */
839
906
  declare function supportsSessionState(store: MessageStore): store is StatefulMessageStore;
907
+ /**
908
+ * 校验目标切点是否处于完整闭合的工具事务边界。
909
+ *
910
+ * 保证与约束:
911
+ * - 沿目标切点因果链从根至切点按因果顺序扫描;
912
+ * - 若因果链中包含发起了 tool_use 的 assistant 消息,必须紧随其后且在切点之前包含全部对应的 tool_result 结果;
913
+ * - 若切点位于未闭合工具事务的内部(包括发起 tool_use 的 assistant 自身,或仅回填了部分工具结果的 tool 消息),
914
+ * 抛出 `UNCLOSED_TOOL_TRANSACTION_FORK` 错误拒绝分叉;
915
+ * - 绝不依赖推测修复,保护持久化分支树的历史闭合不变量。
916
+ *
917
+ * @param records 会话中所有可用记录列表
918
+ * @param targetRecordId 切点记录唯一标识
919
+ * @throws {KapibalaError} 当切点位于未闭合工具事务内部或切点不存在时
920
+ */
921
+ declare function assertClosedToolTransaction(records: SessionRecord[], targetRecordId: string): void;
840
922
  /**
841
923
  * 版本化消息与上下文状态的单文件存储。所有写入串行并 fsync,失败后拒绝继续写入。
842
924
  * 调用者须在打开前取得单写者锁;本类不允许静默跳过中部损坏或重复身份。
@@ -848,29 +930,99 @@ declare class SessionStore implements StatefulMessageStore {
848
930
  private observer?;
849
931
  private onDiagnostic?;
850
932
  private stamp?;
933
+ private schemaVersion;
934
+ private activeBranchId;
935
+ private branchLeaves;
851
936
  private constructor();
937
+ /** 获取当前会话文件使用的 Schema 版本(1 或 2)。 */
938
+ getSchemaVersion(): number;
939
+ /** 判断当前会话是否为只读历史(v1 历史文件强制只读)。 */
940
+ isReadOnly(): boolean;
941
+ /** 获取当前选中的活动分支标识。 */
942
+ getActiveBranchId(): string;
943
+ /** 获取所有分支当前叶子记录 ID 映射快照。 */
944
+ getBranchLeaves(): ReadonlyMap<string, string>;
852
945
  /** 注册可重建缓存的写后通知;缓存失败只诊断,不撤销或毒化已 fsync 的正文。 */
853
946
  setAppendObserver(observer: (record: SessionRecord) => void, onDiagnostic?: (message: string) => void): void;
854
- /** 以独占创建方式安装新头部,已有文件明确失败,绝不覆盖其它会话。 */
947
+ /** 以独占创建方式安装新头部(默认生成 Schema v2 格式),已有文件明确失败,绝不覆盖其它会话。 */
855
948
  static create(filePath: string, header: SessionHeader): Promise<SessionStore>;
856
949
  /** 打开并验证已有会话;尾部残片先保存到隔离文件,中部损坏与未知版本拒绝恢复。 */
857
950
  static open(filePath: string): Promise<SessionStore>;
858
951
  /** 获取完整记录快照,等候已排队写入后读取;调用者不能借此修改内部记录。 */
859
952
  readRecords(): Promise<SessionRecord[]>;
860
953
  /** 消息级持久化,补稳定身份并保留所有终态字段,成功后方可进入下一次写入。 */
861
- append(message: CanonicalMessage): Promise<void>;
954
+ append(message: CanonicalMessage, options?: {
955
+ branchId?: string;
956
+ parentId?: string;
957
+ }): Promise<void>;
862
958
  /** 持久化状态记录,fsync 成功才返回;失败会毒化当前写者,要求重新验证后恢复。 */
863
- appendRecord(type: Exclude<SessionRecordType, 'header' | 'message'>, payload: Record<string, unknown>): Promise<SessionRecord>;
864
- /** 重建 reset 后的状态;统计记录和检查点不会推进正文 revision。 */
865
- loadState(): Promise<SessionState>;
959
+ appendRecord(type: Exclude<SessionRecordType, 'header' | 'message'>, payload: Record<string, unknown>, options?: {
960
+ branchId?: string;
961
+ parentId?: string;
962
+ }): Promise<SessionRecord>;
963
+ /**
964
+ * 创建新分支记录并推进分支叶子。
965
+ *
966
+ * 约束:
967
+ * - 分支标识必须符合命名规范(字母、数字、下划线、短横线);
968
+ * - 目标分支必须不存在;
969
+ * - 切点记录 baseRecordId 必须为正文中已存在的合法记录;
970
+ * - 拒绝未闭合工具事务分叉:因果链上不得包含未全部回填 tool_result 的工具调用;
971
+ * - v1 历史会话禁止创建分支。
972
+ */
973
+ createBranch(branchId: string, baseRecordId: string): Promise<SessionRecord>;
866
974
  /**
867
- * 恢复原始正文,并将幂等修复叠加到原工具事务;不合并连续消息,也不执行工具。
868
- * 缺失结果用 history_repair 落盘,独立于实际工具结果和正文,不伪造成功。
975
+ * 切换活动分支并持久化记录。
976
+ *
977
+ * 约束:
978
+ * - 目标分支必须已被创建或存在;
979
+ * - v1 历史会话禁止切换分支。
980
+ */
981
+ selectBranch(branchId: string): Promise<SessionRecord>;
982
+ /**
983
+ * 追加逻辑归档控制记录。
984
+ *
985
+ * 约束:
986
+ * - 归档状态记录为全局控制记录(parentId 为 null,不推进分支上下文叶子);
987
+ * - payload 结构为 { archived: boolean };
988
+ * - v1 历史会话禁止变更归档状态。
989
+ */
990
+ setArchiveState(archived: boolean): Promise<SessionRecord>;
991
+ /**
992
+ * 查询当前会话是否处于已归档状态。
993
+ */
994
+ isArchived(): Promise<boolean>;
995
+ /**
996
+ * 获取当前会话中所有已知分支的元数据与状态列表。
997
+ */
998
+ getBranches(): Promise<BranchInfo[]>;
999
+ /** 重建指定分支(默认当前活动分支)reset 后的状态视图。 */
1000
+ loadState(options?: {
1001
+ branchId?: string;
1002
+ }): Promise<SessionState>;
1003
+ /**
1004
+ * 沿因果 parentId 链从叶子节点回溯,生成合法线性消息序列投影。
1005
+ *
1006
+ * 保证与约束:
1007
+ * - 仅包含回溯因果链上的消息与状态叠加,全局控制记录与其他分支记录被天然隔离;
1008
+ * - 支持 reset 边界截断与 history_repair 幂等叠加;
1009
+ * - 严格校验工具事务闭合不变量,拒绝半事务破坏;
1010
+ * - 修复缺失结果时自动持久化 history_repair(v2 下在目标分支上记录)。
1011
+ */
1012
+ buildProjection(options?: {
1013
+ branchId?: string;
1014
+ leafRecordId?: string;
1015
+ }): Promise<CanonicalMessage[]>;
1016
+ /**
1017
+ * 恢复当前活动分支的原始正文,并将幂等修复叠加到原工具事务。
869
1018
  */
870
1019
  load(): Promise<CanonicalMessage[]>;
871
1020
  /** SDK 清空语义通过持久边界实现;此前摘要、剪裁及失败状态不再参与恢复。 */
872
1021
  clear(): Promise<void>;
873
- /** 生成前驱关联的 Envelope,前驱仅表达追加次序,未来 DAG 不改变当前恢复规则。 */
1022
+ /**
1023
+ * 生成 Envelope 记录。
1024
+ * v2 下严格维护连续物理序号 seq、物理前驱 prevRecordId 与因果 parentId / branchId。
1025
+ */
874
1026
  private makeRecord;
875
1027
  /** 单写者队列不吞异常;后续写入依赖同一失败 Promise,防止继续污染正文。 */
876
1028
  private enqueue;
@@ -916,6 +1068,8 @@ interface ProjectIdentity {
916
1068
  /** true 表示 cwd 位于 Git 工作树内;同工作树子目录共用同一桶。 */
917
1069
  gitWorktree?: boolean;
918
1070
  }
1071
+ /** Windows 桶和头部使用相同大小写规范,POSIX 保持路径大小写语义。 */
1072
+ declare function normalizedProjectRoot(root: string): string;
919
1073
  /** 解析真实工作树根;同工作树子目录共用桶,非 Git 目录和不同 worktree 独立。不会改变 cwd。 */
920
1074
  declare function resolveSessionProject(cwd: string): ProjectIdentity;
921
1075
  /**
@@ -923,7 +1077,8 @@ declare function resolveSessionProject(cwd: string): ProjectIdentity;
923
1077
  * 正文 JSONL 始终是唯一真源。
924
1078
  */
925
1079
  interface SessionMetadata {
926
- schemaVersion: 1;
1080
+ /** 元数据缓存格式版本(1 或 2)。 */
1081
+ schemaVersion: number;
927
1082
  conversationId: string;
928
1083
  fileName: string;
929
1084
  projectRoot: string;
@@ -939,10 +1094,24 @@ interface SessionMetadata {
939
1094
  lastModelId?: string;
940
1095
  /** 旧历史导入的幂等身份(来源路径 + 内容哈希);重复导入据此跳过。 */
941
1096
  importIdentity?: string;
1097
+ /** v1 副本升级的来源身份哈希。 */
1098
+ upgradeIdentity?: string;
942
1099
  size: number;
943
1100
  mtimeMs: number;
944
- /** 最后计入的记录 ID;与正文 stat 一同用于增量校验。 */
1101
+ /** 兼容字段:最后计入的记录 ID。 */
945
1102
  revision: string;
1103
+ /** 会话文件使用的 Schema 版本(1 或 2)。 */
1104
+ sessionSchemaVersion?: number;
1105
+ /** 物理末记录 ID(与 revision 语义一致)。 */
1106
+ logRevision?: string;
1107
+ /** 内容正文 revision(仅正文/修复/reset 变化)。 */
1108
+ contentRevision?: string;
1109
+ /** 当前活动分支 ID(默认 'main')。 */
1110
+ activeBranchId?: string;
1111
+ /** 当前活动分支叶子记录 ID。 */
1112
+ activeLeafId?: string | null;
1113
+ /** 会话是否已归档。 */
1114
+ archived?: boolean;
946
1115
  }
947
1116
  /** 打开的会话句柄:持有单写者锁与 Store,宿主用毕必须 release。 */
948
1117
  interface ManagedSession {
@@ -960,8 +1129,13 @@ interface ManagedSession {
960
1129
  /** 释放单写者锁并移除句柄;宿主须先结束 AgentSession 的工具/摘要清理。 */
961
1130
  release(): Promise<void>;
962
1131
  }
963
- /** SessionManager 配置;cwd 决定项目桶,homeDirectory 便于测试隔离。 */
1132
+ /** SessionManager 配置;workspaceRoot/projectRoot/cwd 决定项目桶,homeDirectory 便于测试隔离。 */
964
1133
  interface SessionManagerOptions {
1134
+ /** 显式工作区物理根路径。 */
1135
+ workspaceRoot?: string;
1136
+ /** 显式项目根路径。 */
1137
+ projectRoot?: string;
1138
+ /** 执行或参考目录;若未提供工作区根,以此解析项目工作树。 */
965
1139
  cwd?: string;
966
1140
  homeDirectory?: string;
967
1141
  onDiagnostic?: (message: string) => void;
@@ -977,19 +1151,45 @@ declare class SessionManager {
977
1151
  constructor(options?: SessionManagerOptions);
978
1152
  /** 默认新建独立空会话,写入头部并持有单写者锁;不读取其它正文。 */
979
1153
  create(): Promise<ManagedSession>;
980
- /** 每页 20 项按正文活动排序;有效 sidecar 只读元数据,不读取完整 JSONL。 */
981
- list(page?: number): Promise<{
1154
+ /** 每页 20 项按正文活动排序;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。 */
1155
+ list(page?: number, options?: {
1156
+ includeArchived?: boolean;
1157
+ }): Promise<{
982
1158
  items: SessionMetadata[];
983
1159
  total: number;
984
1160
  page: number;
985
1161
  pages: number;
986
1162
  }>;
1163
+ /** 解析完整 ID 或唯一前缀对应的会话文件与 ID。 */
1164
+ private resolveSession;
1165
+ /**
1166
+ * 逻辑归档指定会话。
1167
+ *
1168
+ * 约束:
1169
+ * - 必须取得会话独占锁;
1170
+ * - 若会话当前正处于活动打开状态,拒绝归档并抛出 SESSION_IN_USE;
1171
+ * - 向会话正文追加 archive_state { archived: true } 并刷新 sidecar 缓存。
1172
+ */
1173
+ archiveSession(id: string): Promise<void>;
1174
+ /**
1175
+ * 恢复已逻辑归档的会话。
1176
+ */
1177
+ restoreSession(id: string): Promise<void>;
987
1178
  /** 一次扫描建立排序目录,分页和继续最近会话共用;有效缓存不读取正文。 */
988
1179
  private allMetadata;
989
- /** 打开完整 ID 或唯一前缀;跨桶、缺失与歧义均失败,同一 Manager 已持有的目标直接返回。 */
990
- open(id: string): Promise<ManagedSession>;
1180
+ /**
1181
+ * 打开完整 ID 或唯一前缀;跨桶、缺失与歧义均失败,同一 Manager 已持有的目标直接返回。
1182
+ *
1183
+ * @param id 完整会话 ID 或唯一前缀
1184
+ * @param options 可选参数,autoUpgradeLegacy 为 true 时若目标为 v1 旧会话则自动创建/复用 v2 副本以支持无感续写
1185
+ */
1186
+ open(id: string, options?: {
1187
+ autoUpgradeLegacy?: boolean;
1188
+ }): Promise<ManagedSession>;
991
1189
  /** 继续最近有正文的会话;没有历史才新建,显式打开失败绝不回退为空会话。 */
992
- continueRecent(): Promise<ManagedSession>;
1190
+ continueRecent(options?: {
1191
+ autoUpgradeLegacy?: boolean;
1192
+ }): Promise<ManagedSession>;
993
1193
  /** 标题作为独立耐久记录;标题或浏览不改变正文活动排序。 */
994
1194
  rename(id: string, title: string): Promise<void>;
995
1195
  /** 等候所有存储队列后释放句柄;宿主必须先结束 AgentSession 的工具/摘要清理。 */
@@ -999,6 +1199,40 @@ declare class SessionManager {
999
1199
  * 保留源文件,安装身份写入头部,缓存丢失或进程退出后仍不会重复导入。
1000
1200
  */
1001
1201
  importLegacy(): Promise<string[]>;
1202
+ /**
1203
+ * 将旧版 v1 会话升级为独立的 v2 会话副本。
1204
+ *
1205
+ * 保证与约束:
1206
+ * - 原 v1 会话文件保持只读且绝不进行原地修改;
1207
+ * - 升级生成全新独立会话文件,Header 中记录 upgradeIdentity;
1208
+ * - 幂等:若同一 v1 文件已升级过,直接返回已有 v2 会话句柄,不重复生成副本;
1209
+ * - 升级过程使用单写者锁保护临时文件,原子发布;
1210
+ * - 失败时不污染目标桶目录。
1211
+ *
1212
+ * @param idOrFileName 原会话 conversationId 或文件名(如 `xxx.jsonl`)
1213
+ * @returns 升级后的独立 v2 会话句柄(持有写者锁)
1214
+ */
1215
+ upgradeLegacyV1Session(idOrFileName: string): Promise<ManagedSession>;
1216
+ /**
1217
+ * 从当前会话的指定路径(指定分支或切点)导出生成全新的独立会话文件。
1218
+ *
1219
+ * 保证与约束:
1220
+ * - 新会话拥有全新独立的 conversationId;
1221
+ * - Header 记录 parentSessionId 与 forkPointRecordId;
1222
+ * - 仅复制导出路径上的必需状态,映射为新会话的 main 分支并重排连续 seq/prevRecordId;
1223
+ * - 拒绝半事务分叉:切点若为未闭合工具调用的 assistant 消息,立即报错;
1224
+ * - 历史 usage 标为导入来源(importedFromFork: true),不重复计入新会话执行费用;
1225
+ * - 临时文件写入、fsync 后原子发布,同步目录;
1226
+ * - 导出失败绝不污染或修改源会话。
1227
+ *
1228
+ * @param options 导出配置
1229
+ * @returns 新独立会话句柄(持有写者锁)
1230
+ */
1231
+ forkSession(options: {
1232
+ sourceSessionId: string;
1233
+ branchId?: string;
1234
+ forkPointRecordId?: string;
1235
+ }): Promise<ManagedSession>;
1002
1236
  /** 绑定写后缓存与锁生命周期;正文优先,缓存失败不使保存成功的消息消失。 */
1003
1237
  private attach;
1004
1238
  /** 缓存通过文件名、身份、统计与正文 stat 校验;失败交由正文重建。 */
@@ -1016,6 +1250,184 @@ declare class SessionManager {
1016
1250
  private report;
1017
1251
  }
1018
1252
 
1253
+ /**
1254
+ * @fileoverview 跨项目会话目录扫描(CrossProjectSessionCatalog)与有界全文检索。
1255
+ *
1256
+ * 约束、边界与为什么:
1257
+ * 1. 跨项目扫描与增量 Sidecar 校验(Cross-Project Incremental Discovery):
1258
+ * 扫描 ~/.kapibala/sessions 全局项目桶目录,优先通过 sidecar 缓存校验读取元数据;
1259
+ * 若缓存缺失或 stat(大小/mtime)失配,流式读取正文重建,严禁将未校验缓存当真源。
1260
+ * 2. 有界全文检索(Bounded Full-Text Search):
1261
+ * - 范围限定:仅搜索 user / assistant 可见文本与 branch_summary 分支摘要,
1262
+ * 默认绝对排除 tool_result 原始输出、私有 reasoning、协议私有字段与凭据;
1263
+ * - 检索语法:支持空格 AND、引号短语、project:/branch:/tag: 属性限定与 re: 正则模式;
1264
+ * - 中文检索:按原生字面子串匹配,不依赖第三方分词库;
1265
+ * - 有界保护:单行限长截断、病态正则超时熔断、最大结果数量上限,超限返回 partial 及原因。
1266
+ * 3. 逻辑归档隔离(Archive Isolation):
1267
+ * 默认目录列表与全文搜索严格排除已归档(archived: true)会话,除非显式指定 includeArchived。
1268
+ */
1269
+
1270
+ /**
1271
+ * 跨项目会话目录项。
1272
+ */
1273
+ interface SessionCatalogEntry extends SessionMetadata {
1274
+ /** 所属项目桶键名(SHA256 哈希)。 */
1275
+ readonly projectKey: string;
1276
+ /** 会话文件物理绝对路径。 */
1277
+ readonly filePath: string;
1278
+ }
1279
+ /**
1280
+ * 全文检索命中结果项。
1281
+ */
1282
+ interface SearchHit {
1283
+ /** 所属会话 ID。 */
1284
+ readonly conversationId: string;
1285
+ /** 所属项目根路径。 */
1286
+ readonly projectRoot: string;
1287
+ /** 所属分支 ID。 */
1288
+ readonly branchId: string;
1289
+ /** 命中的记录 ID。 */
1290
+ readonly recordId: string;
1291
+ /** 命中角色(user / assistant / branch_summary)。 */
1292
+ readonly role: 'user' | 'assistant' | 'branch_summary';
1293
+ /** 命中记录的时间戳。 */
1294
+ readonly timestamp: number;
1295
+ /** 命中片段摘要(包含关键词的上下文片段)。 */
1296
+ readonly snippet: string;
1297
+ /** 是否处于可分叉/可续答的合法边界。 */
1298
+ readonly canResume: boolean;
1299
+ }
1300
+ /**
1301
+ * 全文检索选项。
1302
+ */
1303
+ interface SearchOptions {
1304
+ /** 限定项目根路径或 projectKey。 */
1305
+ readonly project?: string;
1306
+ /** 限定分支名。 */
1307
+ readonly branch?: string;
1308
+ /** 限定标签。 */
1309
+ readonly tag?: string;
1310
+ /** 是否包含已归档会话(默认 false)。 */
1311
+ readonly includeArchived?: boolean;
1312
+ /** 最大返回命中记录数(默认 50,最大 200)。 */
1313
+ readonly limit?: number;
1314
+ /** 搜索总体超时时间(毫秒,默认 10,000ms)。 */
1315
+ readonly timeoutMs?: number;
1316
+ /** 取消信号。 */
1317
+ readonly signal?: AbortSignal;
1318
+ }
1319
+ /**
1320
+ * 全文检索结果响应。
1321
+ */
1322
+ interface SearchResponse {
1323
+ /** 命中结果列表。 */
1324
+ readonly hits: readonly SearchHit[];
1325
+ /** 扫描的会话总数。 */
1326
+ readonly totalSessionsScanned: number;
1327
+ /** 扫描的记录总数。 */
1328
+ readonly totalRecordsScanned: number;
1329
+ /** 是否为有界部分截断结果。 */
1330
+ readonly isPartial: boolean;
1331
+ /** 产生截断或跳过的原因列表。 */
1332
+ readonly partialReasons?: readonly string[];
1333
+ }
1334
+ /**
1335
+ * 目录扫描配置选项。
1336
+ */
1337
+ interface CatalogOptions {
1338
+ /** 会话全局存储根目录(缺省为 ~/.kapibala/sessions)。 */
1339
+ readonly sessionsDir?: string;
1340
+ /** 用户主目录(用于测试隔离)。 */
1341
+ readonly homeDirectory?: string;
1342
+ /** 诊断回调。 */
1343
+ readonly onDiagnostic?: (message: string) => void;
1344
+ }
1345
+ /**
1346
+ * 具有超时保护的正则匹配结果。
1347
+ */
1348
+ interface SafeRegexMatchResult {
1349
+ /** 是否匹配成功。 */
1350
+ readonly matched: boolean;
1351
+ /** 首次匹配的字符起始索引,未匹配为 -1。 */
1352
+ readonly matchIndex: number;
1353
+ /** 是否因超时而提前终止。 */
1354
+ readonly timedOut?: boolean;
1355
+ /** 异常信息。 */
1356
+ readonly error?: string;
1357
+ }
1358
+ /**
1359
+ * 在独立 Worker 线程中执行正则匹配,并在超时时强制 terminate 线程。
1360
+ * 彻底防御主事件循环被 ReDoS 灾难性回溯阻塞。
1361
+ *
1362
+ * 保证:
1363
+ * - 默认复用长寿命常驻 Worker 实例,消除每次匹配 ~93ms 的新建开销;
1364
+ * - 超时后强制终止底层卡死 Worker 线程,释放 CPU 资源并重建新实例;
1365
+ * - 捕获正则语法异常与执行异常,显式提供 error 字段供诊断,不向上抛出未捕获错误;
1366
+ * - 纯内存通信,不产生临时磁盘文件。
1367
+ *
1368
+ * @param pattern 正则表达式模式文本
1369
+ * @param flags 正则表达式修饰符(如 'i', 'm' 等)
1370
+ * @param text 待检索的目标文本
1371
+ * @param timeoutMs 超时毫秒数(默认 1000ms)
1372
+ */
1373
+ declare function safeRegexMatch(pattern: string, flags: string, text: string, timeoutMs?: number): Promise<SafeRegexMatchResult>;
1374
+ /**
1375
+ * 跨项目会话目录检索器(CrossProjectSessionCatalog)。
1376
+ */
1377
+ declare class CrossProjectSessionCatalog {
1378
+ readonly sessionsDir: string;
1379
+ private readonly diagnostic?;
1380
+ constructor(options?: CatalogOptions);
1381
+ /**
1382
+ * 跨项目流式扫描全局目录下的所有会话元数据。
1383
+ *
1384
+ * 保证:
1385
+ * - 优先校验并利用 sidecar 增量缓存;
1386
+ * - 缓存损坏或缺失时从正文重建并持久化 sidecar;
1387
+ * - 默认排除已归档(archived)会话。
1388
+ */
1389
+ scanSessions(options?: {
1390
+ projectRoot?: string;
1391
+ projectKey?: string;
1392
+ includeArchived?: boolean;
1393
+ }): Promise<SessionCatalogEntry[]>;
1394
+ /**
1395
+ * 有界跨项目全文检索。
1396
+ *
1397
+ * 保证:
1398
+ * - 仅搜索可见文本(user / assistant 文字)与分支摘要;
1399
+ * - 支持空格 AND、引号短语、project:/branch: 前缀与 re: 正则;
1400
+ * - 中文子串字面匹配;
1401
+ * - 遵守限长、超时与最大返回限制,返回 partial 标志与原因。
1402
+ *
1403
+ * @param query 搜索关键词或查询表达式
1404
+ * @param options 搜索选项
1405
+ */
1406
+ search(query: string, options?: SearchOptions): Promise<SearchResponse>;
1407
+ /**
1408
+ * 解析查询字符串。
1409
+ */
1410
+ private parseQuery;
1411
+ /**
1412
+ * 在单个会话文件中流式搜索匹配记录。
1413
+ */
1414
+ private searchInSessionFile;
1415
+ /**
1416
+ * 判定文本是否匹配查询条件。
1417
+ */
1418
+ private matches;
1419
+ /**
1420
+ * 生成关键词周边的摘录片段。
1421
+ */
1422
+ private generateSnippet;
1423
+ /**
1424
+ * 读取或增量重建单个会话文件的元数据。
1425
+ */
1426
+ private resolveMetadata;
1427
+ private sidecarPath;
1428
+ private report;
1429
+ }
1430
+
1019
1431
  /** 对对象 key 确定性排序,保证摘要、工具 schema 与 fingerprint 不受插入顺序影响。 */
1020
1432
  declare function stableSerialize(value: unknown): string;
1021
1433
 
@@ -1078,6 +1490,546 @@ declare class UnicodeTokenEstimator implements TokenEstimator {
1078
1490
  observe(request: ModelRequest, actualPromptTokens: number, modelFingerprint?: string): void;
1079
1491
  }
1080
1492
 
1493
+ /**
1494
+ * @fileoverview 工作区物理身份解析、路径规范化与目录边界校验。
1495
+ *
1496
+ * 约束、边界与为什么:
1497
+ * 1. 绝对路径与 native 规范化:
1498
+ * Core 处于 Headless 环境,禁止依赖隐式进程工作目录(process.cwd 机制)或 process.chdir 进行相对路径解析。
1499
+ * 所有工作区与执行目录参数必须由宿主提供绝对路径,并通过 fs.realpathSync.native 展开符号链接与 Windows 8.3 短名。
1500
+ * 2. Windows 盘符与大小写统一:
1501
+ * Windows 文件系统大小写不敏感且保留驱动器盘符。在 Windows 下统一盘符大写(如 "c:\" -> "C:\"),
1502
+ * 身份哈希计算使用正斜杠且全小写;POSIX 下保持原始大小写与斜杠。
1503
+ * 3. 工作区越界防御(WORKSPACE_ESCAPE):
1504
+ * 执行目录 executionCwd 必须严格位于 workspaceRoot 内部或与其相同,杜绝利用上层目录跳转越过工作区边界。
1505
+ * 4. 别名与冲突检测:
1506
+ * rootDir / cwd 作为兼容别名;若与 workspaceRoot / executionCwd 同时提供且物理路径不一致,必须立即显式报错。
1507
+ */
1508
+ /**
1509
+ * 规范化 Windows 驱动器盘符为大写。
1510
+ * 非 Windows 路径或非驱动器盘符路径原样返回。
1511
+ */
1512
+ declare function normalizeDriveLetter(p: string): string;
1513
+ /**
1514
+ * 将绝对路径转换为操作系统原生物理长路径。
1515
+ *
1516
+ * 保证:
1517
+ * - 必须接收绝对路径,否则抛出 CONFIG_INVALID;
1518
+ * - 若路径存在,使用 fs.realpathSync.native 展开所有软链接与 Windows 8.3 短名;
1519
+ * - 若路径尚不存在,回溯到最近存在的祖先目录取 native 物理路径后再拼接剩余子路径;
1520
+ * - Windows 下统一规范驱动器盘符为大写。
1521
+ *
1522
+ * 何时失败:
1523
+ * - 传入相对路径时抛出 CONFIG_INVALID。
1524
+ */
1525
+ declare function toNativePhysicalPath(absolutePath: string): string;
1526
+ /**
1527
+ * 判定两个路径在物理上是否指向同一位置。
1528
+ *
1529
+ * 保证:
1530
+ * - 展开物理路径后进行对比;
1531
+ * - Windows 下忽略大小写与斜杠差异,POSIX 下严格区分大小写。
1532
+ */
1533
+ declare function isSamePath(pathA: string, pathB: string): boolean;
1534
+ /**
1535
+ * 检查 target 物理路径是否位于 base 物理路径内部(或两者相同)。
1536
+ *
1537
+ * 保证:
1538
+ * - 跨盘符(Windows)或父路径逃逸(..)判定为 false;
1539
+ * - Windows 下路径对比不区分大小写。
1540
+ *
1541
+ * 不做什么:
1542
+ * - 不检查路径是否实际在文件系统上存在(仅做纯路径层级边界判定)。
1543
+ */
1544
+ declare function isPathInside(base: string, target: string): boolean;
1545
+ /**
1546
+ * 计算规范化项目身份哈希(projectKey)。
1547
+ *
1548
+ * 保证:
1549
+ * - Windows 下统一使用小写与正斜杠,使不同大小写或短名别名映射到相同 projectKey;
1550
+ * - 输出 SHA-256 十六进制摘要,与 SessionManager 存储分桶完全同源。
1551
+ */
1552
+ declare function computeProjectKey(canonicalProjectRoot: string): string;
1553
+ /** 供 resolveWorkspaceContext 消费的工作区解析输入。 */
1554
+ interface WorkspaceResolutionInput {
1555
+ /** 显式工作区物理根路径。 */
1556
+ workspaceRoot?: string;
1557
+ /** 兼容别名:工具执行与会话基目录。 */
1558
+ rootDir?: string;
1559
+ /** 显式命令执行目录(必须位于 workspaceRoot 内部)。 */
1560
+ executionCwd?: string;
1561
+ /** 兼容别名:执行目录。 */
1562
+ cwd?: string;
1563
+ /** 显式项目根路径;缺省与 workspaceRoot 相同。 */
1564
+ projectRoot?: string;
1565
+ }
1566
+ /** 规范化后的工作区上下文。 */
1567
+ interface WorkspaceContext {
1568
+ /** 规范化后的工作区绝对物理根路径。 */
1569
+ readonly workspaceRoot: string;
1570
+ /** 规范化后的默认命令执行绝对物理路径。 */
1571
+ readonly executionCwd: string;
1572
+ /** 规范化后的项目根绝对物理路径。 */
1573
+ readonly projectRoot: string;
1574
+ /** 确定性的项目身份哈希。 */
1575
+ readonly projectKey: string;
1576
+ }
1577
+ /**
1578
+ * 解析并验证工作区上下文。
1579
+ *
1580
+ * 保证:
1581
+ * - 校验 workspaceRoot 与 rootDir 必有其一,缺失时抛出 WORKSPACE_ROOT_REQUIRED;
1582
+ * - 若两者皆提供且物理路径不一致,抛出 CONFIG_INVALID;
1583
+ * - executionCwd / cwd 冲突时抛出 CONFIG_INVALID;
1584
+ * - executionCwd 必须位于 workspaceRoot 内部,越界时抛出 WORKSPACE_ESCAPE;
1585
+ * - 所有输出路径均为 native 规范化绝对路径,不依赖隐式 process.cwd 寻址。
1586
+ *
1587
+ * 何时失败:
1588
+ * - 缺少工作区根(WORKSPACE_ROOT_REQUIRED);
1589
+ * - 路径为非绝对路径或别名冲突(CONFIG_INVALID);
1590
+ * - 执行目录越界(WORKSPACE_ESCAPE)。
1591
+ */
1592
+ declare function resolveWorkspaceContext(input: WorkspaceResolutionInput): WorkspaceContext;
1593
+
1594
+ /** 本次会话的自动执行边界;FullAccess 只能由宿主为本次会话显式选择。 */
1595
+ type SessionMode = 'Approval' | 'Plan' | 'Auto' | 'FullAccess';
1596
+ /** 规则动作与裁决结果共用同一词表;ask 表示交人工审批,不是放行。 */
1597
+ type PermissionAction = 'allow' | 'ask' | 'deny';
1598
+ /** 一次 Shell 执行的精确目标;字段组合构成审批与缓存命中的身份,任何维度都不允许通配。 */
1599
+ interface ShellScope {
1600
+ command: string;
1601
+ interpreter: string;
1602
+ executablePath?: string;
1603
+ cwd: string;
1604
+ /** 解释器身份摘要(路径、大小、mtime 推导);解释器被替换后规则与缓存即失配。 */
1605
+ executableDigest?: string;
1606
+ /** 命令直接引用的工作目录内脚本的内容摘要;仅单脚本命令可计算,组合命令缺省。 */
1607
+ scriptDigest?: string;
1608
+ /** 执行前复核用指纹;审批后重新推导不一致时按目标漂移拒绝执行。 */
1609
+ executionFingerprint?: string;
1610
+ }
1611
+ /** 宿主提供的显式规则;tool / capability / shell 三种范围必须恰好声明一个。 */
1612
+ interface PermissionRule {
1613
+ action: PermissionAction;
1614
+ tool?: string;
1615
+ capability?: Capability;
1616
+ shell?: ShellScope;
1617
+ }
1618
+ /** 权限裁决的全部输入;硬限制与缓存命中由宿主查询后以标志位传入,策略本身不持有状态。 */
1619
+ interface PermissionRequest {
1620
+ mode: SessionMode;
1621
+ toolName: string;
1622
+ capabilities: readonly Capability[];
1623
+ /** 危险性来自工具元数据;未命中 allow 规则时,非 FullAccess 模式一律降级为 ask。 */
1624
+ dangerous?: boolean;
1625
+ /** 宿主硬限制;命中即拒绝,优先级高于一切规则与缓存。 */
1626
+ hardDenied?: boolean;
1627
+ shell?: ShellScope;
1628
+ /** 规则表须先经 validatePermissionRules 校验;同动作规则按声明顺序取首个命中。 */
1629
+ rules?: readonly PermissionRule[];
1630
+ /** 会话缓存命中标志(来自 SessionApprovalCache);仅在 deny / ask 规则都未命中时生效。 */
1631
+ cachedApproval?: boolean;
1632
+ /** 会话缓存拒绝标志;在 deny 规则之后、ask 规则之前生效。 */
1633
+ cachedDenial?: boolean;
1634
+ }
1635
+ /** 裁决结果及其来源;source 供审计区分硬限制、Plan、规则、缓存与模式默认。 */
1636
+ interface PermissionDecision {
1637
+ decision: PermissionAction;
1638
+ source: 'hard_limit' | 'plan' | 'explicit_rule' | 'session_cache' | 'mode_default';
1639
+ /** 命中规则在 rules 中的下标;仅 source 为 explicit_rule 时存在。 */
1640
+ ruleIndex?: number;
1641
+ }
1642
+ /** 拒绝含糊的 Shell 前缀/通配符和结构不完整的规则。 */
1643
+ declare function validatePermissionRules(rules: readonly PermissionRule[]): void;
1644
+ /** 纯策略裁决;宿主硬限制和 Plan 始终先于任何规则或会话缓存。 */
1645
+ declare class PermissionPolicy {
1646
+ /**
1647
+ * 裁决顺序固定:硬限制 → Plan 收窄 → deny 规则 → 会话缓存拒绝 → ask 规则 →
1648
+ * 会话缓存允许 → allow 规则(run_command 必须带 shell 范围,工具级 allow 不能放行命令)
1649
+ * → 模式默认。同一输入总是得到同一裁决,不读取任何外部状态。
1650
+ */
1651
+ decide(request: PermissionRequest): PermissionDecision;
1652
+ }
1653
+ /** 只向模型展示当前模式与整项拒绝规则允许请求的工具。 */
1654
+ declare function visibleTools(tools: readonly Tool[], mode: SessionMode, rules?: readonly PermissionRule[]): Tool[];
1655
+
1656
+ /** 路径沙箱配置;workspaceRoot 是所有文件访问的词法与物理边界。 */
1657
+ interface SandboxConfig {
1658
+ /** 显式工作区物理根路径。 */
1659
+ workspaceRoot?: string;
1660
+ /** 兼容别名:等同于 workspaceRoot。 */
1661
+ rootDir?: string;
1662
+ /**
1663
+ * 严格模式:任何解析后落在 workspaceRoot 之外的物理路径一律拒绝,
1664
+ * 不存在 fail-open 开关。
1665
+ */
1666
+ allowSymlinks?: boolean;
1667
+ }
1668
+ /**
1669
+ * 把文件访问限制在 workspaceRoot 内:先做词法归一化检查,再展开符号链接与 Windows 短名做物理检查,两层都通过才放行。
1670
+ * 由 AgentSession 会话持有独立实例,避免全局单例缓存串扰。
1671
+ */
1672
+ declare class PathSandbox {
1673
+ /** 显式工作区绝对物理根路径。 */
1674
+ readonly workspaceRoot: string;
1675
+ /** 兼容别名:等同于 workspaceRoot。 */
1676
+ readonly rootDir: string;
1677
+ readonly allowSymlinks: boolean;
1678
+ private cachedRealRootDir?;
1679
+ constructor(config: SandboxConfig);
1680
+ /**
1681
+ * workspaceRoot 的物理路径。经过 toNativePhysicalPath 展开符号链接与 8.3 短名。
1682
+ */
1683
+ private get realRootDir();
1684
+ /**
1685
+ * 检查并解析安全路径
1686
+ * 1. 解析相对路径为相对于 workspaceRoot 的绝对路径
1687
+ * 2. 词法检查:`..` 归一化后必须仍在 workspaceRoot 内
1688
+ * 3. 物理检查:解析符号链接与短名后的真实物理路径必须仍在 workspaceRoot 内
1689
+ */
1690
+ resolveSafePath(targetPath: string): string;
1691
+ /**
1692
+ * 把词法路径映射为物理路径。
1693
+ *
1694
+ * 关键点在于**向上回溯到最近一个真实存在的祖先**再取 realpath,然后把尚未存在的尾段拼回去:
1695
+ * - 目标已存在 → 直接 realpath,符号链接立刻被展开;
1696
+ * - 目标不存在(典型场景:write_file 新建文件) → 若只看目标本身,所有校验都会被跳过,
1697
+ * 于是 `write_file('linkDir/new.txt')` 可以借道指向外部的 linkDir 越界写入。
1698
+ * 回溯到 linkDir 取 realpath 即可识破这种穿透。
1699
+ */
1700
+ private toPhysicalPath;
1701
+ }
1702
+
1703
+ /**
1704
+ * @fileoverview 子代理权限求交(ChildGrant)与角色模型路由。
1705
+ *
1706
+ * 约束、边界与为什么:
1707
+ * 1. 逐轴求交(Intersection Only):
1708
+ * 子代理的权限永远是「父级有效策略」、「角色预设上界」与「显式 ChildGrant 请求」三者的交集。
1709
+ * 任何维度(模式、规则、能力、工具、工作区、深度、预算)只能收紧,绝对不得越级放宽。
1710
+ * 2. 祖先 Deny 并集继承与 Ask 保留:
1711
+ * 祖先链上的所有 deny 规则无条件继承,子代理无法绕过;祖先的 ask 规则必须保留,
1712
+ * 不因子代理声明 allow 规则或 FullAccess 模式而消失。
1713
+ * 3. 角色预设为单一真源:
1714
+ * - explore:只读探索,禁用通用 Shell 与写能力,首选场景 fast;
1715
+ * - planner:分析规划,禁用通用 Shell 与写能力,首选场景 planning;
1716
+ * - implement:具体实施,可委派写与执行权限,首选场景 execution;
1717
+ * - advisor:纯文本推理,工具集合严格为空,首选场景 planning;
1718
+ * - custom:自定义工具白名单,继承父场景绑定,必须显式声明 allowedTools。
1719
+ * 4. Plan 模式硬约束与深度熔断:
1720
+ * Plan 模式绝对禁止 agent:spawn;达到最大深度(默认 3,硬上限 5)的子代理绝对禁止继续派生。
1721
+ * 5. 防伪造与不可委派拦截:
1722
+ * 请求不存在于父可用工具列表中的工具名,立即拒绝并抛出 TOOL_NOT_DELEGATABLE。
1723
+ */
1724
+
1725
+ /** 子代理业务角色预设。 */
1726
+ type SubagentRole = 'explore' | 'planner' | 'implement' | 'advisor' | 'custom';
1727
+ /** 默认子代理派生深度限制。根代理深度为 0,深度达到 3 时不可再派生。 */
1728
+ declare const DEFAULT_MAX_SUBAGENT_DEPTH = 3;
1729
+ /** 运行时子代理硬上限深度。任何配置不得超过此深度。 */
1730
+ declare const HARD_LIMIT_MAX_SUBAGENT_DEPTH = 5;
1731
+ /** 子代理限额配置。 */
1732
+ interface ChildLimits {
1733
+ /** 允许的最大模型步骤数;默认 15。 */
1734
+ maxSteps: number;
1735
+ /** 单任务最大墙钟执行时间(毫秒);默认 300,000(5分钟)。 */
1736
+ timeoutMs: number;
1737
+ }
1738
+ /** 默认子代理限额。 */
1739
+ declare const DEFAULT_CHILD_LIMITS: Readonly<ChildLimits>;
1740
+ /** 角色预设定义规范。 */
1741
+ interface RolePresetDefinition {
1742
+ /** 角色唯一标识。 */
1743
+ readonly role: SubagentRole;
1744
+ /** 中文说明。 */
1745
+ readonly description: string;
1746
+ /** 绑定的首选场景模型角色;custom 继承父轮。 */
1747
+ readonly preferredRole: PrimaryModelRole | 'inherit';
1748
+ /** 允许的能力上界集合;不在集合内的能力即使父级具备也被剥离。 */
1749
+ readonly allowedCapabilities: readonly Capability[];
1750
+ /** 绝对禁止的能力集合;在求交时强制剔除。 */
1751
+ readonly disallowedCapabilities: readonly Capability[];
1752
+ /** 是否允许工具集合非空;advisor 强制要求为空。 */
1753
+ readonly allowTools: boolean;
1754
+ /** 是否需要显式提供工具白名单;custom 必须显式提供。 */
1755
+ readonly requireExplicitTools: boolean;
1756
+ }
1757
+ /**
1758
+ * 角色预设单一真源映射表。
1759
+ */
1760
+ declare const ROLE_PRESETS: Readonly<Record<SubagentRole, RolePresetDefinition>>;
1761
+ /** 获取指定角色的预设定义。若角色不存在抛出 CONFIG_INVALID。 */
1762
+ declare function getRolePreset(role: string): RolePresetDefinition;
1763
+ /** 派生子代理时的请求载荷(ChildGrant)。由调用方或 spawn_agent 工具传入。 */
1764
+ interface ChildGrant {
1765
+ /** 申请的角色。 */
1766
+ role: SubagentRole;
1767
+ /** 可选工具白名单收紧;若指定必须为父可用工具子集;custom 角色必选。 */
1768
+ allowedTools?: readonly string[];
1769
+ /** 显式声明允许的能力子集;只能收紧。 */
1770
+ allowedCapabilities?: readonly Capability[];
1771
+ /** 子任务追加的补充权限规则(只能收紧)。 */
1772
+ permissionRules?: readonly PermissionRule[];
1773
+ /** 申请生效的会话模式;只能比父模式更严格或相同,不可放宽。 */
1774
+ mode?: SessionMode;
1775
+ /** 子任务执行工作目录;必须位于父工作区内部。 */
1776
+ executionCwd?: string;
1777
+ /** 子任务运行限额;只能比默认/父限额更严格。 */
1778
+ limits?: Partial<ChildLimits>;
1779
+ /** 显式场景或模型覆盖;仅在宿主允许时生效。 */
1780
+ modelOverride?: string;
1781
+ }
1782
+ /** 父会话在派生时刻的有效策略快照。 */
1783
+ interface ParentPolicySnapshot {
1784
+ /** 父会话当前模式。 */
1785
+ mode: SessionMode;
1786
+ /** 父会话当前生效的全部规则(含祖先 deny 规则)。 */
1787
+ rules: readonly PermissionRule[];
1788
+ /** 父会话可用工具详细列表或元数据。 */
1789
+ availableTools: readonly (Tool | {
1790
+ name: string;
1791
+ metadata?: {
1792
+ permissions?: Capability[];
1793
+ };
1794
+ })[];
1795
+ /** 父会话物理工作区根绝对路径。 */
1796
+ workspaceRoot: string;
1797
+ /** 父会话当前命令执行工作目录绝对路径。 */
1798
+ executionCwd: string;
1799
+ /** 父会话当前深度(根会话为 0)。 */
1800
+ currentDepth: number;
1801
+ /** 允许的最大深度(缺省为 DEFAULT_MAX_SUBAGENT_DEPTH)。 */
1802
+ maxDepth?: number;
1803
+ /** 父会话当前场景模型角色。 */
1804
+ currentPrimaryRole?: PrimaryModelRole;
1805
+ /** 父会话可用限额。 */
1806
+ limits?: Partial<ChildLimits>;
1807
+ }
1808
+ /** 逐轴求交后派生出的子代理有效策略。 */
1809
+ interface DerivedChildPolicy {
1810
+ /** 子代理最终生效的 SessionMode。 */
1811
+ readonly mode: SessionMode;
1812
+ /** 子代理最终生效的权限规则(祖先 deny 并集 + 祖先 ask 保留 + 子收紧规则)。 */
1813
+ readonly rules: readonly PermissionRule[];
1814
+ /** 子代理最终可使用的工具名称列表。 */
1815
+ readonly allowedTools: readonly string[];
1816
+ /** 子代理最终允许的能力集合。 */
1817
+ readonly allowedCapabilities: readonly Capability[];
1818
+ /** 子代理规范化命令执行绝对工作目录。 */
1819
+ readonly executionCwd: string;
1820
+ /** 子代理所在任务树深度。 */
1821
+ readonly depth: number;
1822
+ /** 子代理生效的场景模型角色。 */
1823
+ readonly preferredRole: PrimaryModelRole;
1824
+ /** 子代理是否允许继续派生(agent:spawn)。 */
1825
+ readonly canSpawnSubagent: boolean;
1826
+ /** 子代理生效的运行限额。 */
1827
+ readonly limits: Readonly<ChildLimits>;
1828
+ }
1829
+ /**
1830
+ * 模式收紧计算:比较并选择两者中更严格的模式。
1831
+ * 子代理绝对不能比父模式更宽松。
1832
+ */
1833
+ declare function tightenMode(parentMode: SessionMode, requestedMode?: SessionMode): SessionMode;
1834
+ /**
1835
+ * 核心纯函数:逐轴求交派生子代理有效权限与策略。
1836
+ *
1837
+ * 保证:
1838
+ * - 纯函数无外部副作用,不依赖网络、文件系统(除纯路径层级判断)或全局状态;
1839
+ * - 祖先 deny 规则取并集继承,祖先 ask 规则完整保留;
1840
+ * - 模式、能力、工具、工作区、深度与限额逐轴求交收紧;
1841
+ * - 角色预设与调用方 ChildGrant 白名单求交;
1842
+ * - 若请求未知工具名或父级未提供的工具名,立即拒绝并抛出 TOOL_NOT_DELEGATABLE;
1843
+ * - Plan 模式绝对禁止 agent:spawn;
1844
+ * - 深度达到或超过 maxDepth 时绝对禁止继续派生子代理。
1845
+ *
1846
+ * 何时失败:
1847
+ * - custom 角色未提供 allowedTools(CONFIG_INVALID);
1848
+ * - 包含不可委派的未知工具名(TOOL_NOT_DELEGATABLE);
1849
+ * - 子执行目录越出父工作区根范围(WORKSPACE_ESCAPE);
1850
+ * - 父处于 Plan 模式且尝试申请破坏性能力(PERMISSION_DENIED);
1851
+ * - 角色名称未知(CONFIG_INVALID)。
1852
+ */
1853
+ declare function deriveChildPolicy(parent: ParentPolicySnapshot, grant: ChildGrant): DerivedChildPolicy;
1854
+
1855
+ /** 执行能力的最小分类;权限规则、模式裁决与工具元数据声明共用这一词汇表。 */
1856
+ type Capability = 'fs:read' | 'fs:write' | 'exec' | 'net:outbound' | 'env:read' | 'agent:spawn' | 'external:call';
1857
+ /**
1858
+ * 外部调用的精确执行身份;供审批缓存、发送前复核与审计消费。
1859
+ * 包含服务端物理身份、连接代次、目录 epoch 与定义摘要等不可伪造字段。
1860
+ */
1861
+ interface ToolExecutionIdentity {
1862
+ serverIdentity?: string;
1863
+ connectionGeneration?: number;
1864
+ catalogEpoch?: number;
1865
+ toolDigest?: string;
1866
+ [key: string]: unknown;
1867
+ }
1868
+ /**
1869
+ * 显式 opt-in 规范化执行结果;普通对象返回值保持兼容不强制包装。
1870
+ */
1871
+ interface ToolExecutionResult {
1872
+ content: string;
1873
+ isError?: boolean;
1874
+ errorCode?: string;
1875
+ retryPolicy?: 'never' | 'after_user_action';
1876
+ execution?: ToolResultExecution;
1877
+ }
1878
+ interface ToolMetadata {
1879
+ /** 注册来源标记(如 'builtin');注册表据此执行冲突策略并支持按源注销。 */
1880
+ source?: string;
1881
+ /** 标记危险工具;未命中 allow 规则时,非 FullAccess 模式一律降级为 ask 而非按模式默认放行。 */
1882
+ dangerous?: boolean;
1883
+ /** 所需能力的声明;v0.0.1 不据此授权,v0.0.2 的执行前权限决策才会消费。 */
1884
+ permissions?: Capability[];
1885
+ /** 工具自身等待进程资源回收,执行器不可再使用通用 Promise.race 超时。 */
1886
+ managesTimeout?: boolean;
1887
+ /** 只读提示;工具声明自身无副作用,供 UI 展示与只读过滤参考。 */
1888
+ readOnlyHint?: boolean;
1889
+ }
1890
+ /** 工具执行期由宿主注入的运行环境;信号取消后工具应尽快清理在途资源再返回。 */
1891
+ interface ToolContext {
1892
+ /** 显式工作区物理根路径,经 native realpath 规范化。 */
1893
+ workspaceRoot?: string;
1894
+ /** 显式命令执行工作目录绝对路径(位于 workspaceRoot 内部)。 */
1895
+ executionCwd?: string;
1896
+ /** 会话持有的 PathSandbox 独占实例;文件类工具优先使用此沙箱。 */
1897
+ sandbox?: PathSandbox;
1898
+ /** 兼容别名:本次执行的沙箱根目录;等同于 workspaceRoot。 */
1899
+ rootDir: string;
1900
+ signal?: AbortSignal;
1901
+ logger?: (message: string) => void;
1902
+ /** 命令工具在真实进程创建后调用;审计失败时须先回收进程再报告结果未知。 */
1903
+ onProcessSpawned?: () => Promise<void>;
1904
+ onProgress?: (progress: {
1905
+ elapsedMs: number;
1906
+ outputBytes: number;
1907
+ }) => void;
1908
+ /** 子代理调度与后台执行上下文字段。 */
1909
+ sessionId?: string;
1910
+ branchId?: string;
1911
+ runId?: string;
1912
+ toolCallId?: string;
1913
+ depth?: number;
1914
+ agentId?: string;
1915
+ rootTaskId?: string;
1916
+ /** 父事务提交成功后的回调注册器;仅当整批工具消息持久化落盘后才调用。 */
1917
+ onCommitted?: (action: () => void | Promise<void>) => void;
1918
+ /** 任务准备失败或父事务未持久化时的回滚清理动作注册器。 */
1919
+ onRollback?: (action: () => void | Promise<void>) => void;
1920
+ /** 父级会话有效安全策略快照(用于派生子代理时的真实基线求交)。 */
1921
+ parentPolicy?: ParentPolicySnapshot;
1922
+ }
1923
+ /**
1924
+ * 工具输入参数校验结果;valid 为 false 或抛出异常均阻止审批和发送。
1925
+ */
1926
+ interface ToolInputValidation {
1927
+ valid: boolean;
1928
+ message?: string;
1929
+ }
1930
+ /** 工具契约;parameters 是 JSON Schema,模型只能看到经 toToolDefinition 投影后的三个字段。 */
1931
+ interface Tool<TInput = Record<string, unknown>, TOutput = unknown> {
1932
+ readonly name: string;
1933
+ readonly description: string;
1934
+ readonly parameters: Record<string, unknown>;
1935
+ readonly metadata?: ToolMetadata;
1936
+ /** 声明本次输入的精确执行目标,供审批展示与执行前指纹复核;无固定执行目标的工具不实现。 */
1937
+ approvalScope?(input: TInput, rootDir: string, executionCwd?: string): ShellScope;
1938
+ /** 本次执行身份;审批缓存与执行前复核消费,缺省保持旧工具规则。 */
1939
+ executionIdentity?(input: TInput, rootDir: string): ToolExecutionIdentity;
1940
+ /** 无副作用地校验最终参数,不修改参数、不访问远端;异常与拒绝均阻止审批和发送。 */
1941
+ validateInput?(input: TInput): ToolInputValidation | undefined;
1942
+ /** 显式 opt-in 转换为标准执行结果;未提供时普通返回值继续作为常规输出。 */
1943
+ toExecutionResult?(raw: TOutput): ToolExecutionResult;
1944
+ execute(input: TInput, ctx: ToolContext): Promise<TOutput>;
1945
+ }
1946
+ /** 恒等构造器:只为工具实现提供类型推断与统一书写形式,不产生任何运行时包装。 */
1947
+ declare function defineTool<TInput = Record<string, unknown>, TOutput = unknown>(tool: Tool<TInput, TOutput>): Tool<TInput, TOutput>;
1948
+ /** 投影为模型可见的工具描述;刻意丢弃 metadata 与 approvalScope,执行侧信息不进入协议。 */
1949
+ declare function toToolDefinition(tool: Tool): ToolDefinition;
1950
+
1951
+ /**
1952
+ * @fileoverview 共享工作区写租约(Workspace Write Lease)协调器。
1953
+ *
1954
+ * 约束、边界与为什么:
1955
+ * 1. 串行化共享工作区写操作:
1956
+ * 当多个智能体(如父代理与后台子代理)在同一物理工作区运行且未挂载独立 Git worktree 时,
1957
+ * 并发写入会导致文件撕裂与状态脏化。通过写租约对文件写入、Shell 执行与外部写操作进行强制互斥。
1958
+ * 2. 覆盖范围不仅限文件写:
1959
+ * 写操作涵盖声明了 `fs:write` 的工具、声明了 `exec` 的命令执行、以及未显式声明 `readOnlyHint: true` 的外部 MCP 工具。
1960
+ * 3. 安全释放与排队唤醒:
1961
+ * 操作完成、异常中止或被取消时,必须在 finally 中安全释放写租约;释放后原子唤醒队列中的下一个排队者。
1962
+ * 支持 AbortSignal 取消与超时保护,被取消的排队项安全从队列剔除,防止死锁。
1963
+ * 4. 物理根分桶与大小写归一:
1964
+ * 租约按物理路径(经 toNativePhysicalPath 规范化)分桶,不同工作区互不影响;
1965
+ * Windows 下路径对比大小写不敏感。
1966
+ */
1967
+
1968
+ /** 活动写租约句柄。持有者调用 release() 释放写锁。 */
1969
+ interface WorkspaceWriteLease {
1970
+ /** 租约唯一标识。 */
1971
+ readonly leaseId: string;
1972
+ /** 规范化工作区物理根路径。 */
1973
+ readonly workspaceRoot: string;
1974
+ /** 租约持有者标识(如 sessionId 或 agentId)。 */
1975
+ readonly ownerId: string;
1976
+ /** 获取租约的时间戳(毫秒)。 */
1977
+ readonly acquiredAt: number;
1978
+ /** 释放租约并唤醒后续排队者;多次调用幂等。 */
1979
+ release(): void;
1980
+ }
1981
+ /** 判定一个工具是否属于具有写副作用的操作。 */
1982
+ declare function isWriteOperation(tool: Tool): boolean;
1983
+ /**
1984
+ * 工作区写租约协调器。
1985
+ * 支持同工作区写操作排队与互斥,异工作区并发无阻。
1986
+ */
1987
+ declare class WorkspaceLeaseCoordinator {
1988
+ private readonly buckets;
1989
+ private getBucketKey;
1990
+ private getOrCreateBucket;
1991
+ /**
1992
+ * 检查指定工作区当前是否有活跃的写租约。
1993
+ */
1994
+ isLocked(workspaceRoot: string): boolean;
1995
+ /**
1996
+ * 获取指定工作区当前活跃的租约所有者信息。
1997
+ */
1998
+ getActiveLease(workspaceRoot: string): {
1999
+ leaseId: string;
2000
+ ownerId: string;
2001
+ acquiredAt: number;
2002
+ } | undefined;
2003
+ /**
2004
+ * 尝试非阻塞获取写租约。若当前被占用立即返回 undefined。
2005
+ */
2006
+ tryAcquire(workspaceRoot: string, ownerId: string): WorkspaceWriteLease | undefined;
2007
+ /**
2008
+ * 阻塞排队获取写租约。
2009
+ *
2010
+ * 保证:
2011
+ * - 若无活动租约,立即获取并返回;
2012
+ * - 若被占用,加入 FIFO 队列等待;
2013
+ * - 支持 AbortSignal 取消;取消时立即移出队列并抛出 ABORTED;
2014
+ * - 支持可选超时,超时抛出 LEASE_TIMEOUT。
2015
+ */
2016
+ acquire(workspaceRoot: string, ownerId: string, options?: {
2017
+ signal?: AbortSignal;
2018
+ timeoutMs?: number;
2019
+ }): Promise<WorkspaceWriteLease>;
2020
+ private removeFromQueue;
2021
+ private releaseLease;
2022
+ /**
2023
+ * 使用写租约包装异步操作。执行完毕或发生异常时在 finally 中安全释放。
2024
+ */
2025
+ withWriteLease<T>(workspaceRoot: string, ownerId: string, action: (lease: WorkspaceWriteLease) => Promise<T>, options?: {
2026
+ signal?: AbortSignal;
2027
+ timeoutMs?: number;
2028
+ }): Promise<T>;
2029
+ }
2030
+ /** 运行时共享写租约协调器单例。 */
2031
+ declare const sharedWorkspaceLeaseCoordinator: WorkspaceLeaseCoordinator;
2032
+
1081
2033
  type CompactionReason = 'threshold' | 'manual' | 'overflow';
1082
2034
  /**
1083
2035
  * 最近一次请求准备或只读检查发布的上下文快照,供宿主展示与诊断。
@@ -1126,8 +2078,8 @@ interface ContextManagerOptions {
1126
2078
  onDiagnostic?: (message: string) => void;
1127
2079
  /** 摘要角色绑定来源;缺省时跳过二级摘要,仅保留一级剪裁。 */
1128
2080
  router?: ModelRouter;
1129
- /** 转发给文件观察提取;项目根不作为历史工具相对路径的推断依据。 */
1130
- projectRoot?: string;
2081
+ /** 转发给文件观察提取;必须显式指定物理项目根绝对路径,禁止缺省隐式回退。 */
2082
+ projectRoot: string;
1131
2083
  /** 当前已注册的内置工具名集合;剪裁白名单只认可其中的内置只读工具。 */
1132
2084
  builtInToolNames?: () => ReadonlySet<string>;
1133
2085
  /** 每个摘要 attempt 的使用量回调;在候选校验前触发,失败摘要仍计消耗。 */
@@ -1461,193 +2413,55 @@ interface SkillCatalog {
1461
2413
  text: string;
1462
2414
  included: number;
1463
2415
  omitted: number;
1464
- estimatedTokens: number;
1465
- }
1466
- /** 生成确定性 L2.5;预算含标题、XML、转义及遗漏提示,只删完整条目。 */
1467
- declare function formatSkillCatalog(skills: readonly SkillMetadata[], contextWindow?: number, remainingTokens?: number): SkillCatalog;
1468
- /** 模型目录分页输入;游标只定位快照,不提供信任或正文访问授权。 */
1469
- interface SkillQuery {
1470
- query?: string;
1471
- cursor?: string;
1472
- limit?: number;
1473
- }
1474
- /** 有界模型元数据页;不包含正文,游标按实际返回条目推进。 */
1475
- interface SkillQueryPage {
1476
- skills: {
1477
- name: string;
1478
- description: string;
1479
- scope: string;
1480
- argumentHint?: string;
1481
- }[];
1482
- total: number;
1483
- nextCursor?: string;
1484
- }
1485
-
1486
- /** 确定性技能注册表;刷新原子替换快照,运行中加载必须与发现指纹一致。 */
1487
- declare class SkillRegistry {
1488
- private readonly options;
1489
- private definitions;
1490
- private warnings;
1491
- private revisionValue;
1492
- /** 固定宿主配置副本,外部对象变更不能静默改变本轮发现或信任。 */
1493
- constructor(options: SkillOptions);
1494
- /** 获取独立诊断副本,调用方不能修改生效候选或权限。 */
1495
- get diagnostics(): SkillDiagnostic[];
1496
- /** 快照游标身份随正文、来源、可用性变化而失效。 */
1497
- get revision(): string;
1498
- /** 是否由宿主启用;关闭只影响本次能力,不删除历史或文件。 */
1499
- get enabled(): boolean;
1500
- /** 每轮开始重新发现;取消不发布半个快照,非法单文件只产生诊断。 */
1501
- refresh(signal?: AbortSignal): Promise<void>;
1502
- /** 按名称查询胜出元数据副本;未知名称返回 undefined,正文仅由 load 校验后懒读取。 */
1503
- get(name: string): SkillMetadata | undefined;
1504
- /** 宿主可检查不可用条目;模型/用户视图分别施加调用控制,均不读取正文。 */
1505
- list(caller?: 'host' | 'model' | 'user', query?: string): SkillMetadata[];
1506
- /** 按当前快照校验调用控制与物理身份,不接受模型提供的信任或 caller 升级。 */
1507
- load(name: string, caller: 'model' | 'user', signal?: AbortSignal): Promise<SkillDefinition>;
1508
- /** 查询可信模型集合;过期游标可修正,预算不足不返回不前进的分页。 */
1509
- queryModel(input?: SkillQuery, remainingTokens?: number): SkillQueryPage;
1510
- /** 复核配置根、词法发现路径和原文件字节,返回本次有界读取文本;漂移要求新运行,不能热替换。 */
1511
- verify(skill: SkillMetadata, signal?: AbortSignal): Promise<string>;
1512
- }
1513
-
1514
- /** 本次会话的自动执行边界;FullAccess 只能由宿主为本次会话显式选择。 */
1515
- type SessionMode = 'Approval' | 'Plan' | 'Auto' | 'FullAccess';
1516
- /** 规则动作与裁决结果共用同一词表;ask 表示交人工审批,不是放行。 */
1517
- type PermissionAction = 'allow' | 'ask' | 'deny';
1518
- /** 一次 Shell 执行的精确目标;字段组合构成审批与缓存命中的身份,任何维度都不允许通配。 */
1519
- interface ShellScope {
1520
- command: string;
1521
- interpreter: string;
1522
- executablePath?: string;
1523
- cwd: string;
1524
- /** 解释器身份摘要(路径、大小、mtime 推导);解释器被替换后规则与缓存即失配。 */
1525
- executableDigest?: string;
1526
- /** 命令直接引用的工作目录内脚本的内容摘要;仅单脚本命令可计算,组合命令缺省。 */
1527
- scriptDigest?: string;
1528
- /** 执行前复核用指纹;审批后重新推导不一致时按目标漂移拒绝执行。 */
1529
- executionFingerprint?: string;
1530
- }
1531
- /** 宿主提供的显式规则;tool / capability / shell 三种范围必须恰好声明一个。 */
1532
- interface PermissionRule {
1533
- action: PermissionAction;
1534
- tool?: string;
1535
- capability?: Capability;
1536
- shell?: ShellScope;
1537
- }
1538
- /** 权限裁决的全部输入;硬限制与缓存命中由宿主查询后以标志位传入,策略本身不持有状态。 */
1539
- interface PermissionRequest {
1540
- mode: SessionMode;
1541
- toolName: string;
1542
- capabilities: readonly Capability[];
1543
- /** 危险性来自工具元数据;未命中 allow 规则时,非 FullAccess 模式一律降级为 ask。 */
1544
- dangerous?: boolean;
1545
- /** 宿主硬限制;命中即拒绝,优先级高于一切规则与缓存。 */
1546
- hardDenied?: boolean;
1547
- shell?: ShellScope;
1548
- /** 规则表须先经 validatePermissionRules 校验;同动作规则按声明顺序取首个命中。 */
1549
- rules?: readonly PermissionRule[];
1550
- /** 会话缓存命中标志(来自 SessionApprovalCache);仅在 deny / ask 规则都未命中时生效。 */
1551
- cachedApproval?: boolean;
1552
- /** 会话缓存拒绝标志;在 deny 规则之后、ask 规则之前生效。 */
1553
- cachedDenial?: boolean;
1554
- }
1555
- /** 裁决结果及其来源;source 供审计区分硬限制、Plan、规则、缓存与模式默认。 */
1556
- interface PermissionDecision {
1557
- decision: PermissionAction;
1558
- source: 'hard_limit' | 'plan' | 'explicit_rule' | 'session_cache' | 'mode_default';
1559
- /** 命中规则在 rules 中的下标;仅 source 为 explicit_rule 时存在。 */
1560
- ruleIndex?: number;
1561
- }
1562
- /** 拒绝含糊的 Shell 前缀/通配符和结构不完整的规则。 */
1563
- declare function validatePermissionRules(rules: readonly PermissionRule[]): void;
1564
- /** 纯策略裁决;宿主硬限制和 Plan 始终先于任何规则或会话缓存。 */
1565
- declare class PermissionPolicy {
1566
- /**
1567
- * 裁决顺序固定:硬限制 → Plan 收窄 → deny 规则 → 会话缓存拒绝 → ask 规则 →
1568
- * 会话缓存允许 → allow 规则(run_command 必须带 shell 范围,工具级 allow 不能放行命令)
1569
- * → 模式默认。同一输入总是得到同一裁决,不读取任何外部状态。
1570
- */
1571
- decide(request: PermissionRequest): PermissionDecision;
1572
- }
1573
- /** 只向模型展示当前模式与整项拒绝规则允许请求的工具。 */
1574
- declare function visibleTools(tools: readonly Tool[], mode: SessionMode, rules?: readonly PermissionRule[]): Tool[];
1575
-
1576
- /** 执行能力的最小分类;权限规则、模式裁决与工具元数据声明共用这一词汇表。 */
1577
- type Capability = 'fs:read' | 'fs:write' | 'exec' | 'net:outbound' | 'env:read' | 'agent:spawn' | 'external:call';
1578
- /**
1579
- * 外部调用的精确执行身份;供审批缓存、发送前复核与审计消费。
1580
- * 包含服务端物理身份、连接代次、目录 epoch 与定义摘要等不可伪造字段。
1581
- */
1582
- interface ToolExecutionIdentity {
1583
- serverIdentity?: string;
1584
- connectionGeneration?: number;
1585
- catalogEpoch?: number;
1586
- toolDigest?: string;
1587
- [key: string]: unknown;
1588
- }
1589
- /**
1590
- * 显式 opt-in 规范化执行结果;普通对象返回值保持兼容不强制包装。
1591
- */
1592
- interface ToolExecutionResult {
1593
- content: string;
1594
- isError?: boolean;
1595
- errorCode?: string;
1596
- retryPolicy?: 'never' | 'after_user_action';
1597
- execution?: ToolResultExecution;
1598
- }
1599
- interface ToolMetadata {
1600
- /** 注册来源标记(如 'builtin');注册表据此执行冲突策略并支持按源注销。 */
1601
- source?: string;
1602
- /** 标记危险工具;未命中 allow 规则时,非 FullAccess 模式一律降级为 ask 而非按模式默认放行。 */
1603
- dangerous?: boolean;
1604
- /** 所需能力的声明;v0.0.1 不据此授权,v0.0.2 的执行前权限决策才会消费。 */
1605
- permissions?: Capability[];
1606
- /** 工具自身等待进程资源回收,执行器不可再使用通用 Promise.race 超时。 */
1607
- managesTimeout?: boolean;
1608
- /** 只读提示;工具声明自身无副作用,供 UI 展示与只读过滤参考。 */
1609
- readOnlyHint?: boolean;
1610
- }
1611
- /** 工具执行期由宿主注入的运行环境;信号取消后工具应尽快清理在途资源再返回。 */
1612
- interface ToolContext {
1613
- /** 本次执行的沙箱根目录;文件类工具以此为界解析相对路径并拒绝越界。 */
1614
- rootDir: string;
1615
- signal?: AbortSignal;
1616
- logger?: (message: string) => void;
1617
- /** 命令工具在真实进程创建后调用;审计失败时须先回收进程再报告结果未知。 */
1618
- onProcessSpawned?: () => Promise<void>;
1619
- onProgress?: (progress: {
1620
- elapsedMs: number;
1621
- outputBytes: number;
1622
- }) => void;
2416
+ estimatedTokens: number;
1623
2417
  }
1624
- /**
1625
- * 工具输入参数校验结果;valid 为 false 或抛出异常均阻止审批和发送。
1626
- */
1627
- interface ToolInputValidation {
1628
- valid: boolean;
1629
- message?: string;
2418
+ /** 生成确定性 L2.5;预算含标题、XML、转义及遗漏提示,只删完整条目。 */
2419
+ declare function formatSkillCatalog(skills: readonly SkillMetadata[], contextWindow?: number, remainingTokens?: number): SkillCatalog;
2420
+ /** 模型目录分页输入;游标只定位快照,不提供信任或正文访问授权。 */
2421
+ interface SkillQuery {
2422
+ query?: string;
2423
+ cursor?: string;
2424
+ limit?: number;
1630
2425
  }
1631
- /** 工具契约;parameters 是 JSON Schema,模型只能看到经 toToolDefinition 投影后的三个字段。 */
1632
- interface Tool<TInput = Record<string, unknown>, TOutput = unknown> {
1633
- readonly name: string;
1634
- readonly description: string;
1635
- readonly parameters: Record<string, unknown>;
1636
- readonly metadata?: ToolMetadata;
1637
- /** 声明本次输入的精确执行目标,供审批展示与执行前指纹复核;无固定执行目标的工具不实现。 */
1638
- approvalScope?(input: TInput, rootDir: string): ShellScope;
1639
- /** 本次执行身份;审批缓存与执行前复核消费,缺省保持旧工具规则。 */
1640
- executionIdentity?(input: TInput, rootDir: string): ToolExecutionIdentity;
1641
- /** 无副作用地校验最终参数,不修改参数、不访问远端;异常与拒绝均阻止审批和发送。 */
1642
- validateInput?(input: TInput): ToolInputValidation | undefined;
1643
- /** 显式 opt-in 转换为标准执行结果;未提供时普通返回值继续作为常规输出。 */
1644
- toExecutionResult?(raw: TOutput): ToolExecutionResult;
1645
- execute(input: TInput, ctx: ToolContext): Promise<TOutput>;
2426
+ /** 有界模型元数据页;不包含正文,游标按实际返回条目推进。 */
2427
+ interface SkillQueryPage {
2428
+ skills: {
2429
+ name: string;
2430
+ description: string;
2431
+ scope: string;
2432
+ argumentHint?: string;
2433
+ }[];
2434
+ total: number;
2435
+ nextCursor?: string;
2436
+ }
2437
+
2438
+ /** 确定性技能注册表;刷新原子替换快照,运行中加载必须与发现指纹一致。 */
2439
+ declare class SkillRegistry {
2440
+ private readonly options;
2441
+ private definitions;
2442
+ private warnings;
2443
+ private revisionValue;
2444
+ /** 固定宿主配置副本,外部对象变更不能静默改变本轮发现或信任。 */
2445
+ constructor(options: SkillOptions);
2446
+ /** 获取独立诊断副本,调用方不能修改生效候选或权限。 */
2447
+ get diagnostics(): SkillDiagnostic[];
2448
+ /** 快照游标身份随正文、来源、可用性变化而失效。 */
2449
+ get revision(): string;
2450
+ /** 是否由宿主启用;关闭只影响本次能力,不删除历史或文件。 */
2451
+ get enabled(): boolean;
2452
+ /** 每轮开始重新发现;取消不发布半个快照,非法单文件只产生诊断。 */
2453
+ refresh(signal?: AbortSignal): Promise<void>;
2454
+ /** 按名称查询胜出元数据副本;未知名称返回 undefined,正文仅由 load 校验后懒读取。 */
2455
+ get(name: string): SkillMetadata | undefined;
2456
+ /** 宿主可检查不可用条目;模型/用户视图分别施加调用控制,均不读取正文。 */
2457
+ list(caller?: 'host' | 'model' | 'user', query?: string): SkillMetadata[];
2458
+ /** 按当前快照校验调用控制与物理身份,不接受模型提供的信任或 caller 升级。 */
2459
+ load(name: string, caller: 'model' | 'user', signal?: AbortSignal): Promise<SkillDefinition>;
2460
+ /** 查询可信模型集合;过期游标可修正,预算不足不返回不前进的分页。 */
2461
+ queryModel(input?: SkillQuery, remainingTokens?: number): SkillQueryPage;
2462
+ /** 复核配置根、词法发现路径和原文件字节,返回本次有界读取文本;漂移要求新运行,不能热替换。 */
2463
+ verify(skill: SkillMetadata, signal?: AbortSignal): Promise<string>;
1646
2464
  }
1647
- /** 恒等构造器:只为工具实现提供类型推断与统一书写形式,不产生任何运行时包装。 */
1648
- declare function defineTool<TInput = Record<string, unknown>, TOutput = unknown>(tool: Tool<TInput, TOutput>): Tool<TInput, TOutput>;
1649
- /** 投影为模型可见的工具描述;刻意丢弃 metadata 与 approvalScope,执行侧信息不进入协议。 */
1650
- declare function toToolDefinition(tool: Tool): ToolDefinition;
1651
2465
 
1652
2466
  /** 归一化技能白名单;参数模式/未知名称不得退化成宽泛命令授权。 */
1653
2467
  declare function normalizeSkillTools(skill: SkillDefinition, tools: readonly Tool[]): ReadonlySet<string> | undefined;
@@ -1856,6 +2670,14 @@ interface ExecutorOptions {
1856
2670
  onToolResult?: (tool: Tool, input: Record<string, unknown>, result: ToolResultBlock) => void | Promise<void>;
1857
2671
  tools: ToolRegistry | ToolRegistrySnapshot;
1858
2672
  hooks: HookRegistry;
2673
+ /** 显式工作区物理根路径,经 native realpath 规范化;缺省回退到 rootDir。 */
2674
+ workspaceRoot?: string;
2675
+ /** 显式命令执行工作目录绝对路径(位于 workspaceRoot 内部);缺省回退到 rootDir。 */
2676
+ executionCwd?: string;
2677
+ /** 会话持有的 PathSandbox 独占实例;文件类工具优先使用此沙箱。 */
2678
+ sandbox?: PathSandbox;
2679
+ /** 共享工作区写租约协调器;并发写入互斥保护。 */
2680
+ leaseCoordinator?: WorkspaceLeaseCoordinator;
1859
2681
  /** 工具执行的绝对根目录;路径解析与审批均以此为基准。 */
1860
2682
  rootDir: string;
1861
2683
  /** 会话级取消信号;与 cancel() 的内部信号合并生效。 */
@@ -1866,6 +2688,10 @@ interface ExecutorOptions {
1866
2688
  eventLogger?: EventLogger;
1867
2689
  sessionId?: string;
1868
2690
  runId?: string;
2691
+ branchId?: string;
2692
+ rootTaskId?: string;
2693
+ depth?: number;
2694
+ agentId?: string;
1869
2695
  /** 固定模式或每次裁决时读取的取值函数;宿主可中途切换。 */
1870
2696
  mode?: SessionMode | (() => SessionMode);
1871
2697
  permissionRules?: readonly PermissionRule[];
@@ -1884,6 +2710,10 @@ declare class ToolExecutor {
1884
2710
  private readonly onToolResult?;
1885
2711
  private readonly tools;
1886
2712
  private readonly hooks;
2713
+ private readonly workspaceRoot;
2714
+ private readonly executionCwd;
2715
+ private readonly sandbox?;
2716
+ private readonly leaseCoordinator?;
1887
2717
  private readonly rootDir;
1888
2718
  private readonly signal?;
1889
2719
  private readonly logger?;
@@ -1891,6 +2721,12 @@ declare class ToolExecutor {
1891
2721
  private readonly eventLogger?;
1892
2722
  private readonly sessionId?;
1893
2723
  private readonly runId?;
2724
+ private readonly branchId?;
2725
+ private readonly rootTaskId?;
2726
+ private readonly depth?;
2727
+ private readonly agentId?;
2728
+ private readonly committedActions;
2729
+ private readonly rollbackActions;
1894
2730
  private readonly mode;
1895
2731
  private readonly permissionRules;
1896
2732
  private readonly approvalChannel?;
@@ -1899,6 +2735,15 @@ declare class ToolExecutor {
1899
2735
  private readonly neverFailures;
1900
2736
  private readonly cancellation;
1901
2737
  constructor(options: ExecutorOptions);
2738
+ /**
2739
+ * 父工具事务提交成功后调用,按注册顺序执行所有提交动作。
2740
+ * 动作执行成功后逐项清理对应回滚动作,若某项失败保留剩余回滚动作。
2741
+ */
2742
+ commit(): Promise<void>;
2743
+ /**
2744
+ * 父工具事务提交失败或取消时调用,按逆序执行所有回滚清理动作。
2745
+ */
2746
+ rollback(): Promise<void>;
1902
2747
  /** 中止本轮正在等待或执行的工具;调用方仍须等待 runAll 完成资源回收及结果审计。 */
1903
2748
  cancel(): void;
1904
2749
  /**
@@ -1930,6 +2775,10 @@ declare class ToolExecutor {
1930
2775
  * 因此内置工具仍需避免执行用户可控的同步高复杂度计算。
1931
2776
  */
1932
2777
  private withTimeout;
2778
+ /**
2779
+ * 构建当前会话在派生时刻的父权限策略快照。
2780
+ */
2781
+ private deriveParentPolicySnapshot;
1933
2782
  }
1934
2783
 
1935
2784
  /** 加载预检结果;只有最终成功工具结果或真实用户消息提交后才形成活动资格。 */
@@ -2062,48 +2911,6 @@ declare function cleanupCommandResults(rootDir: string, now?: number): void;
2062
2911
  /** 使用固定解释器执行命令;超时和中止必须先处理进程树再返回。 */
2063
2912
  declare function createRunCommandTool(environment: ShellEnvironment): Tool<RunCommandInput, CommandResult>;
2064
2913
 
2065
- /** 路径沙箱配置;rootDir 是所有文件访问的词法与物理边界。 */
2066
- interface SandboxConfig {
2067
- rootDir: string;
2068
- /**
2069
- * v0.0.1 恒为严格模式:任何解析后落在 rootDir 之外的物理路径一律拒绝,
2070
- * 不存在 fail-open 开关。该字段为 v0.0.2 权限引擎预留,当前不改变校验行为。
2071
- */
2072
- allowSymlinks?: boolean;
2073
- }
2074
- /**
2075
- * 把文件访问限制在 rootDir 内:先做词法归一化检查,再展开符号链接做物理检查,两层都通过才放行。
2076
- * 实例会缓存 rootDir 的物理路径,应按 rootDir 复用实例,而不是每次调用新建。
2077
- */
2078
- declare class PathSandbox {
2079
- readonly rootDir: string;
2080
- readonly allowSymlinks: boolean;
2081
- private cachedRealRootDir?;
2082
- constructor(config: SandboxConfig);
2083
- /**
2084
- * rootDir 的物理路径。rootDir 自身可能是一个符号链接(如 macOS 的 /var → /private/var),
2085
- * 必须先归一化,否则物理路径与 rootDir 比较时会产生误判。
2086
- */
2087
- private get realRootDir();
2088
- /**
2089
- * 检查并解析安全路径
2090
- * 1. 解析相对路径为相对于 rootDir 的绝对路径
2091
- * 2. 词法检查:`..` 归一化后必须仍在 rootDir 内
2092
- * 3. 物理检查:解析符号链接后的真实路径必须仍在 rootDir 内
2093
- */
2094
- resolveSafePath(targetPath: string): string;
2095
- /**
2096
- * 把词法路径映射为物理路径。
2097
- *
2098
- * 关键点在于**向上回溯到最近一个真实存在的祖先**再取 realpath,然后把尚未存在的尾段拼回去:
2099
- * - 目标已存在 → 直接 realpath,符号链接立刻被展开;
2100
- * - 目标不存在(典型场景:write_file 新建文件) → 若只看目标本身,所有校验都会被跳过,
2101
- * 于是 `write_file('linkDir/new.txt')` 可以借道指向外部的 linkDir 越界写入。
2102
- * 回溯到 linkDir 取 realpath 即可识破这种穿透。
2103
- */
2104
- private toPhysicalPath;
2105
- }
2106
-
2107
2914
  declare const readFileTool: Tool<{
2108
2915
  path: string;
2109
2916
  startLine?: number;
@@ -2452,6 +3259,532 @@ declare class AgentLoop {
2452
3259
  run(history: CanonicalMessage[]): AsyncIterable<SessionEvent>;
2453
3260
  }
2454
3261
 
3262
+ /**
3263
+ * @fileoverview 后台子代理任务状态机、来源元数据与限额类型定义。
3264
+ *
3265
+ * 约束、边界与为什么:
3266
+ * 1. 状态机严格单向/受控回环:
3267
+ * preparing → accepted → running → waiting_children → completed / failed / cancelled / interrupted。
3268
+ * 有未结束后代时,自身主轮结束必须进入 waiting_children,等待后代收口后返回 running 完成终结。
3269
+ * 2. 来源链不可伪造(Origin Invariant):
3270
+ * 每项任务持有稳定的 rootTaskId、parentAgentId、parentSessionId、originBranchId、originRunId
3271
+ * 与 spawnToolCallId,用作跨轮次对账、收件箱投递与去重键。
3272
+ * 3. 严格容量控制:
3273
+ * 每树活动上限 4,整运行时活动上限 8,每树累计上限 16,超额立即拒绝不排队,防止死锁。
3274
+ */
3275
+
3276
+ /**
3277
+ * 子代理任务生命周期状态。
3278
+ */
3279
+ type AgentTaskStatus = 'preparing' | 'accepted' | 'running' | 'waiting_children' | 'cancelling' | 'completed' | 'failed' | 'cancelled' | 'interrupted';
3280
+ /**
3281
+ * 判断指定状态是否属于活跃占用槽位状态(preparing / accepted / running / waiting_children / cancelling)。
3282
+ */
3283
+ declare function isActiveTaskStatus(status: AgentTaskStatus): boolean;
3284
+ /**
3285
+ * 判断指定状态是否为终态(completed / failed / cancelled / interrupted)。
3286
+ */
3287
+ declare function isTerminalTaskStatus(status: AgentTaskStatus): boolean;
3288
+ /**
3289
+ * 描述子代理任务的来源与继承上下文。
3290
+ */
3291
+ interface AgentTaskOrigin {
3292
+ /** 根任务标识(同一次根用户指令启动的所有子孙任务共享)。 */
3293
+ readonly rootTaskId: string;
3294
+ /** 父代理 ID(根任务派生的一级子代理其 parentAgentId 为 undefined)。 */
3295
+ readonly parentAgentId?: string;
3296
+ /** 父会话会话 ID。 */
3297
+ readonly parentSessionId: string;
3298
+ /** 派生来源分支 ID。 */
3299
+ readonly originBranchId: string;
3300
+ /** 派生来源运行轮次 ID。 */
3301
+ readonly originRunId: string;
3302
+ /** 触发派生的工具调用 ID。 */
3303
+ readonly spawnToolCallId: string;
3304
+ /** 派生代次(从 1 开始)。 */
3305
+ readonly generation: number;
3306
+ /** 任务树深度(根会话为 0,一级子代理为 1,最大支持深度通常为 3)。 */
3307
+ readonly depth: number;
3308
+ }
3309
+ /** 每棵任务树允许的最大并发活动子任务数。 */
3310
+ declare const MAX_ACTIVE_TASKS_PER_TREE = 4;
3311
+ /** 整个 AgentRuntime 允许的最大并发活动子任务数。 */
3312
+ declare const MAX_ACTIVE_TASKS_PER_RUNTIME = 8;
3313
+ /** 每棵任务树累计受理的最大任务数(失败/取消不返还额度)。 */
3314
+ declare const MAX_TOTAL_TASKS_PER_TREE = 16;
3315
+ /** 默认最大步骤数。 */
3316
+ declare const DEFAULT_MAX_STEPS = 15;
3317
+ /** 默认墙钟超时毫秒数(5 分钟)。 */
3318
+ declare const DEFAULT_TIMEOUT_MS: number;
3319
+ /** 子代理限额配置。 */
3320
+ interface AgentTaskLimits {
3321
+ /** 最大模型交互步骤数(默认 15)。 */
3322
+ maxSteps?: number;
3323
+ /** 墙钟最大超时毫秒数(默认 5 分钟 = 300,000ms)。 */
3324
+ timeoutMs?: number;
3325
+ }
3326
+ /** 创建子代理输入参数。 */
3327
+ interface SpawnAgentParams {
3328
+ [key: string]: unknown;
3329
+ /** 任务简要描述。 */
3330
+ description: string;
3331
+ /** 任务提示词与具体指令。 */
3332
+ prompt: string;
3333
+ /** 业务角色预设。 */
3334
+ role: SubagentRole;
3335
+ /** 显式限制的工具名称白名单(进一步收紧)。 */
3336
+ allowedTools?: string[];
3337
+ /** 子任务执行目录(必须在工作区根以内)。 */
3338
+ cwd?: string;
3339
+ /** 物理隔离模式。 */
3340
+ isolation?: 'inherit' | 'worktree';
3341
+ /** 模型覆盖参数。 */
3342
+ modelOverride?: string;
3343
+ /** 限额配置。 */
3344
+ limits?: AgentTaskLimits;
3345
+ }
3346
+ /** spawn_agent 启动回执。 */
3347
+ interface SpawnAgentReceipt {
3348
+ /** 生成的子代理唯一标识。 */
3349
+ agentId: string;
3350
+ /** 受理状态(固定为 'accepted')。 */
3351
+ status: 'accepted';
3352
+ /** 角色预设。 */
3353
+ role: SubagentRole;
3354
+ /** 任务简要描述。 */
3355
+ description: string;
3356
+ /** 任务树深度。 */
3357
+ depth: number;
3358
+ /** 归属的根任务标识。 */
3359
+ rootTaskId: string;
3360
+ /** 解析出的模型场景角色。 */
3361
+ modelRole: PrimaryModelRole | 'inherit';
3362
+ /** 实际工作区根。 */
3363
+ workspaceRoot: string;
3364
+ /** 实际执行目录。 */
3365
+ executionCwd: string;
3366
+ }
3367
+ /**
3368
+ * 运行时内存中的子代理任务完整记录。
3369
+ */
3370
+ interface AgentTaskRecord {
3371
+ /** 子代理唯一标识。 */
3372
+ readonly agentId: string;
3373
+ /** 来源上下文。 */
3374
+ readonly origin: AgentTaskOrigin;
3375
+ /** 预设角色。 */
3376
+ readonly role: SubagentRole;
3377
+ /** 任务描述。 */
3378
+ readonly description: string;
3379
+ /** 任务 Prompt。 */
3380
+ readonly prompt: string;
3381
+ /** 当前生命周期状态。 */
3382
+ status: AgentTaskStatus;
3383
+ /** 创建时间。 */
3384
+ readonly createdAt: number;
3385
+ /** 开始运行时间。 */
3386
+ startedAt?: number;
3387
+ /** 终结时间。 */
3388
+ finishedAt?: number;
3389
+ /** 派生的直接子代理 ID 集合。 */
3390
+ readonly childAgentIds: Set<string>;
3391
+ /** 任务结果摘要。 */
3392
+ summary?: string;
3393
+ /** 失败或取消原因。 */
3394
+ error?: string;
3395
+ /** 实际使用的模型标识。 */
3396
+ modelId?: string;
3397
+ /** 工作区物理根路径。 */
3398
+ readonly workspaceRoot: string;
3399
+ /** 执行物理目录。 */
3400
+ readonly executionCwd: string;
3401
+ /** 剩余/分配的限额。 */
3402
+ readonly limits: Readonly<Required<AgentTaskLimits>>;
3403
+ /** 显式限制的工具名称白名单。 */
3404
+ allowedTools?: readonly string[];
3405
+ /** 物理隔离模式。 */
3406
+ isolation?: 'inherit' | 'worktree';
3407
+ /** 模型覆盖参数。 */
3408
+ modelOverride?: string;
3409
+ /** 派生并锁定的不可扩大策略快照。 */
3410
+ effectivePolicy?: unknown;
3411
+ /** 活动槽位是否已被安全释放(防止 cancelTask 与 runTask.finally 重复释放导致容量失真)。 */
3412
+ slotReleased?: boolean;
3413
+ }
3414
+ /** 查询子代理过滤选项。 */
3415
+ interface ListAgentsFilter {
3416
+ /** 限定根任务标识。 */
3417
+ rootTaskId?: string;
3418
+ /** 限定父代理 ID。 */
3419
+ parentAgentId?: string;
3420
+ /** 限定父会话 ID。 */
3421
+ parentSessionId?: string;
3422
+ /** 限定状态。 */
3423
+ status?: AgentTaskStatus | 'active' | 'terminal';
3424
+ }
3425
+
3426
+ /**
3427
+ * @fileoverview 可靠通知投递发件箱(SubagentOutbox)与收件箱(SessionInbox)。
3428
+ *
3429
+ * 约束、边界与为什么:
3430
+ * 1. 至少一次投递与幂等去重(At-least-once & Idempotent Delivery):
3431
+ * 通知持有基于 agentId + generation + terminalRevision 生成的全局确定性 eventId。
3432
+ * 父收件箱严格根据 eventId 去重,即使崩溃重投也绝不重复向父会话注入重复消息。
3433
+ * 2. 消息身份与权限降级:
3434
+ * 消费时通知作为带 subagent 来源的普通背景消息(协议投影为 user)持久化入父历史,
3435
+ * 绝对不能以 system 权限注入,且模型伪造文本不获得特权。
3436
+ * 3. 绝不追加第二个启动工具结果:
3437
+ * spawn_agent 的 tool_result 在受理时已即刻闭合;通知作为独立的背景消息追加,
3438
+ * 严禁伪造或追加第二个 tool_result 污染 canonical 工具事务。
3439
+ */
3440
+
3441
+ /**
3442
+ * 收件箱与协调器所依赖的持久化消息下沉抽象契约。
3443
+ */
3444
+ interface SessionMessageSink {
3445
+ /** 获取当前活动分支标识。 */
3446
+ getActiveBranchId(): string;
3447
+ /** 追加一条持久化消息至指定分支。 */
3448
+ append(message: CanonicalMessage, options?: {
3449
+ branchId?: string;
3450
+ }): Promise<unknown>;
3451
+ /** 读取现有持久化记录列表(用于启动幂等对账)。 */
3452
+ readRecords?(): Promise<ReadonlyArray<{
3453
+ type: string;
3454
+ payload: Record<string, unknown>;
3455
+ }>>;
3456
+ }
3457
+ /**
3458
+ * 子代理终态通知数据结构。
3459
+ */
3460
+ interface AgentNotification {
3461
+ /** 投递事件全局唯一幂等标识。 */
3462
+ readonly eventId: string;
3463
+ /** 任务标识。 */
3464
+ readonly agentId: string;
3465
+ /** 根任务标识。 */
3466
+ readonly rootTaskId: string;
3467
+ /** 目标父会话 ID。 */
3468
+ readonly parentSessionId: string;
3469
+ /** 派生来源分支 ID。 */
3470
+ readonly originBranchId: string;
3471
+ /** 派生来源运行轮次 ID。 */
3472
+ readonly originRunId: string;
3473
+ /** 触发派生的工具调用 ID。 */
3474
+ readonly spawnToolCallId: string;
3475
+ /** 派生代次。 */
3476
+ readonly generation: number;
3477
+ /** 角色预设。 */
3478
+ readonly role: SubagentRole;
3479
+ /** 任务描述。 */
3480
+ readonly description: string;
3481
+ /** 终态状态。 */
3482
+ readonly status: AgentTaskStatus;
3483
+ /** 终态结果摘要。 */
3484
+ readonly summary?: string;
3485
+ /** 错误信息。 */
3486
+ readonly error?: string;
3487
+ /** 产物列表。 */
3488
+ readonly artifacts?: string[];
3489
+ /** 产生时间戳。 */
3490
+ readonly timestamp: number;
3491
+ }
3492
+ /**
3493
+ * 格式化子代理通知内容为协议背景消息文本。
3494
+ */
3495
+ declare function formatNotificationContent(notification: AgentNotification): string;
3496
+ /**
3497
+ * 子代理发件箱配置选项。
3498
+ */
3499
+ interface SubagentOutboxOptions {
3500
+ /** 可选持久化 JSONL 日志路径;配置后自动落盘并在重启时恢复未确认通知。 */
3501
+ storagePath?: string;
3502
+ }
3503
+ /**
3504
+ * 子代理端可靠发件箱(SubagentOutbox)。
3505
+ */
3506
+ declare class SubagentOutbox {
3507
+ private readonly notifications;
3508
+ private readonly acknowledgedEventIds;
3509
+ private readonly storagePath?;
3510
+ constructor(options?: SubagentOutboxOptions);
3511
+ /**
3512
+ * 从已完成的子代理记录生成并登记终态通知。
3513
+ */
3514
+ enqueueFromTask(task: AgentTaskRecord, terminalRevision?: string): AgentNotification;
3515
+ /**
3516
+ * 获取所有未被确认的待投递通知。
3517
+ */
3518
+ getPendingNotifications(): AgentNotification[];
3519
+ /**
3520
+ * 确认指定通知投递已在父会话中落盘(ACK)。
3521
+ */
3522
+ acknowledge(eventId: string): void;
3523
+ /**
3524
+ * 查询指定通知是否已被确认。
3525
+ */
3526
+ isAcknowledged(eventId: string): boolean;
3527
+ }
3528
+ /**
3529
+ * 父会话收件箱(SessionInbox),负责去重与作为背景消息持久化入父历史。
3530
+ */
3531
+ declare class SessionInbox {
3532
+ private static readonly globalInFlightConsumes;
3533
+ private readonly store;
3534
+ private readonly consumedEventIds;
3535
+ constructor(store: SessionMessageSink);
3536
+ /**
3537
+ * 消费并持久化一条子代理通知。
3538
+ *
3539
+ * 保证:
3540
+ * - 幂等去重:已消费过的 eventId 直接返回成功,绝不重复追加消息;
3541
+ * - 并发合并:相同 eventId 的并发消费请求复用在途 Promise,消除竞态窗口;
3542
+ * - 检查父历史现有消息,避免跨进程/重启后重复消费;
3543
+ * - 构造协议兼容的背景消息(role: 'user',带 subagentSource 标记),通过 store.append 保存;
3544
+ * - 严格保持在来源分支上落盘;
3545
+ * - 绝不追加第二个启动结果。
3546
+ *
3547
+ * @param notification 待投递的通知对象
3548
+ * @returns 是否为新写入的消息(false 表示幂等跳过)
3549
+ */
3550
+ consume(notification: AgentNotification): Promise<boolean>;
3551
+ /**
3552
+ * 判断指定 eventId 是否已在收件箱中被消费。
3553
+ */
3554
+ hasConsumed(eventId: string): boolean;
3555
+ }
3556
+
3557
+ /**
3558
+ * @fileoverview 后台子代理任务树运行时调度器(AgentRuntime)。
3559
+ *
3560
+ * 约束、边界与为什么:
3561
+ * 1. 状态机严格管理与等待收口:
3562
+ * preparing → accepted → running → waiting_children → completed / failed / cancelled / interrupted。
3563
+ * 子代理主轮次执行结束若有活跃后代,必须进入 waiting_children 占槽等待收口,不得提前发最终完成通知。
3564
+ * 2. 启动事务即刻闭合(Launch Transaction Invariant):
3565
+ * spawn_agent 在准备阶段完成参数/权限/容量校验并登记意图后,立即向父返回 accepted 回执,
3566
+ * 父工具事务即刻闭合,父代理继续推进后续步骤;父事务提交确认后异步激活启动子会话。
3567
+ * 3. 严格容量控制与死锁防护:
3568
+ * 每树活动槽 4,运行时活动槽 8,每树累计受理 16,超额立即抛出 AGENT_CAPACITY_EXCEEDED,
3569
+ * 严禁持槽等待或隐式启动队列,防止祖先等待子级、子级等待槽位产生死锁。
3570
+ * 4. 级联取消与后代收口:
3571
+ * 任务失败或取消时无条件级联取消所有后代任务,并等待后代清理完成后才释放自身槽位与写入终态。
3572
+ */
3573
+
3574
+ /** 子代理会话执行器类型;生产环境调用真实的 AgentSession,测试环境可注入 Mock。 */
3575
+ type SubagentSessionRunner = (record: AgentTaskRecord, signal: AbortSignal) => Promise<{
3576
+ summary: string;
3577
+ modelId?: string;
3578
+ }>;
3579
+ /** 启动子代理时的调用方上下文。 */
3580
+ interface SpawnContext {
3581
+ /** 根任务标识;若为根会话直接派生,可缺省由 Runtime 自动初始化。 */
3582
+ rootTaskId?: string;
3583
+ /** 父会话会话 ID。 */
3584
+ sessionId: string;
3585
+ /** 派生来源分支 ID。 */
3586
+ branchId: string;
3587
+ /** 派生来源运行轮次 ID。 */
3588
+ runId: string;
3589
+ /** 触发派生的工具调用 ID。 */
3590
+ toolCallId: string;
3591
+ /** 当前父任务深度;根会话为 0。 */
3592
+ depth: number;
3593
+ /** 父代理 ID;根会话时为 undefined。 */
3594
+ agentId?: string;
3595
+ /** 当前派生代次。 */
3596
+ generation?: number;
3597
+ /** 父工作区根。 */
3598
+ workspaceRoot: string;
3599
+ /** 父执行目录。 */
3600
+ executionCwd: string;
3601
+ /** 父权限策略快照。 */
3602
+ parentPolicy?: ParentPolicySnapshot;
3603
+ }
3604
+ /**
3605
+ * AgentRuntime 初始化选项。
3606
+ */
3607
+ interface AgentRuntimeOptions {
3608
+ runner?: SubagentSessionRunner;
3609
+ validateModelOverride?: (modelId: string) => boolean;
3610
+ outboxPath?: string;
3611
+ }
3612
+ /**
3613
+ * 后台子代理任务树调度与状态机协调器。
3614
+ */
3615
+ declare class AgentRuntime {
3616
+ private readonly tasks;
3617
+ private readonly controllers;
3618
+ private readonly timers;
3619
+ private readonly stateListeners;
3620
+ /** 宿主观察订阅独立于调度等待;关闭宿主订阅不能影响任务收口。 */
3621
+ private readonly taskChangeListeners;
3622
+ private taskChangeNotificationPending;
3623
+ private readonly outbox;
3624
+ private readonly runningPromises;
3625
+ private runner;
3626
+ private readonly validateModelOverride?;
3627
+ private isClosed;
3628
+ private totalActiveCount;
3629
+ private readonly treeActiveCounts;
3630
+ private readonly treeTotalCounts;
3631
+ constructor(options?: AgentRuntimeOptions);
3632
+ /**
3633
+ * 获取发件箱实例,供通知查询与 ACK 对账。
3634
+ */
3635
+ getOutbox(): SubagentOutbox;
3636
+ /**
3637
+ * 注入或替换子代理执行器。
3638
+ */
3639
+ setRunner(runner: SubagentSessionRunner): void;
3640
+ /**
3641
+ * 获取指定子代理记录快照。
3642
+ */
3643
+ getTask(agentId: string): AgentTaskRecord | undefined;
3644
+ /**
3645
+ * 订阅任务创建与状态变化;通知只表示快照可能已更新,不提供可变任务对象。
3646
+ * 同一轮微任务内的变化可合并,不保证逐个中间状态;订阅时不主动发送通知,
3647
+ * 宿主应先订阅,再通过 listTasks 按会话和根任务读取独立复制的快照。
3648
+ * 监听器的同步异常与异步拒绝均隔离,不等待监听器,也不触发结果投递或父模型请求。
3649
+ *
3650
+ * @param listener 无参数变化监听器;应只读取展示状态,异步监听器可自行重叠执行。
3651
+ * @returns 幂等取消函数;同一监听器的多次订阅独立取消,运行时关闭时全部释放。
3652
+ * 已关闭的运行时不保留新订阅,返回的取消函数可安全调用。
3653
+ */
3654
+ subscribeTaskChanges(listener: () => void | Promise<void>): () => void;
3655
+ /**
3656
+ * 判断目标任务是否为指定祖先任务的后代(直接或间接子任务)。
3657
+ */
3658
+ isDescendantOf(targetId: string, ancestorId: string): boolean;
3659
+ /**
3660
+ * 准备并受理子代理启动请求(spawn_agent 执行第一阶段)。
3661
+ *
3662
+ * 保证:
3663
+ * - 严格校验参数必填项与预设角色;
3664
+ * - 深度超限立即拒绝(SUBAGENT_DEPTH_EXCEEDED);
3665
+ * - 容量超限立即拒绝(AGENT_CAPACITY_EXCEEDED);
3666
+ * - 工作区路径越界立即拒绝(SUBAGENT_WORKSPACE_VIOLATION);
3667
+ * - 生成 agentId 并原子预留活动槽与累计槽;
3668
+ * - 登记为 preparing 状态并返回 accepted 回执,使父工具事务能立刻闭合。
3669
+ */
3670
+ prepareSpawn(context: SpawnContext, params: SpawnAgentParams): Promise<SpawnAgentReceipt>;
3671
+ /**
3672
+ * 激活并启动已受理的子代理任务(父事务提交确认后触发)。
3673
+ *
3674
+ * 状态跃迁:preparing → accepted → running。
3675
+ */
3676
+ activateSpawn(agentId: string): Promise<void>;
3677
+ /**
3678
+ * 撤销处于 preparing 状态的子代理任务(父事务提交失败或异常中止时触发)。
3679
+ */
3680
+ rollbackPreparedSpawn(agentId: string): Promise<void>;
3681
+ /**
3682
+ * 任务主执行流程与生命周期状态机驱动。
3683
+ */
3684
+ private runTask;
3685
+ /**
3686
+ * 等待指定任务的所有直接与间接后代达到终态。
3687
+ */
3688
+ private waitForChildren;
3689
+ /**
3690
+ * 级联取消指定任务的所有直接与间接活跃后代。
3691
+ */
3692
+ private cascadeCancelChildren;
3693
+ /**
3694
+ * 处理任务超时事件。
3695
+ */
3696
+ private handleTaskTimeout;
3697
+ /**
3698
+ * 显式取消指定子代理任务。
3699
+ *
3700
+ * 保证:
3701
+ * - 幂等性:已处于终态直接返回;
3702
+ * - 跃迁为 cancelling 并中断当前执行信号;
3703
+ * - 级联取消所有后代子代理并等待后代清理完成;
3704
+ * - 等待自身 runner 退出并完成清理(R07);
3705
+ * - 释放活动槽位,写入 cancelled 终态,生成可靠通知(R08)。
3706
+ */
3707
+ cancelTask(agentId: string, reason?: string): Promise<void>;
3708
+ /**
3709
+ * 等待指定的子代理任务终结或超时。
3710
+ *
3711
+ * @param agentIds 目标子代理 ID 列表
3712
+ * @param timeoutMs 超时毫秒数(默认 30,000,上限 60,000)
3713
+ * @param signal 中止信号
3714
+ */
3715
+ waitAgents(agentIds: string[], timeoutMs?: number, signal?: AbortSignal): Promise<{
3716
+ completed: string[];
3717
+ pending: string[];
3718
+ }>;
3719
+ /**
3720
+ * 按过滤条件查询子代理任务列表;每条记录深度复制,调用方修改快照不影响运行时。
3721
+ */
3722
+ listTasks(filter?: ListAgentsFilter): AgentTaskRecord[];
3723
+ /**
3724
+ * 关闭 Runtime 并取消所有活动任务;立即释放宿主订阅,再等待任务清理收口。
3725
+ */
3726
+ close(): Promise<void>;
3727
+ /**
3728
+ * 幂等释放指定任务占用的活动容量槽位。
3729
+ * 防止取消操作与主轮次 finally 重复扣减导致槽位泄漏。
3730
+ */
3731
+ private releaseTaskSlotOnce;
3732
+ private releaseActiveSlot;
3733
+ private clearTaskTimer;
3734
+ /** 先保留调度等待者的同步唤醒时序,再异步通知宿主读取任务快照。 */
3735
+ private notifyStateChange;
3736
+ /**
3737
+ * 合并宿主变化通知,避免宿主回调同步重入任务状态转换;不改变内部等待者的唤醒时序。
3738
+ * 派发前再次检查订阅与关闭状态,取消后的回调不会执行,观察者失败不传播至任务。
3739
+ */
3740
+ private notifyTaskChanges;
3741
+ private waitForNextStateChange;
3742
+ }
3743
+
3744
+ /**
3745
+ * @fileoverview 子代理四大调度与管理工具实现(spawn_agent、list_agents、wait_agent、cancel_agent)。
3746
+ *
3747
+ * 约束、边界与为什么:
3748
+ * 1. 启动事务闭合不变量(Launch Transaction Closure):
3749
+ * spawn_agent 在准备阶段完成校验并预留容量后,立即返回 accepted 回执,
3750
+ * 父工具事务即刻闭合,父代理继续推进后续步骤;父事务确认后异步激活启动子代理,
3751
+ * 严禁在 spawn_agent 的 execute 中 await 子任务完成。
3752
+ * 2. 权限与能力声明:
3753
+ * 四大管理工具均显式声明 agent:spawn capability,经正常 PermissionPolicy 策略检查,
3754
+ * Plan 模式自动隐藏与拦截。
3755
+ * 3. 超时自管理(managesTimeout: true):
3756
+ * spawn_agent、wait_agent、cancel_agent 自行管理超时与资源清理,不受通用工具超时误杀。
3757
+ */
3758
+
3759
+ /**
3760
+ * 创建 spawn_agent 工具。
3761
+ *
3762
+ * @param runtime AgentRuntime 调度器实例
3763
+ */
3764
+ declare function createSpawnAgentTool(runtime: AgentRuntime): Tool<SpawnAgentParams, SpawnAgentReceipt>;
3765
+ /**
3766
+ * 创建 list_agents 工具。
3767
+ */
3768
+ declare function createListAgentsTool(runtime: AgentRuntime): Tool<ListAgentsFilter, unknown>;
3769
+ /**
3770
+ * 创建 wait_agent 工具。
3771
+ */
3772
+ declare function createWaitAgentTool(runtime: AgentRuntime): Tool<{
3773
+ agentIds: string[];
3774
+ timeoutMs?: number;
3775
+ }, unknown>;
3776
+ /**
3777
+ * 创建 cancel_agent 工具。
3778
+ */
3779
+ declare function createCancelAgentTool(runtime: AgentRuntime): Tool<{
3780
+ agentId: string;
3781
+ reason?: string;
3782
+ }, unknown>;
3783
+ /**
3784
+ * 创建完整的子代理四大管理工具集合。
3785
+ */
3786
+ declare function createAgentTools(runtime: AgentRuntime): Tool[];
3787
+
2455
3788
  /**
2456
3789
  * 任务准备上下文;提供当前会话取消信号、runId 与不可变工具快照。
2457
3790
  */
@@ -2489,7 +3822,11 @@ interface SessionConfig {
2489
3822
  defaultProvider: ModelProvider;
2490
3823
  /** 消息级落盘通道;支持状态能力的 Store 额外启用持久压缩与交互终态。 */
2491
3824
  store?: MessageStore;
2492
- /** 工具执行与会话基目录;projectRoot/cwd 缺省沿用此值。 */
3825
+ /** 文件访问与沙箱隔离的物理根绝对路径,经 native realpath 规范化;缺失时抛出 WORKSPACE_ROOT_REQUIRED。 */
3826
+ workspaceRoot?: string;
3827
+ /** 默认命令执行目录绝对路径,必须位于 workspaceRoot 内部;缺省为 workspaceRoot。 */
3828
+ executionCwd?: string;
3829
+ /** 工具执行与会话基目录兼容别名;与 workspaceRoot 冲突时失败。 */
2493
3830
  rootDir?: string;
2494
3831
  systemPrompt?: string;
2495
3832
  maxSteps?: number;
@@ -2500,13 +3837,25 @@ interface SessionConfig {
2500
3837
  mode?: SessionMode;
2501
3838
  permissionRules?: readonly PermissionRule[];
2502
3839
  approvalChannel?: ApprovalChannel;
3840
+ /** 项目根路径;缺省为 workspaceRoot。 */
2503
3841
  projectRoot?: string;
3842
+ /** 兼容别名:执行目录。 */
2504
3843
  cwd?: string;
2505
3844
  userInstructionsPath?: string;
2506
3845
  /** 未提供时使用默认日志 sink 的审计目录;init 时恢复不完整审计。 */
2507
3846
  auditRecoveryDirectory?: string;
2508
3847
  /** 接收普通运行日志失败的脱敏诊断;诊断失败也不得中断问答或替代审计。 */
2509
3848
  onDiagnostic?: (message: string) => void;
3849
+ /** 会话持有的沙箱实例;缺省基于 workspaceRoot 自动创建独占实例。 */
3850
+ sandbox?: PathSandbox;
3851
+ /** 共享工作区写租约协调器;缺省使用全局共享单例。 */
3852
+ leaseCoordinator?: WorkspaceLeaseCoordinator;
3853
+ /** 父任务或任务树根 ID,用于多智能体任务层级限制与追踪。 */
3854
+ rootTaskId?: string;
3855
+ /** 当前子会话在代理树中的深度,根会话为 0。 */
3856
+ depth?: number;
3857
+ /** 当前子会话对应的 agentId。 */
3858
+ agentId?: string;
2510
3859
  }
2511
3860
  /** getStats 返回的统计快照;全部字段为独立副本,宿主修改不影响会话内部状态。 */
2512
3861
  interface SessionStats {
@@ -2547,9 +3896,19 @@ declare class AgentSession {
2547
3896
  private summaryUsage;
2548
3897
  private readonly summaryAttempts;
2549
3898
  private readonly accountedAttempts;
3899
+ /** 文件访问与沙箱隔离的物理根绝对路径,经 native realpath 规范化。 */
3900
+ readonly workspaceRoot: string;
3901
+ /** 默认命令执行目录绝对路径,必须位于 workspaceRoot 内部。 */
3902
+ readonly executionCwd: string;
3903
+ /** 规范化项目身份哈希。 */
3904
+ readonly projectKey: string;
3905
+ /** 工具执行与会话基目录兼容别名;语义等同于 workspaceRoot。 */
2550
3906
  readonly rootDir: string;
2551
3907
  readonly tools: ToolRegistry;
2552
3908
  readonly hooks: HookRegistry;
3909
+ /** 会话持有的独占路径沙箱实例。 */
3910
+ readonly sandbox: PathSandbox;
3911
+ private readonly leaseCoordinator;
2553
3912
  private readonly router;
2554
3913
  private readonly store?;
2555
3914
  private readonly customSystemPrompt?;
@@ -2566,6 +3925,9 @@ declare class AgentSession {
2566
3925
  private readonly userInstructionsPath?;
2567
3926
  private instructionSnapshot?;
2568
3927
  private readonly auditRecoveryDirectory?;
3928
+ private readonly rootTaskId?;
3929
+ private readonly depth;
3930
+ private readonly agentId?;
2569
3931
  private history;
2570
3932
  private totalTurns;
2571
3933
  private usageStats;
@@ -2593,6 +3955,14 @@ declare class AgentSession {
2593
3955
  * 保证返回当前状态的独立切片,外部修改不污染内部挂载表。
2594
3956
  */
2595
3957
  getPlugins(): readonly AgentPlugin[];
3958
+ /**
3959
+ * 获取当前会话绑定的路径沙箱实例。
3960
+ *
3961
+ * 保证:
3962
+ * - 返回由当前会话独立持有的 PathSandbox 实例,其根目录严格绑定到当前会话的 workspaceRoot;
3963
+ * - 外部通过此沙箱执行路径规范化与逃逸校验时,遵循 native realpath 解析语义。
3964
+ */
3965
+ getSandbox(): PathSandbox;
2596
3966
  /**
2597
3967
  * 空闲时原子替换角色的模型绑定;本方法不改变当前角色或工具权限。
2598
3968
  * @param profile 模型协议、请求目标和输出预算。
@@ -2721,4 +4091,4 @@ declare class AgentSession {
2721
4091
  private findClosedToolMessages;
2722
4092
  }
2723
4093
 
2724
- export { AbortError, AgentLoop, type AgentLoopOptions, type AgentPlugin, AgentSession, AnthropicProvider, type AnthropicProviderOptions, type ApprovalChannel, type ApprovalChoice, type ApprovalRequest, type CanonicalMessage, type Capability, type ChatCapabilities, type CommandResult, type ConflictPolicy, type ContentBlock, type ContextBudget, ContextBudgetError, ContextManager, type ContextManagerOptions, ContextOverflowError, type ContextSnapshot, ContextStorageError, type ContextSummary, type ContextUsage, type ContextWindowValue, DEFAULT_CONTEXT_WINDOW_TOKENS, type EventLogger, type ExecutorOptions, FatalError, type FileDetails, FileLogSink, type FileLogSinkOptions, type FileObservation, type HistoryRepair, type HookContext, type HookHandlers, type HookPoint, HookRegistry, type InstructionLoadOptions, type InstructionSnapshot, type InstructionSource, type InteractionBoundary, type InteractionTerminal, JSONLMessageStore, KapibalaError, type LogChannel, type LogEvent, type LogField, type LogInput, type LogLevel, type LogSink, type ManagedSession, type MessageRole, type MessageStore, ModelError, type ModelErrorCategory, type ModelErrorInfo, type ModelErrorOptions, type ModelEvent, type ModelProfile, type ModelProtocol, type ModelProvider, type ModelProviderBinding, type ModelRequest, type ModelRole, type ModelRouter, type NormalizedHistory, OpenAICompatibleProvider, type OpenAIProviderOptions, OpenAIResponsesProvider, type OpenAIResponsesProviderOptions, PathSandbox, type PermissionAction, type PermissionDecision, PermissionPolicy, type PermissionRequest, type PermissionRule, type PluginCommandContribution, type PluginContext, type PluginContribution, PreDispatchError, type PreparedSkill, type PreparedTaskContext, type PreparedTaskResult, type PrimaryModelRole, type ProjectIdentity, PromptAssembler, type PromptAssemblerOptions, type PromptContentSource, type ProtocolItemMetadata, type ProtocolOrigin, type ProviderStateBlock, type RedactedThinkingBlock, type RequestPreparation, type ResolvedContextWindow, type RunCommandInput, type RunMetrics, SESSION_SCHEMA_VERSION, SKILL_LIMITS, SUMMARY_OUTPUT_BUFFER_MULTIPLIER, type SandboxConfig, SessionApprovalCache, SessionBusyError, type SessionConfig, type SessionEvent, type SessionHeader, SessionLock, SessionManager, type SessionManagerOptions, type SessionMetadata, type SessionMode, type SessionRecord, type SessionRecordType, type SessionState, type SessionStats, SessionStore, type ShellDetectOptions, type ShellEnvironment, type ShellKind, type ShellPreference, type ShellScope, SimpleModelRouter, type SkillActivation, type SkillCatalog, type SkillContentSource, type SkillContextState, type SkillDefinition, type SkillDiagnostic, type SkillDocument, type SkillMetadata, type SkillOptions, type SkillQuery, type SkillQueryPage, SkillRegistry, type SkillResourceInput, type SkillResourcePage, type SkillRoot, SkillRuntime, type SkillScanResult, type SkillScope, type StatefulMessageStore, type StepLogEntry, type StepLogStage, StructuredLogger, type SummaryCandidate, SummaryService, type SummaryServiceOptions, type TextBlock, type ThinkingBlock, type TokenEstimate, type TokenEstimator, type Tool, type ToolContext, type ToolDecision, type ToolDefinition, ToolError, type ToolExecutionIdentity, type ToolExecutionResult, ToolExecutor, type ToolHardDenial, type ToolInputValidation, type ToolMetadata, ToolNotFound, ToolRegistry, type ToolRegistrySnapshot, type ToolResultBlock, type ToolResultExecution, type ToolUseBlock, TransportError, type TurnMetrics, UnicodeTokenEstimator, type Usage, assembleCanonicalToolResults, builtinTools, classifyBashOutput, cleanupCommandResults, commandAuditSummary, compareSkillPaths, createContextBudget, createDefaultLogSinks, createLogId, createMessageId, createRunCommandTool, defineTool, describeModelError, detectShell, editFileTool, escapeSkillXml, estimateSkillTokens, executionFingerprint, extractFileDetails, findSkillContent, formatSkillCatalog, globTool, grepTool, identifyHistory, indexInteractions, inspectSkillContent, intersectSkillTools, isSkillName, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, isWithinSkillRoot, listSkillResources, loadInstructions, normalizeHistory, normalizeSkillTools, parseSkillDocument, projectSafeFields, readBoundedSkillText, readFileTool, readSkillResource, recoverIncompleteAudit, renderFileDetails, renderSkillReloads, requestFingerprint, resolveContextWindow, resolveSessionProject, sanitizeModelErrorMessage, sanitizeSessionTitle, scanSkillRoot, skillDigest, skillFailure, skillPathKey, stableJsonStringify, stableSerialize, supportsSessionState, toToolDefinition, truncateToolOutput, validateModelBinding, validatePermissionRules, validateSummary, visibleTools, writeFileTool };
4094
+ export { AbortError, AgentLoop, type AgentLoopOptions, type AgentNotification, type AgentPlugin, AgentRuntime, type AgentRuntimeOptions, AgentSession, type AgentTaskLimits, type AgentTaskOrigin, type AgentTaskRecord, type AgentTaskStatus, AnthropicProvider, type AnthropicProviderOptions, type ApprovalChannel, type ApprovalChoice, type ApprovalRequest, type BranchInfo, type CanonicalMessage, type Capability, type CatalogOptions, type ChatCapabilities, type ChildGrant, type ChildLimits, type CommandResult, type ConflictPolicy, type ContentBlock, type ContextBudget, ContextBudgetError, ContextManager, type ContextManagerOptions, ContextOverflowError, type ContextSnapshot, ContextStorageError, type ContextSummary, type ContextUsage, type ContextWindowValue, CrossProjectSessionCatalog, DEFAULT_CHILD_LIMITS, DEFAULT_CONTEXT_WINDOW_TOKENS, DEFAULT_MAX_STEPS, DEFAULT_MAX_SUBAGENT_DEPTH, DEFAULT_TIMEOUT_MS, type DerivedChildPolicy, type EventLogger, type ExecutorOptions, FatalError, type FileDetails, FileLogSink, type FileLogSinkOptions, type FileObservation, HARD_LIMIT_MAX_SUBAGENT_DEPTH, type HistoryRepair, type HookContext, type HookHandlers, type HookPoint, HookRegistry, type InstructionLoadOptions, type InstructionSnapshot, type InstructionSource, type InteractionBoundary, type InteractionTerminal, JSONLMessageStore, KapibalaError, type ListAgentsFilter, type LogChannel, type LogEvent, type LogField, type LogInput, type LogLevel, type LogSink, MAIN_BRANCH_ID, MAX_ACTIVE_TASKS_PER_RUNTIME, MAX_ACTIVE_TASKS_PER_TREE, MAX_TOTAL_TASKS_PER_TREE, type ManagedSession, type MessageRole, type MessageStore, ModelError, type ModelErrorCategory, type ModelErrorInfo, type ModelErrorOptions, type ModelEvent, type ModelProfile, type ModelProtocol, type ModelProvider, type ModelProviderBinding, type ModelRequest, type ModelRole, type ModelRouter, type NormalizedHistory, OpenAICompatibleProvider, type OpenAIProviderOptions, OpenAIResponsesProvider, type OpenAIResponsesProviderOptions, type ParentPolicySnapshot, PathSandbox, type PermissionAction, type PermissionDecision, PermissionPolicy, type PermissionRequest, type PermissionRule, type PluginCommandContribution, type PluginContext, type PluginContribution, PreDispatchError, type PreparedSkill, type PreparedTaskContext, type PreparedTaskResult, type PrimaryModelRole, type ProjectIdentity, PromptAssembler, type PromptAssemblerOptions, type PromptContentSource, type ProtocolItemMetadata, type ProtocolOrigin, type ProviderStateBlock, ROLE_PRESETS, type RedactedThinkingBlock, type RequestPreparation, type ResolvedContextWindow, type RolePresetDefinition, type RunCommandInput, type RunMetrics, SESSION_SCHEMA_VERSION, SESSION_SCHEMA_VERSION_V1, SESSION_SCHEMA_VERSION_V2, SKILL_LIMITS, SUMMARY_OUTPUT_BUFFER_MULTIPLIER, type SafeRegexMatchResult, type SandboxConfig, type SearchHit, type SearchOptions, type SearchResponse, SessionApprovalCache, SessionBusyError, type SessionCatalogEntry, type SessionConfig, type SessionEvent, type SessionHeader, SessionInbox, SessionLock, SessionManager, type SessionManagerOptions, type SessionMessageSink, type SessionMetadata, type SessionMode, type SessionRecord, type SessionRecordType, type SessionState, type SessionStats, SessionStore, type ShellDetectOptions, type ShellEnvironment, type ShellKind, type ShellPreference, type ShellScope, SimpleModelRouter, type SkillActivation, type SkillCatalog, type SkillContentSource, type SkillContextState, type SkillDefinition, type SkillDiagnostic, type SkillDocument, type SkillMetadata, type SkillOptions, type SkillQuery, type SkillQueryPage, SkillRegistry, type SkillResourceInput, type SkillResourcePage, type SkillRoot, SkillRuntime, type SkillScanResult, type SkillScope, type SpawnAgentParams, type SpawnAgentReceipt, type SpawnContext, type StatefulMessageStore, type StepLogEntry, type StepLogStage, StructuredLogger, SubagentOutbox, type SubagentOutboxOptions, type SubagentRole, type SubagentSessionRunner, type SubagentSourceMetadata, type SummaryCandidate, SummaryService, type SummaryServiceOptions, type TextBlock, type ThinkingBlock, type TokenEstimate, type TokenEstimator, type Tool, type ToolContext, type ToolDecision, type ToolDefinition, ToolError, type ToolExecutionIdentity, type ToolExecutionResult, ToolExecutor, type ToolHardDenial, type ToolInputValidation, type ToolMetadata, ToolNotFound, ToolRegistry, type ToolRegistrySnapshot, type ToolResultBlock, type ToolResultExecution, type ToolUseBlock, TransportError, type TurnMetrics, UnicodeTokenEstimator, type Usage, type WorkspaceContext, WorkspaceLeaseCoordinator, type WorkspaceResolutionInput, type WorkspaceWriteLease, assembleCanonicalToolResults, assertClosedToolTransaction, builtinTools, classifyBashOutput, cleanupCommandResults, commandAuditSummary, compareSkillPaths, computeProjectKey, createAgentTools, createCancelAgentTool, createContextBudget, createDefaultLogSinks, createListAgentsTool, createLogId, createMessageId, createRunCommandTool, createSpawnAgentTool, createWaitAgentTool, defineTool, deriveChildPolicy, describeModelError, detectShell, editFileTool, escapeSkillXml, estimateSkillTokens, executionFingerprint, extractFileDetails, findSkillContent, formatNotificationContent, formatSkillCatalog, getRolePreset, globTool, grepTool, identifyHistory, indexInteractions, inspectSkillContent, intersectSkillTools, isActiveTaskStatus, isGlobalControlRecordType, isPathInside, isSamePath, isSkillName, isTerminalTaskStatus, isTextBlock, isThinkingBlock, isToolResultBlock, isToolUseBlock, isWithinSkillRoot, isWriteOperation, listSkillResources, loadInstructions, normalizeDriveLetter, normalizeHistory, normalizeSkillTools, normalizedProjectRoot, parseSkillDocument, projectSafeFields, readBoundedSkillText, readFileTool, readSkillResource, recoverIncompleteAudit, renderFileDetails, renderSkillReloads, requestFingerprint, resolveContextWindow, resolveSessionProject, resolveWorkspaceContext, safeRegexMatch, sanitizeModelErrorMessage, sanitizeSessionTitle, scanSkillRoot, sharedWorkspaceLeaseCoordinator, skillDigest, skillFailure, skillPathKey, stableJsonStringify, stableSerialize, supportsSessionState, tightenMode, toNativePhysicalPath, toToolDefinition, truncateToolOutput, validateModelBinding, validatePermissionRules, validateSummary, visibleTools, writeFileTool };