psadk 1.4.7 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/README.md +153 -0
  2. package/build/main/index.d.ts +1 -0
  3. package/build/main/lib/PSAI.js +1 -2
  4. package/build/main/lib/PSAgent.d.ts +50 -13
  5. package/build/main/lib/PSAgent.js +179 -502
  6. package/build/main/lib/PSAgentConfig.d.ts +114 -2
  7. package/build/main/lib/PSAgentLogger.js +1 -2
  8. package/build/main/lib/PSAgentTool.d.ts +8 -3
  9. package/build/main/lib/PSAgentTool.js +3 -3
  10. package/build/main/lib/agent-core/package.json +1 -1
  11. package/build/main/lib/agent-core/{agent-loop.d.ts → src/agent-loop.d.ts} +1 -1
  12. package/build/main/lib/agent-core/src/agent-loop.js +514 -0
  13. package/build/{module/lib/agent-core → main/lib/agent-core/src}/agent.d.ts +2 -2
  14. package/build/main/lib/agent-core/src/agent.js +419 -0
  15. package/build/main/lib/agent-core/{harness → src/harness}/agent-harness.d.ts +36 -26
  16. package/build/main/lib/agent-core/src/harness/agent-harness.js +1028 -0
  17. package/build/main/lib/agent-core/src/harness/compaction/branch-summarization.d.ts +52 -0
  18. package/build/main/lib/agent-core/src/harness/compaction/branch-summarization.js +182 -0
  19. package/build/main/lib/agent-core/src/harness/compaction/compaction.d.ts +94 -0
  20. package/build/main/lib/agent-core/src/harness/compaction/compaction.js +550 -0
  21. package/build/main/lib/agent-core/src/harness/compaction/utils.d.ts +24 -0
  22. package/build/main/lib/agent-core/src/harness/compaction/utils.js +131 -0
  23. package/build/main/lib/agent-core/src/harness/env/nodejs.d.ts +50 -0
  24. package/build/main/lib/agent-core/src/harness/env/nodejs.js +494 -0
  25. package/build/main/lib/agent-core/{harness → src/harness}/messages.d.ts +2 -2
  26. package/build/{module/lib/agent-core → main/lib/agent-core/src}/harness/messages.js +1 -1
  27. package/build/main/lib/agent-core/{harness → src/harness}/prompt-templates.d.ts +4 -1
  28. package/build/main/lib/agent-core/src/harness/prompt-templates.js +235 -0
  29. package/build/{module/lib/agent-core/harness/session/repo/jsonl.d.ts → main/lib/agent-core/src/harness/session/jsonl-repo.d.ts} +7 -1
  30. package/build/main/lib/agent-core/src/harness/session/jsonl-repo.js +106 -0
  31. package/build/{module/lib/agent-core/harness/session/storage/jsonl.d.ts → main/lib/agent-core/src/harness/session/jsonl-storage.d.ts} +7 -4
  32. package/build/main/lib/agent-core/src/harness/session/jsonl-storage.js +234 -0
  33. package/build/main/lib/agent-core/{harness/session/repo/memory.d.ts → src/harness/session/memory-repo.d.ts} +1 -1
  34. package/build/main/lib/agent-core/src/harness/session/memory-repo.js +45 -0
  35. package/build/main/lib/agent-core/{harness/session/storage/memory.d.ts → src/harness/session/memory-storage.d.ts} +4 -5
  36. package/build/main/lib/agent-core/src/harness/session/memory-storage.js +116 -0
  37. package/build/main/lib/agent-core/{harness/session/repo/shared.d.ts → src/harness/session/repo-utils.d.ts} +3 -2
  38. package/build/main/lib/agent-core/src/harness/session/repo-utils.js +39 -0
  39. package/build/{module/lib/agent-core → main/lib/agent-core/src}/harness/session/session.d.ts +3 -2
  40. package/build/main/lib/agent-core/src/harness/session/session.js +213 -0
  41. package/build/main/lib/agent-core/src/harness/session/uuid.d.ts +1 -0
  42. package/build/main/lib/agent-core/src/harness/session/uuid.js +54 -0
  43. package/build/main/lib/agent-core/{harness → src/harness}/skills.d.ts +4 -1
  44. package/build/main/lib/agent-core/src/harness/skills.js +353 -0
  45. package/build/main/lib/agent-core/{harness → src/harness}/system-prompt.d.ts +1 -1
  46. package/build/main/lib/agent-core/src/harness/system-prompt.js +30 -0
  47. package/build/{module/lib/agent-core → main/lib/agent-core/src}/harness/types.d.ts +160 -70
  48. package/build/main/lib/agent-core/src/harness/types.js +94 -0
  49. package/build/main/lib/agent-core/{harness → src/harness}/utils/shell-output.d.ts +2 -2
  50. package/build/main/lib/agent-core/src/harness/utils/shell-output.js +134 -0
  51. package/build/main/lib/agent-core/src/harness/utils/truncate.js +294 -0
  52. package/build/main/lib/agent-core/src/index.d.ts +19 -0
  53. package/build/main/lib/agent-core/src/index.js +25 -0
  54. package/build/main/lib/agent-core/src/node.d.ts +2 -0
  55. package/build/main/lib/agent-core/src/node.js +3 -0
  56. package/build/main/lib/agent-core/{proxy.js → src/proxy.js} +3 -2
  57. package/build/{module/lib/agent-core → main/lib/agent-core/src}/types.d.ts +13 -1
  58. package/build/{module/lib/agent-core → main/lib/agent-core/src}/types.js +1 -1
  59. package/build/main/lib/localAgent.d.ts +35 -0
  60. package/build/main/lib/localAgent.js +329 -0
  61. package/build/main/lib/remoteAgent.d.ts +25 -0
  62. package/build/main/lib/remoteAgent.js +311 -0
  63. package/build/main/lib/tools/BraveWebSearchTool.js +1 -2
  64. package/build/main/lib/tools/PSArtifactTool.js +1 -2
  65. package/build/main/lib/tools/PSClarifyTool.js +1 -2
  66. package/build/main/lib/tools/PSCommandLineTool.js +1 -2
  67. package/build/main/lib/tools/PSMemoryTool.js +1 -2
  68. package/build/main/lib/tools/PSReadFileTool.js +1 -2
  69. package/build/main/lib/tools/PSRetrievalTool.js +1 -2
  70. package/build/main/lib/tools/PSSkillTool.js +1 -2
  71. package/build/main/lib/tools/PSSubAgentTool.js +1 -1
  72. package/build/main/lib/tools/PSWriteFileTool.js +1 -2
  73. package/build/main/lib/tools/TodoTool.js +1 -2
  74. package/build/main/lib/utils/debuglogger.js +1 -2
  75. package/build/main/lib/utils/helpers.js +1 -6
  76. package/build/module/index.d.ts +1 -0
  77. package/build/module/lib/PSAI.js +1 -2
  78. package/build/module/lib/PSAgent.d.ts +50 -13
  79. package/build/module/lib/PSAgent.js +179 -502
  80. package/build/module/lib/PSAgentConfig.d.ts +114 -2
  81. package/build/module/lib/PSAgentLogger.js +1 -2
  82. package/build/module/lib/PSAgentTool.d.ts +8 -3
  83. package/build/module/lib/PSAgentTool.js +3 -3
  84. package/build/module/lib/agent-core/{agent-loop.d.ts → src/agent-loop.d.ts} +1 -1
  85. package/build/module/lib/agent-core/src/agent-loop.js +514 -0
  86. package/build/{main/lib/agent-core → module/lib/agent-core/src}/agent.d.ts +2 -2
  87. package/build/module/lib/agent-core/src/agent.js +419 -0
  88. package/build/module/lib/agent-core/{harness → src/harness}/agent-harness.d.ts +36 -26
  89. package/build/module/lib/agent-core/src/harness/agent-harness.js +1028 -0
  90. package/build/module/lib/agent-core/src/harness/compaction/branch-summarization.d.ts +52 -0
  91. package/build/module/lib/agent-core/src/harness/compaction/branch-summarization.js +182 -0
  92. package/build/module/lib/agent-core/src/harness/compaction/compaction.d.ts +94 -0
  93. package/build/module/lib/agent-core/src/harness/compaction/compaction.js +550 -0
  94. package/build/module/lib/agent-core/src/harness/compaction/utils.d.ts +24 -0
  95. package/build/module/lib/agent-core/src/harness/compaction/utils.js +131 -0
  96. package/build/module/lib/agent-core/src/harness/env/nodejs.d.ts +50 -0
  97. package/build/module/lib/agent-core/src/harness/env/nodejs.js +494 -0
  98. package/build/module/lib/agent-core/{harness → src/harness}/messages.d.ts +2 -2
  99. package/build/{main/lib/agent-core → module/lib/agent-core/src}/harness/messages.js +1 -1
  100. package/build/module/lib/agent-core/{harness → src/harness}/prompt-templates.d.ts +4 -1
  101. package/build/module/lib/agent-core/src/harness/prompt-templates.js +235 -0
  102. package/build/{main/lib/agent-core/harness/session/repo/jsonl.d.ts → module/lib/agent-core/src/harness/session/jsonl-repo.d.ts} +7 -1
  103. package/build/module/lib/agent-core/src/harness/session/jsonl-repo.js +106 -0
  104. package/build/{main/lib/agent-core/harness/session/storage/jsonl.d.ts → module/lib/agent-core/src/harness/session/jsonl-storage.d.ts} +7 -4
  105. package/build/module/lib/agent-core/src/harness/session/jsonl-storage.js +234 -0
  106. package/build/module/lib/agent-core/{harness/session/repo/memory.d.ts → src/harness/session/memory-repo.d.ts} +1 -1
  107. package/build/module/lib/agent-core/src/harness/session/memory-repo.js +45 -0
  108. package/build/module/lib/agent-core/{harness/session/storage/memory.d.ts → src/harness/session/memory-storage.d.ts} +4 -5
  109. package/build/module/lib/agent-core/src/harness/session/memory-storage.js +116 -0
  110. package/build/module/lib/agent-core/{harness/session/repo/shared.d.ts → src/harness/session/repo-utils.d.ts} +3 -2
  111. package/build/module/lib/agent-core/src/harness/session/repo-utils.js +39 -0
  112. package/build/{main/lib/agent-core → module/lib/agent-core/src}/harness/session/session.d.ts +3 -2
  113. package/build/module/lib/agent-core/src/harness/session/session.js +213 -0
  114. package/build/module/lib/agent-core/src/harness/session/uuid.d.ts +1 -0
  115. package/build/module/lib/agent-core/src/harness/session/uuid.js +54 -0
  116. package/build/module/lib/agent-core/{harness → src/harness}/skills.d.ts +4 -1
  117. package/build/module/lib/agent-core/src/harness/skills.js +353 -0
  118. package/build/module/lib/agent-core/{harness → src/harness}/system-prompt.d.ts +1 -1
  119. package/build/module/lib/agent-core/src/harness/system-prompt.js +30 -0
  120. package/build/{main/lib/agent-core → module/lib/agent-core/src}/harness/types.d.ts +160 -70
  121. package/build/module/lib/agent-core/src/harness/types.js +94 -0
  122. package/build/module/lib/agent-core/{harness → src/harness}/utils/shell-output.d.ts +2 -2
  123. package/build/module/lib/agent-core/src/harness/utils/shell-output.js +134 -0
  124. package/build/module/lib/agent-core/src/harness/utils/truncate.js +294 -0
  125. package/build/module/lib/agent-core/src/index.d.ts +19 -0
  126. package/build/module/lib/agent-core/src/index.js +25 -0
  127. package/build/module/lib/agent-core/src/node.d.ts +2 -0
  128. package/build/module/lib/agent-core/src/node.js +3 -0
  129. package/build/module/lib/agent-core/{proxy.js → src/proxy.js} +3 -2
  130. package/build/{main/lib/agent-core → module/lib/agent-core/src}/types.d.ts +13 -1
  131. package/build/{main/lib/agent-core → module/lib/agent-core/src}/types.js +1 -1
  132. package/build/module/lib/localAgent.d.ts +35 -0
  133. package/build/module/lib/localAgent.js +329 -0
  134. package/build/module/lib/remoteAgent.d.ts +25 -0
  135. package/build/module/lib/remoteAgent.js +311 -0
  136. package/build/module/lib/tools/BraveWebSearchTool.js +1 -2
  137. package/build/module/lib/tools/PSArtifactTool.js +1 -2
  138. package/build/module/lib/tools/PSClarifyTool.js +1 -2
  139. package/build/module/lib/tools/PSCommandLineTool.js +1 -2
  140. package/build/module/lib/tools/PSMemoryTool.js +1 -2
  141. package/build/module/lib/tools/PSReadFileTool.js +1 -2
  142. package/build/module/lib/tools/PSRetrievalTool.js +1 -2
  143. package/build/module/lib/tools/PSSkillTool.js +1 -2
  144. package/build/module/lib/tools/PSSubAgentTool.js +1 -1
  145. package/build/module/lib/tools/PSWriteFileTool.js +1 -2
  146. package/build/module/lib/tools/TodoTool.js +1 -2
  147. package/build/module/lib/utils/debuglogger.js +1 -2
  148. package/build/module/lib/utils/helpers.js +1 -6
  149. package/package.json +3 -2
  150. package/build/main/lib/agent-core/agent-loop.js +0 -483
  151. package/build/main/lib/agent-core/agent.js +0 -419
  152. package/build/main/lib/agent-core/harness/agent-harness.js +0 -772
  153. package/build/main/lib/agent-core/harness/compaction/branch-summarization.d.ts +0 -87
  154. package/build/main/lib/agent-core/harness/compaction/branch-summarization.js +0 -246
  155. package/build/main/lib/agent-core/harness/compaction/compaction.d.ts +0 -121
  156. package/build/main/lib/agent-core/harness/compaction/compaction.js +0 -637
  157. package/build/main/lib/agent-core/harness/compaction/utils.d.ts +0 -37
  158. package/build/main/lib/agent-core/harness/compaction/utils.js +0 -153
  159. package/build/main/lib/agent-core/harness/env/nodejs.d.ts +0 -43
  160. package/build/main/lib/agent-core/harness/env/nodejs.js +0 -353
  161. package/build/main/lib/agent-core/harness/execution-env.d.ts +0 -3
  162. package/build/main/lib/agent-core/harness/execution-env.js +0 -3
  163. package/build/main/lib/agent-core/harness/prompt-templates.js +0 -204
  164. package/build/main/lib/agent-core/harness/session/repo/jsonl.js +0 -98
  165. package/build/main/lib/agent-core/harness/session/repo/memory.js +0 -46
  166. package/build/main/lib/agent-core/harness/session/repo/shared.js +0 -31
  167. package/build/main/lib/agent-core/harness/session/session.js +0 -199
  168. package/build/main/lib/agent-core/harness/session/storage/jsonl.js +0 -170
  169. package/build/main/lib/agent-core/harness/session/storage/memory.js +0 -94
  170. package/build/main/lib/agent-core/harness/skills.js +0 -266
  171. package/build/main/lib/agent-core/harness/system-prompt.js +0 -30
  172. package/build/main/lib/agent-core/harness/types.js +0 -16
  173. package/build/main/lib/agent-core/harness/utils/shell-output.js +0 -101
  174. package/build/main/lib/agent-core/harness/utils/truncate.js +0 -208
  175. package/build/main/lib/agent-core/index.d.ts +0 -19
  176. package/build/main/lib/agent-core/index.js +0 -25
  177. package/build/module/lib/agent-core/agent-loop.js +0 -483
  178. package/build/module/lib/agent-core/agent.js +0 -419
  179. package/build/module/lib/agent-core/harness/agent-harness.js +0 -772
  180. package/build/module/lib/agent-core/harness/compaction/branch-summarization.d.ts +0 -87
  181. package/build/module/lib/agent-core/harness/compaction/branch-summarization.js +0 -246
  182. package/build/module/lib/agent-core/harness/compaction/compaction.d.ts +0 -121
  183. package/build/module/lib/agent-core/harness/compaction/compaction.js +0 -637
  184. package/build/module/lib/agent-core/harness/compaction/utils.d.ts +0 -37
  185. package/build/module/lib/agent-core/harness/compaction/utils.js +0 -153
  186. package/build/module/lib/agent-core/harness/env/nodejs.d.ts +0 -43
  187. package/build/module/lib/agent-core/harness/env/nodejs.js +0 -353
  188. package/build/module/lib/agent-core/harness/execution-env.d.ts +0 -3
  189. package/build/module/lib/agent-core/harness/execution-env.js +0 -3
  190. package/build/module/lib/agent-core/harness/prompt-templates.js +0 -204
  191. package/build/module/lib/agent-core/harness/session/repo/jsonl.js +0 -98
  192. package/build/module/lib/agent-core/harness/session/repo/memory.js +0 -46
  193. package/build/module/lib/agent-core/harness/session/repo/shared.js +0 -31
  194. package/build/module/lib/agent-core/harness/session/session.js +0 -199
  195. package/build/module/lib/agent-core/harness/session/storage/jsonl.js +0 -170
  196. package/build/module/lib/agent-core/harness/session/storage/memory.js +0 -94
  197. package/build/module/lib/agent-core/harness/skills.js +0 -266
  198. package/build/module/lib/agent-core/harness/system-prompt.js +0 -30
  199. package/build/module/lib/agent-core/harness/types.js +0 -16
  200. package/build/module/lib/agent-core/harness/utils/shell-output.js +0 -101
  201. package/build/module/lib/agent-core/harness/utils/truncate.js +0 -208
  202. package/build/module/lib/agent-core/index.d.ts +0 -19
  203. package/build/module/lib/agent-core/index.js +0 -25
  204. /package/build/main/lib/agent-core/{harness → src/harness}/utils/truncate.d.ts +0 -0
  205. /package/build/main/lib/agent-core/{proxy.d.ts → src/proxy.d.ts} +0 -0
  206. /package/build/module/lib/agent-core/{harness → src/harness}/utils/truncate.d.ts +0 -0
  207. /package/build/module/lib/agent-core/{proxy.d.ts → src/proxy.d.ts} +0 -0
