@modelprofile.com/flexharness 6.0.0 → 7.0.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 (169) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts_chat/classes.chatsession.d.ts +37 -0
  3. package/dist_ts_chat/classes.chatsession.js +102 -0
  4. package/dist_ts_chat/index.d.ts +2 -0
  5. package/dist_ts_chat/index.js +2 -0
  6. package/dist_ts_chat/interfaces.d.ts +72 -0
  7. package/dist_ts_chat/interfaces.js +2 -0
  8. package/dist_ts_chat/plugins.d.ts +4 -0
  9. package/dist_ts_chat/plugins.js +4 -0
  10. package/dist_ts_chat_cli/components.chatapp.d.ts +10 -0
  11. package/dist_ts_chat_cli/components.chatapp.js +75 -0
  12. package/dist_ts_chat_cli/components.inputarea.d.ts +7 -0
  13. package/dist_ts_chat_cli/components.inputarea.js +18 -0
  14. package/dist_ts_chat_cli/components.message.d.ts +12 -0
  15. package/dist_ts_chat_cli/components.message.js +21 -0
  16. package/dist_ts_chat_cli/components.messagelist.d.ts +9 -0
  17. package/dist_ts_chat_cli/components.messagelist.js +19 -0
  18. package/dist_ts_chat_cli/components.statusbar.d.ts +9 -0
  19. package/dist_ts_chat_cli/components.statusbar.js +15 -0
  20. package/dist_ts_chat_cli/index.d.ts +2 -0
  21. package/dist_ts_chat_cli/index.js +2 -0
  22. package/dist_ts_chat_cli/plugins.d.ts +12 -0
  23. package/dist_ts_chat_cli/plugins.js +14 -0
  24. package/dist_ts_chat_cli/startchat.d.ts +18 -0
  25. package/dist_ts_chat_cli/startchat.js +17 -0
  26. package/dist_ts_chat_web/flexchat-input.d.ts +21 -0
  27. package/dist_ts_chat_web/flexchat-input.js +172 -0
  28. package/dist_ts_chat_web/flexchat-message.d.ts +26 -0
  29. package/dist_ts_chat_web/flexchat-message.js +174 -0
  30. package/dist_ts_chat_web/flexchat-window.d.ts +34 -0
  31. package/dist_ts_chat_web/flexchat-window.js +394 -0
  32. package/dist_ts_chat_web/index.d.ts +3 -0
  33. package/dist_ts_chat_web/index.js +4 -0
  34. package/dist_ts_chat_web/plugins.d.ts +6 -0
  35. package/dist_ts_chat_web/plugins.js +4 -0
  36. package/dist_ts_compaction/index.d.ts +2 -0
  37. package/dist_ts_compaction/index.js +2 -0
  38. package/dist_ts_compaction/plugins.d.ts +4 -0
  39. package/dist_ts_compaction/plugins.js +3 -0
  40. package/dist_ts_compaction/smartagent.compaction.d.ts +14 -0
  41. package/dist_ts_compaction/smartagent.compaction.js +49 -0
  42. package/dist_ts_document/index.d.ts +19 -0
  43. package/dist_ts_document/index.js +55 -0
  44. package/dist_ts_document/plugins.d.ts +3 -0
  45. package/dist_ts_document/plugins.js +4 -0
  46. package/dist_ts_kvm/classes.browserkvm.d.ts +22 -0
  47. package/dist_ts_kvm/classes.browserkvm.js +271 -0
  48. package/dist_ts_kvm/classes.kvmterminal.d.ts +8 -0
  49. package/dist_ts_kvm/classes.kvmterminal.js +88 -0
  50. package/dist_ts_kvm/commandwrappers.d.ts +14 -0
  51. package/dist_ts_kvm/commandwrappers.js +58 -0
  52. package/dist_ts_kvm/index.d.ts +6 -0
  53. package/dist_ts_kvm/index.js +7 -0
  54. package/dist_ts_kvm/interfaces.d.ts +106 -0
  55. package/dist_ts_kvm/interfaces.js +2 -0
  56. package/dist_ts_kvm/ocr.d.ts +14 -0
  57. package/dist_ts_kvm/ocr.js +23 -0
  58. package/dist_ts_kvm/plugins.d.ts +6 -0
  59. package/dist_ts_kvm/plugins.js +10 -0
  60. package/dist_ts_kvm/tools.d.ts +15 -0
  61. package/dist_ts_kvm/tools.js +40 -0
  62. package/dist_ts_mcp/index.d.ts +86 -0
  63. package/dist_ts_mcp/index.js +284 -0
  64. package/dist_ts_mcp/requestcontext.d.ts +11 -0
  65. package/dist_ts_mcp/requestcontext.js +42 -0
  66. package/dist_ts_media/index.d.ts +8 -0
  67. package/dist_ts_media/index.js +21 -0
  68. package/dist_ts_media/plugins.d.ts +2 -0
  69. package/dist_ts_media/plugins.js +3 -0
  70. package/dist_ts_ocr/classes.imageocr.d.ts +19 -0
  71. package/dist_ts_ocr/classes.imageocr.js +27 -0
  72. package/dist_ts_ocr/index.d.ts +2 -0
  73. package/dist_ts_ocr/index.js +3 -0
  74. package/dist_ts_ocr/ocr.mistral.d.ts +75 -0
  75. package/dist_ts_ocr/ocr.mistral.js +77 -0
  76. package/dist_ts_tools/index.d.ts +17 -0
  77. package/dist_ts_tools/index.js +10 -0
  78. package/dist_ts_tools/plugins.d.ts +7 -0
  79. package/dist_ts_tools/plugins.js +6 -0
  80. package/dist_ts_tools/tool.browser.d.ts +11 -0
  81. package/dist_ts_tools/tool.browser.js +128 -0
  82. package/dist_ts_tools/tool.context.d.ts +4 -0
  83. package/dist_ts_tools/tool.context.js +23 -0
  84. package/dist_ts_tools/tool.filesystem.d.ts +11 -0
  85. package/dist_ts_tools/tool.filesystem.js +106 -0
  86. package/dist_ts_tools/tool.http.d.ts +2 -0
  87. package/dist_ts_tools/tool.http.js +65 -0
  88. package/dist_ts_tools/tool.json.d.ts +2 -0
  89. package/dist_ts_tools/tool.json.js +47 -0
  90. package/dist_ts_tools/tool.shell.d.ts +15 -0
  91. package/dist_ts_tools/tool.shell.js +329 -0
  92. package/dist_ts_tools/utils.truncation.d.ts +10 -0
  93. package/dist_ts_tools/utils.truncation.js +26 -0
  94. package/dist_ts_tools_node/index.d.ts +5 -0
  95. package/dist_ts_tools_node/index.js +4 -0
  96. package/dist_ts_tools_node/plugins.d.ts +13 -0
  97. package/dist_ts_tools_node/plugins.js +13 -0
  98. package/dist_ts_tools_node/tool.context.d.ts +31 -0
  99. package/dist_ts_tools_node/tool.context.js +837 -0
  100. package/dist_ts_tools_node/tool.persistence.d.ts +15 -0
  101. package/dist_ts_tools_node/tool.persistence.js +129 -0
  102. package/dist_ts_tools_node/tools.local.d.ts +11 -0
  103. package/dist_ts_tools_node/tools.local.js +15 -0
  104. package/package.json +112 -4
  105. package/readme.md +122 -66
  106. package/ts/00_commitinfo_data.ts +1 -1
  107. package/ts/readme.md +122 -66
  108. package/ts_chat/classes.chatsession.ts +116 -0
  109. package/ts_chat/index.ts +8 -0
  110. package/ts_chat/interfaces.ts +64 -0
  111. package/ts_chat/plugins.ts +7 -0
  112. package/ts_chat/readme.md +49 -0
  113. package/ts_chat_cli/components.chatapp.ts +103 -0
  114. package/ts_chat_cli/components.inputarea.ts +29 -0
  115. package/ts_chat_cli/components.message.ts +48 -0
  116. package/ts_chat_cli/components.messagelist.ts +45 -0
  117. package/ts_chat_cli/components.statusbar.ts +31 -0
  118. package/ts_chat_cli/index.ts +2 -0
  119. package/ts_chat_cli/plugins.ts +21 -0
  120. package/ts_chat_cli/readme.md +40 -0
  121. package/ts_chat_cli/startchat.ts +34 -0
  122. package/ts_chat_web/flexchat-input.ts +184 -0
  123. package/ts_chat_web/flexchat-message.ts +185 -0
  124. package/ts_chat_web/flexchat-window.ts +416 -0
  125. package/ts_chat_web/index.ts +3 -0
  126. package/ts_chat_web/plugins.ts +9 -0
  127. package/ts_chat_web/readme.md +46 -0
  128. package/ts_compaction/index.ts +2 -0
  129. package/ts_compaction/plugins.ts +6 -0
  130. package/ts_compaction/readme.md +37 -0
  131. package/ts_compaction/smartagent.compaction.ts +59 -0
  132. package/ts_document/index.ts +82 -0
  133. package/ts_document/plugins.ts +3 -0
  134. package/ts_document/readme.md +49 -0
  135. package/ts_kvm/classes.browserkvm.ts +335 -0
  136. package/ts_kvm/classes.kvmterminal.ts +103 -0
  137. package/ts_kvm/commandwrappers.ts +83 -0
  138. package/ts_kvm/index.ts +6 -0
  139. package/ts_kvm/interfaces.ts +152 -0
  140. package/ts_kvm/ocr.ts +41 -0
  141. package/ts_kvm/plugins.ts +13 -0
  142. package/ts_kvm/readme.md +482 -0
  143. package/ts_kvm/tools.ts +58 -0
  144. package/ts_mcp/index.ts +470 -0
  145. package/ts_mcp/readme.md +37 -0
  146. package/ts_mcp/requestcontext.ts +66 -0
  147. package/ts_media/index.ts +29 -0
  148. package/ts_media/plugins.ts +2 -0
  149. package/ts_media/readme.md +37 -0
  150. package/ts_ocr/classes.imageocr.ts +53 -0
  151. package/ts_ocr/index.ts +2 -0
  152. package/ts_ocr/ocr.mistral.ts +192 -0
  153. package/ts_ocr/readme.md +48 -0
  154. package/ts_tools/index.ts +49 -0
  155. package/ts_tools/plugins.ts +7 -0
  156. package/ts_tools/readme.md +37 -0
  157. package/ts_tools/tool.browser.ts +159 -0
  158. package/ts_tools/tool.context.ts +23 -0
  159. package/ts_tools/tool.filesystem.ts +144 -0
  160. package/ts_tools/tool.http.ts +78 -0
  161. package/ts_tools/tool.json.ts +53 -0
  162. package/ts_tools/tool.shell.ts +418 -0
  163. package/ts_tools/utils.truncation.ts +39 -0
  164. package/ts_tools_node/index.ts +5 -0
  165. package/ts_tools_node/plugins.ts +16 -0
  166. package/ts_tools_node/readme.md +37 -0
  167. package/ts_tools_node/tool.context.ts +991 -0
  168. package/ts_tools_node/tool.persistence.ts +146 -0
  169. package/ts_tools_node/tools.local.ts +26 -0
