@defai.digital/ax-cli 3.8.6 → 3.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/README.md +28 -393
  2. package/config-defaults/models.yaml +0 -24
  3. package/config-defaults/settings.yaml +16 -16
  4. package/dist/agent/dependency-resolver.js +22 -1
  5. package/dist/agent/dependency-resolver.js.map +1 -1
  6. package/dist/agent/llm-agent.d.ts +23 -2
  7. package/dist/agent/llm-agent.js +126 -122
  8. package/dist/agent/llm-agent.js.map +1 -1
  9. package/dist/agent/loop-detector.d.ts +70 -0
  10. package/dist/agent/loop-detector.js +339 -0
  11. package/dist/agent/loop-detector.js.map +1 -0
  12. package/dist/agent/progress-tracker.d.ts +94 -0
  13. package/dist/agent/progress-tracker.js +222 -0
  14. package/dist/agent/progress-tracker.js.map +1 -0
  15. package/dist/agent/status-reporter.js +2 -2
  16. package/dist/agent/status-reporter.js.map +1 -1
  17. package/dist/agent/subagent.js +7 -3
  18. package/dist/agent/subagent.js.map +1 -1
  19. package/dist/analyzers/architecture/project-structure-scanner.js +6 -2
  20. package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -1
  21. package/dist/analyzers/git/churn-calculator.js +2 -1
  22. package/dist/analyzers/git/churn-calculator.js.map +1 -1
  23. package/dist/checkpoint/manager.js +18 -4
  24. package/dist/checkpoint/manager.js.map +1 -1
  25. package/dist/checkpoint/storage.d.ts +6 -0
  26. package/dist/checkpoint/storage.js +96 -49
  27. package/dist/checkpoint/storage.js.map +1 -1
  28. package/dist/commands/cache.js +8 -6
  29. package/dist/commands/cache.js.map +1 -1
  30. package/dist/commands/doctor.js +19 -27
  31. package/dist/commands/doctor.js.map +1 -1
  32. package/dist/commands/mcp-migrate.js +6 -5
  33. package/dist/commands/mcp-migrate.js.map +1 -1
  34. package/dist/commands/mcp.js +14 -2
  35. package/dist/commands/mcp.js.map +1 -1
  36. package/dist/commands/models.js +8 -12
  37. package/dist/commands/models.js.map +1 -1
  38. package/dist/commands/plan.js +1 -10
  39. package/dist/commands/plan.js.map +1 -1
  40. package/dist/commands/setup.js +4 -3
  41. package/dist/commands/setup.js.map +1 -1
  42. package/dist/commands/status.js +40 -14
  43. package/dist/commands/status.js.map +1 -1
  44. package/dist/constants.d.ts +12 -0
  45. package/dist/constants.js +16 -4
  46. package/dist/constants.js.map +1 -1
  47. package/dist/hooks/hook-runner.d.ts +138 -0
  48. package/dist/hooks/hook-runner.js +429 -0
  49. package/dist/hooks/hook-runner.js.map +1 -0
  50. package/dist/hooks/index.d.ts +6 -0
  51. package/dist/hooks/index.js +7 -0
  52. package/dist/hooks/index.js.map +1 -0
  53. package/dist/index.js +3 -21
  54. package/dist/index.js.map +1 -1
  55. package/dist/llm/client.d.ts +9 -0
  56. package/dist/llm/client.js +306 -45
  57. package/dist/llm/client.js.map +1 -1
  58. package/dist/llm/tools.js +2 -39
  59. package/dist/llm/tools.js.map +1 -1
  60. package/dist/llm/types.d.ts +1 -47
  61. package/dist/llm/types.js +0 -18
  62. package/dist/llm/types.js.map +1 -1
  63. package/dist/mcp/automatosx-loader.js +2 -1
  64. package/dist/mcp/automatosx-loader.js.map +1 -1
  65. package/dist/mcp/client-v2.d.ts +3 -0
  66. package/dist/mcp/client-v2.js +85 -19
  67. package/dist/mcp/client-v2.js.map +1 -1
  68. package/dist/mcp/config-migrator.js +3 -2
  69. package/dist/mcp/config-migrator.js.map +1 -1
  70. package/dist/mcp/config-v2.d.ts +5 -0
  71. package/dist/mcp/config-v2.js +26 -0
  72. package/dist/mcp/config-v2.js.map +1 -1
  73. package/dist/mcp/error-formatter.js +4 -1
  74. package/dist/mcp/error-formatter.js.map +1 -1
  75. package/dist/mcp/health.js +1 -1
  76. package/dist/mcp/health.js.map +1 -1
  77. package/dist/mcp/reconnection.js +2 -1
  78. package/dist/mcp/reconnection.js.map +1 -1
  79. package/dist/mcp/registry.js +3 -2
  80. package/dist/mcp/registry.js.map +1 -1
  81. package/dist/mcp/resources.js +2 -1
  82. package/dist/mcp/resources.js.map +1 -1
  83. package/dist/mcp/validation.js +9 -0
  84. package/dist/mcp/validation.js.map +1 -1
  85. package/dist/memory/context-store.js +4 -6
  86. package/dist/memory/context-store.js.map +1 -1
  87. package/dist/memory/types.d.ts +2 -0
  88. package/dist/memory/types.js +4 -1
  89. package/dist/memory/types.js.map +1 -1
  90. package/dist/permissions/index.d.ts +6 -0
  91. package/dist/permissions/index.js +7 -0
  92. package/dist/permissions/index.js.map +1 -0
  93. package/dist/permissions/permission-manager.d.ts +145 -0
  94. package/dist/permissions/permission-manager.js +401 -0
  95. package/dist/permissions/permission-manager.js.map +1 -0
  96. package/dist/planner/plan-storage.js +3 -2
  97. package/dist/planner/plan-storage.js.map +1 -1
  98. package/dist/planner/task-planner.js +2 -1
  99. package/dist/planner/task-planner.js.map +1 -1
  100. package/dist/planner/types.d.ts +6 -6
  101. package/dist/schemas/settings-schemas.d.ts +0 -14
  102. package/dist/schemas/settings-schemas.js +0 -10
  103. package/dist/schemas/settings-schemas.js.map +1 -1
  104. package/dist/schemas/tool-schemas.d.ts +2 -2
  105. package/dist/schemas/yaml-schemas.d.ts +15 -0
  106. package/dist/schemas/yaml-schemas.js +3 -0
  107. package/dist/schemas/yaml-schemas.js.map +1 -1
  108. package/dist/tools/bash.js +35 -10
  109. package/dist/tools/bash.js.map +1 -1
  110. package/dist/tools/confirmation-tool.js +3 -2
  111. package/dist/tools/confirmation-tool.js.map +1 -1
  112. package/dist/tools/registry.d.ts +1 -1
  113. package/dist/tools/registry.js +2 -1
  114. package/dist/tools/registry.js.map +1 -1
  115. package/dist/tools/search.js +12 -13
  116. package/dist/tools/search.js.map +1 -1
  117. package/dist/tools/text-editor.d.ts +46 -0
  118. package/dist/tools/text-editor.js +455 -11
  119. package/dist/tools/text-editor.js.map +1 -1
  120. package/dist/tools/todo-tool.js +5 -4
  121. package/dist/tools/todo-tool.js.map +1 -1
  122. package/dist/ui/components/chat-input.js +10 -1
  123. package/dist/ui/components/chat-input.js.map +1 -1
  124. package/dist/ui/components/chat-interface.js +1 -0
  125. package/dist/ui/components/chat-interface.js.map +1 -1
  126. package/dist/ui/components/tool-group-display.js +0 -6
  127. package/dist/ui/components/tool-group-display.js.map +1 -1
  128. package/dist/ui/hooks/use-input-handler.js +7 -6
  129. package/dist/ui/hooks/use-input-handler.js.map +1 -1
  130. package/dist/ui/hooks/use-input-history.js +21 -13
  131. package/dist/ui/hooks/use-input-history.js.map +1 -1
  132. package/dist/ui/utils/tool-grouper.d.ts +1 -2
  133. package/dist/ui/utils/tool-grouper.js +4 -15
  134. package/dist/ui/utils/tool-grouper.js.map +1 -1
  135. package/dist/utils/api-error.d.ts +61 -0
  136. package/dist/utils/api-error.js +176 -0
  137. package/dist/utils/api-error.js.map +1 -0
  138. package/dist/utils/audit-logger.js +2 -1
  139. package/dist/utils/audit-logger.js.map +1 -1
  140. package/dist/utils/auto-accept-logger.js +3 -3
  141. package/dist/utils/auto-accept-logger.js.map +1 -1
  142. package/dist/utils/config-loader.d.ts +3 -0
  143. package/dist/utils/config-loader.js +27 -2
  144. package/dist/utils/config-loader.js.map +1 -1
  145. package/dist/utils/encryption.js +2 -1
  146. package/dist/utils/encryption.js.map +1 -1
  147. package/dist/utils/file-cache.js +4 -2
  148. package/dist/utils/file-cache.js.map +1 -1
  149. package/dist/utils/history-migration.js +5 -4
  150. package/dist/utils/history-migration.js.map +1 -1
  151. package/dist/utils/onboarding-manager.js +2 -1
  152. package/dist/utils/onboarding-manager.js.map +1 -1
  153. package/dist/utils/path-helpers.d.ts +8 -0
  154. package/dist/utils/path-helpers.js +35 -0
  155. package/dist/utils/path-helpers.js.map +1 -0
  156. package/dist/utils/path-security.js +3 -2
  157. package/dist/utils/path-security.js.map +1 -1
  158. package/dist/utils/retry-helper.d.ts +61 -0
  159. package/dist/utils/retry-helper.js +206 -0
  160. package/dist/utils/retry-helper.js.map +1 -0
  161. package/dist/utils/settings-manager.d.ts +1 -21
  162. package/dist/utils/settings-manager.js +2 -82
  163. package/dist/utils/settings-manager.js.map +1 -1
  164. package/dist/utils/streaming-analyzer.d.ts +2 -13
  165. package/dist/utils/streaming-analyzer.js +3 -25
  166. package/dist/utils/streaming-analyzer.js.map +1 -1
  167. package/dist/utils/token-counter.d.ts +13 -1
  168. package/dist/utils/token-counter.js +31 -6
  169. package/dist/utils/token-counter.js.map +1 -1
  170. package/package.json +3 -2
  171. package/packages/schemas/README.md +1 -1
  172. package/packages/schemas/package.json +1 -1
  173. package/dist/tools/web-search/cache.d.ts +0 -62
  174. package/dist/tools/web-search/cache.js +0 -105
  175. package/dist/tools/web-search/cache.js.map +0 -1
  176. package/dist/tools/web-search/engines/crates.d.ts +0 -19
  177. package/dist/tools/web-search/engines/crates.js +0 -87
  178. package/dist/tools/web-search/engines/crates.js.map +0 -1
  179. package/dist/tools/web-search/engines/npm.d.ts +0 -18
  180. package/dist/tools/web-search/engines/npm.js +0 -86
  181. package/dist/tools/web-search/engines/npm.js.map +0 -1
  182. package/dist/tools/web-search/engines/pypi.d.ts +0 -18
  183. package/dist/tools/web-search/engines/pypi.js +0 -75
  184. package/dist/tools/web-search/engines/pypi.js.map +0 -1
  185. package/dist/tools/web-search/index.d.ts +0 -11
  186. package/dist/tools/web-search/index.js +0 -11
  187. package/dist/tools/web-search/index.js.map +0 -1
  188. package/dist/tools/web-search/router.d.ts +0 -34
  189. package/dist/tools/web-search/router.js +0 -245
  190. package/dist/tools/web-search/router.js.map +0 -1
  191. package/dist/tools/web-search/types.d.ts +0 -45
  192. package/dist/tools/web-search/types.js +0 -6
  193. package/dist/tools/web-search/types.js.map +0 -1
  194. package/dist/tools/web-search/web-search-tool.d.ts +0 -51
  195. package/dist/tools/web-search/web-search-tool.js +0 -246
  196. package/dist/tools/web-search/web-search-tool.js.map +0 -1