@@ -1,7 +1,24 @@
1
1
  import type { ImageContent, Model, SimpleStreamOptions, TextContent, Transport } from '@earendil-works/pi-ai';
2
- import type { QueueMode } from '../agent.js';
3
- import type { AgentEvent, AgentMessage, AgentTool, ThinkingLevel } from '../index.js';
4
- import type { Session } from './session/session.js';
2
+ import type { AgentEvent, AgentMessage, AgentTool, QueueMode, ThinkingLevel } from '../index.ts';
3
+ import type { Session } from './session/session.ts';
4
+ /** Result of a fallible operation. Expected failures are returned as `ok: false` instead of thrown. */
5
+ export type Result<TValue, TError> = {
6
+ ok: true;
7
+ value: TValue;
8
+ } | {
9
+ ok: false;
10
+ error: TError;
11
+ };
12
+ /** Create a successful {@link Result}. */
13
+ export declare function ok<TValue, TError>(value: TValue): Result<TValue, TError>;
14
+ /** Create a failed {@link Result}. */
15
+ export declare function err<TValue, TError>(error: TError): Result<TValue, TError>;
16
+ /** Return the success value or throw the failure error. Intended for tests and explicit adapter boundaries. */
17
+ export declare function getOrThrow<TValue, TError>(result: Result<TValue, TError>): TValue;
18
+ /** Return the success value or `undefined`. Only object values are allowed to avoid truthiness bugs with primitives. */
19
+ export declare function getOrUndefined<TValue extends object, TError>(result: Result<TValue, TError>): TValue | undefined;
20
+ /** Normalize unknown thrown values into Error instances before using them as typed error causes. */
21
+ export declare function toError(error: unknown): Error;
5
22
  /**
6
23
  * Skill loaded from a `SKILL.md` file or provided by an application.
7
24
  *
@@ -60,100 +77,156 @@ export interface AgentHarnessStreamOptionsPatch extends Omit<Partial<AgentHarnes
60
77
  /** Metadata patch. `undefined` values delete keys; explicit `metadata: undefined` clears all metadata. */
