@animus-labs/cortex 0.2.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 (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/budget-guard.d.ts +75 -0
  4. package/dist/budget-guard.d.ts.map +1 -0
  5. package/dist/budget-guard.js +142 -0
  6. package/dist/budget-guard.js.map +1 -0
  7. package/dist/compaction/compaction.d.ts +99 -0
  8. package/dist/compaction/compaction.d.ts.map +1 -0
  9. package/dist/compaction/compaction.js +302 -0
  10. package/dist/compaction/compaction.js.map +1 -0
  11. package/dist/compaction/failsafe.d.ts +57 -0
  12. package/dist/compaction/failsafe.d.ts.map +1 -0
  13. package/dist/compaction/failsafe.js +135 -0
  14. package/dist/compaction/failsafe.js.map +1 -0
  15. package/dist/compaction/index.d.ts +381 -0
  16. package/dist/compaction/index.d.ts.map +1 -0
  17. package/dist/compaction/index.js +979 -0
  18. package/dist/compaction/index.js.map +1 -0
  19. package/dist/compaction/microcompaction.d.ts +219 -0
  20. package/dist/compaction/microcompaction.d.ts.map +1 -0
  21. package/dist/compaction/microcompaction.js +536 -0
  22. package/dist/compaction/microcompaction.js.map +1 -0
  23. package/dist/compaction/observational/buffering.d.ts +225 -0
  24. package/dist/compaction/observational/buffering.d.ts.map +1 -0
  25. package/dist/compaction/observational/buffering.js +354 -0
  26. package/dist/compaction/observational/buffering.js.map +1 -0
  27. package/dist/compaction/observational/constants.d.ts +70 -0
  28. package/dist/compaction/observational/constants.d.ts.map +1 -0
  29. package/dist/compaction/observational/constants.js +507 -0
  30. package/dist/compaction/observational/constants.js.map +1 -0
  31. package/dist/compaction/observational/index.d.ts +219 -0
  32. package/dist/compaction/observational/index.d.ts.map +1 -0
  33. package/dist/compaction/observational/index.js +641 -0
  34. package/dist/compaction/observational/index.js.map +1 -0
  35. package/dist/compaction/observational/observer.d.ts +97 -0
  36. package/dist/compaction/observational/observer.d.ts.map +1 -0
  37. package/dist/compaction/observational/observer.js +424 -0
  38. package/dist/compaction/observational/observer.js.map +1 -0
  39. package/dist/compaction/observational/recall-tool.d.ts +27 -0
  40. package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
  41. package/dist/compaction/observational/recall-tool.js +93 -0
  42. package/dist/compaction/observational/recall-tool.js.map +1 -0
  43. package/dist/compaction/observational/reflector.d.ts +94 -0
  44. package/dist/compaction/observational/reflector.d.ts.map +1 -0
  45. package/dist/compaction/observational/reflector.js +167 -0
  46. package/dist/compaction/observational/reflector.js.map +1 -0
  47. package/dist/compaction/observational/types.d.ts +271 -0
  48. package/dist/compaction/observational/types.d.ts.map +1 -0
  49. package/dist/compaction/observational/types.js +15 -0
  50. package/dist/compaction/observational/types.js.map +1 -0
  51. package/dist/context-manager.d.ts +134 -0
  52. package/dist/context-manager.d.ts.map +1 -0
  53. package/dist/context-manager.js +170 -0
  54. package/dist/context-manager.js.map +1 -0
  55. package/dist/cortex-agent.d.ts +1020 -0
  56. package/dist/cortex-agent.d.ts.map +1 -0
  57. package/dist/cortex-agent.js +3589 -0
  58. package/dist/cortex-agent.js.map +1 -0
  59. package/dist/error-classifier.d.ts +48 -0
  60. package/dist/error-classifier.d.ts.map +1 -0
  61. package/dist/error-classifier.js +152 -0
  62. package/dist/error-classifier.js.map +1 -0
  63. package/dist/event-bridge.d.ts +166 -0
  64. package/dist/event-bridge.d.ts.map +1 -0
  65. package/dist/event-bridge.js +381 -0
  66. package/dist/event-bridge.js.map +1 -0
  67. package/dist/index.d.ts +55 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +57 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/mcp-client.d.ts +119 -0
  72. package/dist/mcp-client.d.ts.map +1 -0
  73. package/dist/mcp-client.js +474 -0
  74. package/dist/mcp-client.js.map +1 -0
  75. package/dist/model-wrapper.d.ts +58 -0
  76. package/dist/model-wrapper.d.ts.map +1 -0
  77. package/dist/model-wrapper.js +86 -0
  78. package/dist/model-wrapper.js.map +1 -0
  79. package/dist/noop-logger.d.ts +4 -0
  80. package/dist/noop-logger.d.ts.map +1 -0
  81. package/dist/noop-logger.js +8 -0
  82. package/dist/noop-logger.js.map +1 -0
  83. package/dist/prompt-diagnostics.d.ts +47 -0
  84. package/dist/prompt-diagnostics.d.ts.map +1 -0
  85. package/dist/prompt-diagnostics.js +230 -0
  86. package/dist/prompt-diagnostics.js.map +1 -0
  87. package/dist/provider-manager.d.ts +224 -0
  88. package/dist/provider-manager.d.ts.map +1 -0
  89. package/dist/provider-manager.js +563 -0
  90. package/dist/provider-manager.js.map +1 -0
  91. package/dist/provider-registry.d.ts +115 -0
  92. package/dist/provider-registry.d.ts.map +1 -0
  93. package/dist/provider-registry.js +305 -0
  94. package/dist/provider-registry.js.map +1 -0
  95. package/dist/schema-converter.d.ts +20 -0
  96. package/dist/schema-converter.d.ts.map +1 -0
  97. package/dist/schema-converter.js +48 -0
  98. package/dist/schema-converter.js.map +1 -0
  99. package/dist/skill-preprocessor.d.ts +46 -0
  100. package/dist/skill-preprocessor.d.ts.map +1 -0
  101. package/dist/skill-preprocessor.js +237 -0
  102. package/dist/skill-preprocessor.js.map +1 -0
  103. package/dist/skill-registry.d.ts +107 -0
  104. package/dist/skill-registry.d.ts.map +1 -0
  105. package/dist/skill-registry.js +330 -0
  106. package/dist/skill-registry.js.map +1 -0
  107. package/dist/skill-tool.d.ts +54 -0
  108. package/dist/skill-tool.d.ts.map +1 -0
  109. package/dist/skill-tool.js +88 -0
  110. package/dist/skill-tool.js.map +1 -0
  111. package/dist/sub-agent-manager.d.ts +90 -0
  112. package/dist/sub-agent-manager.d.ts.map +1 -0
  113. package/dist/sub-agent-manager.js +192 -0
  114. package/dist/sub-agent-manager.js.map +1 -0
  115. package/dist/token-estimator.d.ts +23 -0
  116. package/dist/token-estimator.d.ts.map +1 -0
  117. package/dist/token-estimator.js +27 -0
  118. package/dist/token-estimator.js.map +1 -0
  119. package/dist/tool-contract.d.ts +68 -0
  120. package/dist/tool-contract.d.ts.map +1 -0
  121. package/dist/tool-contract.js +35 -0
  122. package/dist/tool-contract.js.map +1 -0
  123. package/dist/tool-result-persistence.d.ts +89 -0
  124. package/dist/tool-result-persistence.d.ts.map +1 -0
  125. package/dist/tool-result-persistence.js +152 -0
  126. package/dist/tool-result-persistence.js.map +1 -0
  127. package/dist/tools/bash/index.d.ts +71 -0
  128. package/dist/tools/bash/index.d.ts.map +1 -0
  129. package/dist/tools/bash/index.js +485 -0
  130. package/dist/tools/bash/index.js.map +1 -0
  131. package/dist/tools/bash/interactive.d.ts +47 -0
  132. package/dist/tools/bash/interactive.d.ts.map +1 -0
  133. package/dist/tools/bash/interactive.js +262 -0
  134. package/dist/tools/bash/interactive.js.map +1 -0
  135. package/dist/tools/bash/safety.d.ts +149 -0
  136. package/dist/tools/bash/safety.d.ts.map +1 -0
  137. package/dist/tools/bash/safety.js +1116 -0
  138. package/dist/tools/bash/safety.js.map +1 -0
  139. package/dist/tools/edit.d.ts +57 -0
  140. package/dist/tools/edit.d.ts.map +1 -0
  141. package/dist/tools/edit.js +310 -0
  142. package/dist/tools/edit.js.map +1 -0
  143. package/dist/tools/glob.d.ts +34 -0
  144. package/dist/tools/glob.d.ts.map +1 -0
  145. package/dist/tools/glob.js +268 -0
  146. package/dist/tools/glob.js.map +1 -0
  147. package/dist/tools/grep.d.ts +53 -0
  148. package/dist/tools/grep.d.ts.map +1 -0
  149. package/dist/tools/grep.js +673 -0
  150. package/dist/tools/grep.js.map +1 -0
  151. package/dist/tools/index.d.ts +62 -0
  152. package/dist/tools/index.d.ts.map +1 -0
  153. package/dist/tools/index.js +52 -0
  154. package/dist/tools/index.js.map +1 -0
  155. package/dist/tools/read.d.ts +43 -0
  156. package/dist/tools/read.d.ts.map +1 -0
  157. package/dist/tools/read.js +459 -0
  158. package/dist/tools/read.js.map +1 -0
  159. package/dist/tools/runtime.d.ts +62 -0
  160. package/dist/tools/runtime.d.ts.map +1 -0
  161. package/dist/tools/runtime.js +116 -0
  162. package/dist/tools/runtime.js.map +1 -0
  163. package/dist/tools/shared/cwd-tracker.d.ts +32 -0
  164. package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
  165. package/dist/tools/shared/cwd-tracker.js +44 -0
  166. package/dist/tools/shared/cwd-tracker.js.map +1 -0
  167. package/dist/tools/shared/edit-history.d.ts +55 -0
  168. package/dist/tools/shared/edit-history.d.ts.map +1 -0
  169. package/dist/tools/shared/edit-history.js +72 -0
  170. package/dist/tools/shared/edit-history.js.map +1 -0
  171. package/dist/tools/shared/edit-matcher.d.ts +83 -0
  172. package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
  173. package/dist/tools/shared/edit-matcher.js +359 -0
  174. package/dist/tools/shared/edit-matcher.js.map +1 -0
  175. package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
  176. package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
  177. package/dist/tools/shared/file-mutation-lock.js +35 -0
  178. package/dist/tools/shared/file-mutation-lock.js.map +1 -0
  179. package/dist/tools/shared/gitignore.d.ts +17 -0
  180. package/dist/tools/shared/gitignore.d.ts.map +1 -0
  181. package/dist/tools/shared/gitignore.js +59 -0
  182. package/dist/tools/shared/gitignore.js.map +1 -0
  183. package/dist/tools/shared/pdf-extractor.d.ts +96 -0
  184. package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
  185. package/dist/tools/shared/pdf-extractor.js +196 -0
  186. package/dist/tools/shared/pdf-extractor.js.map +1 -0
  187. package/dist/tools/shared/read-registry.d.ts +66 -0
  188. package/dist/tools/shared/read-registry.d.ts.map +1 -0
  189. package/dist/tools/shared/read-registry.js +65 -0
  190. package/dist/tools/shared/read-registry.js.map +1 -0
  191. package/dist/tools/shared/safe-env.d.ts +18 -0
  192. package/dist/tools/shared/safe-env.d.ts.map +1 -0
  193. package/dist/tools/shared/safe-env.js +70 -0
  194. package/dist/tools/shared/safe-env.js.map +1 -0
  195. package/dist/tools/sub-agent.d.ts +91 -0
  196. package/dist/tools/sub-agent.d.ts.map +1 -0
  197. package/dist/tools/sub-agent.js +89 -0
  198. package/dist/tools/sub-agent.js.map +1 -0
  199. package/dist/tools/task-output.d.ts +38 -0
  200. package/dist/tools/task-output.d.ts.map +1 -0
  201. package/dist/tools/task-output.js +186 -0
  202. package/dist/tools/task-output.js.map +1 -0
  203. package/dist/tools/tool-search/index.d.ts +40 -0
  204. package/dist/tools/tool-search/index.d.ts.map +1 -0
  205. package/dist/tools/tool-search/index.js +110 -0
  206. package/dist/tools/tool-search/index.js.map +1 -0
  207. package/dist/tools/tool-search/registry.d.ts +82 -0
  208. package/dist/tools/tool-search/registry.d.ts.map +1 -0
  209. package/dist/tools/tool-search/registry.js +238 -0
  210. package/dist/tools/tool-search/registry.js.map +1 -0
  211. package/dist/tools/undo-edit.d.ts +51 -0
  212. package/dist/tools/undo-edit.d.ts.map +1 -0
  213. package/dist/tools/undo-edit.js +231 -0
  214. package/dist/tools/undo-edit.js.map +1 -0
  215. package/dist/tools/web-fetch/cache.d.ts +49 -0
  216. package/dist/tools/web-fetch/cache.d.ts.map +1 -0
  217. package/dist/tools/web-fetch/cache.js +89 -0
  218. package/dist/tools/web-fetch/cache.js.map +1 -0
  219. package/dist/tools/web-fetch/index.d.ts +53 -0
  220. package/dist/tools/web-fetch/index.d.ts.map +1 -0
  221. package/dist/tools/web-fetch/index.js +513 -0
  222. package/dist/tools/web-fetch/index.js.map +1 -0
  223. package/dist/tools/write.d.ts +59 -0
  224. package/dist/tools/write.d.ts.map +1 -0
  225. package/dist/tools/write.js +316 -0
  226. package/dist/tools/write.js.map +1 -0
  227. package/dist/types.d.ts +881 -0
  228. package/dist/types.d.ts.map +1 -0
  229. package/dist/types.js +16 -0
  230. package/dist/types.js.map +1 -0
  231. package/dist/working-tags.d.ts +44 -0
  232. package/dist/working-tags.d.ts.map +1 -0
  233. package/dist/working-tags.js +103 -0
  234. package/dist/working-tags.js.map +1 -0
  235. package/package.json +87 -0
  236. package/src/budget-guard.ts +170 -0
  237. package/src/compaction/compaction.ts +386 -0
  238. package/src/compaction/failsafe.ts +185 -0
  239. package/src/compaction/index.ts +1199 -0
  240. package/src/compaction/microcompaction.ts +709 -0
  241. package/src/compaction/observational/buffering.ts +430 -0
  242. package/src/compaction/observational/constants.ts +532 -0
  243. package/src/compaction/observational/index.ts +837 -0
  244. package/src/compaction/observational/observer.ts +510 -0
  245. package/src/compaction/observational/recall-tool.ts +130 -0
  246. package/src/compaction/observational/reflector.ts +221 -0
  247. package/src/compaction/observational/types.ts +343 -0
  248. package/src/context-manager.ts +237 -0
  249. package/src/cortex-agent.ts +4297 -0
  250. package/src/error-classifier.ts +199 -0
  251. package/src/event-bridge.ts +508 -0
  252. package/src/index.ts +292 -0
  253. package/src/mcp-client.ts +582 -0
  254. package/src/model-wrapper.ts +128 -0
  255. package/src/noop-logger.ts +9 -0
  256. package/src/prompt-diagnostics.ts +296 -0
  257. package/src/provider-manager.ts +823 -0
  258. package/src/provider-registry.ts +386 -0
  259. package/src/schema-converter.ts +51 -0
  260. package/src/skill-preprocessor.ts +314 -0
  261. package/src/skill-registry.ts +378 -0
  262. package/src/skill-tool.ts +130 -0
  263. package/src/sub-agent-manager.ts +236 -0
  264. package/src/token-estimator.ts +26 -0
  265. package/src/tool-contract.ts +113 -0
  266. package/src/tool-result-persistence.ts +197 -0
  267. package/src/tools/bash/index.ts +633 -0
  268. package/src/tools/bash/interactive.ts +302 -0
  269. package/src/tools/bash/safety.ts +1297 -0
  270. package/src/tools/edit.ts +422 -0
  271. package/src/tools/glob.ts +330 -0
  272. package/src/tools/grep.ts +819 -0
  273. package/src/tools/index.ts +110 -0
  274. package/src/tools/read.ts +580 -0
  275. package/src/tools/runtime.ts +173 -0
  276. package/src/tools/shared/cwd-tracker.ts +50 -0
  277. package/src/tools/shared/edit-history.ts +96 -0
  278. package/src/tools/shared/edit-matcher.ts +457 -0
  279. package/src/tools/shared/file-mutation-lock.ts +40 -0
  280. package/src/tools/shared/gitignore.ts +61 -0
  281. package/src/tools/shared/pdf-extractor.ts +290 -0
  282. package/src/tools/shared/read-registry.ts +93 -0
  283. package/src/tools/shared/safe-env.ts +82 -0
  284. package/src/tools/sub-agent.ts +171 -0
  285. package/src/tools/task-output.ts +236 -0
  286. package/src/tools/tool-search/index.ts +167 -0
  287. package/src/tools/tool-search/registry.ts +278 -0
  288. package/src/tools/undo-edit.ts +314 -0
  289. package/src/tools/web-fetch/cache.ts +112 -0
  290. package/src/tools/web-fetch/index.ts +604 -0
  291. package/src/tools/write.ts +385 -0
  292. package/src/types.ts +1057 -0
  293. package/src/working-tags.ts +118 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Bash tool: execute shell commands in the host environment.
3
+ *
4
+ * Cross-platform: bash/zsh on macOS and Linux, PowerShell on Windows.
5
+ * Tracks working directory across calls within an agentic loop.
6
+ * Supports background execution with auto-yield.
7
+ *
8
+ * Reference: docs/cortex/tools/bash.md
9
+ */
10
+ import { Type, type Static } from 'typebox';
11
+ import type { CwdTracker } from '../shared/cwd-tracker.js';
12
+ import type { ToolContentDetails, ToolExecuteContext } from '../../types.js';
13
+ import { type BackgroundTask, type CortexToolRuntime } from '../runtime.js';
14
+ export declare const BashParams: Type.TObject<{
15
+ command: Type.TString;
16
+ timeout: Type.TOptional<Type.TNumber>;
17
+ description: Type.TOptional<Type.TString>;
18
+ background: Type.TOptional<Type.TBoolean>;
19
+ }>;
20
+ export type BashParamsType = Static<typeof BashParams>;
21
+ export interface BashDetails {
22
+ stdout: string;
23
+ stderr: string;
24
+ exitCode: number | null;
25
+ duration: number;
26
+ interrupted: boolean;
27
+ timedOut: boolean;
28
+ backgrounded: boolean;
29
+ taskId: string | null;
30
+ finalCwd: string;
31
+ }
32
+ /**
33
+ * Partial result details emitted during bash streaming via onUpdate.
34
+ */
35
+ export interface BashStreamUpdate {
36
+ /** New stdout chunk since last update (complete lines only). */
37
+ stdout: string;
38
+ /** New stderr chunk since last update. */
39
+ stderr: string;
40
+ /** Total stdout lines emitted so far. */
41
+ totalLines: number;
42
+ }
43
+ export interface BashToolConfig {
44
+ runtime?: CortexToolRuntime | undefined;
45
+ cwdTracker?: CwdTracker | undefined;
46
+ /** Custom shell path override. */
47
+ shellPath?: string | undefined;
48
+ /** Auto-yield threshold in ms. Default: 10000. */
49
+ autoYieldThreshold?: number | undefined;
50
+ /** Callback for tracking subprocess PIDs (for cleanup on exit). */
51
+ onProcessSpawned?: ((pid: number) => void) | undefined;
52
+ /** Callback for removing tracked PIDs when process exits. */
53
+ onProcessExited?: ((pid: number) => void) | undefined;
54
+ /** Utility model completion function for Layer 7 safety classifier. */
55
+ utilityComplete?: ((context: unknown) => Promise<unknown>) | undefined;
56
+ /**
57
+ * Consumer-set environment variable overrides that bypass the security blocklist.
58
+ * Merged ON TOP of the sanitized environment for shell subprocesses.
59
+ * Used for macOS dock icon suppression vars (DYLD_INSERT_LIBRARIES, etc.).
60
+ */
61
+ envOverrides?: Record<string, string> | undefined;
62
+ }
63
+ export declare function getBackgroundTask(id: string): BackgroundTask | undefined;
64
+ export declare function getAllBackgroundTasks(): Map<string, BackgroundTask>;
65
+ export declare function createBashTool(config: BashToolConfig): {
66
+ name: string;
67
+ description: string;
68
+ parameters: typeof BashParams;
69
+ execute: (params: BashParamsType, context?: ToolExecuteContext) => Promise<ToolContentDetails<BashDetails>>;
70
+ };
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/bash/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EAGvB,MAAM,eAAe,CAAC;AAMvB,eAAO,MAAM,UAAU;;;;;EAWrB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAMvD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB;AAeD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACxC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACpC,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACvD,6DAA6D;IAC7D,eAAe,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtD,uEAAuE;IACvE,eAAe,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACvE;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACnD;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAExE;AAED,wBAAgB,qBAAqB,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAEnE;AA0ID,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,OAAO,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC;CAC7G,CA8VA"}
@@ -0,0 +1,485 @@
1
+ /**
2
+ * Bash tool: execute shell commands in the host environment.
3
+ *
4
+ * Cross-platform: bash/zsh on macOS and Linux, PowerShell on Windows.
5
+ * Tracks working directory across calls within an agentic loop.
6
+ * Supports background execution with auto-yield.
7
+ *
8
+ * Reference: docs/cortex/tools/bash.md
9
+ */
10
+ import * as child_process from 'node:child_process';
11
+ import * as fs from 'node:fs';
12
+ import { Type } from 'typebox';
13
+ import { buildSafeEnv, runSafetyChecks } from './safety.js';
14
+ import { attachRuntimeAwareTool, globalBackgroundTaskStore, } from '../runtime.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Schema
17
+ // ---------------------------------------------------------------------------
18
+ export const BashParams = Type.Object({
19
+ command: Type.String({ description: 'The shell command to execute' }),
20
+ timeout: Type.Optional(Type.Number({ description: 'Timeout in milliseconds. Default: 120000 (2 min). Max: 600000 (10 min).' })),
21
+ description: Type.Optional(Type.String({ description: 'Human-readable explanation of the command.' })),
22
+ background: Type.Optional(Type.Boolean({ description: 'Run the command in the background immediately. Default: false.' })),
23
+ });
24
+ // ---------------------------------------------------------------------------
25
+ // Constants
26
+ // ---------------------------------------------------------------------------
27
+ const DEFAULT_TIMEOUT = 120_000;
28
+ const MAX_TIMEOUT = 600_000;
29
+ const AUTO_YIELD_THRESHOLD = 10_000; // 10 seconds
30
+ const CWD_MARKER = '___CWD___';
31
+ export function getBackgroundTask(id) {
32
+ return globalBackgroundTaskStore.get(id);
33
+ }
34
+ export function getAllBackgroundTasks() {
35
+ return globalBackgroundTaskStore.getAll();
36
+ }
37
+ /**
38
+ * Read /etc/shells and return the set of trusted shell paths.
39
+ */
40
+ function readTrustedShells() {
41
+ const trusted = new Set();
42
+ try {
43
+ const content = fs.readFileSync('/etc/shells', 'utf8');
44
+ for (const line of content.split('\n')) {
45
+ const trimmed = line.trim();
46
+ if (trimmed && !trimmed.startsWith('#')) {
47
+ trusted.add(trimmed);
48
+ }
49
+ }
50
+ }
51
+ catch {
52
+ // /etc/shells not available; empty set means we fall back
53
+ }
54
+ return trusted;
55
+ }
56
+ /**
57
+ * Select the appropriate shell for the current platform.
58
+ */
59
+ function selectShell(customShellPath) {
60
+ // Custom override
61
+ if (customShellPath) {
62
+ if (process.platform === 'win32') {
63
+ return { shell: customShellPath, args: ['-NoProfile', '-NonInteractive', '-Command'] };
64
+ }
65
+ return { shell: customShellPath, args: ['-c'] };
66
+ }
67
+ if (process.platform === 'win32') {
68
+ return selectWindowsShell();
69
+ }
70
+ return selectUnixShell();
71
+ }
72
+ function selectUnixShell() {
73
+ const userShell = process.env['SHELL'];
74
+ if (userShell) {
75
+ // Reject fish (incompatible with common bashisms)
76
+ if (userShell.endsWith('/fish')) {
77
+ return findUnixFallback();
78
+ }
79
+ // Validate against /etc/shells
80
+ const trusted = readTrustedShells();
81
+ if (trusted.size === 0 || trusted.has(userShell)) {
82
+ return { shell: userShell, args: ['-c'] };
83
+ }
84
+ }
85
+ return findUnixFallback();
86
+ }
87
+ function findUnixFallback() {
88
+ // Try /bin/bash first, then /bin/sh
89
+ for (const shell of ['/bin/bash', '/bin/sh']) {
90
+ try {
91
+ fs.accessSync(shell, fs.constants.X_OK);
92
+ return { shell, args: ['-c'] };
93
+ }
94
+ catch {
95
+ continue;
96
+ }
97
+ }
98
+ return { shell: '/bin/sh', args: ['-c'] };
99
+ }
100
+ function selectWindowsShell() {
101
+ // Try PowerShell 7 first
102
+ const ps7Paths = [
103
+ 'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
104
+ `${process.env['ProgramW6432']}\\PowerShell\\7\\pwsh.exe`,
105
+ ];
106
+ for (const ps7 of ps7Paths) {
107
+ try {
108
+ fs.accessSync(ps7, fs.constants.X_OK);
109
+ return { shell: ps7, args: ['-NoProfile', '-NonInteractive', '-Command'] };
110
+ }
111
+ catch {
112
+ continue;
113
+ }
114
+ }
115
+ // Fall back to Windows PowerShell 5.1
116
+ const ps5 = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
117
+ return { shell: ps5, args: ['-NoProfile', '-NonInteractive', '-Command'] };
118
+ }
119
+ // ---------------------------------------------------------------------------
120
+ // Output handling
121
+ // ---------------------------------------------------------------------------
122
+ /**
123
+ * Sanitize output by stripping binary control characters.
124
+ * Preserves tab, newline, and carriage return.
125
+ */
126
+ function sanitizeOutput(output) {
127
+ // eslint-disable-next-line no-control-regex
128
+ return output.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
129
+ }
130
+ /**
131
+ * Extract CWD from output using the CWD_MARKER.
132
+ * Returns [cleanedOutput, extractedCwd].
133
+ */
134
+ function extractCwd(output) {
135
+ const markerIdx = output.lastIndexOf(CWD_MARKER);
136
+ if (markerIdx === -1)
137
+ return [output, null];
138
+ const beforeMarker = output.slice(0, markerIdx);
139
+ const afterMarker = output.slice(markerIdx + CWD_MARKER.length).trim();
140
+ // The CWD is on the line after the marker
141
+ const lines = afterMarker.split('\n');
142
+ const cwd = (lines[0] ?? '').trim();
143
+ return [beforeMarker.trimEnd(), cwd || null];
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // Tool factory
147
+ // ---------------------------------------------------------------------------
148
+ export function createBashTool(config) {
149
+ const cwdTracker = config.runtime?.cwdTracker ?? config.cwdTracker;
150
+ if (!cwdTracker) {
151
+ throw new Error('createBashTool requires either runtime or cwdTracker');
152
+ }
153
+ const backgroundTasks = config.runtime?.backgroundTasks ?? globalBackgroundTaskStore;
154
+ const autoYieldThreshold = config.autoYieldThreshold ?? AUTO_YIELD_THRESHOLD;
155
+ const tool = {
156
+ name: 'Bash',
157
+ description: 'Execute a shell command in the host environment.',
158
+ parameters: BashParams,
159
+ async execute(params, context) {
160
+ backgroundTasks.cleanupCompletedTasks();
161
+ const timeout = Math.min(params.timeout ?? DEFAULT_TIMEOUT, MAX_TIMEOUT);
162
+ const background = params.background ?? false;
163
+ const startTime = Date.now();
164
+ // Run safety checks (Layers 2-7)
165
+ const safetyResult = await runSafetyChecks(params.command, cwdTracker.getDefaultDir(), cwdTracker.getCwd(), {
166
+ utilityComplete: config.utilityComplete,
167
+ description: params.description,
168
+ });
169
+ if (!safetyResult.allowed) {
170
+ return {
171
+ content: [{ type: 'text', text: safetyResult.reason ?? 'Command blocked by safety check.' }],
172
+ details: {
173
+ stdout: '',
174
+ stderr: '',
175
+ exitCode: null,
176
+ duration: Date.now() - startTime,
177
+ interrupted: false,
178
+ timedOut: false,
179
+ backgrounded: false,
180
+ taskId: null,
181
+ finalCwd: cwdTracker.getCwd(),
182
+ },
183
+ };
184
+ }
185
+ // Select shell
186
+ const shellConfig = selectShell(config.shellPath);
187
+ // Verify shell exists
188
+ try {
189
+ fs.accessSync(shellConfig.shell, fs.constants.X_OK);
190
+ }
191
+ catch {
192
+ return {
193
+ content: [{ type: 'text', text: `Shell not found: ${shellConfig.shell}. Configure a custom shell in settings.` }],
194
+ details: {
195
+ stdout: '',
196
+ stderr: '',
197
+ exitCode: null,
198
+ duration: Date.now() - startTime,
199
+ interrupted: false,
200
+ timedOut: false,
201
+ backgrounded: false,
202
+ taskId: null,
203
+ finalCwd: cwdTracker.getCwd(),
204
+ },
205
+ };
206
+ }
207
+ // Build safe environment (Layer 1), with consumer overrides merged on top
208
+ const safeEnv = buildSafeEnv(process.env, config.envOverrides);
209
+ // Append CWD capture suffix
210
+ const isWindows = process.platform === 'win32';
211
+ // Capture exit code before CWD suffix so pwd/Get-Location don't mask it
212
+ const cwdSuffix = isWindows
213
+ ? `; $__ec=$LASTEXITCODE; Write-Host "${CWD_MARKER}"; Get-Location; exit $__ec`
214
+ : `; __ec=$?; echo "${CWD_MARKER}"; pwd; exit $__ec`;
215
+ // UTF-8 prefix for Windows PowerShell
216
+ const utf8Prefix = isWindows
217
+ ? '$OutputEncoding = [System.Text.Encoding]::UTF8; [Console]::OutputEncoding = [System.Text.Encoding]::UTF8; '
218
+ : '';
219
+ const fullCommand = `${utf8Prefix}${params.command}${cwdSuffix}`;
220
+ // Spawn the process
221
+ const proc = child_process.spawn(shellConfig.shell, [...shellConfig.args, fullCommand], {
222
+ cwd: cwdTracker.getCwd(),
223
+ env: safeEnv,
224
+ stdio: ['pipe', 'pipe', 'pipe'],
225
+ detached: !isWindows, // Process group for Unix cleanup
226
+ });
227
+ // Track PID
228
+ if (proc.pid && config.onProcessSpawned) {
229
+ config.onProcessSpawned(proc.pid);
230
+ }
231
+ // Background execution
232
+ if (background) {
233
+ const taskId = backgroundTasks.nextTaskId();
234
+ const task = {
235
+ id: taskId,
236
+ command: params.command.slice(0, 120),
237
+ process: proc,
238
+ stdout: '',
239
+ stderr: '',
240
+ exitCode: null,
241
+ completed: false,
242
+ startTime: Date.now(),
243
+ };
244
+ backgroundTasks.set(task);
245
+ proc.stdout?.setEncoding('utf8');
246
+ proc.stderr?.setEncoding('utf8');
247
+ proc.stdout?.on('data', (data) => { task.stdout += data; });
248
+ proc.stderr?.on('data', (data) => { task.stderr += data; });
249
+ proc.on('close', (code) => {
250
+ task.exitCode = code;
251
+ task.completed = true;
252
+ if (proc.pid && config.onProcessExited) {
253
+ config.onProcessExited(proc.pid);
254
+ }
255
+ });
256
+ return {
257
+ content: [{ type: 'text', text: `Command running in background. Task ID: ${taskId}\nUse TaskOutput to poll, send input, or kill.` }],
258
+ details: {
259
+ stdout: '',
260
+ stderr: '',
261
+ exitCode: null,
262
+ duration: 0,
263
+ interrupted: false,
264
+ timedOut: false,
265
+ backgrounded: true,
266
+ taskId,
267
+ finalCwd: cwdTracker.getCwd(),
268
+ },
269
+ };
270
+ }
271
+ // Foreground execution
272
+ return new Promise((resolve) => {
273
+ let stdout = '';
274
+ let stderr = '';
275
+ let timedOut = false;
276
+ let autoYielded = false;
277
+ let taskId = null;
278
+ // Streaming state: buffer chunks and emit complete lines every 100ms
279
+ const onUpdate = context?.onUpdate;
280
+ let pendingStdout = '';
281
+ let pendingStderr = '';
282
+ let totalLinesEmitted = 0;
283
+ const flushStreamUpdate = () => {
284
+ if (!onUpdate)
285
+ return;
286
+ // Only emit complete lines (hold partial lines in the buffer)
287
+ const lastNewline = pendingStdout.lastIndexOf('\n');
288
+ const lastStderrNewline = pendingStderr.lastIndexOf('\n');
289
+ if (lastNewline === -1 && lastStderrNewline === -1)
290
+ return;
291
+ let stdoutChunk = '';
292
+ if (lastNewline >= 0) {
293
+ stdoutChunk = pendingStdout.slice(0, lastNewline + 1);
294
+ pendingStdout = pendingStdout.slice(lastNewline + 1);
295
+ totalLinesEmitted += stdoutChunk.split('\n').length - 1;
296
+ }
297
+ let stderrChunk = '';
298
+ if (lastStderrNewline >= 0) {
299
+ stderrChunk = pendingStderr.slice(0, lastStderrNewline + 1);
300
+ pendingStderr = pendingStderr.slice(lastStderrNewline + 1);
301
+ }
302
+ onUpdate({
303
+ content: [{ type: 'text', text: stdoutChunk + stderrChunk }],
304
+ details: { stdout: stdoutChunk, stderr: stderrChunk, totalLines: totalLinesEmitted },
305
+ });
306
+ };
307
+ const streamInterval = onUpdate ? setInterval(flushStreamUpdate, 100) : null;
308
+ proc.stdout?.setEncoding('utf8');
309
+ proc.stderr?.setEncoding('utf8');
310
+ proc.stdout?.on('data', (data) => {
311
+ stdout += data;
312
+ pendingStdout += data;
313
+ });
314
+ proc.stderr?.on('data', (data) => {
315
+ stderr += data;
316
+ pendingStderr += data;
317
+ });
318
+ // Timeout handler
319
+ const timeoutTimer = setTimeout(() => {
320
+ timedOut = true;
321
+ killProcessTree(proc);
322
+ }, timeout);
323
+ // Auto-yield handler
324
+ const autoYieldTimer = setTimeout(() => {
325
+ if (!proc.exitCode && proc.pid) {
326
+ autoYielded = true;
327
+ taskId = backgroundTasks.nextTaskId();
328
+ const task = {
329
+ id: taskId,
330
+ command: params.command.slice(0, 120),
331
+ process: proc,
332
+ stdout,
333
+ stderr,
334
+ exitCode: null,
335
+ completed: false,
336
+ startTime: Date.now(),
337
+ };
338
+ backgroundTasks.set(task);
339
+ // Remove original foreground listeners to prevent memory leak
340
+ proc.stdout?.removeAllListeners('data');
341
+ proc.stderr?.removeAllListeners('data');
342
+ // Continue collecting output for the background task
343
+ proc.stdout?.on('data', (data) => { task.stdout += data; });
344
+ proc.stderr?.on('data', (data) => { task.stderr += data; });
345
+ proc.on('close', (code) => {
346
+ task.exitCode = code;
347
+ task.completed = true;
348
+ if (proc.pid && config.onProcessExited) {
349
+ config.onProcessExited(proc.pid);
350
+ }
351
+ });
352
+ clearTimeout(timeoutTimer);
353
+ if (streamInterval) {
354
+ clearInterval(streamInterval);
355
+ flushStreamUpdate();
356
+ }
357
+ const [cleanedOutput] = extractCwd(sanitizeOutput(stdout));
358
+ resolve({
359
+ content: [{ type: 'text', text: `${cleanedOutput}\n\n[Command auto-yielded after ${autoYieldThreshold}ms. Task ID: ${taskId}]` }],
360
+ details: {
361
+ stdout: cleanedOutput,
362
+ stderr,
363
+ exitCode: null,
364
+ duration: Date.now() - startTime,
365
+ interrupted: false,
366
+ timedOut: false,
367
+ backgrounded: true,
368
+ taskId,
369
+ finalCwd: cwdTracker.getCwd(),
370
+ },
371
+ });
372
+ }
373
+ }, autoYieldThreshold);
374
+ proc.on('close', (code) => {
375
+ clearTimeout(timeoutTimer);
376
+ clearTimeout(autoYieldTimer);
377
+ if (streamInterval) {
378
+ clearInterval(streamInterval);
379
+ flushStreamUpdate();
380
+ }
381
+ if (proc.pid && config.onProcessExited) {
382
+ config.onProcessExited(proc.pid);
383
+ }
384
+ // If already auto-yielded, don't resolve again
385
+ if (autoYielded)
386
+ return;
387
+ const rawOutput = sanitizeOutput(stdout);
388
+ const [cleanedOutput, newCwd] = extractCwd(rawOutput);
389
+ // Update CWD tracker
390
+ if (newCwd) {
391
+ cwdTracker.updateCwd(newCwd);
392
+ }
393
+ const duration = Date.now() - startTime;
394
+ let text = cleanedOutput;
395
+ if (stderr) {
396
+ text += `\nstderr: ${stderr}`;
397
+ }
398
+ if (timedOut) {
399
+ text += `\nCommand timed out after ${timeout}ms.`;
400
+ }
401
+ if (code !== null && code !== 0) {
402
+ text += `\nExit code: ${code}`;
403
+ }
404
+ resolve({
405
+ content: [{ type: 'text', text: text || '(no output)' }],
406
+ details: {
407
+ stdout: cleanedOutput,
408
+ stderr,
409
+ exitCode: code,
410
+ duration,
411
+ interrupted: false,
412
+ timedOut,
413
+ backgrounded: false,
414
+ taskId: null,
415
+ finalCwd: newCwd ?? cwdTracker.getCwd(),
416
+ },
417
+ });
418
+ });
419
+ proc.on('error', (err) => {
420
+ clearTimeout(timeoutTimer);
421
+ clearTimeout(autoYieldTimer);
422
+ if (streamInterval) {
423
+ clearInterval(streamInterval);
424
+ flushStreamUpdate();
425
+ }
426
+ if (autoYielded)
427
+ return;
428
+ resolve({
429
+ content: [{ type: 'text', text: `Failed to execute command: ${err.message}` }],
430
+ details: {
431
+ stdout,
432
+ stderr,
433
+ exitCode: null,
434
+ duration: Date.now() - startTime,
435
+ interrupted: false,
436
+ timedOut: false,
437
+ backgrounded: false,
438
+ taskId: null,
439
+ finalCwd: cwdTracker.getCwd(),
440
+ },
441
+ });
442
+ });
443
+ });
444
+ },
445
+ };
446
+ return attachRuntimeAwareTool(tool, {
447
+ toolKind: 'Bash',
448
+ cloneForRuntime: (runtime) => createBashTool({
449
+ ...config,
450
+ runtime,
451
+ cwdTracker: runtime.cwdTracker,
452
+ }),
453
+ });
454
+ }
455
+ // ---------------------------------------------------------------------------
456
+ // Process tree cleanup
457
+ // ---------------------------------------------------------------------------
458
+ /**
459
+ * Kill the entire process tree.
460
+ * Unix: send SIGKILL to the process group.
461
+ * Windows: use taskkill /F /T.
462
+ */
463
+ function killProcessTree(proc) {
464
+ if (!proc.pid)
465
+ return;
466
+ try {
467
+ if (process.platform === 'win32') {
468
+ child_process.execFileSync('taskkill', ['/F', '/T', '/PID', String(proc.pid)], { stdio: 'ignore' });
469
+ }
470
+ else {
471
+ // Kill the entire process group
472
+ process.kill(-proc.pid, 'SIGKILL');
473
+ }
474
+ }
475
+ catch {
476
+ // Process may have already exited
477
+ try {
478
+ proc.kill('SIGKILL');
479
+ }
480
+ catch {
481
+ // Ignore
482
+ }
483
+ }
484
+ }
485
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/bash/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Interactive command detection for Bash.
3
+ *
4
+ * Catches commands that would block waiting for TTY input (editors,
5
+ * pagers, REPLs, interactive DB clients) and rejects them with a
6
+ * concrete non-interactive suggestion. Prevents the agent from burning
7
+ * its entire timeout budget on a hung `vim` or `psql` invocation.
8
+ *
9
+ * This is a UX gate, not a security gate: it sits at the end of the
10
+ * safety cascade after all security layers have passed. Security checks
11
+ * always come first.
12
+ *
13
+ * The module is pure — no I/O, no global state — so the rule set can be
14
+ * exhaustively unit-tested without a shell.
15
+ */
16
+ import { type SafetyCheckResult } from './safety.js';
17
+ /**
18
+ * Check a full shell command for interactive invocations. Splits on
19
+ * shell operators (`;`, `&&`, `||`, `|`) and inspects each sub-command
20
+ * independently — `cat file | less` is rejected because the `less`
21
+ * sub-command is interactive, even though `cat` is not.
22
+ *
23
+ * Returns the first interactive sub-command's rejection; if all
24
+ * sub-commands are non-interactive, returns `{ allowed: true }`.
25
+ */
26
+ export declare function checkInteractive(command: string): SafetyCheckResult;
27
+ /**
28
+ * Minimal shell-aware tokenizer: splits on unquoted whitespace, keeps
29
+ * single/double-quoted regions intact (quotes themselves are stripped),
30
+ * and honors backslash escapes. Sufficient for identifying the program
31
+ * token and distinguishing flags from positional args; not a complete
32
+ * POSIX shell parser.
33
+ */
34
+ export declare function tokenize(command: string): string[];
35
+ /**
36
+ * Find the effective program name and argument list, accounting for:
37
+ * 1. Leading `KEY=VALUE` env var prefixes (`FOO=bar vim file`)
38
+ * 2. The `env` wrapper (`env FOO=bar vim file` or `env -u BAR vim`)
39
+ *
40
+ * Returns the program's basename (last path segment) and the remaining
41
+ * arg tokens, or `null` if no program token is present.
42
+ */
43
+ export declare function findProgram(tokens: string[]): {
44
+ name: string;
45
+ args: string[];
46
+ } | null;
47
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/tools/bash/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAyB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA4E5E;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAiBnE;AAMD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BlD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EAAE,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CA+BzC"}