@@ -0,0 +1,47 @@
1
+ import * as plugins from './plugins.js';
2
+ export function jsonTool() {
3
+ return {
4
+ json_validate: plugins.tool({
5
+ description: 'Validate a JSON string and optionally check for required fields.',
6
+ inputSchema: plugins.z.object({
7
+ jsonString: plugins.z.string().describe('JSON string to validate'),
8
+ requiredFields: plugins.z
9
+ .array(plugins.z.string())
10
+ .optional()
11
+ .describe('Fields that must exist at the top level'),
12
+ }),
13
+ execute: async ({ jsonString, requiredFields, }) => {
14
+ try {
15
+ const parsed = JSON.parse(jsonString);
16
+ if (requiredFields?.length) {
17
+ const missing = requiredFields.filter((f) => !(f in parsed));
18
+ if (missing.length) {
19
+ return `Invalid: missing required fields: ${missing.join(', ')}`;
20
+ }
21
+ }
22
+ const type = Array.isArray(parsed) ? 'array' : typeof parsed;
23
+ return `Valid JSON (${type})`;
24
+ }
25
+ catch (e) {
26
+ return `Invalid JSON: ${e.message}`;
27
+ }
28
+ },
29
+ }),
30
+ json_transform: plugins.tool({
31
+ description: 'Parse a JSON string and return it pretty-printed.',
32
+ inputSchema: plugins.z.object({
33
+ jsonString: plugins.z.string().describe('JSON string to format'),
34
+ }),
35
+ execute: async ({ jsonString }) => {
36
+ try {
37
+ const parsed = JSON.parse(jsonString);
38
+ return JSON.stringify(parsed, null, 2);
39
+ }
40
+ catch (e) {
41
+ return `Error parsing JSON: ${e.message}`;
42
+ }
43
+ },
44
+ }),
45
+ };
46
+ }
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfdG9vbHMvdG9vbC5qc29uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE1BQU0sVUFBVSxRQUFRO0lBQ3RCLE9BQU87UUFDTCxhQUFhLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQztZQUMxQixXQUFXLEVBQ1Qsa0VBQWtFO1lBQ3BFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDNUIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDO2dCQUNsRSxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQ3RCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUN6QixRQUFRLEVBQUU7cUJBQ1YsUUFBUSxDQUFDLHlDQUF5QyxDQUFDO2FBQ3ZELENBQUM7WUFDRixPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQ2QsVUFBVSxFQUNWLGNBQWMsR0FJZixFQUFFLEVBQUU7Z0JBQ0gsSUFBSSxDQUFDO29CQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3RDLElBQUksY0FBYyxFQUFFLE1BQU0sRUFBRSxDQUFDO3dCQUMzQixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUM7d0JBQzdELElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDOzRCQUNuQixPQUFPLHFDQUFxQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7d0JBQ25FLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sTUFBTSxDQUFDO29CQUM3RCxPQUFPLGVBQWUsSUFBSSxHQUFHLENBQUM7Z0JBQ2hDLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCxPQUFPLGlCQUFrQixDQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2pELENBQUM7WUFDSCxDQUFDO1NBQ0YsQ0FBQztRQUVGLGNBQWMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzNCLFdBQVcsRUFBRSxtREFBbUQ7WUFDaEUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUM1QixVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUM7YUFDakUsQ0FBQztZQUNGLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQTBCLEVBQUUsRUFBRTtnQkFDeEQsSUFBSSxDQUFDO29CQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3RDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1gsT0FBTyx1QkFBd0IsQ0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN2RCxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyJ9
@@ -0,0 +1,15 @@
1
+ import * as plugins from './plugins.js';
2
+ import { type IToolExecutionContext } from './tool.context.js';
3
+ export interface ICreateShellToolsOptions {
4
+ /**
5
+ * Exact executable allowlist for structured execution. Raw command filtering is advisory.
6
+ */
7
+ allowedCommands?: string[];
8
+ /** Maximum output lines before truncating. */
9
+ maxLines?: number;
10
+ /** Maximum output bytes before truncating. */
11
+ maxBytes?: number;
12
+ /** Expose start_shell when context.jobs exists. Default: true. */
13
+ includeBackground?: boolean;
14
+ }
15
+ export declare function createShellTools(context: IToolExecutionContext, options?: ICreateShellToolsOptions): plugins.ToolSet;
@@ -0,0 +1,329 @@
1
+ import * as plugins from './plugins.js';
2
+ import { formatShellResult, } from './tool.context.js';
3
+ const DEFAULT_FOREGROUND_PREVIEW_BYTES = 50 * 1024;
4
+ const MAX_FOREGROUND_PRELIMINARY_CHUNKS = 64;
5
+ const MAX_FOREGROUND_PRELIMINARY_BYTES = 256 * 1024;
6
+ const singleShellOutput = async function* (output) {
7
+ yield output;
8
+ };
9
+ const foregroundPreviewByteLimit = (configuredMaxBytes) => (Number.isSafeInteger(configuredMaxBytes) && configuredMaxBytes > 0
10
+ ? Math.min(configuredMaxBytes, DEFAULT_FOREGROUND_PREVIEW_BYTES)
11
+ : DEFAULT_FOREGROUND_PREVIEW_BYTES);
12
+ const formatForegroundShellPreview = (stdout, stderr, captureTruncated) => {
13
+ const output = stderr
14
+ ? stdout
15
+ ? `stdout:\n${stdout}\nstderr:\n${stderr}`
16
+ : `stderr:\n${stderr}`
17
+ : stdout;
18
+ return captureTruncated
19
+ ? `${output}${output ? '\n' : ''}[Live output preview truncated; final output will follow.]`
20
+ : output;
21
+ };
22
+ class ForegroundShellResultStream {
23
+ options;
24
+ abortController = new AbortController();
25
+ abortSignal;
26
+ previewByteLimit;
27
+ queue = [];
28
+ waiters = [];
29
+ completion;
30
+ stdout = '';
31
+ stderr = '';
32
+ previewBytes = 0;
33
+ captureTruncated = false;
34
+ lastPreview = '';
35
+ preliminaryChunks = 0;
36
+ preliminaryBytes = 0;
37
+ previewsDisabled = false;
38
+ settled = false;
39
+ returned = false;
40
+ terminalError;
41
+ constructor(options) {
42
+ this.options = options;
43
+ this.abortSignal = options.abortSignal
44
+ ? AbortSignal.any([options.abortSignal, this.abortController.signal])
45
+ : this.abortController.signal;
46
+ this.previewByteLimit = foregroundPreviewByteLimit(options.maxBytes);
47
+ }
48
+ [Symbol.asyncIterator]() {
49
+ return this;
50
+ }
51
+ next() {
52
+ if (this.returned)
53
+ return Promise.resolve({ done: true, value: undefined });
54
+ this.ensureStarted();
55
+ const queued = this.queue.shift();
56
+ if (queued)
57
+ return Promise.resolve(this.deliver(queued));
58
+ if (this.settled) {
59
+ return this.terminalError === undefined
60
+ ? Promise.resolve({ done: true, value: undefined })
61
+ : Promise.reject(this.terminalError);
62
+ }
63
+ return new Promise((resolve, reject) => {
64
+ this.waiters.push({ resolve, reject });
65
+ });
66
+ }
67
+ async return() {
68
+ if (!this.returned) {
69
+ this.returned = true;
70
+ this.abortController.abort(new DOMException('Foreground shell iteration stopped.', 'AbortError'));
71
+ this.queue.length = 0;
72
+ this.flushWaiters();
73
+ }
74
+ if (this.completion) {
75
+ try {
76
+ await this.completion;
77
+ }
78
+ catch {
79
+ // Iterator cancellation owns the abort; the cancelled command result is not a tool failure.
80
+ }
81
+ }
82
+ return { done: true, value: undefined };
83
+ }
84
+ async throw(error) {
85
+ if (!this.returned) {
86
+ this.returned = true;
87
+ this.abortController.abort(error);
88
+ this.queue.length = 0;
89
+ while (this.waiters.length > 0)
90
+ this.waiters.shift().reject(error);
91
+ }
92
+ if (this.completion) {
93
+ try {
94
+ await this.completion;
95
+ }
96
+ catch {
97
+ // The caller-provided iterator error remains authoritative.
98
+ }
99
+ }
100
+ throw error;
101
+ }
102
+ async handleOutput(stream, chunk) {
103
+ if (this.returned || this.settled || this.previewsDisabled || !chunk)
104
+ return;
105
+ let accepted = '';
106
+ let acceptedBytes = 0;
107
+ for (const character of chunk) {
108
+ const characterBytes = Buffer.byteLength(character);
109
+ if (this.previewBytes + acceptedBytes + characterBytes > this.previewByteLimit)
110
+ break;
111
+ accepted += character;
112
+ acceptedBytes += characterBytes;
113
+ }
114
+ if (acceptedBytes < Buffer.byteLength(chunk))
115
+ this.captureTruncated = true;
116
+ if (accepted) {
117
+ if (stream === 'stdout')
118
+ this.stdout += accepted;
119
+ else
120
+ this.stderr += accepted;
121
+ this.previewBytes += acceptedBytes;
122
+ }
123
+ const preview = plugins.truncateOutput(formatForegroundShellPreview(this.stdout, this.stderr, this.captureTruncated), { maxLines: this.options.maxLines, maxBytes: this.options.maxBytes }).content;
124
+ if (!preview || preview === this.lastPreview)
125
+ return;
126
+ const bytes = Buffer.byteLength(JSON.stringify(preview));
127
+ if (this.preliminaryChunks + 1 > MAX_FOREGROUND_PRELIMINARY_CHUNKS
128
+ || this.preliminaryBytes + bytes > MAX_FOREGROUND_PRELIMINARY_BYTES) {
129
+ this.previewsDisabled = true;
130
+ return;
131
+ }
132
+ this.lastPreview = preview;
133
+ for (let index = this.queue.length - 1; index >= 0; index--) {
134
+ if (this.queue[index].kind === 'preliminary')
135
+ this.queue.splice(index, 1);
136
+ }
137
+ this.queue.push({ kind: 'preliminary', content: preview, bytes });
138
+ if (this.captureTruncated)
139
+ this.previewsDisabled = true;
140
+ this.flushWaiters();
141
+ }
142
+ ensureStarted() {
143
+ if (this.completion)
144
+ return;
145
+ const completion = Promise.resolve().then(() => this.options.start(this.abortSignal, async (stream, chunk) => this.handleOutput(stream, chunk)));
146
+ this.completion = completion;
147
+ void completion.then((result) => this.finish(result), (error) => this.fail(error));
148
+ }
149
+ finish(result) {
150
+ this.settled = true;
151
+ if (this.returned)
152
+ return;
153
+ const content = plugins.truncateOutput(formatShellResult(result), {
154
+ maxLines: this.options.maxLines,
155
+ maxBytes: this.options.maxBytes,
156
+ }).content;
157
+ this.queue.push({ kind: 'final', content, bytes: Buffer.byteLength(content) });
158
+ this.flushWaiters();
159
+ }
160
+ fail(error) {
161
+ this.settled = true;
162
+ this.terminalError = error;
163
+ this.flushWaiters();
164
+ }
165
+ deliver(output) {
166
+ if (output.kind === 'preliminary') {
167
+ this.preliminaryChunks++;
168
+ this.preliminaryBytes += output.bytes;
169
+ }
170
+ return { done: false, value: output.content };
171
+ }
172
+ flushWaiters() {
173
+ while (this.waiters.length > 0 && this.queue.length > 0) {
174
+ this.waiters.shift().resolve(this.deliver(this.queue.shift()));
175
+ }
176
+ if (!this.settled && !this.returned)
177
+ return;
178
+ while (this.waiters.length > 0) {
179
+ const waiter = this.waiters.shift();
180
+ if (!this.returned && this.terminalError !== undefined)
181
+ waiter.reject(this.terminalError);
182
+ else
183
+ waiter.resolve({ done: true, value: undefined });
184
+ }
185
+ }
186
+ }
187
+ export function createShellTools(context, options = {}) {
188
+ const tools = {
189
+ run_command: plugins.tool({
190
+ description: 'Execute a raw shell command through bash -lc. Shell composition is supported. Prefer run_shell when direct structured execution is sufficient.',
191
+ inputSchema: plugins.z.object({
192
+ command: plugins.z.string().describe('The shell command to execute'),
193
+ cwd: plugins.z
194
+ .string()
195
+ .optional()
196
+ .describe('Working directory for the command'),
197
+ timeout: plugins.z
198
+ .number()
199
+ .optional()
200
+ .describe('Timeout in milliseconds'),
201
+ timeoutMs: plugins.z
202
+ .number()
203
+ .optional()
204
+ .describe('Timeout in milliseconds'),
205
+ }),
206
+ execute: ({ command, cwd, timeout, timeoutMs, }, invocationOptions) => {
207
+ const shell = context.shell;
208
+ if (!shell) {
209
+ throw new Error('Shell tool is not available in this execution context.');
210
+ }
211
+ if (options.allowedCommands?.length) {
212
+ const baseCommand = command.trim().split(/\s+/)[0];
213
+ if (!options.allowedCommands.includes(baseCommand)) {
214
+ return singleShellOutput(`Raw command "${baseCommand}" is not in the advisory allowed commands list: ${options.allowedCommands.join(', ')}`);
215
+ }
216
+ }
217
+ const abortSignal = invocationOptions?.abortSignal ?? context.abortSignal;
218
+ return new ForegroundShellResultStream({
219
+ abortSignal,
220
+ maxLines: options.maxLines,
221
+ maxBytes: options.maxBytes,
222
+ start: async (executionSignal, onOutput) => {
223
+ await context.requestPermission?.({
224
+ type: 'shell',
225
+ title: 'Run shell command',
226
+ metadata: { command, cwd: cwd ?? context.cwd },
227
+ toolCallId: invocationOptions?.toolCallId,
228
+ abortSignal: executionSignal,
229
+ });
230
+ executionSignal.throwIfAborted();
231
+ return shell.run(command, {
232
+ cwd: cwd ?? context.cwd,
233
+ timeoutMs: timeoutMs ?? timeout,
234
+ toolCallId: invocationOptions?.toolCallId,
235
+ abortSignal: executionSignal,
236
+ onOutput,
237
+ });
238
+ },
239
+ });
240
+ },
241
+ }),
242
+ };
243
+ if (context.shell?.runStructured) {
244
+ tools.run_shell = plugins.tool({
245
+ description: 'Execute an executable directly with a literal argument array. No shell parsing or shell composition is performed.',
246
+ inputSchema: plugins.z.object({
247
+ executable: plugins.z.string().describe('Exact executable name or path'),
248
+ args: plugins.z.array(plugins.z.string()).default([]).describe('Literal argument array'),
249
+ cwd: plugins.z.string().optional().describe('Working directory for the command'),
250
+ timeoutMs: plugins.z.number().optional().describe('Timeout in milliseconds'),
251
+ }),
252
+ execute: (input, invocationOptions) => {
253
+ const runStructured = context.shell?.runStructured;
254
+ if (!runStructured) {
255
+ throw new Error('Structured shell execution is not available in this execution context.');
256
+ }
257
+ if (options.allowedCommands?.length && !options.allowedCommands.includes(input.executable)) {
258
+ return singleShellOutput({
259
+ error: `Executable "${input.executable}" is not in the allowed commands list.`,
260
+ allowedCommands: options.allowedCommands,
261
+ });
262
+ }
263
+ const abortSignal = invocationOptions?.abortSignal ?? context.abortSignal;
264
+ return new ForegroundShellResultStream({
265
+ abortSignal,
266
+ maxLines: options.maxLines,
267
+ maxBytes: options.maxBytes,
268
+ start: async (executionSignal, onOutput) => {
269
+ await context.requestPermission?.({
270
+ type: 'shell',
271
+ title: 'Run structured command',
272
+ metadata: { executable: input.executable, args: input.args, cwd: input.cwd ?? context.cwd },
273
+ toolCallId: invocationOptions?.toolCallId,
274
+ abortSignal: executionSignal,
275
+ });
276
+ executionSignal.throwIfAborted();
277
+ return runStructured({ executable: input.executable, args: input.args }, {
278
+ cwd: input.cwd ?? context.cwd,
279
+ timeoutMs: input.timeoutMs,
280
+ toolCallId: invocationOptions?.toolCallId,
281
+ abortSignal: executionSignal,
282
+ onOutput,
283
+ });
284
+ },
285
+ });
286
+ },
287
+ });
288
+ }
289
+ if (context.jobs && options.includeBackground !== false) {
290
+ tools.start_shell = plugins.tool({
291
+ description: 'Start a structured shell command as an independent background execution and return its execution ID immediately.',
292
+ inputSchema: plugins.z.object({
293
+ executable: plugins.z.string().describe('Exact executable name or path'),
294
+ args: plugins.z.array(plugins.z.string()).default([]).describe('Literal argument array'),
295
+ cwd: plugins.z.string().optional().describe('Working directory for the command'),
296
+ timeoutMs: plugins.z.number().optional().describe('Background execution timeout in milliseconds'),
297
+ }),
298
+ execute: async (input, invocationOptions) => {
299
+ if (!context.jobs)
300
+ throw new Error('Background jobs are not available in this execution context.');
301
+ if (options.allowedCommands?.length && !options.allowedCommands.includes(input.executable)) {
302
+ throw new Error(`Executable "${input.executable}" is not in the allowed commands list.`);
303
+ }
304
+ const admissionSignal = invocationOptions?.abortSignal ?? context.abortSignal;
305
+ await context.requestPermission?.({
306
+ type: 'shell-background',
307
+ title: 'Start background shell command',
308
+ metadata: { executable: input.executable, args: input.args, cwd: input.cwd ?? context.cwd },
309
+ toolCallId: invocationOptions?.toolCallId,
310
+ abortSignal: admissionSignal,
311
+ });
312
+ admissionSignal?.throwIfAborted();
313
+ const handle = await context.jobs.start({
314
+ type: 'shell',
315
+ command: { executable: input.executable, args: input.args },
316
+ cwd: input.cwd ?? context.cwd,
317
+ timeoutMs: input.timeoutMs,
318
+ metadata: { toolCallId: invocationOptions?.toolCallId },
319
+ }, {
320
+ toolCallId: invocationOptions?.toolCallId,
321
+ abortSignal: admissionSignal,
322
+ });
323
+ return { executionId: handle.executionId, state: 'running' };
324
+ },
325
+ });
326
+ }
327
+ return tools;
328
+ }
329
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5zaGVsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3Rvb2xzL3Rvb2wuc2hlbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLGlCQUFpQixHQUtsQixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLE1BQU0sZ0NBQWdDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNuRCxNQUFNLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQztBQUM3QyxNQUFNLGdDQUFnQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUE0QnBELE1BQU0saUJBQWlCLEdBQUcsS0FBSyxTQUFTLENBQUMsRUFBVyxNQUFlO0lBQ2pFLE1BQU0sTUFBTSxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBRUYsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLGtCQUEyQixFQUFVLEVBQUUsQ0FBQyxDQUMxRSxNQUFNLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLElBQUksa0JBQW1CLEdBQUcsQ0FBQztJQUNqRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBbUIsRUFBRSxnQ0FBZ0MsQ0FBQztJQUNqRSxDQUFDLENBQUMsZ0NBQWdDLENBQ3JDLENBQUM7QUFFRixNQUFNLDRCQUE0QixHQUFHLENBQ25DLE1BQWMsRUFDZCxNQUFjLEVBQ2QsZ0JBQXlCLEVBQ2pCLEVBQUU7SUFDVixNQUFNLE1BQU0sR0FBRyxNQUFNO1FBQ25CLENBQUMsQ0FBQyxNQUFNO1lBQ04sQ0FBQyxDQUFDLFlBQVksTUFBTSxjQUFjLE1BQU0sRUFBRTtZQUMxQyxDQUFDLENBQUMsWUFBWSxNQUFNLEVBQUU7UUFDeEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNYLE9BQU8sZ0JBQWdCO1FBQ3JCLENBQUMsQ0FBQyxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMs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
@@ -0,0 +1,10 @@
1
+ export interface ITruncateResult {
2
+ content: string;
3
+ truncated: boolean;
4
+ /** Set when truncated: describes what was dropped */
5
+ notice?: string;
6
+ }
7
+ export declare function truncateOutput(text: string, options?: {
8
+ maxLines?: number;
9
+ maxBytes?: number;
10
+ }): ITruncateResult;
@@ -0,0 +1,26 @@
1
+ // Truncation logic derived from opencode (MIT) — https://github.com/sst/opencode
2
+ const MAX_LINES = 2000;
3
+ const MAX_BYTES = 50 * 1024; // 50 KB
4
+ export function truncateOutput(text, options) {
5
+ const maxLines = options?.maxLines ?? MAX_LINES;
6
+ const maxBytes = options?.maxBytes ?? MAX_BYTES;
7
+ const lines = text.split('\n');
8
+ const totalBytes = Buffer.byteLength(text, 'utf-8');
9
+ if (lines.length <= maxLines && totalBytes <= maxBytes) {
10
+ return { content: text, truncated: false };
11
+ }
12
+ const out = [];
13
+ let bytes = 0;
14
+ for (let i = 0; i < lines.length && i < maxLines; i++) {
15
+ const size = Buffer.byteLength(lines[i], 'utf-8') + (i > 0 ? 1 : 0);
16
+ if (bytes + size > maxBytes)
17
+ break;
18
+ out.push(lines[i]);
19
+ bytes += size;
20
+ }
21
+ const kept = out.length;
22
+ const dropped = lines.length - kept;
23
+ const notice = `\n[Output truncated: showing ${kept}/${lines.length} lines. ${dropped} lines omitted.]`;
24
+ return { content: out.join('\n') + notice, truncated: true, notice };
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMudHJ1bmNhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3Rvb2xzL3V0aWxzLnRydW5jYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUZBQWlGO0FBRWpGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQztBQUN2QixNQUFNLFNBQVMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsUUFBUTtBQVNyQyxNQUFNLFVBQVUsY0FBYyxDQUM1QixJQUFZLEVBQ1osT0FBa0Q7SUFFbEQsTUFBTSxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxTQUFTLENBQUM7SUFDaEQsTUFBTSxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxTQUFTLENBQUM7SUFDaEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUVwRCxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksUUFBUSxJQUFJLFVBQVUsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUN2RCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDN0MsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQztJQUN6QixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDdEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxRQUFRO1lBQUUsTUFBTTtRQUNuQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25CLEtBQUssSUFBSSxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFDeEIsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDcEMsTUFBTSxNQUFNLEdBQUcsZ0NBQWdDLElBQUksSUFBSSxLQUFLLENBQUMsTUFBTSxXQUFXLE9BQU8sa0JBQWtCLENBQUM7SUFDeEcsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ3ZFLENBQUMifQ==
@@ -0,0 +1,5 @@
1
+ export { createLocalToolExecutionContext } from './tool.context.js';
2
+ export type { ILocalToolExecutionContextOptions } from './tool.context.js';
3
+ export { FileToolJobStore } from './tool.persistence.js';
4
+ export type { IFileToolJobStoreOptions } from './tool.persistence.js';
5
+ export * from './tools.local.js';
@@ -0,0 +1,4 @@
1
+ export { createLocalToolExecutionContext } from './tool.context.js';
2
+ export { FileToolJobStore } from './tool.persistence.js';
3
+ export * from './tools.local.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c190b29sc19ub2RlL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXBFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXpELGNBQWMsa0JBQWtCLENBQUMifQ==
@@ -0,0 +1,13 @@
1
+ import * as childProcess from 'node:child_process';
2
+ import * as crypto from 'node:crypto';
3
+ import * as fs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ import { StringDecoder } from 'node:string_decoder';
6
+ import * as v8 from 'node:v8';
7
+ export { childProcess, crypto, fs, path, StringDecoder, v8 };
8
+ import { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError } from '@modelprofile.com/flexharness-agent';
9
+ export { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError };
10
+ import { createFilesystemTools, createShellTools } from '@modelprofile.com/flexharness/tools';
11
+ export { createFilesystemTools, createShellTools };
12
+ export type { ICreateFilesystemToolsOptions, ICreateShellToolsOptions, ToolSet } from '@modelprofile.com/flexharness/tools';
13
+ export type { IToolExecutionContext } from '@modelprofile.com/flexharness-agent';
@@ -0,0 +1,13 @@
1
+ // node native
2
+ import * as childProcess from 'node:child_process';
3
+ import * as crypto from 'node:crypto';
4
+ import * as fs from 'node:fs';
5
+ import * as path from 'node:path';
6
+ import { StringDecoder } from 'node:string_decoder';
7
+ import * as v8 from 'node:v8';
8
+ export { childProcess, crypto, fs, path, StringDecoder, v8 };
9
+ import { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError } from '@modelprofile.com/flexharness-agent';
10
+ export { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError };
11
+ import { createFilesystemTools, createShellTools } from '@modelprofile.com/flexharness/tools';
12
+ export { createFilesystemTools, createShellTools };
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3Rvb2xzX25vZGUvcGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjO0FBQ2QsT0FBTyxLQUFLLFlBQVksTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEtBQUssTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUNsQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFOUIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFFN0QsT0FBTyxFQUFFLHFCQUFxQixFQUFFLDJCQUEyQixFQUFFLHlCQUF5QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDcEksT0FBTyxFQUFFLHFCQUFxQixFQUFFLDJCQUEyQixFQUFFLHlCQUF5QixFQUFFLENBQUM7QUFDekYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDOUYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLENBQUMifQ==
@@ -0,0 +1,31 @@
1
+ import type { IToolJobStore } from '@modelprofile.com/flexharness-agent';
2
+ import type { IToolPermissionRequest, IToolJobState, IToolExecutionContext } from '@modelprofile.com/flexharness-agent';
3
+ export interface ILocalToolExecutionContextOptions {
4
+ cwd?: string;
5
+ rootDir?: string;
6
+ /** Additional canonical roots available to filesystem read/list operations only. */
7
+ additionalReadOnlyRoots?: string[];
8
+ abortSignal?: AbortSignal;
9
+ /** Guards each local filesystem operation or shell side effect. */
10
+ beforeOperation?: () => Promise<void> | void;
11
+ /** Hard combined stdout/stderr capture limit for each local shell command. Default: 1 MiB. */
12
+ maxShellOutputBytes?: number;
13
+ /** Number of terminal background job snapshots retained for get/list. Default: 100. */
14
+ maxRetainedJobs?: number;
15
+ /** Optional durable store used to restore terminal jobs after host restarts. */
16
+ jobStore?: IToolJobStore;
17
+ /** Maximum wait for each local shell output listener before its process is terminated. Default: 30 seconds. */
18
+ outputListenerTimeoutMs?: number;
19
+ /** Maximum wait for job-store load/save operations. Defaults to outputListenerTimeoutMs. */
20
+ jobStoreOperationTimeoutMs?: number;
21
+ /** Reconciles a persisted running job whose original process ownership was lost. */
22
+ settleOrphanedJob?: (job: IToolJobState, abortSignal: AbortSignal) => Promise<IToolJobState> | IToolJobState;
23
+ requestPermission?: (request: IToolPermissionRequest) => Promise<void>;
24
+ }
25
+ export declare const createLocalToolExecutionContext: (options?: ILocalToolExecutionContextOptions) => IToolExecutionContext;
26
+ /** @internal */
27
+ export declare const handleLocalShellChildError: (error: Error, childPid: number | undefined, handlers: {
28
+ settleSpawnFailure: (error: Error) => void;
29
+ retainError: (error: Error) => void;
30
+ requestTermination: () => void;
31
+ }) => void;