61
78
  metadata?: Record<string, unknown | undefined>;
62
79
  }
63
- /** Kind of filesystem object as addressed by an {@link ExecutionEnv}. Symlinks are not followed automatically. */
80
+ /** Kind of filesystem object as addressed by a {@link FileSystem}. Symlinks are not followed automatically. */
64
81
  export type FileKind = 'file' | 'directory' | 'symlink';
65
- /** Stable, backend-independent file error codes thrown by {@link ExecutionEnv} file operations. */
66
- export type FileErrorCode = 'not_found' | 'permission_denied' | 'not_directory' | 'is_directory' | 'invalid' | 'not_supported' | 'unknown';
67
- /** Error thrown by {@link ExecutionEnv} file operations. */
82
+ /** Stable, backend-independent file error codes returned by {@link FileSystem} file operations. */
83
+ export type FileErrorCode = 'aborted' | 'not_found' | 'permission_denied' | 'not_directory' | 'is_directory' | 'invalid' | 'not_supported' | 'unknown';
84
+ /** Error returned by {@link FileSystem} file operations. */
68
85
  export declare class FileError extends Error {
69
86
  /** Backend-independent error code. */
70
87
  code: FileErrorCode;
71
88
  /** Absolute addressed path associated with the failure, when available. */
72
- path?: string | undefined;
73
- constructor(
89
+ path?: string;
90
+ constructor(code: FileErrorCode, message: string, path?: string, cause?: Error);
91
+ }
92
+ /** Stable, backend-independent execution error codes returned by {@link ExecutionEnv.exec}. */
93
+ export type ExecutionErrorCode = 'aborted' | 'timeout' | 'shell_unavailable' | 'spawn_error' | 'callback_error' | 'unknown';
94
+ /** Error returned by {@link ExecutionEnv.exec}. */
95
+ export declare class ExecutionError extends Error {
74
96
  /** Backend-independent error code. */
75
- code: FileErrorCode, message: string,
76
- /** Absolute addressed path associated with the failure, when available. */
77
- path?: string | undefined, options?: ErrorOptions);
97
+ code: ExecutionErrorCode;
98
+ constructor(code: ExecutionErrorCode, message: string, cause?: Error);
99
+ }
100
+ /** Stable compaction error codes returned by compaction helpers. */
101
+ export type CompactionErrorCode = 'aborted' | 'summarization_failed' | 'invalid_session' | 'unknown';
102
+ /** Error returned by compaction helpers. */
103
+ export declare class CompactionError extends Error {
104
+ /** Backend-independent error code. */
105
+ code: CompactionErrorCode;
106
+ constructor(code: CompactionErrorCode, message: string, cause?: Error);
78
107
  }
