@kiturone/kapibala 0.0.8 → 0.0.10

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
@@ -239,6 +239,18 @@ declare class KapibalaError extends Error {
239
239
  dispatchOutcome?: 'not_sent' | 'succeeded' | 'failed' | 'unknown';
240
240
  });
241
241
  }
242
+ declare const SESSION_SAFE_MESSAGES: {
243
+ readonly SESSION_LOCKED: "会话已被其他持有者占用";
244
+ readonly SESSION_RECOVERY_IN_PROGRESS: "会话正在恢复";
245
+ readonly SESSION_LOCK_OWNER_CHANGED: "会话锁持有者已变化";
246
+ readonly SESSION_NOT_FOUND: "未找到指定会话";
247
+ readonly SESSION_ID_AMBIGUOUS: "会话前缀不唯一";
248
+ readonly HISTORY_PAGE_INVALID: "历史页参数无效";
249
+ };
250
+ /** 会话身份与存储锁的稳定分类;不将内部诊断文本当作机器协议。 */
251
+ type SessionErrorCode = keyof typeof SESSION_SAFE_MESSAGES;
252
+ /** 生成固定安全文案的会话错误;内部 message 保留兼容诊断,重试必须由调用者决定。 */
253
+ declare function createSessionError(code: SessionErrorCode, message: string): KapibalaError;
242
254
  /** 工具向外部发送前在微任务复核或状态检查中被撤销/拒绝;dispatchOutcome 固定 not_sent。 */