@@ -2,7 +2,11 @@
2
2
  * Application-wide constants
3
3
  * Now loaded from YAML configuration files for better maintainability
4
4
  */
5
+ /** Configuration directory name */
6
+ export declare const CONFIG_DIR_NAME = ".ax-cli";
5
7
  export declare const CONFIG_PATHS: {
8
+ /** Configuration directory name */
9
+ readonly DIR_NAME: ".ax-cli";
6
10
  /** User-level settings directory */
7
11
  readonly USER_DIR: string;
8
12
  /** User-level configuration file */
@@ -11,12 +15,16 @@ export declare const CONFIG_PATHS: {
11
15
  readonly PROJECT_DIR: string;
12
16
  /** Project-level settings file */
13
17
  readonly PROJECT_SETTINGS: string;
18
+ /** AutomatosX temporary files directory */
19
+ readonly AUTOMATOSX_TMP: string;
14
20
  };
15
21
  export declare const AGENT_CONFIG: {
16
22
  readonly MAX_TOOL_ROUNDS: number;
17
23
  readonly DEFAULT_TIMEOUT: number;
18
24
  readonly DEFAULT_MAX_TOKENS: number;
19
25
  readonly MAX_RECENT_TOOL_CALLS: number;
26
+ /** Maximum number of messages to keep in chat history */
27
+ readonly MAX_MESSAGES: number;
20
28
  readonly LOOP_DETECTION_THRESHOLD: number;
21
29
  readonly ENABLE_LOOP_DETECTION: boolean;
22
30
  };
@@ -80,6 +88,10 @@ export declare const TOKEN_CONFIG: {
80
88
  export declare const CACHE_CONFIG: {
81
89
  readonly DEFAULT_MAX_SIZE: number;
82
90
  readonly DEFAULT_TTL: number;
91
+ /** Max entries for tool call arguments cache */
92
+ readonly TOOL_ARGS_CACHE_MAX_SIZE: number;
93
+ /** Number of entries to remove when cache is full */
94
+ readonly TOOL_ARGS_CACHE_PRUNE_COUNT: number;
83
95
  };
84
96
  export declare const PERF_CONFIG: {
85
97
  readonly DEBOUNCE_DELAY: number;
package/dist/constants.js CHANGED
@@ -9,16 +9,22 @@ import { loadModelsConfig, loadSettingsConfig, loadMessagesConfig, formatMessage
9
9
  const modelsYaml = loadModelsConfig();
10
10
  const settingsYaml = loadSettingsConfig();
11
11
  const messagesYaml = loadMessagesConfig();
12
+ /** Configuration directory name */
13
+ export const CONFIG_DIR_NAME = '.ax-cli';
12
14
  // Configuration Paths
13
15
  export const CONFIG_PATHS = {
16
+ /** Configuration directory name */
17
+ DIR_NAME: CONFIG_DIR_NAME,
14
18
  /** User-level settings directory */
15
- USER_DIR: join(homedir(), '.ax-cli'),
19
+ USER_DIR: join(homedir(), CONFIG_DIR_NAME),
16
20
  /** User-level configuration file */
17
- USER_CONFIG: join(homedir(), '.ax-cli', 'config.json'),
21
+ USER_CONFIG: join(homedir(), CONFIG_DIR_NAME, 'config.json'),
18
22
  /** Project-level settings directory */
19
- PROJECT_DIR: join(process.cwd(), '.ax-cli'),
23
+ PROJECT_DIR: join(process.cwd(), CONFIG_DIR_NAME),
20
24
  /** Project-level settings file */
21
- PROJECT_SETTINGS: join(process.cwd(), '.ax-cli', 'settings.json'),
25
+ PROJECT_SETTINGS: join(process.cwd(), CONFIG_DIR_NAME, 'settings.json'),
26
+ /** AutomatosX temporary files directory */
27
+ AUTOMATOSX_TMP: join(homedir(), 'automatosx', 'tmp'),
22
28
  };
23
29
  // Agent Configuration
24
30
  export const AGENT_CONFIG = {
@@ -26,6 +32,8 @@ export const AGENT_CONFIG = {
26
32
  DEFAULT_TIMEOUT: settingsYaml.agent.default_timeout,
27
33
  DEFAULT_MAX_TOKENS: settingsYaml.agent.default_max_tokens,
28
34
  MAX_RECENT_TOOL_CALLS: settingsYaml.agent.max_recent_tool_calls,
35
+ /** Maximum number of messages to keep in chat history */
36
+ MAX_MESSAGES: settingsYaml.agent.max_messages || 500,
29
37
  LOOP_DETECTION_THRESHOLD: settingsYaml.agent.loop_detection_threshold,
30
38
  ENABLE_LOOP_DETECTION: settingsYaml.agent.enable_loop_detection,
31
39
  };
@@ -113,6 +121,10 @@ export const TOKEN_CONFIG = {
113
121
  export const CACHE_CONFIG = {
114
122
  DEFAULT_MAX_SIZE: settingsYaml.cache.default_max_size,
115
123
  DEFAULT_TTL: settingsYaml.cache.default_ttl,
124
+ /** Max entries for tool call arguments cache */
125
+ TOOL_ARGS_CACHE_MAX_SIZE: settingsYaml.cache.tool_args_cache_max_size || 500,
126
+ /** Number of entries to remove when cache is full */
127
+ TOOL_ARGS_CACHE_PRUNE_COUNT: settingsYaml.cache.tool_args_cache_prune_count || 100,
116
128
  };
117
129
  // Performance Monitoring
118
130
  export const PERF_CONFIG = {
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEnH,sCAAsC;AACtC,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;AACtC,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;AAC1C,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;AAE1C,mCAAmC;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;AAEzC,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,mCAAmC;IACnC,QAAQ,EAAE,eAAe;IACzB,oCAAoC;IACpC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC;IAC1C,oCAAoC;IACpC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC;IAC5D,uCAAuC;IACvC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC;IACjD,kCAAkC;IAClC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,eAAe,CAAC;IACvE,2CAA2C;IAC3C,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC;CAC5C,CAAC;AAEX,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,eAAe,EAAE,YAAY,CAAC,KAAK,CAAC,eAAe;IACnD,eAAe,EAAE,YAAY,CAAC,KAAK,CAAC,eAAe;IACnD,kBAAkB,EAAE,YAAY,CAAC,KAAK,CAAC,kBAAkB;IACzD,qBAAqB,EAAE,YAAY,CAAC,KAAK,CAAC,qBAAqB;IAC/D,yDAAyD;IACzD,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,YAAY,IAAI,GAAG;IACpD,wBAAwB,EAAE,YAAY,CAAC,KAAK,CAAC,wBAAwB;IACrE,qBAAqB,EAAE,YAAY,CAAC,KAAK,CAAC,qBAAqB;CACvD,CAAC;AAEX,8CAA8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;IACvF,GAAG,CAAC,GAAG,CAAC,GAAG;QACT,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,aAAa,EAAE,KAAK,CAAC,cAAc;QACnC,eAAe,EAAE,KAAK,CAAC,iBAAiB;QACxC,gBAAgB,EAAE,KAAK,CAAC,kBAAkB;QAC1C,gBAAgB,EAAE,KAAK,CAAC,iBAAiB;QACzC,cAAc,EAAE,KAAK,CAAC,eAAe,IAAI,KAAK;QAC9C,kBAAkB,EAAE,KAAK,CAAC,mBAAmB;QAC7C,gBAAgB,EAAE;YAChB,GAAG,EAAE,KAAK,CAAC,iBAAiB,CAAC,GAAG;YAChC,GAAG,EAAE,KAAK,CAAC,iBAAiB,CAAC,GAAG;SACjC;QACD,eAAe,EAAE,KAAK,CAAC,gBAAgB;KACxC,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC,EAAE,EAUD,CAAC,CAAC;AAGJ,MAAM,CAAC,MAAM,aAAa,GAAmB,UAAU,CAAC,aAA+B,CAAC;AAExF,kBAAkB;AAClB,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,aAAa,EAAE,YAAY,CAAC,IAAI,CAAC,aAAa;IAC9C,eAAe,EAAE,YAAY,CAAC,IAAI,CAAC,eAAe;IAClD,kBAAkB,EAAE,YAAY,CAAC,IAAI,CAAC,kBAAkB;CAChD,CAAC;AAEX,wBAAwB;AACxB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,gBAAgB,EAAE,YAAY,CAAC,OAAO,CAAC,gBAAgB;CAC/C,CAAC;AAEX,oBAAoB;AACpB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,WAAW;IACzC,cAAc,EAAE,YAAY,CAAC,GAAG,CAAC,cAAc;IAC/C,eAAe,EAAE,YAAY,CAAC,GAAG,CAAC,eAAe;IACjD,uBAAuB,EAAE,YAAY,CAAC,GAAG,CAAC,uBAAuB;IACjE,gBAAgB,EAAE,YAAY,CAAC,GAAG,CAAC,gBAAgB;IACnD,kBAAkB,EAAE,YAAY,CAAC,GAAG,CAAC,kBAAkB;CAC/C,CAAC;AAEX,mBAAmB;AACnB,MAAM,CAAN,IAAY,cAOX;AAPD,WAAY,cAAc;IACxB,sDAAsD;IACtD,qDAAS,CAAA;IACT,kCAAkC;IAClC,yDAAW,CAAA;IACX,8CAA8C;IAC9C,yDAAW,CAAA;AACb,CAAC,EAPW,cAAc,KAAd,cAAc,QAOzB;AAED,wCAAwC;AACxC,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,QAAQ,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,KAAK,OAAO;YACV,OAAO,cAAc,CAAC,KAAK,CAAC;QAC9B,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,OAAO,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,OAAO,CAAC;QAChC;YACE,OAAO,cAAc,CAAC,KAAK,CAAC;IAChC,CAAC;AACH,CAAC;AAED,mBAAmB;AACnB,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,sBAAsB,EAAE,YAAY,CAAC,EAAE,CAAC,sBAAsB;IAC9D,yBAAyB,EAAE,YAAY,CAAC,EAAE,CAAC,yBAAyB;IACpE,qBAAqB;IACrB,uBAAuB,EAAE,mBAAmB,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,IAAI,OAAO,CAAC;IACxF,gBAAgB,EAAE,YAAY,CAAC,EAAE,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI;IAC1G,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC,cAAc,IAAI,EAAE;IACpD,iBAAiB,EAAE,YAAY,CAAC,EAAE,CAAC,iBAAiB,IAAI,GAAG;CACnD,CAAC;AAEX,iBAAiB;AACjB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,kBAAkB,EAAE,YAAY,CAAC,KAAK,CAAC,kBAAkB;IACzD,wBAAwB,EAAE,YAAY,CAAC,KAAK,CAAC,wBAAwB;IACrE,aAAa,EAAE,YAAY,CAAC,KAAK,CAAC,aAAa;IAC/C,gBAAgB,EAAE,YAAY,CAAC,KAAK,CAAC,gBAAgB;IACrD,cAAc,EAAE,YAAY,CAAC,KAAK,CAAC,cAAc;IACjD,wBAAwB,EAAE,YAAY,CAAC,KAAK,CAAC,wBAAwB;CAC7D,CAAC;AAEX,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,gBAAgB,EAAE,YAAY,CAAC,KAAK,CAAC,gBAAgB;IACrD,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,WAAW;IAC3C,gDAAgD;IAChD,wBAAwB,EAAE,YAAY,CAAC,KAAK,CAAC,wBAAwB,IAAI,GAAG;IAC5E,qDAAqD;IACrD,2BAA2B,EAAE,YAAY,CAAC,KAAK,CAAC,2BAA2B,IAAI,GAAG;CAC1E,CAAC;AAEX,yBAAyB;AACzB,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc,EAAE,YAAY,CAAC,WAAW,CAAC,cAAc;IACvD,cAAc,EAAE,YAAY,CAAC,WAAW,CAAC,cAAc;IACvD,wBAAwB,EAAE,YAAY,CAAC,WAAW,CAAC,wBAAwB;CACnE,CAAC;AAEX,aAAa;AACb,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC,UAAoC,CAAC;AAE5E,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,gBAAgB,EAAE,YAAY,CAAC,MAAM,CAAC,gBAAgB;IACtD,yBAAyB,EAAE,YAAY,CAAC,MAAM,CAAC,yBAAyB;IACxE,cAAc,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,CAAC;IACrG,oBAAoB,EAAE,CAAC,UAAkB,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,oBAAoB,EAAE,EAAE,UAAU,EAAE,CAAC;IACrH,cAAc,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,CAAC;IACrG,mBAAmB,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,CAAC;CACrG,CAAC;AAEX,yCAAyC;AACzC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,kCAAkC;IAClC,OAAO,EAAE,IAAI;IAEb,8FAA8F;IAC9F,mBAAmB,EAAE,CAAC;IAEtB,8BAA8B;IAC9B,UAAU,EAAE,EAAE;IAEd,iDAAiD;IACjD,gBAAgB,EAAE,MAAM;IAExB,8BAA8B;IAC9B,mBAAmB,EAAE,CAAC;IAEtB,2CAA2C;IAC3C,eAAe,EAAE,IAAI;IAErB,8FAA8F;IAC9F,qBAAqB,EAAE,KAAK;IAE5B,4CAA4C;IAC5C,0BAA0B,EAAE,IAAI;IAEhC,mFAAmF;IACnF,qBAAqB,EAAE,IAAI;IAE3B,mCAAmC;IACnC,iBAAiB,EAAE,IAAI;IAEvB,8CAA8C;IAC9C,yBAAyB,EAAE,EAAE;IAE7B,oCAAoC;IACpC,mBAAmB,EAAE,EAAE;IAEvB,6BAA6B;IAC7B,YAAY,EAAE,IAAI;IAElB,0EAA0E;IAC1E,WAAW,EAAE,IAAI;IAEjB,oDAAoD;IACpD,cAAc,EAAE,KAAK;CACb,CAAC"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Hook System (Phase 4)
3
+ *
4
+ * Based on Claude Code's hook architecture.
5
+ * Allows custom logic intercept points for tool execution.
6
+ *
7
+ * Hook Types:
8
+ * - PreToolUse: Before tool execution (validation, permission checks, logging)
9
+ * - PostToolUse: After tool execution (result transformation, analytics)
10
+ * - OnError: On tool failure (custom error handling, retry logic)
11
+ * - SessionStart: On session begin (setup, context loading)
12
+ * - SessionEnd: On session end (cleanup, reporting)
13
+ */
14
+ import { EventEmitter } from 'events';
15
+ import { LLMToolCall } from '../llm/client.js';
16
+ import { ToolResult } from '../types/index.js';
17
+ /**
18
+ * Hook execution timing
19
+ */
20
+ export declare enum HookType {
21
+ PreToolUse = "pre_tool_use",
22
+ PostToolUse = "post_tool_use",
23
+ OnError = "on_error",
24
+ SessionStart = "session_start",
25
+ SessionEnd = "session_end"
26
+ }
27
+ /**
28
+ * Input passed to hook scripts (via stdin as JSON)
29
+ */
30
+ export interface HookInput {
31
+ event: HookType;
32
+ tool: string;
33
+ args: Record<string, unknown>;
34
+ session: {
35
+ id: string;
36
+ startedAt: string;
37
+ messageCount: number;
38
+ };
39
+ result?: ToolResult;
40
+ error?: string;
41
+ }
42
+ /**
43
+ * Output expected from hook scripts (via stdout as JSON)
44
+ */
45
+ export interface HookOutput {
46
+ action: 'continue' | 'block' | 'modify';
47
+ reason?: string;
48
+ modifiedArgs?: Record<string, unknown>;
49
+ }
50
+ /**
51
+ * Hook configuration
52
+ */
53
+ interface HookDefinition {
54
+ name: string;
55
+ script: string;
56
+ tools: string[];
57
+ timeout?: number;
58
+ enabled?: boolean;
59
+ }
60
+ /**
61
+ * Hook configuration file structure
62
+ */
63
+ interface HookConfig {
64
+ hooks: {
65
+ pre_tool_use?: HookDefinition[];
66
+ post_tool_use?: HookDefinition[];
67
+ on_error?: HookDefinition[];
68
+ session_start?: HookDefinition[];
69
+ session_end?: HookDefinition[];
70
+ };
71
+ }
72
+ /**
73
+ * Hook Runner
74
+ *
75
+ * Executes hooks at various points in tool execution lifecycle.
76
+ */
77
+ export declare class HookRunner extends EventEmitter {
78
+ private config;
79
+ private configPath;
80
+ private sessionId;
81
+ private sessionStartedAt;
82
+ private messageCount;
83
+ /** Running hook processes for cleanup */
84
+ private runningProcesses;
85
+ constructor();
86
+ /**
87
+ * Initialize the hook runner (load config)
88
+ */
89
+ initialize(): Promise<void>;
90
+ /**
91
+ * Run pre-tool-use hooks
92
+ * Returns modified args or blocks execution
93
+ */
94
+ runPreToolUse(toolCall: LLMToolCall, args: Record<string, unknown>): Promise<HookOutput>;
95
+ /**
96
+ * Run post-tool-use hooks
97
+ */
98
+ runPostToolUse(toolCall: LLMToolCall, args: Record<string, unknown>, result: ToolResult): Promise<void>;
99
+ /**
100
+ * Run on-error hooks
101
+ */
102
+ runOnError(toolCall: LLMToolCall, args: Record<string, unknown>, error: string): Promise<HookOutput>;
103
+ /**
104
+ * Run session start hooks
105
+ */
106
+ private runSessionStartHooks;
107
+ /**
108
+ * Run session end hooks
109
+ */
110
+ runSessionEndHooks(): Promise<void>;
111
+ /**
112
+ * Increment message count (for session tracking)
113
+ */
114
+ incrementMessageCount(): void;
115
+ /**
116
+ * Get current hook configuration
117
+ */
118
+ getConfig(): HookConfig;
119
+ /**
120
+ * Reload configuration from file
121
+ */
122
+ reloadConfig(): Promise<void>;
123
+ /**
124
+ * Cleanup running processes
125
+ */
126
+ dispose(): Promise<void>;
127
+ private getHooksForType;
128
+ private shouldRunHook;
129
+ private executeHook;
130
+ private resolveScriptPath;
131
+ private getSessionInfo;
132
+ private generateSessionId;
133
+ private loadConfig;
134
+ }
135
+ export declare function getHookRunner(): HookRunner;
136
+ export declare function initializeHookRunner(): Promise<HookRunner>;
137
+ export declare function disposeHookRunner(): Promise<void>;
138
+ export {};
@@ -0,0 +1,429 @@
1
+ /**
2
+ * Hook System (Phase 4)
3
+ *
4
+ * Based on Claude Code's hook architecture.
5
+ * Allows custom logic intercept points for tool execution.
6
+ *
7
+ * Hook Types:
8
+ * - PreToolUse: Before tool execution (validation, permission checks, logging)
9
+ * - PostToolUse: After tool execution (result transformation, analytics)
10
+ * - OnError: On tool failure (custom error handling, retry logic)
11
+ * - SessionStart: On session begin (setup, context loading)
12
+ * - SessionEnd: On session end (cleanup, reporting)
13
+ */
14
+ import { EventEmitter } from 'events';
15
+ import { spawn } from 'child_process';
16
+ import { readFile, stat } from 'fs/promises';
17
+ import { homedir } from 'os';
18
+ import { join, dirname, resolve } from 'path';
19
+ import * as yaml from 'js-yaml';
20
+ import { extractErrorMessage } from '../utils/error-handler.js';
21
+ import { CONFIG_DIR_NAME } from '../constants.js';
22
+ /**
23
+ * Hook execution timing
24
+ */
25
+ export var HookType;
26
+ (function (HookType) {
27
+ HookType["PreToolUse"] = "pre_tool_use";
28
+ HookType["PostToolUse"] = "post_tool_use";
29
+ HookType["OnError"] = "on_error";
30
+ HookType["SessionStart"] = "session_start";
31
+ HookType["SessionEnd"] = "session_end";
32
+ })(HookType || (HookType = {}));
33
+ /**
34
+ * Default hook configuration
35
+ */
36
+ const DEFAULT_CONFIG = {
37
+ hooks: {
38
+ pre_tool_use: [],
39
+ post_tool_use: [],
40
+ on_error: [],
41
+ session_start: [],
42
+ session_end: [],
43
+ },
44
+ };
45
+ /**
46
+ * Hook exit codes
47
+ */
48
+ const EXIT_CODES = {
49
+ CONTINUE: 0, // Continue (approve)
50
+ ERROR: 1, // Error (log and continue)
51
+ BLOCK: 2, // Block execution
52
+ };
53
+ /**
54
+ * Hook Runner
55
+ *
56
+ * Executes hooks at various points in tool execution lifecycle.
57
+ */
58
+ export class HookRunner extends EventEmitter {
59
+ config;
60
+ configPath;
61
+ sessionId;
62
+ sessionStartedAt;
63
+ messageCount = 0;
64
+ /** Running hook processes for cleanup */
65
+ runningProcesses = new Set();
66
+ constructor() {
67
+ super();
68
+ this.configPath = join(homedir(), CONFIG_DIR_NAME, 'hooks.yaml');
69
+ this.config = DEFAULT_CONFIG;
70
+ this.sessionId = this.generateSessionId();
71
+ this.sessionStartedAt = new Date().toISOString();
72
+ }
73
+ /**
74
+ * Initialize the hook runner (load config)
75
+ */
76
+ async initialize() {
77
+ try {
78
+ await this.loadConfig();
79
+ }
80
+ catch (error) {
81
+ // Use default config if loading fails
82
+ console.warn('Using default hook configuration');
83
+ }
84
+ // Run session start hooks
85
+ await this.runSessionStartHooks();
86
+ }
87
+ /**
88
+ * Run pre-tool-use hooks
89
+ * Returns modified args or blocks execution
90
+ */
91
+ async runPreToolUse(toolCall, args) {
92
+ const hooks = this.getHooksForType(HookType.PreToolUse);
93
+ let currentArgs = { ...args };
94
+ for (const hook of hooks) {
95
+ if (!this.shouldRunHook(hook, toolCall.function.name))
96
+ continue;
97
+ const input = {
98
+ event: HookType.PreToolUse,
99
+ tool: toolCall.function.name,
100
+ args: currentArgs,
101
+ session: this.getSessionInfo(),
102
+ };
103
+ try {
104
+ const result = await this.executeHook(hook, input);
105
+ if (result.action === 'block') {
106
+ this.emit('hook:blocked', {
107
+ hook: hook.name,
108
+ tool: toolCall.function.name,
109
+ reason: result.reason,
110
+ });
111
+ return result;
112
+ }
113
+ if (result.action === 'modify' && result.modifiedArgs) {
114
+ currentArgs = result.modifiedArgs;
115
+ this.emit('hook:modified', {
116
+ hook: hook.name,
117
+ tool: toolCall.function.name,
118
+ originalArgs: args,
119
+ modifiedArgs: currentArgs,
120
+ });
121
+ }
122
+ }
123
+ catch (error) {
124
+ this.emit('hook:error', {
125
+ hook: hook.name,
126
+ tool: toolCall.function.name,
127
+ error: extractErrorMessage(error),
128
+ });
129
+ // Continue on hook error (don't block tool execution)
130
+ }
131
+ }
132
+ return {
133
+ action: 'continue',
134
+ modifiedArgs: currentArgs,
135
+ };
136
+ }
137
+ /**
138
+ * Run post-tool-use hooks
139
+ */
140
+ async runPostToolUse(toolCall, args, result) {
141
+ const hooks = this.getHooksForType(HookType.PostToolUse);
142
+ for (const hook of hooks) {
143
+ if (!this.shouldRunHook(hook, toolCall.function.name))
144
+ continue;
145
+ const input = {
146
+ event: HookType.PostToolUse,
147
+ tool: toolCall.function.name,
148
+ args,
149
+ session: this.getSessionInfo(),
150
+ result,
151
+ };
152
+ try {
153
+ await this.executeHook(hook, input);
154
+ }
155
+ catch (error) {
156
+ this.emit('hook:error', {
157
+ hook: hook.name,
158
+ tool: toolCall.function.name,
159
+ error: extractErrorMessage(error),
160
+ });
161
+ }
162
+ }
163
+ }
164
+ /**
165
+ * Run on-error hooks
166
+ */
167
+ async runOnError(toolCall, args, error) {
168
+ const hooks = this.getHooksForType(HookType.OnError);
169
+ for (const hook of hooks) {
170
+ if (!this.shouldRunHook(hook, toolCall.function.name))
171
+ continue;
172
+ const input = {
173
+ event: HookType.OnError,
174
+ tool: toolCall.function.name,
175
+ args,
176
+ session: this.getSessionInfo(),
177
+ error,
178
+ };
179
+ try {
180
+ const result = await this.executeHook(hook, input);
181
+ if (result.action === 'modify' && result.modifiedArgs) {
182
+ // Hook wants to retry with modified args
183
+ return result;
184
+ }
185
+ }
186
+ catch (hookError) {
187
+ this.emit('hook:error', {
188
+ hook: hook.name,
189
+ tool: toolCall.function.name,
190
+ error: hookError instanceof Error ? hookError.message : String(hookError),
191
+ });
192
+ }
193
+ }
194
+ return { action: 'continue' };
195
+ }
196
+ /**
197
+ * Run session start hooks
198
+ */
199
+ async runSessionStartHooks() {
200
+ const hooks = this.getHooksForType(HookType.SessionStart);
201
+ for (const hook of hooks) {
202
+ const input = {
203
+ event: HookType.SessionStart,
204
+ tool: '',
205
+ args: {},
206
+ session: this.getSessionInfo(),
207
+ };
208
+ try {
209
+ await this.executeHook(hook, input);
210
+ this.emit('hook:session_start', { hook: hook.name });
211
+ }
212
+ catch (error) {
213
+ this.emit('hook:error', {
214
+ hook: hook.name,
215
+ error: extractErrorMessage(error),
216
+ });
217
+ }
218
+ }
219
+ }
220
+ /**
221
+ * Run session end hooks
222
+ */
223
+ async runSessionEndHooks() {
224
+ const hooks = this.getHooksForType(HookType.SessionEnd);
225
+ for (const hook of hooks) {
226
+ const input = {
227
+ event: HookType.SessionEnd,
228
+ tool: '',
229
+ args: {},
230
+ session: this.getSessionInfo(),
231
+ };
232
+ try {
233
+ await this.executeHook(hook, input);
234
+ this.emit('hook:session_end', { hook: hook.name });
235
+ }
236
+ catch (error) {
237
+ this.emit('hook:error', {
238
+ hook: hook.name,
239
+ error: extractErrorMessage(error),
240
+ });
241
+ }
242
+ }
243
+ }
244
+ /**
245
+ * Increment message count (for session tracking)
246
+ */
247
+ incrementMessageCount() {
248
+ this.messageCount++;
249
+ }
250
+ /**
251
+ * Get current hook configuration
252
+ */
253
+ getConfig() {
254
+ return { ...this.config };
255
+ }
256
+ /**
257
+ * Reload configuration from file
258
+ */
259
+ async reloadConfig() {
260
+ await this.loadConfig();
261
+ this.emit('hook:config_reloaded');
262
+ }
263
+ /**
264
+ * Cleanup running processes
265
+ */
266
+ async dispose() {
267
+ // Run session end hooks
268
+ await this.runSessionEndHooks();
269
+ // Kill any running processes
270
+ for (const proc of this.runningProcesses) {
271
+ try {
272
+ proc.kill('SIGTERM');
273
+ }
274
+ catch {
275
+ // Process may have already exited
276
+ }
277
+ }
278
+ this.runningProcesses.clear();
279
+ }
280
+ // ============================================================================
281
+ // Private Methods
282
+ // ============================================================================
283
+ getHooksForType(type) {
284
+ const hookKey = type;
285
+ const hooks = this.config.hooks[hookKey] || [];
286
+ return hooks.filter((h) => h.enabled !== false);
287
+ }
288
+ shouldRunHook(hook, toolName) {
289
+ if (!hook.tools || hook.tools.length === 0)
290
+ return true;
291
+ if (hook.tools.includes('*'))
292
+ return true;
293
+ return hook.tools.some((pattern) => {
294
+ if (pattern.endsWith('*')) {
295
+ return toolName.startsWith(pattern.slice(0, -1));
296
+ }
297
+ return toolName === pattern;
298
+ });
299
+ }
300
+ async executeHook(hook, input) {
301
+ const scriptPath = this.resolveScriptPath(hook.script);
302
+ const timeout = hook.timeout || 30000;
303
+ // Check if script exists
304
+ try {
305
+ await stat(scriptPath);
306
+ }
307
+ catch {
308
+ throw new Error(`Hook script not found: ${scriptPath}`);
309
+ }
310
+ return new Promise((resolve, reject) => {
311
+ const proc = spawn(scriptPath, [], {
312
+ stdio: ['pipe', 'pipe', 'pipe'],
313
+ timeout,
314
+ shell: true,
315
+ });
316
+ this.runningProcesses.add(proc);
317
+ let stdout = '';
318
+ let stderr = '';
319
+ proc.stdout?.on('data', (data) => {
320
+ stdout += data.toString();
321
+ });
322
+ proc.stderr?.on('data', (data) => {
323
+ stderr += data.toString();
324
+ });
325
+ proc.on('close', (code) => {
326
+ this.runningProcesses.delete(proc);
327
+ // Handle exit codes
328
+ if (code === EXIT_CODES.BLOCK) {
329
+ resolve({
330
+ action: 'block',
331
+ reason: stderr || stdout || 'Blocked by hook',
332
+ });
333
+ return;
334
+ }
335
+ if (code === EXIT_CODES.ERROR) {
336
+ // Log error but continue
337
+ this.emit('hook:warning', {
338
+ hook: hook.name,
339
+ message: stderr || stdout || 'Hook returned error',
340
+ });
341
+ resolve({ action: 'continue' });
342
+ return;
343
+ }
344
+ // Try to parse JSON output
345
+ try {
346
+ if (stdout.trim()) {
347
+ const output = JSON.parse(stdout.trim());
348
+ resolve(output);
349
+ }
350
+ else {
351
+ resolve({ action: 'continue' });
352
+ }
353
+ }
354
+ catch {
355
+ // Non-JSON output, treat as continue
356
+ resolve({ action: 'continue' });
357
+ }
358
+ });
359
+ proc.on('error', (error) => {
360
+ this.runningProcesses.delete(proc);
361
+ reject(error);
362
+ });
363
+ // Send input via stdin
364
+ proc.stdin?.write(JSON.stringify(input));
365
+ proc.stdin?.end();
366
+ });
367
+ }
368
+ resolveScriptPath(script) {
369
+ // Expand ~ to home directory
370
+ if (script.startsWith('~')) {
371
+ return join(homedir(), script.slice(1));
372
+ }
373
+ // Resolve relative paths from config directory
374
+ if (!script.startsWith('/')) {
375
+ return resolve(dirname(this.configPath), script);
376
+ }
377
+ return script;
378
+ }
379
+ getSessionInfo() {
380
+ return {
381
+ id: this.sessionId,
382
+ startedAt: this.sessionStartedAt,
383
+ messageCount: this.messageCount,
384
+ };
385
+ }
386
+ generateSessionId() {
387
+ return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
388
+ }
389
+ async loadConfig() {
390
+ try {
391
+ const content = await readFile(this.configPath, 'utf-8');
392
+ const loaded = yaml.load(content);
393
+ if (loaded?.hooks) {
394
+ this.config = {
395
+ hooks: {
396
+ ...DEFAULT_CONFIG.hooks,
397
+ ...loaded.hooks,
398
+ },
399
+ };
400
+ }
401
+ }
402
+ catch (error) {
403
+ // File doesn't exist or is invalid, use defaults
404
+ this.config = DEFAULT_CONFIG;
405
+ }
406
+ }
407
+ }
408
+ /**
409
+ * Singleton instance
410
+ */
411
+ let hookRunnerInstance = null;
412
+ export function getHookRunner() {
413
+ if (!hookRunnerInstance) {
414
+ hookRunnerInstance = new HookRunner();
415
+ }
416
+ return hookRunnerInstance;
417
+ }
418
+ export async function initializeHookRunner() {
419
+ const runner = getHookRunner();
420
+ await runner.initialize();
421
+ return runner;
422
+ }
423
+ export async function disposeHookRunner() {
424
+ if (hookRunnerInstance) {
425
+ await hookRunnerInstance.dispose();
426
+ hookRunnerInstance = null;
427
+ }
428
+ }
429
+ //# sourceMappingURL=hook-runner.js.map