79
- /** Metadata for one filesystem object in an {@link ExecutionEnv}. */
108
+ /** Stable branch-summary error codes returned by branch summarization helpers. */
109
+ export type BranchSummaryErrorCode = 'aborted' | 'summarization_failed' | 'invalid_session';
110
+ /** Error returned by branch summarization helpers. */
111
+ export declare class BranchSummaryError extends Error {
112
+ /** Backend-independent error code. */
113
+ code: BranchSummaryErrorCode;
114
+ constructor(code: BranchSummaryErrorCode, message: string, cause?: Error);
115
+ }
116
+ export type SessionErrorCode = 'not_found' | 'invalid_session' | 'invalid_entry' | 'invalid_fork_target' | 'storage' | 'unknown';
117
+ /** Error thrown by session storage, repositories, and session tree operations. */
118
+ export declare class SessionError extends Error {
119
+ /** Session subsystem error code. */
120
+ code: SessionErrorCode;
121
+ constructor(code: SessionErrorCode, message: string, cause?: Error);
122
+ }
123
+ export type AgentHarnessErrorCode = 'busy' | 'invalid_state' | 'invalid_argument' | 'session' | 'hook' | 'auth' | 'compaction' | 'branch_summary' | 'unknown';
124
+ /** Public AgentHarness failure with a stable top-level classification. */
125
+ export declare class AgentHarnessError extends Error {
126
+ code: AgentHarnessErrorCode;
127
+ constructor(code: AgentHarnessErrorCode, message: string, cause?: Error);
128
+ }
129
+ /** Metadata for one filesystem object in a {@link FileSystem}. */
80
130
  export interface FileInfo {
81
131
  /** Basename of {@link path}. */
82
132
  name: string;
83
133
  /** Absolute, syntactically normalized addressed path in the execution environment. Symlinks are not followed. */
84
134
  path: string;
85
- /** Object kind. Symlink targets are not followed; use {@link ExecutionEnv.resolvePath} explicitly. */
135
+ /** Object kind. Symlink targets are not followed; use {@link FileSystem.canonicalPath} explicitly. */
86
136
  kind: FileKind;
87
137
  /** Size in bytes for the addressed filesystem object. */
88
138
  size: number;
89
139
  /** Modification time as milliseconds since Unix epoch. */
90
140
  mtimeMs: number;
91
141
  }
92
- /** Options for {@link ExecutionEnv.exec}. */
142
+ /** Options for {@link Shell.exec}. */
93
143
  export interface ExecutionEnvExecOptions {
94
- /** Working directory for the command. Relative paths are resolved against {@link ExecutionEnv.cwd}. */
144
+ /** Working directory for the command. Relative paths are resolved against {@link ExecutionEnv.cwd}. Defaults to {@link ExecutionEnv.cwd}. */
95
145
  cwd?: string;
96
- /** Additional environment variables for the command. Values override the environment defaults. */
146
+ /** Additional environment variables for the command. Values override the environment defaults. Defaults to no overrides. */
97
147
  env?: Record<string, string>;
98
- /** Timeout in seconds. Implementations should reject when the command exceeds this duration. */
148
+ /** Timeout in seconds. Implementations should return a timeout error when the command exceeds this duration. Defaults to no timeout. */
99
149
  timeout?: number;
100
- /** Abort signal used to terminate the command. */
101
- signal?: AbortSignal;
150
+ /** Abort signal used to terminate the command. Defaults to no abort signal. */
151
+ abortSignal?: AbortSignal;
102
152
  /** Called with stdout chunks as they are produced. */
103
153
  onStdout?: (chunk: string) => void;
104
154
  /** Called with stderr chunks as they are produced. */
105
155
  onStderr?: (chunk: string) => void;
106
156
  }
107
157
  /**
108
- * Filesystem and process execution environment used by the harness.
158
+ * Filesystem capability used by the harness.
109
159
  *
110
- * Paths passed to methods may be absolute or relative to {@link cwd}. Paths returned by this interface are absolute
111
- * addressed paths in the environment, but are not canonicalized through symlinks unless returned by {@link resolvePath}.
160
+ * Paths passed to methods may be absolute or relative to {@link cwd}. Paths returned by file operations are addressed paths
161
+ * in the filesystem namespace, but are not canonicalized through symlinks unless returned by {@link canonicalPath}.
112
162
  *
113
- * File operations throw {@link FileError} for expected filesystem failures such as missing paths or permission errors.
163
+ * Operation methods must never throw or reject. All filesystem failures, including unexpected backend failures, must be
164
+ * encoded in the returned {@link Result}. Implementations must preserve this invariant.
114
165
  */