243
255
  declare class PreDispatchError extends KapibalaError {
244
256
  constructor(message: string, options?: {
@@ -1151,9 +1163,13 @@ declare class SessionManager {
1151
1163
  constructor(options?: SessionManagerOptions);
1152
1164
  /** 默认新建独立空会话,写入头部并持有单写者锁;不读取其它正文。 */
1153
1165
  create(): Promise<ManagedSession>;
1154
- /** 每页 20 项按正文活动排序;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。 */
1166
+ /**
1167
+ * 按正文活动排序分页;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。
1168
+ * pageSize 由调用方显式给出时必须在 1–100 之间;非法页参数直接失败,不静默修正。
1169
+ */
1155
1170
  list(page?: number, options?: {
1156
1171
  includeArchived?: boolean;
1172
+ pageSize?: number;
1157
1173
  }): Promise<{
1158
1174
  items: SessionMetadata[];
1159
1175
  total: number;
@@ -1889,6 +1905,8 @@ interface ToolMetadata {
1889
1905
  }
1890
1906
  /** 工具执行期由宿主注入的运行环境;信号取消后工具应尽快清理在途资源再返回。 */
1891
1907
  interface ToolContext {
1908
+ /** 父会话实际协调器的内存引用;spawn 必须显式传递,禁止放入模型输入或持久记录。 */
1909
+ readonly leaseCoordinator?: WorkspaceLeaseCoordinator;
1892
1910
  /** 显式工作区物理根路径,经 native realpath 规范化。 */
1893
1911
  workspaceRoot?: string;
1894
1912
  /** 显式命令执行工作目录绝对路径(位于 workspaceRoot 内部)。 */
@@ -2027,8 +2045,6 @@ declare class WorkspaceLeaseCoordinator {
2027
2045
  timeoutMs?: number;
2028
2046
  }): Promise<T>;
2029
2047
  }
2030
- /** 运行时共享写租约协调器单例。 */
2031
- declare const sharedWorkspaceLeaseCoordinator: WorkspaceLeaseCoordinator;
2032
2048
 
2033
2049
  type CompactionReason = 'threshold' | 'manual' | 'overflow';
2034
2050
  /**
@@ -3572,12 +3588,18 @@ declare class SessionInbox {
3572
3588
  */
3573
3589
 
3574
3590
  /** 子代理会话执行器类型;生产环境调用真实的 AgentSession,测试环境可注入 Mock。 */
3575
- type SubagentSessionRunner = (record: AgentTaskRecord, signal: AbortSignal) => Promise<{
3591
+ type SubagentSessionRunner = (record: AgentTaskRecord, signal: AbortSignal, context: SubagentRunnerContext) => Promise<{
3576
3592
  summary: string;
3577
3593
  modelId?: string;
3578
3594
  }>;
3595
+ /** 子任务仅在内存中接收父协调器;runner 创建子会话时必须注入,不可序列化到任务记录。 */
3596
+ interface SubagentRunnerContext {
3597
+ readonly leaseCoordinator: WorkspaceLeaseCoordinator;
3598
+ }
3579
3599
  /** 启动子代理时的调用方上下文。 */
3580
3600
  interface SpawnContext {
3601
+ /** 父会话实际持有的协调器;缺失时在受理和持久副作用前拒绝启动。 */
3602
+ readonly leaseCoordinator: WorkspaceLeaseCoordinator;
3581
3603
  /** 根任务标识;若为根会话直接派生,可缺省由 Runtime 自动初始化。 */
3582
3604
  rootTaskId?: string;
3583
3605
  /** 父会话会话 ID。 */
@@ -3613,6 +3635,7 @@ interface AgentRuntimeOptions {
3613
3635
  * 后台子代理任务树调度与状态机协调器。
3614
3636
  */
3615
3637
  declare class AgentRuntime {
3638
+ private readonly runnerContexts;
3616
3639
  private readonly tasks;
3617
3640
  private readonly controllers;
3618
3641
  private readonly timers;
@@ -3807,8 +3830,8 @@ interface PreparedTaskResult {
3807
3830
  skillName?: string;
3808
3831
  }
3809
3832
 
3810
- /** AgentSession 的构造配置;除主任务绑定外均可缺省,缺省行为见各字段。 */
3811
- interface SessionConfig {
3833
+ /** 会话的非根选项;扩展配置时与 SessionConfig 的显式根联合组合,不能隐式推导工作区。 */
3834
+ interface SessionOptions {
3812
3835
  /** 宿主显式技能配置;缺省不扫描home,项目根需独立信任。 */
3813
3836
  skills?: SkillOptions;
3814
3837
  /** 持久会话身份;有版本化 Store 时须与头部一致,日志实例身份保持独立。 */
@@ -3822,12 +3845,8 @@ interface SessionConfig {
3822
3845
  defaultProvider: ModelProvider;
3823
3846
  /** 消息级落盘通道;支持状态能力的 Store 额外启用持久压缩与交互终态。 */
3824
3847
  store?: MessageStore;
3825
- /** 文件访问与沙箱隔离的物理根绝对路径,经 native realpath 规范化;缺失时抛出 WORKSPACE_ROOT_REQUIRED。 */
3826
- workspaceRoot?: string;
3827
3848
  /** 默认命令执行目录绝对路径,必须位于 workspaceRoot 内部;缺省为 workspaceRoot。 */
3828
3849
  executionCwd?: string;
3829
- /** 工具执行与会话基目录兼容别名;与 workspaceRoot 冲突时失败。 */
3830
- rootDir?: string;
3831
3850
  systemPrompt?: string;
3832
3851
  maxSteps?: number;
3833
3852
  logger?: (msg: string) => void;
@@ -3848,7 +3867,7 @@ interface SessionConfig {
3848
3867
  onDiagnostic?: (message: string) => void;
3849
3868
  /** 会话持有的沙箱实例;缺省基于 workspaceRoot 自动创建独占实例。 */
3850
3869
  sandbox?: PathSandbox;
3851
- /** 共享工作区写租约协调器;缺省使用全局共享单例。 */
3870
+ /** 宿主显式共享的写租约协调器;缺省为本会话独占实例,不隐含跨会话互斥。 */
3852
3871
  leaseCoordinator?: WorkspaceLeaseCoordinator;
3853
3872
  /** 父任务或任务树根 ID,用于多智能体任务层级限制与追踪。 */
3854
3873
  rootTaskId?: string;
@@ -3857,6 +3876,14 @@ interface SessionConfig {
3857
3876
  /** 当前子会话对应的 agentId。 */
3858
3877
  agentId?: string;
3859
3878
  }
3879
+ /** 显式工作区根至少提供其一;保留 rootDir-only 兼容输入,双字段物理冲突在构造时拒绝。 */
3880
+ type SessionConfig = SessionOptions & ({
3881
+ workspaceRoot: string;
3882
+ rootDir?: string;
3883
+ } | {
3884
+ workspaceRoot?: never;
3885
+ rootDir: string;
3886
+ });
3860
3887
  /** getStats 返回的统计快照;全部字段为独立副本,宿主修改不影响会话内部状态。 */
3861
3888
  interface SessionStats {
3862
3889
  conversationId?: string;
@@ -4091,4 +4118,4 @@ declare class AgentSession {
4091
4118
  private findClosedToolMessages;
4092
4119
  }
4093
4120
 
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 };
4121
+ 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 SessionErrorCode, type SessionEvent, type SessionHeader, SessionInbox, SessionLock, SessionManager, type SessionManagerOptions, type SessionMessageSink, type SessionMetadata, type SessionMode, type SessionOptions, 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 SubagentRunnerContext, 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, createSessionError, 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, skillDigest, skillFailure, skillPathKey, stableJsonStringify, stableSerialize, supportsSessionState, tightenMode, toNativePhysicalPath, toToolDefinition, truncateToolOutput, validateModelBinding, validatePermissionRules, validateSummary, visibleTools, writeFileTool };
package/dist/index.d.ts CHANGED
@@ -239,6 +239,18 @@ declare class KapibalaError extends Error {
239
239
  dispatchOutcome?: 'not_sent' | 'succeeded' | 'failed' | 'unknown';
240
240
  });
241
241
  }
242
+ declare const SESSION_SAFE_MESSAGES: {
243
+ readonly SESSION_LOCKED: "会话已被其他持有者占用";
244
+ readonly SESSION_RECOVERY_IN_PROGRESS: "会话正在恢复";
245
+ readonly SESSION_LOCK_OWNER_CHANGED: "会话锁持有者已变化";
246
+ readonly SESSION_NOT_FOUND: "未找到指定会话";
247
+ readonly SESSION_ID_AMBIGUOUS: "会话前缀不唯一";
248
+ readonly HISTORY_PAGE_INVALID: "历史页参数无效";
249
+ };
250
+ /** 会话身份与存储锁的稳定分类;不将内部诊断文本当作机器协议。 */
251
+ type SessionErrorCode = keyof typeof SESSION_SAFE_MESSAGES;
252
+ /** 生成固定安全文案的会话错误;内部 message 保留兼容诊断,重试必须由调用者决定。 */
253
+ declare function createSessionError(code: SessionErrorCode, message: string): KapibalaError;
242
254
  /** 工具向外部发送前在微任务复核或状态检查中被撤销/拒绝;dispatchOutcome 固定 not_sent。 */
243
255
  declare class PreDispatchError extends KapibalaError {
244
256
  constructor(message: string, options?: {
@@ -1151,9 +1163,13 @@ declare class SessionManager {
1151
1163
  constructor(options?: SessionManagerOptions);
1152
1164
  /** 默认新建独立空会话,写入头部并持有单写者锁;不读取其它正文。 */
1153
1165
  create(): Promise<ManagedSession>;
1154
- /** 每页 20 项按正文活动排序;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。 */
1166
+ /**
1167
+ * 按正文活动排序分页;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。
1168
+ * pageSize 由调用方显式给出时必须在 1–100 之间;非法页参数直接失败,不静默修正。
1169
+ */
1155
1170
  list(page?: number, options?: {
1156
1171
  includeArchived?: boolean;
1172
+ pageSize?: number;
1157
1173
  }): Promise<{
1158
1174
  items: SessionMetadata[];
1159
1175
  total: number;
@@ -1889,6 +1905,8 @@ interface ToolMetadata {
1889
1905
  }
1890
1906
  /** 工具执行期由宿主注入的运行环境;信号取消后工具应尽快清理在途资源再返回。 */
1891
1907
  interface ToolContext {
1908
+ /** 父会话实际协调器的内存引用;spawn 必须显式传递,禁止放入模型输入或持久记录。 */
1909
+ readonly leaseCoordinator?: WorkspaceLeaseCoordinator;
1892
1910
  /** 显式工作区物理根路径,经 native realpath 规范化。 */
1893
1911
  workspaceRoot?: string;
1894
1912
  /** 显式命令执行工作目录绝对路径(位于 workspaceRoot 内部)。 */
@@ -2027,8 +2045,6 @@ declare class WorkspaceLeaseCoordinator {
2027
2045
  timeoutMs?: number;
2028
2046
  }): Promise<T>;
2029
2047
  }
2030
- /** 运行时共享写租约协调器单例。 */
2031
- declare const sharedWorkspaceLeaseCoordinator: WorkspaceLeaseCoordinator;
2032
2048
 
2033
2049
  type CompactionReason = 'threshold' | 'manual' | 'overflow';
2034
2050
  /**
@@ -3572,12 +3588,18 @@ declare class SessionInbox {
3572
3588
  */
3573
3589
 
3574
3590
  /** 子代理会话执行器类型;生产环境调用真实的 AgentSession,测试环境可注入 Mock。 */
3575
- type SubagentSessionRunner = (record: AgentTaskRecord, signal: AbortSignal) => Promise<{
3591
+ type SubagentSessionRunner = (record: AgentTaskRecord, signal: AbortSignal, context: SubagentRunnerContext) => Promise<{
3576
3592
  summary: string;
3577
3593
  modelId?: string;
3578
3594
  }>;
3595
+ /** 子任务仅在内存中接收父协调器;runner 创建子会话时必须注入,不可序列化到任务记录。 */
3596
+ interface SubagentRunnerContext {
3597
+ readonly leaseCoordinator: WorkspaceLeaseCoordinator;
3598
+ }
3579
3599
  /** 启动子代理时的调用方上下文。 */
3580
3600
  interface SpawnContext {
3601
+ /** 父会话实际持有的协调器;缺失时在受理和持久副作用前拒绝启动。 */
3602
+ readonly leaseCoordinator: WorkspaceLeaseCoordinator;
3581
3603
  /** 根任务标识;若为根会话直接派生,可缺省由 Runtime 自动初始化。 */
3582
3604
  rootTaskId?: string;
3583
3605
  /** 父会话会话 ID。 */
@@ -3613,6 +3635,7 @@ interface AgentRuntimeOptions {
3613
3635
  * 后台子代理任务树调度与状态机协调器。
3614
3636
  */
3615
3637
  declare class AgentRuntime {
3638
+ private readonly runnerContexts;
3616
3639
  private readonly tasks;
3617
3640
  private readonly controllers;
3618
3641
  private readonly timers;
@@ -3807,8 +3830,8 @@ interface PreparedTaskResult {
3807
3830
  skillName?: string;
3808
3831
  }
3809
3832
 
3810
- /** AgentSession 的构造配置;除主任务绑定外均可缺省,缺省行为见各字段。 */
3811
- interface SessionConfig {
3833
+ /** 会话的非根选项;扩展配置时与 SessionConfig 的显式根联合组合,不能隐式推导工作区。 */
3834
+ interface SessionOptions {
3812
3835
  /** 宿主显式技能配置;缺省不扫描home,项目根需独立信任。 */
3813
3836
  skills?: SkillOptions;
3814
3837
  /** 持久会话身份;有版本化 Store 时须与头部一致,日志实例身份保持独立。 */
@@ -3822,12 +3845,8 @@ interface SessionConfig {
3822
3845
  defaultProvider: ModelProvider;
3823
3846
  /** 消息级落盘通道;支持状态能力的 Store 额外启用持久压缩与交互终态。 */
3824
3847
  store?: MessageStore;
3825
- /** 文件访问与沙箱隔离的物理根绝对路径,经 native realpath 规范化;缺失时抛出 WORKSPACE_ROOT_REQUIRED。 */
3826
- workspaceRoot?: string;
3827
3848
  /** 默认命令执行目录绝对路径,必须位于 workspaceRoot 内部;缺省为 workspaceRoot。 */
3828
3849
  executionCwd?: string;
3829
- /** 工具执行与会话基目录兼容别名;与 workspaceRoot 冲突时失败。 */
3830
- rootDir?: string;
3831
3850
  systemPrompt?: string;
3832
3851
  maxSteps?: number;
3833
3852
  logger?: (msg: string) => void;
@@ -3848,7 +3867,7 @@ interface SessionConfig {
3848
3867
  onDiagnostic?: (message: string) => void;
3849
3868
  /** 会话持有的沙箱实例;缺省基于 workspaceRoot 自动创建独占实例。 */
3850
3869
  sandbox?: PathSandbox;
3851
- /** 共享工作区写租约协调器;缺省使用全局共享单例。 */
3870
+ /** 宿主显式共享的写租约协调器;缺省为本会话独占实例,不隐含跨会话互斥。 */
3852
3871
  leaseCoordinator?: WorkspaceLeaseCoordinator;
3853
3872
  /** 父任务或任务树根 ID,用于多智能体任务层级限制与追踪。 */
3854
3873
  rootTaskId?: string;
@@ -3857,6 +3876,14 @@ interface SessionConfig {
3857
3876
  /** 当前子会话对应的 agentId。 */
3858
3877
  agentId?: string;
3859
3878
  }
3879
+ /** 显式工作区根至少提供其一;保留 rootDir-only 兼容输入,双字段物理冲突在构造时拒绝。 */
3880
+ type SessionConfig = SessionOptions & ({
3881
+ workspaceRoot: string;
3882
+ rootDir?: string;
3883
+ } | {
3884
+ workspaceRoot?: never;
3885
+ rootDir: string;
3886
+ });
3860
3887
  /** getStats 返回的统计快照;全部字段为独立副本,宿主修改不影响会话内部状态。 */
3861
3888
  interface SessionStats {
3862
3889
  conversationId?: string;
@@ -4091,4 +4118,4 @@ declare class AgentSession {
4091
4118
  private findClosedToolMessages;
4092
4119
  }
4093
4120
 
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 };
4121
+ 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 SessionErrorCode, type SessionEvent, type SessionHeader, SessionInbox, SessionLock, SessionManager, type SessionManagerOptions, type SessionMessageSink, type SessionMetadata, type SessionMode, type SessionOptions, 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 SubagentRunnerContext, 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, createSessionError, 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, skillDigest, skillFailure, skillPathKey, stableJsonStringify, stableSerialize, supportsSessionState, tightenMode, toNativePhysicalPath, toToolDefinition, truncateToolOutput, validateModelBinding, validatePermissionRules, validateSummary, visibleTools, writeFileTool };
package/dist/index.js CHANGED
@@ -129,6 +129,21 @@ var KapibalaError = class extends Error {
129
129
  this.dispatchOutcome = options?.dispatchOutcome;
130
130
  }
131
131
  };
132
+ var SESSION_SAFE_MESSAGES = {
133
+ SESSION_LOCKED: "\u4F1A\u8BDD\u5DF2\u88AB\u5176\u4ED6\u6301\u6709\u8005\u5360\u7528",
134
+ SESSION_RECOVERY_IN_PROGRESS: "\u4F1A\u8BDD\u6B63\u5728\u6062\u590D",
135
+ SESSION_LOCK_OWNER_CHANGED: "\u4F1A\u8BDD\u9501\u6301\u6709\u8005\u5DF2\u53D8\u5316",
136
+ SESSION_NOT_FOUND: "\u672A\u627E\u5230\u6307\u5B9A\u4F1A\u8BDD",
137
+ SESSION_ID_AMBIGUOUS: "\u4F1A\u8BDD\u524D\u7F00\u4E0D\u552F\u4E00",
138
+ HISTORY_PAGE_INVALID: "\u5386\u53F2\u9875\u53C2\u6570\u65E0\u6548"
139
+ };
140
+ function createSessionError(code, message) {
141
+ return new KapibalaError(message, {
142
+ code,
143
+ safeMessage: SESSION_SAFE_MESSAGES[code],
144
+ retryPolicy: "after_user_action"
145
+ });
146
+ }
132
147
  var PreDispatchError = class extends KapibalaError {
133
148
  constructor(message, options) {
134
149
  super(message, {
@@ -1274,19 +1289,23 @@ var SessionLock = class _SessionLock {
1274
1289
  if (error.code !== "EEXIST") throw error;
1275
1290
  const stale = _SessionLock.readOwner(lockPath);
1276
1291
  if (!stale || !_SessionLock.isDead(stale.pid))
1277
- throw new Error(
1292
+ throw createSessionError(
1293
+ "SESSION_LOCKED",
1278
1294
  `Session locked by a live or unknown owner${stale ? ` (pid=${stale.pid})` : ""}`
1279
1295
  );
1280
1296
  try {
1281
1297
  fs3.mkdirSync(recovery);
1282
1298
  } catch {
1283
- throw new Error("Session locked: recovery in progress");
1299
+ throw createSessionError(
1300
+ "SESSION_RECOVERY_IN_PROGRESS",
1301
+ "Session locked: recovery in progress"
1302
+ );
1284
1303
  }
1285
1304
  try {
1286
1305
  fs3.writeFileSync(path2.join(recovery, "owner.json"), JSON.stringify(owner), { flag: "wx" });
1287
1306
  const current = _SessionLock.readOwner(lockPath);
1288
1307
  if (current?.nonce !== stale.nonce || current.pid !== stale.pid || !_SessionLock.isDead(current.pid)) {
1289
- throw new Error("Session locked: owner changed");
1308
+ throw createSessionError("SESSION_LOCK_OWNER_CHANGED", "Session locked: owner changed");
1290
1309
  }
1291
1310
  const quarantine = `${lockPath}.stale-${randomUUID2()}`;
1292
1311
  fs3.renameSync(lockPath, quarantine);
@@ -1306,7 +1325,8 @@ var SessionLock = class _SessionLock {
1306
1325
  }
1307
1326
  if (installError.code === "EEXIST") {
1308
1327
  const winner = _SessionLock.readOwner(lockPath);
1309
- throw new Error(
1328
+ throw createSessionError(
1329
+ "SESSION_LOCKED",
1310
1330
  `Session locked by a live or unknown owner${winner ? ` (pid=${winner.pid})` : ""}`
1311
1331
  );
1312
1332
  }
@@ -1340,7 +1360,7 @@ var SessionLock = class _SessionLock {
1340
1360
  if (this.released) return;
1341
1361
  const current = _SessionLock.readOwner(this.lockPath);
1342
1362
  if (current?.nonce !== this.owner.nonce || current.pid !== this.owner.pid)
1343
- throw new Error("Session lock owner changed");
1363
+ throw createSessionError("SESSION_LOCK_OWNER_CHANGED", "Session lock owner changed");
1344
1364
  fs3.unlinkSync(path2.join(this.lockPath, "owner.json"));
1345
1365
  fs3.rmdirSync(this.lockPath);
1346
1366
  this.released = true;
@@ -1371,7 +1391,11 @@ var SessionLock = class _SessionLock {
1371
1391
  /** 无残留或残留进程已死亡时放行;确认存活的回收进行中则明确失败。 */
1372
1392
  static ensureNoLiveRecovery(recovery) {
1373
1393
  _SessionLock.clearAbandonedRecovery(recovery);
1374
- if (fs3.existsSync(recovery)) throw new Error("Session locked: recovery in progress");
1394
+ if (fs3.existsSync(recovery))
1395
+ throw createSessionError(
1396
+ "SESSION_RECOVERY_IN_PROGRESS",
1397
+ "Session locked: recovery in progress"
1398
+ );
1375
1399
  }
1376
1400
  /** 仅 ESRCH 表示确定死亡;PID 复用或 EPERM 均保持原锁。 */
1377
1401
  static isDead(pid) {
@@ -1598,30 +1622,36 @@ var SessionManager = class {
1598
1622
  throw error;
1599
1623
  }
1600
1624
  }
1601
- /** 每页 20 项按正文活动排序;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。 */
1625
+ /**
1626
+ * 按正文活动排序分页;有效 sidecar 只读元数据,不读取完整 JSONL。默认排除已归档会话。
1627
+ * pageSize 由调用方显式给出时必须在 1–100 之间;非法页参数直接失败,不静默修正。
1628
+ */
1602
1629
  async list(page = 1, options) {
1603
- if (!Number.isSafeInteger(page) || page < 1)
1604
- throw new Error("History page must be a positive integer");
1630
+ const pageSize = options?.pageSize ?? 20;
1631
+ if (!Number.isSafeInteger(page) || page < 1 || !Number.isSafeInteger(pageSize) || pageSize < 1 || pageSize > 100)
1632
+ throw createSessionError("HISTORY_PAGE_INVALID", "History page must be a positive integer");
1605
1633
  const all = await this.allMetadata();
1606
1634
  const filtered = options?.includeArchived ? all : all.filter((m) => !m.archived);
1607
1635
  return {
1608
- items: filtered.slice((page - 1) * 20, page * 20),
1636
+ items: filtered.slice((page - 1) * pageSize, page * pageSize),
1609
1637
  total: filtered.length,
1610
1638
  page,
1611
- pages: Math.max(1, Math.ceil(filtered.length / 20))
1639
+ pages: Math.max(1, Math.ceil(filtered.length / pageSize))
1612
1640
  };
1613
1641
  }
1614
1642
  /** 解析完整 ID 或唯一前缀对应的会话文件与 ID。 */
1615
1643
  resolveSession(id) {
1616
- if (!id || !/^[a-zA-Z0-9-]+$/.test(id)) throw new Error("Session not found");
1644
+ if (!id || !/^[a-zA-Z0-9-]+$/.test(id))
1645
+ throw createSessionError("SESSION_NOT_FOUND", "Session not found");
1617
1646
  const all = fs5.readdirSync(this.directory).filter((name) => /^\d+_[a-zA-Z0-9-]+\.jsonl$/.test(name)).map((fileName) => ({
1618
1647
  fileName,
1619
1648
  conversationId: fileName.slice(fileName.indexOf("_") + 1, -6)
1620
1649
  }));
1621
1650
  const exact = all.find((m) => m.conversationId === id || m.fileName === id);
1622
1651
  const matches = exact ? [exact] : all.filter((m) => m.conversationId.startsWith(id));
1623
- if (!matches.length) throw new Error(`Session not found: ${id}`);
1624
- if (matches.length !== 1) throw new Error(`Ambiguous session prefix: ${id}`);
1652
+ if (!matches.length) throw createSessionError("SESSION_NOT_FOUND", `Session not found: ${id}`);
1653
+ if (matches.length !== 1)
1654
+ throw createSessionError("SESSION_ID_AMBIGUOUS", `Ambiguous session prefix: ${id}`);
1625
1655
  return matches[0];
1626
1656
  }
1627
1657
  /**
@@ -1880,13 +1910,18 @@ var SessionManager = class {
1880
1910
  }));
1881
1911
  const exact = all.find((m) => m.conversationId === idOrFileName);
1882
1912
  const matches = exact ? [exact] : all.filter((m) => m.conversationId.startsWith(idOrFileName));
1883
- if (!matches.length) throw new Error(`Session not found: ${idOrFileName}`);
1884
- if (matches.length !== 1) throw new Error(`Ambiguous session prefix: ${idOrFileName}`);
1913
+ if (!matches.length)
1914
+ throw createSessionError("SESSION_NOT_FOUND", `Session not found: ${idOrFileName}`);
1915
+ if (matches.length !== 1)
1916
+ throw createSessionError(
1917
+ "SESSION_ID_AMBIGUOUS",
1918
+ `Ambiguous session prefix: ${idOrFileName}`
1919
+ );
1885
1920
  sourceFileName = matches[0].fileName;
1886
1921
  }
1887
1922
  const sourcePath = path4.join(this.directory, sourceFileName);
1888
1923
  if (!fs5.existsSync(sourcePath)) {
1889
- throw new Error(`Session not found: ${idOrFileName}`);
1924
+ throw createSessionError("SESSION_NOT_FOUND", `Session not found: ${idOrFileName}`);
1890
1925
  }
1891
1926
  const nativeSource = toNativePhysicalPath(sourcePath);
1892
1927
  const beforeStat = fs5.statSync(nativeSource);
@@ -3255,7 +3290,6 @@ var WorkspaceLeaseCoordinator = class {
3255
3290
  }
3256
3291
  }
3257
3292
  };
3258
- var sharedWorkspaceLeaseCoordinator = new WorkspaceLeaseCoordinator();
3259
3293
 
3260
3294
  // src/context/manager.ts
3261
3295
  import { createHash as createHash7 } from "crypto";
@@ -7934,6 +7968,7 @@ var ToolExecutor = class {
7934
7968
  this.signal?.addEventListener("abort", abortFromSession, { once: true });
7935
7969
  }
7936
7970
  const toolCtx = {
7971
+ leaseCoordinator: this.leaseCoordinator,
7937
7972
  workspaceRoot: this.workspaceRoot,
7938
7973
  executionCwd: this.executionCwd,
7939
7974
  sandbox: this.sandbox,
@@ -10656,6 +10691,7 @@ var SessionInbox = class _SessionInbox {
10656
10691
 
10657
10692
  // src/runtime/agent/runtime.ts
10658
10693
  var AgentRuntime = class {
10694
+ runnerContexts = /* @__PURE__ */ new Map();
10659
10695
  tasks = /* @__PURE__ */ new Map();
10660
10696
  controllers = /* @__PURE__ */ new Map();
10661
10697
  timers = /* @__PURE__ */ new Map();
@@ -10739,6 +10775,13 @@ var AgentRuntime = class {
10739
10775
  * - 登记为 preparing 状态并返回 accepted 回执,使父工具事务能立刻闭合。
10740
10776
  */
10741
10777
  async prepareSpawn(context, params) {
10778
+ const coordinator = context.leaseCoordinator;
10779
+ if (!coordinator || typeof coordinator !== "object" || typeof coordinator.isLocked !== "function" || typeof coordinator.getActiveLease !== "function" || typeof coordinator.tryAcquire !== "function" || typeof coordinator.acquire !== "function") {
10780
+ throw new KapibalaError("Spawn requires the parent workspace lease coordinator", {
10781
+ code: "CONFIG_INVALID",
10782
+ safeMessage: "\u5FC5\u987B\u663E\u5F0F\u4F20\u5165\u7236\u4F1A\u8BDD\u5199\u79DF\u7EA6\u534F\u8C03\u5668"
10783
+ });
10784
+ }
10742
10785
  if (this.isClosed) {
10743
10786
  throw new KapibalaError("AgentRuntime is closed", {
10744
10787
  code: "CONFIG_INVALID",
@@ -10881,6 +10924,7 @@ var AgentRuntime = class {
10881
10924
  timeoutMs
10882
10925
  })
10883
10926
  };
10927
+ this.runnerContexts.set(agentId, Object.freeze({ leaseCoordinator: context.leaseCoordinator }));
10884
10928
  this.tasks.set(agentId, taskRecord);
10885
10929
  this.totalActiveCount++;
10886
10930
  this.treeActiveCounts.set(rootTaskId, treeActive + 1);
@@ -10933,6 +10977,7 @@ var AgentRuntime = class {
10933
10977
  const task = this.tasks.get(agentId);
10934
10978
  if (!task) return;
10935
10979
  if (task.status === "preparing") {
10980
+ this.runnerContexts.delete(agentId);
10936
10981
  task.status = "cancelled";
10937
10982
  task.error = "Parent transaction aborted before commit";
10938
10983
  task.finishedAt = Date.now();
@@ -10958,7 +11003,10 @@ var AgentRuntime = class {
10958
11003
  this.timers.set(task.agentId, timer);
10959
11004
  let runError;
10960
11005
  try {
10961
- const result = await this.runner(task, controller.signal);
11006
+ const context = this.runnerContexts.get(task.agentId);
11007
+ if (!context)
11008
+ throw new KapibalaError("Runner context is unavailable", { code: "CONFIG_INVALID" });
11009
+ const result = await this.runner(task, controller.signal, context);
10962
11010
  if (task.status === "cancelling") {
10963
11011
  task.status = "cancelled";
10964
11012
  return;
@@ -11009,6 +11057,7 @@ var AgentRuntime = class {
11009
11057
  task.error = runError.message;
11010
11058
  await this.cascadeCancelChildren(task.agentId, "Parent task failed");
11011
11059
  } finally {
11060
+ this.runnerContexts.delete(task.agentId);
11012
11061
  this.clearTaskTimer(task.agentId);
11013
11062
  this.controllers.delete(task.agentId);
11014
11063
  if (!isTerminalTaskStatus(task.status)) {
@@ -11084,6 +11133,7 @@ var AgentRuntime = class {
11084
11133
  controller?.abort(new Error(reason));
11085
11134
  await this.cascadeCancelChildren(agentId, reason);
11086
11135
  const inFlight = this.runningPromises.get(agentId);
11136
+ if (!inFlight) this.runnerContexts.delete(agentId);
11087
11137
  if (inFlight) {
11088
11138
  const GRACE_PERIOD_MS = 5e3;
11089
11139
  let timer;
@@ -11192,6 +11242,7 @@ var AgentRuntime = class {
11192
11242
  }
11193
11243
  this.timers.clear();
11194
11244
  this.controllers.clear();
11245
+ this.runnerContexts.clear();
11195
11246
  this.stateListeners.clear();
11196
11247
  }
11197
11248
  /**
@@ -11332,9 +11383,15 @@ function createSpawnAgentTool(runtime) {
11332
11383
  required: ["description", "prompt", "role"]
11333
11384
  },
11334
11385
  async execute(input, ctx) {
11386
+ if (!ctx.leaseCoordinator)
11387
+ throw new KapibalaError("Missing parent lease coordinator", {
11388
+ code: "CONFIG_INVALID",
11389
+ safeMessage: "\u7F3A\u5C11\u7236\u4F1A\u8BDD\u5199\u79DF\u7EA6\u534F\u8C03\u5668"
11390
+ });
11335
11391
  const workspaceRoot = ctx.workspaceRoot ?? ctx.rootDir;
11336
11392
  const executionCwd = ctx.executionCwd ?? workspaceRoot;
11337
11393
  const spawnContext = {
11394
+ leaseCoordinator: ctx.leaseCoordinator,
11338
11395
  rootTaskId: ctx.rootTaskId,
11339
11396
  sessionId: ctx.sessionId ?? "session-default",
11340
11397
  branchId: ctx.branchId ?? "main",
@@ -11697,7 +11754,7 @@ var AgentSession = class {
11697
11754
  this.cwd = resolvedWorkspace.executionCwd;
11698
11755
  this.projectKey = resolvedWorkspace.projectKey;
11699
11756
  this.sandbox = config.sandbox ?? new PathSandbox({ workspaceRoot: this.workspaceRoot });
11700
- this.leaseCoordinator = config.leaseCoordinator ?? sharedWorkspaceLeaseCoordinator;
11757
+ this.leaseCoordinator = config.leaseCoordinator ?? new WorkspaceLeaseCoordinator();
11701
11758
  this.tools = new ToolRegistry();
11702
11759
  if (config.skills) {
11703
11760
  this.skillRegistry = new SkillRegistry(config.skills);
@@ -13025,6 +13082,7 @@ export {
13025
13082
  createLogId,
13026
13083
  createMessageId,
13027
13084
  createRunCommandTool,
13085
+ createSessionError,
13028
13086
  createSpawnAgentTool,
13029
13087
  createWaitAgentTool,
13030
13088
  defineTool,
@@ -13080,7 +13138,6 @@ export {
13080
13138
  sanitizeModelErrorMessage,
13081
13139
  sanitizeSessionTitle,
13082
13140
  scanSkillRoot,
13083
- sharedWorkspaceLeaseCoordinator,
13084
13141
  skillDigest,
13085
13142
  skillFailure,
13086
13143
  skillPathKey,