115
- export interface ExecutionEnv {
116
- /** Current working directory for relative paths and command execution. */
166
+ export interface FileSystem {
167
+ /** Current working directory for relative paths. */
117
168
  cwd: string;
118
- /** Execute a shell command in {@link cwd} unless `options.cwd` is provided. */
119
- exec(command: string, options?: ExecutionEnvExecOptions): Promise<{
120
- stdout: string;
121
- stderr: string;
122
- exitCode: number;
123
- }>;
124
- /** Read a UTF-8 text file. Throws {@link FileError}. */
125
- readTextFile(path: string): Promise<string>;
126
- /** Read a binary file. Throws {@link FileError}. */
127
- readBinaryFile(path: string): Promise<Uint8Array>;
128
- /** Create or overwrite a file, creating parent directories when supported. Throws {@link FileError}. */
129
- writeFile(path: string, content: string | Uint8Array): Promise<void>;
130
- /** Return metadata for the addressed path without following symlinks. Throws {@link FileError}. */
131
- fileInfo(path: string): Promise<FileInfo>;
132
- /** List direct children of a directory without following symlinks. Throws {@link FileError}. */
133
- listDir(path: string): Promise<FileInfo[]>;
134
- /** Return the canonical path for a path, following symlinks. Throws {@link FileError}. */
135
- realPath(path: string): Promise<string>;
136
- /** Return false for missing paths. Other errors, such as permission failures, may throw {@link FileError}. */
137
- exists(path: string): Promise<boolean>;
138
- /** Create a directory. */
169
+ /** Return an absolute addressed path without requiring it to exist and without resolving symlinks. */
170
+ absolutePath(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
171
+ /** Join path segments in the filesystem namespace without requiring the result to exist. */
172
+ joinPath(parts: string[], abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
173
+ /** Read a UTF-8 text file. */
174
+ readTextFile(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
175
+ /** Read UTF-8 text lines. Implementations should stop once `maxLines` lines have been read. */
176
+ readTextLines(path: string, options?: {
177
+ maxLines?: number;
178
+ abortSignal?: AbortSignal;
179
+ }): Promise<Result<string[], FileError>>;
180
+ /** Read a binary file. */
181
+ readBinaryFile(path: string, abortSignal?: AbortSignal): Promise<Result<Uint8Array, FileError>>;
182
+ /** Create or overwrite a file, creating parent directories when supported. */
183
+ writeFile(path: string, content: string | Uint8Array, abortSignal?: AbortSignal): Promise<Result<void, FileError>>;
184
+ /** Create or append to a file, creating parent directories when supported. */
185
+ appendFile(path: string, content: string | Uint8Array, abortSignal?: AbortSignal): Promise<Result<void, FileError>>;
186
+ /** Return metadata for the addressed path without following symlinks. */
187
+ fileInfo(path: string, abortSignal?: AbortSignal): Promise<Result<FileInfo, FileError>>;
188
+ /** List direct children of a directory without following symlinks. */
189
+ listDir(path: string, abortSignal?: AbortSignal): Promise<Result<FileInfo[], FileError>>;
190
+ /** Return the canonical path for an existing path, resolving symlinks where supported. */
191
+ canonicalPath(path: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
192
+ /** Return false for missing paths. Other errors, such as permission failures, return a {@link FileError}. */
193
+ exists(path: string, abortSignal?: AbortSignal): Promise<Result<boolean, FileError>>;
194
+ /** Create a directory. Defaults: `recursive: true`, no abort signal. */
139
195
  createDir(path: string, options?: {
140
196
  recursive?: boolean;
141
- }): Promise<void>;
142
- /** Remove a file or directory. */
197
+ abortSignal?: AbortSignal;
198
+ }): Promise<Result<void, FileError>>;
199
+ /** Remove a file or directory. Defaults: `recursive: false`, `force: false`, no abort signal. */
143
200
  remove(path: string, options?: {
144
201
  recursive?: boolean;
145
202
  force?: boolean;
146
- }): Promise<void>;
147
- /** Create a temporary directory and return its absolute path. */
148
- createTempDir(prefix?: string): Promise<string>;
149
- /** Create a temporary file and return its absolute path. */
203
+ abortSignal?: AbortSignal;
204
+ }): Promise<Result<void, FileError>>;
205
+ /** Create a temporary directory and return its absolute path. Defaults: `prefix: "tmp-"`, no abort signal. */
206
+ createTempDir(prefix?: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
207
+ /** Create a temporary file and return its absolute path. Defaults: `prefix: ""`, `suffix: ""`, no abort signal. */
150
208
  createTempFile(options?: {
151
209
  prefix?: string;
152
210
  suffix?: string;
153
- }): Promise<string>;
154
- /** Release resources owned by the environment. */
211
+ abortSignal?: AbortSignal;
212
+ }): Promise<Result<string, FileError>>;
213
+ /** Release filesystem resources. Must be best-effort and must not throw or reject. */
214
+ cleanup(): Promise<void>;
215
+ }
216
+ /** Shell execution capability used by the harness. */
217
+ export interface Shell {
218
+ /** Execute a shell command in {@link FileSystem.cwd} unless `options.cwd` is provided. */
219
+ exec(command: string, options?: ExecutionEnvExecOptions): Promise<Result<{
220
+ stdout: string;
221
+ stderr: string;
222
+ exitCode: number;
223
+ }, ExecutionError>>;
224
+ /** Release shell resources. Must be best-effort and must not throw or reject. */
155
225
  cleanup(): Promise<void>;
156
226
  }
227
+ /** Filesystem and process execution environment used by the harness. */
228
+ export interface ExecutionEnv extends FileSystem, Shell {
229
+ }
157
230
  export interface SessionTreeEntryBase {
158
231
  type: string;
159
232
  id: string;
@@ -173,6 +246,10 @@ export interface ModelChangeEntry extends SessionTreeEntryBase {
173
246
  provider: string;
174
247
  modelId: string;
175
248
  }
249
+ export interface ActiveToolsChangeEntry extends SessionTreeEntryBase {
250
+ type: 'active_tools_change';
251
+ activeToolNames: string[];
252
+ }
176
253
  export interface CompactionEntry<T = unknown> extends SessionTreeEntryBase {
177
254
  type: 'compaction';
178
255
  summary: string;
@@ -209,7 +286,11 @@ export interface SessionInfoEntry extends SessionTreeEntryBase {
209
286
  type: 'session_info';
210
287
  name?: string;
211
288
  }
212
- export type SessionTreeEntry = MessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | SessionInfoEntry;
289
+ export interface LeafEntry extends SessionTreeEntryBase {
290
+ type: 'leaf';
291
+ targetId: string | null;
292
+ }
293
+ export type SessionTreeEntry = MessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ActiveToolsChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | SessionInfoEntry | LeafEntry;
213
294
  export interface SessionContext {
214
295
  messages: AgentMessage[];
215
296
  thinkingLevel: string;
@@ -217,6 +298,7 @@ export interface SessionContext {
217
298
  provider: string;
218
299
  modelId: string;
219
300
  } | null;
301
+ activeToolNames: string[] | null;
220
302
  }
221
303
  export interface SessionMetadata {
222
304
  id: string;
@@ -230,6 +312,7 @@ export interface JsonlSessionMetadata extends SessionMetadata {
230
312
  export interface SessionStorage<TMetadata extends SessionMetadata = SessionMetadata> {
231
313
  getMetadata(): Promise<TMetadata>;
232
314
  getLeafId(): Promise<string | null>;
315
+ /** Persist a leaf entry that records the active session-tree leaf. */
233
316
  setLeafId(leafId: string | null): Promise<void>;
234
317
  createEntryId(): Promise<string>;
235
318
  appendEntry(entry: SessionTreeEntry): Promise<void>;
@@ -241,7 +324,7 @@ export interface SessionStorage<TMetadata extends SessionMetadata = SessionMetad
241
324
  getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]>;
242
325
  getEntries(): Promise<SessionTreeEntry[]>;
243
326
  }
244
- export type { Session } from './session/session.js';
327
+ export type { Session } from './session/session.ts';
245
328
  export interface SessionCreateOptions {
246
329
  id?: string;
247
330
  }
@@ -353,23 +436,31 @@ export interface SessionTreeEvent {
353
436
  summaryEntry?: BranchSummaryEntry;
354
437
  fromHook?: boolean;
355
438
  }
356
- export interface ModelSelectEvent {
357
- type: 'model_select';
439
+ export interface ModelUpdateEvent {
440
+ type: 'model_update';
358
441
  model: Model<any>;
359
442
  previousModel: Model<any> | undefined;
360
443
  source: 'set' | 'restore';
361
444
  }
362
- export interface ThinkingLevelSelectEvent {
363
- type: 'thinking_level_select';
445
+ export interface ThinkingLevelUpdateEvent {
446
+ type: 'thinking_level_update';
364
447
  level: ThinkingLevel;
365
448
  previousLevel: ThinkingLevel;
366
449
  }
450
+ export interface ToolsUpdateEvent {
451
+ type: 'tools_update';
452
+ toolNames: string[];
453
+ previousToolNames: string[];
454
+ activeToolNames: string[];
455
+ previousActiveToolNames: string[];
456
+ source: 'set' | 'restore';
457
+ }
367
458
  export interface ResourcesUpdateEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> {
368
459
  type: 'resources_update';
369
460
  resources: AgentHarnessResources<TSkill, TPromptTemplate>;
370
461
  previousResources: AgentHarnessResources<TSkill, TPromptTemplate>;
371
462
  }
372
- export type AgentHarnessOwnEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> = QueueUpdateEvent | SavePointEvent | AbortEvent | SettledEvent | BeforeAgentStartEvent<TSkill, TPromptTemplate> | ContextEvent | BeforeProviderRequestEvent | BeforeProviderPayloadEvent | AfterProviderResponseEvent | ToolCallEvent | ToolResultEvent | SessionBeforeCompactEvent | SessionCompactEvent | SessionBeforeTreeEvent | SessionTreeEvent | ModelSelectEvent | ThinkingLevelSelectEvent | ResourcesUpdateEvent<TSkill, TPromptTemplate>;
463
+ export type AgentHarnessOwnEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> = QueueUpdateEvent | SavePointEvent | AbortEvent | SettledEvent | BeforeAgentStartEvent<TSkill, TPromptTemplate> | ContextEvent | BeforeProviderRequestEvent | BeforeProviderPayloadEvent | AfterProviderResponseEvent | ToolCallEvent | ToolResultEvent | SessionBeforeCompactEvent | SessionCompactEvent | SessionBeforeTreeEvent | SessionTreeEvent | ModelUpdateEvent | ThinkingLevelUpdateEvent | ResourcesUpdateEvent<TSkill, TPromptTemplate> | ToolsUpdateEvent;
373
464
  export type AgentHarnessEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> = AgentEvent | AgentHarnessOwnEvent<TSkill, TPromptTemplate>;
374
465
  export interface BeforeAgentStartResult {
375
466
  messages?: AgentMessage[];
@@ -420,9 +511,10 @@ export type AgentHarnessEventResultMap = {
420
511
  session_compact: undefined;
421
512
  session_before_tree: SessionBeforeTreeResult | undefined;
422
513
  session_tree: undefined;
423
- model_select: undefined;
424
- thinking_level_select: undefined;
514
+ model_update: undefined;
515
+ thinking_level_update: undefined;
425
516
  resources_update: undefined;
517
+ tools_update: undefined;
426
518
  queue_update: undefined;
427
519
  save_point: undefined;
428
520
  abort: undefined;
@@ -486,11 +578,9 @@ export interface GenerateBranchSummaryOptions {
486
578
  reserveTokens?: number;
487
579
  }
488
580
  export interface BranchSummaryResult {
489
- summary?: string;
490
- readFiles?: string[];
491
- modifiedFiles?: string[];
492
- aborted?: boolean;
493
- error?: string;
581
+ summary: string;
582
+ readFiles: string[];
583
+ modifiedFiles: string[];
494
584
  }
495
585
  export interface AgentHarnessOptions<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate, TTool extends AgentTool = AgentTool> {
496
586
  env: ExecutionEnv;
@@ -521,4 +611,4 @@ export interface AgentHarnessOptions<TSkill extends Skill = Skill, TPromptTempla
521
611
  steeringMode?: QueueMode;
522
612
  followUpMode?: QueueMode;
523
613
  }
524
- export type { AgentHarness } from './agent-harness.js';
614
+ export type { AgentHarness } from './agent-harness.ts';
@@ -0,0 +1,94 @@
1
+ /** Create a successful {@link Result}. */
2
+ export function ok(value) {
3
+ return { ok: true, value };
4
+ }
5
+ /** Create a failed {@link Result}. */
6
+ export function err(error) {
7
+ return { ok: false, error };
8
+ }
9
+ /** Return the success value or throw the failure error. Intended for tests and explicit adapter boundaries. */
10
+ export function getOrThrow(result) {
11
+ if (!result.ok)
12
+ throw result.error;
13
+ return result.value;
14
+ }
15
+ /** Return the success value or `undefined`. Only object values are allowed to avoid truthiness bugs with primitives. */
16
+ export function getOrUndefined(result) {
17
+ return result.ok ? result.value : undefined;
18
+ }
19
+ /** Normalize unknown thrown values into Error instances before using them as typed error causes. */
20
+ export function toError(error) {
21
+ if (error instanceof Error)
22
+ return error;
23
+ if (typeof error === 'string')
24
+ return new Error(error);
25
+ try {
26
+ return new Error(JSON.stringify(error));
27
+ }
28
+ catch {
29
+ return new Error(String(error));
30
+ }
31
+ }
32
+ /** Error returned by {@link FileSystem} file operations. */
33
+ export class FileError extends Error {
34
+ /** Backend-independent error code. */
35
+ code;
36
+ /** Absolute addressed path associated with the failure, when available. */
37
+ path;
38
+ constructor(code, message, path, cause) {
39
+ super(message, cause === undefined ? undefined : { cause });
40
+ this.name = 'FileError';
41
+ this.code = code;
42
+ this.path = path;
43
+ }
44
+ }
45
+ /** Error returned by {@link ExecutionEnv.exec}. */
46
+ export class ExecutionError extends Error {
47
+ /** Backend-independent error code. */
48
+ code;
49
+ constructor(code, message, cause) {
50
+ super(message, cause === undefined ? undefined : { cause });
51
+ this.name = 'ExecutionError';
52
+ this.code = code;
53
+ }
54
+ }
55
+ /** Error returned by compaction helpers. */
56
+ export class CompactionError extends Error {
57
+ /** Backend-independent error code. */
58
+ code;
59
+ constructor(code, message, cause) {
60
+ super(message, cause === undefined ? undefined : { cause });
61
+ this.name = 'CompactionError';
62
+ this.code = code;
63
+ }
64
+ }
65
+ /** Error returned by branch summarization helpers. */
66
+ export class BranchSummaryError extends Error {
67
+ /** Backend-independent error code. */
68
+ code;
69
+ constructor(code, message, cause) {
70
+ super(message, cause === undefined ? undefined : { cause });
71
+ this.name = 'BranchSummaryError';
72
+ this.code = code;
73
+ }
74
+ }
75
+ /** Error thrown by session storage, repositories, and session tree operations. */
76
+ export class SessionError extends Error {
77
+ /** Session subsystem error code. */
78
+ code;
79
+ constructor(code, message, cause) {
80
+ super(message, cause === undefined ? undefined : { cause });
81
+ this.name = 'SessionError';
82
+ this.code = code;
83
+ }
84
+ }
85
+ /** Public AgentHarness failure with a stable top-level classification. */
86
+ export class AgentHarnessError extends Error {
87
+ code;
88
+ constructor(code, message, cause) {
89
+ super(message, cause === undefined ? undefined : { cause });
90
+ this.name = 'AgentHarnessError';
91
+ this.code = code;
92
+ }
93
+ }
94
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2FnZW50LWNvcmUvc3JjL2hhcm5lc3MvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBdUJBLDBDQUEwQztBQUMxQyxNQUFNLFVBQVUsRUFBRSxDQUFpQixLQUFhO0lBQzlDLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQzdCLENBQUM7QUFFRCxzQ0FBc0M7QUFDdEMsTUFBTSxVQUFVLEdBQUcsQ0FBaUIsS0FBYTtJQUMvQyxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUM5QixDQUFDO0FBRUQsK0dBQStHO0FBQy9HLE1BQU0sVUFBVSxVQUFVLENBQ3hCLE1BQThCO0lBRTlCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUFFLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQztJQUNuQyxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDdEIsQ0FBQztBQUVELHdIQUF3SDtBQUN4SCxNQUFNLFVBQVUsY0FBYyxDQUM1QixNQUE4QjtJQUU5QixPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsb0dBQW9HO0FBQ3BHLE1BQU0sVUFBVSxPQUFPLENBQUMsS0FBYztJQUNwQyxJQUFJLEtBQUssWUFBWSxLQUFLO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDekMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2RCxJQUFJLENBQUM7UUFDSCxPQUFPLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNsQyxDQUFDO0FBQ0gsQ0FBQztBQXFGRCw0REFBNEQ7QUFDNUQsTUFBTSxPQUFPLFNBQVUsU0FBUSxLQUFLO0lBQ2xDLHNDQUFzQztJQUMvQixJQUFJLENBQWdCO0lBQzNCLDJFQUEyRTtJQUNwRSxJQUFJLENBQVU7SUFFckIsWUFDRSxJQUFtQixFQUNuQixPQUFlLEVBQ2YsSUFBYSxFQUNiLEtBQWE7UUFFYixLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQVdELG1EQUFtRDtBQUNuRCxNQUFNLE9BQU8sY0FBZSxTQUFRLEtBQUs7SUFDdkMsc0NBQXNDO0lBQy9CLElBQUksQ0FBcUI7SUFFaEMsWUFBWSxJQUF3QixFQUFFLE9BQWUsRUFBRSxLQUFhO1FBQ2xFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLElBQUksR0FBRyxnQkFBZ0IsQ0FBQztRQUM3QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0NBQ0Y7QUFTRCw0Q0FBNEM7QUFDNUMsTUFBTSxPQUFPLGVBQWdCLFNBQVEsS0FBSztJQUN4QyxzQ0FBc0M7SUFDL0IsSUFBSSxDQUFzQjtJQUVqQyxZQUFZLElBQXlCLEVBQUUsT0FBZSxFQUFFLEtBQWE7UUFDbkUsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDO1FBQzlCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQVFELHNEQUFzRDtBQUN0RCxNQUFNLE9BQU8sa0JBQW1CLFNBQVEsS0FBSztJQUMzQyxzQ0FBc0M7SUFDL0IsSUFBSSxDQUF5QjtJQUVwQyxZQUFZLElBQTRCLEVBQUUsT0FBZSxFQUFFLEtBQWE7UUFDdEUsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQixDQUFDO1FBQ2pDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQVVELGtGQUFrRjtBQUNsRixNQUFNLE9BQU8sWUFBYSxTQUFRLEtBQUs7SUFDckMsb0NBQW9DO0lBQzdCLElBQUksQ0FBbUI7SUFFOUIsWUFBWSxJQUFzQixFQUFFLE9BQWUsRUFBRSxLQUFhO1FBQ2hFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLElBQUksR0FBRyxjQUFjLENBQUM7UUFDM0IsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbkIsQ0FBQztDQUNGO0FBYUQsMEVBQTBFO0FBQzFFLE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxLQUFLO0lBQ25DLElBQUksQ0FBd0I7SUFFbkMsWUFBWSxJQUEyQixFQUFFLE9BQWUsRUFBRSxLQUFhO1FBQ3JFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLElBQUksR0FBRyxtQkFBbUIsQ0FBQztRQUNoQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0NBQ0YifQ==
@@ -1,4 +1,4 @@
1
- import type { ExecutionEnv, ExecutionEnvExecOptions } from '../types.js';
1
+ import { type ExecutionEnv, type ExecutionEnvExecOptions, ExecutionError, type Result } from '../types.ts';
2
2
  export interface ShellCaptureOptions extends Omit<ExecutionEnvExecOptions, 'onStdout' | 'onStderr'> {
3
3
  onChunk?: (chunk: string) => void;
4
4
  }
@@ -10,4 +10,4 @@ export interface ShellCaptureResult {
10
10
  fullOutputPath?: string;
11
11
  }
12
12
  export declare function sanitizeBinaryOutput(str: string): string;
13
- export declare function executeShellWithCapture(env: ExecutionEnv, command: string, options?: ShellCaptureOptions): Promise<ShellCaptureResult>;
13
+ export declare function executeShellWithCapture(env: ExecutionEnv, command: string, options?: ShellCaptureOptions): Promise<Result<ShellCaptureResult, ExecutionError>>;
@@ -0,0 +1,134 @@
1
+ import { err, ExecutionError, ok, toError, } from "../types.js";
2
+ import { DEFAULT_MAX_BYTES, truncateTail } from "./truncate.js";
3
+ function toExecutionError(error) {
4
+ if (error instanceof ExecutionError)
5
+ return error;
6
+ const cause = toError(error);
7
+ return new ExecutionError('unknown', cause.message, cause);
8
+ }
9
+ export function sanitizeBinaryOutput(str) {
10
+ return Array.from(str)
11
+ .filter((char) => {
12
+ const code = char.codePointAt(0);
13
+ if (code === undefined)
14
+ return false;
15
+ if (code === 0x09 || code === 0x0a || code === 0x0d)
16
+ return true;
17
+ if (code <= 0x1f)
18
+ return false;
19
+ if (code >= 0xfff9 && code <= 0xfffb)
20
+ return false;
21
+ return true;
22
+ })
23
+ .join('');
24
+ }
25
+ export async function executeShellWithCapture(env, command, options) {
26
+ const outputChunks = [];
27
+ let outputBytes = 0;
28
+ const maxOutputBytes = DEFAULT_MAX_BYTES * 2;
29
+ const encoder = new TextEncoder();
30
+ let totalBytes = 0;
31
+ let fullOutputPath;
32
+ let writeChain = Promise.resolve(ok(undefined));
33
+ let captureError;
34
+ const appendFullOutput = (text) => {
35
+ if (!fullOutputPath || captureError)
36
+ return;
37
+ const path = fullOutputPath;
38
+ writeChain = writeChain.then(async (previous) => {
39
+ if (!previous.ok)
40
+ return previous;
41
+ const appendResult = await env.appendFile(path, text, options?.abortSignal);
42
+ return appendResult.ok
43
+ ? ok(undefined)
44
+ : err(toExecutionError(appendResult.error));
45
+ });
46
+ };
47
+ const ensureFullOutputFile = (initialContent) => {
48
+ if (fullOutputPath || captureError)
49
+ return;
50
+ writeChain = writeChain.then(async (previous) => {
51
+ if (!previous.ok)
52
+ return previous;
53
+ const tempFile = await env.createTempFile({
54
+ prefix: 'bash-',
55
+ suffix: '.log',
56
+ abortSignal: options?.abortSignal,
57
+ });
58
+ if (!tempFile.ok)
59
+ return err(toExecutionError(tempFile.error));
60
+ fullOutputPath = tempFile.value;
61
+ const appendResult = await env.appendFile(tempFile.value, initialContent, options?.abortSignal);
62
+ return appendResult.ok
63
+ ? ok(undefined)
64
+ : err(toExecutionError(appendResult.error));
65
+ });
66
+ };
67
+ const onChunk = (chunk) => {
68
+ try {
69
+ totalBytes += encoder.encode(chunk).byteLength;
70
+ const text = sanitizeBinaryOutput(chunk).replace(/\r/g, '');
71
+ if (totalBytes > DEFAULT_MAX_BYTES && !fullOutputPath) {
72
+ ensureFullOutputFile(outputChunks.join('') + text);
73
+ }
74
+ else {
75
+ appendFullOutput(text);
76
+ }
77
+ outputChunks.push(text);
78
+ outputBytes += text.length;
79
+ while (outputBytes > maxOutputBytes && outputChunks.length > 1) {
80
+ const removed = outputChunks.shift();
81
+ outputBytes -= removed.length;
82
+ }
83
+ options?.onChunk?.(text);
84
+ }
85
+ catch (error) {
86
+ captureError = toExecutionError(error);
87
+ }
88
+ };
89
+ try {
90
+ const result = await env.exec(command, {
91
+ ...(options ?? {}),
92
+ onStdout: onChunk,
93
+ onStderr: onChunk,
94
+ });
95
+ const tailOutput = outputChunks.join('');
96
+ const truncationResult = truncateTail(tailOutput);
97
+ if (truncationResult.truncated && !fullOutputPath) {
98
+ ensureFullOutputFile(tailOutput);
99
+ }
100
+ const writeResult = await writeChain;
101
+ if (!writeResult.ok)
102
+ return err(writeResult.error);
103
+ if (captureError)
104
+ return err(captureError);
105
+ if (!result.ok) {
106
+ if (result.error.code === 'aborted' || options?.abortSignal?.aborted) {
107
+ return ok({
108
+ output: truncationResult.truncated
109
+ ? truncationResult.content
110
+ : tailOutput,
111
+ exitCode: undefined,
112
+ cancelled: true,
113
+ truncated: truncationResult.truncated,
114
+ fullOutputPath,
115
+ });
116
+ }
117
+ return err(result.error);
118
+ }
119
+ const cancelled = options?.abortSignal?.aborted ?? false;
120
+ return ok({
121
+ output: truncationResult.truncated
122
+ ? truncationResult.content
123
+ : tailOutput,
124
+ exitCode: cancelled ? undefined : result.value.exitCode,
125
+ cancelled,
126
+ truncated: truncationResult.truncated,
127
+ fullOutputPath,
128
+ });
129
+ }
130
+ catch (error) {
131
+ return err(toExecutionError(error));
132
+ }
133
+ }
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGwtb3V0cHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9hZ2VudC1jb3JlL3NyYy9oYXJuZXNzL3V0aWxzL3NoZWxsLW91dHB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsR0FBRyxFQUdILGNBQWMsRUFDZCxFQUFFLEVBRUYsT0FBTyxHQUNSLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFpQmhFLFNBQVMsZ0JBQWdCLENBQUMsS0FBYztJQUN0QyxJQUFJLEtBQUssWUFBWSxjQUFjO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdCLE9BQU8sSUFBSSxjQUFjLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVELE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxHQUFXO0lBQzlDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7U0FDbkIsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDZixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksSUFBSSxLQUFLLFNBQVM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNyQyxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ2pFLElBQUksSUFBSSxJQUFJLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUMvQixJQUFJLElBQUksSUFBSSxNQUFNLElBQUksSUFBSSxJQUFJLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQztR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