@maincode-ai/matilda-code 0.21.12 → 0.21.13-nightly.20261027.e00306cd3

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 (269) hide show
  1. package/chunks/agent-H5JE3RJQ.js +3 -0
  2. package/chunks/agent-headless-H2JZZ7UV.js +3 -0
  3. package/chunks/{askUserQuestion-2QI4NSFJ.js → askUserQuestion-L3WDL2T4.js} +3 -3
  4. package/chunks/ca-UBWUTZVZ.js +25 -0
  5. package/chunks/chunk-4CVGYUEL.js +3 -0
  6. package/chunks/{chunk-RNKDFE2S.js → chunk-5B2QERWR.js} +1 -1
  7. package/chunks/chunk-62GTGPTP.js +8 -0
  8. package/chunks/chunk-6365AZBW.js +56 -0
  9. package/chunks/chunk-6PFK4XTH.js +207 -0
  10. package/chunks/chunk-7ZODGQO6.js +4 -0
  11. package/chunks/chunk-DB5LMKXU.js +31 -0
  12. package/chunks/chunk-EYZPVR7N.js +13 -0
  13. package/chunks/chunk-FKHUEFMK.js +8 -0
  14. package/chunks/{chunk-6T2GIM76.js → chunk-GILXFDEG.js} +1 -1
  15. package/chunks/{chunk-VTGICC67.js → chunk-GKEUZTOB.js} +1 -1
  16. package/chunks/chunk-GSRXW64P.js +120 -0
  17. package/chunks/chunk-GT6MSEK4.js +3 -0
  18. package/chunks/chunk-HEJO7OBH.js +3 -0
  19. package/chunks/chunk-HPO2YWG4.js +78 -0
  20. package/chunks/chunk-I3CV4LOD.js +8 -0
  21. package/chunks/{chunk-DOOFGSRV.js → chunk-J3AMKDX6.js} +1 -1
  22. package/chunks/chunk-JU7QTSKS.js +14 -0
  23. package/chunks/chunk-LBQNFSZ2.js +9 -0
  24. package/chunks/chunk-LOB42ODE.js +9 -0
  25. package/chunks/chunk-LVDDFAK4.js +89 -0
  26. package/chunks/{chunk-27Q5KW3A.js → chunk-NK2QMGCC.js} +13 -13
  27. package/chunks/{chunk-YRQP3SLC.js → chunk-O7VPFJ3R.js} +1 -1
  28. package/chunks/chunk-OBE5S4GG.js +9 -0
  29. package/chunks/{chunk-CZGZ3KK7.js → chunk-ONANBLIE.js} +1 -1
  30. package/chunks/chunk-QXSBPCBA.js +8 -0
  31. package/chunks/chunk-TUKNB5CQ.js +33 -0
  32. package/chunks/chunk-UM6CLO7D.js +7 -0
  33. package/chunks/chunk-V4D3LER3.js +2615 -0
  34. package/chunks/{chunk-HYVP4472.js → chunk-V6UPUMP3.js} +1 -1
  35. package/chunks/chunk-VUJRLLGL.js +8 -0
  36. package/chunks/{chunk-MCQUPLRE.js → chunk-WTU6GSZH.js} +1 -1
  37. package/chunks/chunk-XBTBZHRC.js +8 -0
  38. package/chunks/{chunk-WV3IUPZS.js → chunk-YTB3OFTT.js} +1 -1
  39. package/chunks/chunk-ZQKABJBB.js +8 -0
  40. package/chunks/chunk-ZSGBDQXU.js +11 -0
  41. package/chunks/{computer-use-WKDNUTLD.js → computer-use-N6KGNST6.js} +1 -1
  42. package/chunks/{cron-create-F2LXM2OA.js → cron-create-4XBY5RVI.js} +1 -1
  43. package/chunks/cron-delete-BH4VP3LX.js +3 -0
  44. package/chunks/cron-list-XXRFKNGM.js +5 -0
  45. package/chunks/de-LEEHWWJ2.js +25 -0
  46. package/chunks/{devtools-5JRKK3E7.js → devtools-7YNCRYZV.js} +1 -1
  47. package/chunks/{chunk-OOEH6ZSV.js → dist-UWUWLWTO.js} +2 -2
  48. package/chunks/{edit-QQNJZ55P.js → edit-6ULTLTJQ.js} +1 -1
  49. package/chunks/{en-EJLDYIBM.js → en-LNOIHFSQ.js} +4 -4
  50. package/chunks/{enter-worktree-5X5SAMBJ.js → enter-worktree-V2VANZYJ.js} +1 -1
  51. package/chunks/enterPlanMode-75H54S3Z.js +18 -0
  52. package/chunks/{exit-worktree-SRKZBEYF.js → exit-worktree-KPB32K6P.js} +1 -1
  53. package/chunks/{exitPlanMode-WSPTGGVN.js → exitPlanMode-K7JRP22Y.js} +2 -2
  54. package/chunks/fr-4TA2AIU6.js +25 -0
  55. package/chunks/{getMachineId-bsd-ZYBNK2JG.js → getMachineId-bsd-ETKQTB6C.js} +1 -1
  56. package/chunks/{getMachineId-darwin-CM2MQGUI.js → getMachineId-darwin-AKNRWOWB.js} +1 -1
  57. package/chunks/{getMachineId-linux-SYE2KMCW.js → getMachineId-linux-2QSD7FTP.js} +1 -1
  58. package/chunks/{getMachineId-unsupported-6IHVG2XO.js → getMachineId-unsupported-UXSV7I24.js} +1 -1
  59. package/chunks/{getMachineId-win-S3J3JSUM.js → getMachineId-win-4MTFXGP3.js} +1 -1
  60. package/chunks/glob-ACAIHWST.js +22 -0
  61. package/chunks/{goal-tools-C6BSBHCF.js → goal-tools-VPFXBI6M.js} +3 -3
  62. package/chunks/{grep-MVCOBUYW.js → grep-R4K75RXS.js} +1 -1
  63. package/chunks/{ja-GGNJR7AR.js → ja-VXDMQKRW.js} +5 -5
  64. package/chunks/keychain-token-storage-7VYNARRB.js +3 -0
  65. package/chunks/ls-4ZEICYPK.js +15 -0
  66. package/chunks/{lsp-DYDK6XCS.js → lsp-4US2RIIV.js} +1 -1
  67. package/chunks/mcp-client-ZKQFYCFN.js +3 -0
  68. package/chunks/monitor-KSNFIY54.js +32 -0
  69. package/chunks/{multipart-parser-JI75T2O5.js → multipart-parser-FKHYAVGR.js} +1 -1
  70. package/chunks/notebook-edit-655ZNV6Q.js +17 -0
  71. package/chunks/openaiContentGenerator-BG3OM453.js +52 -0
  72. package/chunks/pt-WEIMCOKI.js +25 -0
  73. package/chunks/read-file-4VSUKSRB.js +3 -0
  74. package/chunks/ripGrep-PNALN2GG.js +3 -0
  75. package/chunks/ru-WFLK34ZL.js +25 -0
  76. package/chunks/scheduler-AVYCIBEK.js +8 -0
  77. package/chunks/send-message-ND2SRKX5.js +8 -0
  78. package/chunks/shell-GUHQNOMZ.js +3 -0
  79. package/chunks/{skill-HZPFEAPF.js → skill-AB2X2DTC.js} +1 -1
  80. package/chunks/src-LZEU4AYF.js +5 -0
  81. package/chunks/symbol-search-VICSUEZH.js +19 -0
  82. package/chunks/{syntheticOutput-432LXITX.js → syntheticOutput-Z7DQKMRI.js} +1 -1
  83. package/chunks/task-create-BQ73FRTH.js +3 -0
  84. package/chunks/{task-detach-XMSJ3HBM.js → task-detach-JCHSLUOR.js} +1 -1
  85. package/chunks/task-list-6ESRFO5F.js +9 -0
  86. package/chunks/{task-stop-NTS62FLG.js → task-stop-74H2CPAJ.js} +1 -1
  87. package/chunks/{task-update-AR26UFYZ.js → task-update-R3BN6KPQ.js} +1 -1
  88. package/chunks/{team-create-PYXFVIR5.js → team-create-UTKRPUPZ.js} +3 -3
  89. package/chunks/team-delete-PCCGTLGL.js +8 -0
  90. package/chunks/todoWrite-BZI75DFV.js +3 -0
  91. package/chunks/{tool-search-RKZDSRYS.js → tool-search-FJ5MAPQ6.js} +1 -1
  92. package/chunks/{web-fetch-VW3SVDQ6.js → web-fetch-DEUGZQZS.js} +17 -17
  93. package/chunks/{web-search-XQUIZARL.js → web-search-PUUIEFJO.js} +3 -3
  94. package/chunks/{workflow-YXNXDRWZ.js → workflow-CBADL3IM.js} +2 -2
  95. package/chunks/write-file-QGCL2AJL.js +15 -0
  96. package/cli.js +644 -679
  97. package/examples/starter/README.md +0 -3
  98. package/locales/ca.js +1 -37
  99. package/locales/de.js +1 -42
  100. package/locales/en.js +1 -43
  101. package/locales/fr.js +1 -39
  102. package/locales/ja.js +1 -42
  103. package/locales/pt.js +1 -42
  104. package/locales/ru.js +1 -42
  105. package/package.json +2 -2
  106. package/sandbox-macos-permissive-closed.sb +0 -1
  107. package/sandbox-macos-permissive-open.sb +0 -1
  108. package/sandbox-macos-permissive-proxied.sb +1 -2
  109. package/sandbox-macos-restrictive-closed.sb +14 -2
  110. package/sandbox-macos-restrictive-open.sb +14 -2
  111. package/sandbox-macos-restrictive-proxied.sb +15 -3
  112. package/bundled/mainy/SKILL.md +0 -157
  113. package/bundled/mainy/docs/_meta.ts +0 -32
  114. package/bundled/mainy/docs/common-workflow.md +0 -571
  115. package/bundled/mainy/docs/configuration/_meta.ts +0 -7
  116. package/bundled/mainy/docs/configuration/auth.md +0 -82
  117. package/bundled/mainy/docs/configuration/matilda-ignore.md +0 -55
  118. package/bundled/mainy/docs/configuration/model-providers.md +0 -598
  119. package/bundled/mainy/docs/configuration/settings.md +0 -790
  120. package/bundled/mainy/docs/configuration/themes.md +0 -199
  121. package/bundled/mainy/docs/configuration/trusted-folders.md +0 -67
  122. package/bundled/mainy/docs/extension/_meta.ts +0 -9
  123. package/bundled/mainy/docs/extension/extension-releasing.md +0 -204
  124. package/bundled/mainy/docs/extension/getting-started-extensions.md +0 -299
  125. package/bundled/mainy/docs/extension/introduction.md +0 -338
  126. package/bundled/mainy/docs/features/_meta.ts +0 -27
  127. package/bundled/mainy/docs/features/approval-mode.md +0 -388
  128. package/bundled/mainy/docs/features/arena.md +0 -219
  129. package/bundled/mainy/docs/features/auto-mode.md +0 -308
  130. package/bundled/mainy/docs/features/channels/_meta.ts +0 -8
  131. package/bundled/mainy/docs/features/channels/dingtalk.md +0 -134
  132. package/bundled/mainy/docs/features/channels/feishu.md +0 -186
  133. package/bundled/mainy/docs/features/channels/overview.md +0 -336
  134. package/bundled/mainy/docs/features/channels/plugins.md +0 -87
  135. package/bundled/mainy/docs/features/channels/telegram.md +0 -120
  136. package/bundled/mainy/docs/features/channels/weixin.md +0 -106
  137. package/bundled/mainy/docs/features/code-review.md +0 -291
  138. package/bundled/mainy/docs/features/commands.md +0 -528
  139. package/bundled/mainy/docs/features/dual-output.md +0 -627
  140. package/bundled/mainy/docs/features/followup-suggestions.md +0 -109
  141. package/bundled/mainy/docs/features/headless.md +0 -448
  142. package/bundled/mainy/docs/features/hooks.md +0 -1306
  143. package/bundled/mainy/docs/features/language.md +0 -171
  144. package/bundled/mainy/docs/features/lsp.md +0 -496
  145. package/bundled/mainy/docs/features/markdown-rendering.md +0 -183
  146. package/bundled/mainy/docs/features/mcp.md +0 -423
  147. package/bundled/mainy/docs/features/memory.md +0 -185
  148. package/bundled/mainy/docs/features/sandbox.md +0 -249
  149. package/bundled/mainy/docs/features/scheduled-tasks.md +0 -139
  150. package/bundled/mainy/docs/features/skills.md +0 -347
  151. package/bundled/mainy/docs/features/status-line.md +0 -397
  152. package/bundled/mainy/docs/features/structured-output.md +0 -309
  153. package/bundled/mainy/docs/features/sub-agents.md +0 -737
  154. package/bundled/mainy/docs/features/tips.md +0 -54
  155. package/bundled/mainy/docs/features/token-caching.md +0 -29
  156. package/bundled/mainy/docs/features/tool-use-summaries.md +0 -178
  157. package/bundled/mainy/docs/features/worktree.md +0 -345
  158. package/bundled/mainy/docs/ide-integration/_meta.ts +0 -4
  159. package/bundled/mainy/docs/ide-integration/ide-companion-spec.md +0 -182
  160. package/bundled/mainy/docs/ide-integration/ide-integration.md +0 -144
  161. package/bundled/mainy/docs/integration-github-action.md +0 -241
  162. package/bundled/mainy/docs/integration-jetbrains.md +0 -81
  163. package/bundled/mainy/docs/integration-vscode.md +0 -39
  164. package/bundled/mainy/docs/integration-zed.md +0 -72
  165. package/bundled/mainy/docs/matilda-serve-deploy-local.md +0 -221
  166. package/bundled/mainy/docs/matilda-serve.md +0 -661
  167. package/bundled/mainy/docs/overview.md +0 -64
  168. package/bundled/mainy/docs/quickstart.md +0 -234
  169. package/bundled/mainy/docs/reference/_meta.ts +0 -3
  170. package/bundled/mainy/docs/reference/keyboard-shortcuts.md +0 -91
  171. package/bundled/mainy/docs/support/Uninstall.md +0 -65
  172. package/bundled/mainy/docs/support/_meta.ts +0 -6
  173. package/bundled/mainy/docs/support/tos-privacy.md +0 -94
  174. package/bundled/mainy/docs/support/troubleshooting.md +0 -127
  175. package/chunks/agent-WM63A6NK.js +0 -3
  176. package/chunks/agent-headless-QIUBDKPW.js +0 -3
  177. package/chunks/anthropicContentGenerator-VKFTAIU3.js +0 -39
  178. package/chunks/ca-I2HEEIL7.js +0 -25
  179. package/chunks/chunk-2HTPVSGT.js +0 -3
  180. package/chunks/chunk-2MOGYHWM.js +0 -8
  181. package/chunks/chunk-3IRGBRSP.js +0 -113
  182. package/chunks/chunk-3YLXGE6T.js +0 -8
  183. package/chunks/chunk-47XR7IMP.js +0 -8
  184. package/chunks/chunk-4F4DA5UI.js +0 -8
  185. package/chunks/chunk-4J6DC24J.js +0 -59
  186. package/chunks/chunk-4Q2SNBUH.js +0 -18
  187. package/chunks/chunk-5C2RJ5RR.js +0 -37
  188. package/chunks/chunk-6E766NPX.js +0 -31
  189. package/chunks/chunk-6EQMZNIY.js +0 -8
  190. package/chunks/chunk-6GBNB5Z2.js +0 -3
  191. package/chunks/chunk-6Z2MV7ZY.js +0 -186
  192. package/chunks/chunk-BVOCFLC4.js +0 -56
  193. package/chunks/chunk-CSJTA7NE.js +0 -101
  194. package/chunks/chunk-DC7LAFZZ.js +0 -8
  195. package/chunks/chunk-DE3HKC2W.js +0 -9
  196. package/chunks/chunk-EQGA7LH7.js +0 -30
  197. package/chunks/chunk-FPO57O66.js +0 -39
  198. package/chunks/chunk-FWDMPRKU.js +0 -3
  199. package/chunks/chunk-G7R2XEEF.js +0 -7
  200. package/chunks/chunk-GOJCMVJJ.js +0 -8
  201. package/chunks/chunk-GTVCJCHR.js +0 -8
  202. package/chunks/chunk-JCE3JAVC.js +0 -25
  203. package/chunks/chunk-JRECUFB3.js +0 -2630
  204. package/chunks/chunk-KHHJYBR5.js +0 -9
  205. package/chunks/chunk-LJR4RZZ2.js +0 -3
  206. package/chunks/chunk-LUNDTQ3G.js +0 -8
  207. package/chunks/chunk-M53RP3YP.js +0 -31
  208. package/chunks/chunk-MO2HXJG5.js +0 -9
  209. package/chunks/chunk-MTMU7JYZ.js +0 -11
  210. package/chunks/chunk-O44XK65C.js +0 -8
  211. package/chunks/chunk-OA56BXPD.js +0 -3
  212. package/chunks/chunk-PA6532AY.js +0 -6
  213. package/chunks/chunk-PGXQZVLX.js +0 -8
  214. package/chunks/chunk-QKYGQLWC.js +0 -8
  215. package/chunks/chunk-QN6Y6NPA.js +0 -3
  216. package/chunks/chunk-QVCGLQCI.js +0 -32
  217. package/chunks/chunk-S3CWEVTS.js +0 -15
  218. package/chunks/chunk-SDTWBD62.js +0 -8
  219. package/chunks/chunk-T2T2UEPY.js +0 -4
  220. package/chunks/chunk-TISQNFB5.js +0 -3
  221. package/chunks/chunk-U347OO7S.js +0 -9
  222. package/chunks/chunk-UIRBHC5X.js +0 -3
  223. package/chunks/chunk-VI74YQQO.js +0 -8
  224. package/chunks/chunk-VYZOOSMP.js +0 -30
  225. package/chunks/chunk-WC2VTVCE.js +0 -27
  226. package/chunks/chunk-WVY2P6WH.js +0 -26
  227. package/chunks/chunk-WZ75OGYY.js +0 -14
  228. package/chunks/chunk-XMZIY7XX.js +0 -13
  229. package/chunks/chunk-YJAKOETP.js +0 -22
  230. package/chunks/chunk-YV3PUOBU.js +0 -65
  231. package/chunks/contextCommand-DAB3HOHY.js +0 -3
  232. package/chunks/cron-delete-DE6Q2S2L.js +0 -3
  233. package/chunks/cron-list-IAQEJVV7.js +0 -5
  234. package/chunks/de-AQXFJYZI.js +0 -25
  235. package/chunks/dist-7UYRLSLE.js +0 -3
  236. package/chunks/dist-ME6647DQ.js +0 -195
  237. package/chunks/dist-P6SLWL5V.js +0 -42
  238. package/chunks/dist-VG3ZDJ2A.js +0 -28
  239. package/chunks/dist-YTCHM57U.js +0 -23
  240. package/chunks/enterPlanMode-HP35SPLN.js +0 -18
  241. package/chunks/fileFromPath-7UCWPD4W.js +0 -3
  242. package/chunks/fr-6TDHK7F2.js +0 -25
  243. package/chunks/geminiContentGenerator-RJ73DQAP.js +0 -8
  244. package/chunks/glob-QQ6LGKDX.js +0 -22
  245. package/chunks/keychain-token-storage-KQK6MNOJ.js +0 -3
  246. package/chunks/ls-JYJXFSXN.js +0 -15
  247. package/chunks/matildaAgentContentGenerator-YUYS4336.js +0 -8
  248. package/chunks/matildaContentGenerator-O4Z2QPCP.js +0 -8
  249. package/chunks/matildaOAuth2-7COTQQR2.js +0 -3
  250. package/chunks/mcp-client-RXVQU5VI.js +0 -3
  251. package/chunks/monitor-77KXDXPR.js +0 -32
  252. package/chunks/notebook-edit-TKJD2EQZ.js +0 -17
  253. package/chunks/openaiContentGenerator-2EALAM3U.js +0 -3
  254. package/chunks/pt-D6L2QTDM.js +0 -25
  255. package/chunks/read-file-3KUAH6ND.js +0 -3
  256. package/chunks/ripGrep-U2PLKXMY.js +0 -3
  257. package/chunks/ru-BNJCHDYO.js +0 -25
  258. package/chunks/scheduler-J7VU2V5Y.js +0 -8
  259. package/chunks/send-message-P3SMWNEE.js +0 -8
  260. package/chunks/serve-FXH6EBQ6.js +0 -1015
  261. package/chunks/shell-PXR2AXDD.js +0 -3
  262. package/chunks/src-RFAEPLY7.js +0 -3
  263. package/chunks/src-WZTRMETQ.js +0 -5
  264. package/chunks/symbol-search-EAIZPWN7.js +0 -19
  265. package/chunks/task-create-Z3QRCMX4.js +0 -3
  266. package/chunks/task-list-GXAJW3JP.js +0 -9
  267. package/chunks/team-delete-OMYVUAQU.js +0 -8
  268. package/chunks/todoWrite-5NZ7CHTC.js +0 -3
  269. package/chunks/write-file-XDDLTGSG.js +0 -15
@@ -1,1306 +0,0 @@
1
- # Matilda Code Hooks
2
-
3
- ## Overview
4
-
5
- Matilda Code hooks provide a powerful mechanism for extending and customizing the behavior of the Matilda Code application. Hooks allow users to execute custom scripts or programs at specific points in the application lifecycle, such as before tool execution, after tool execution, at session start/end, and during other key events.
6
-
7
- Hooks are enabled by default. You can temporarily disable all hooks by setting `disableAllHooks` to `true` in your settings file (at the top level, alongside `hooks`):
8
-
9
- ```json
10
- {
11
- "disableAllHooks": true,
12
- "hooks": {
13
- "PreToolUse": [...]
14
- }
15
- }
16
- ```
17
-
18
- This disables all hooks without deleting their configurations.
19
-
20
- ## What are Hooks?
21
-
22
- Hooks are user-defined scripts or programs that are automatically executed by Matilda Code at predefined points in the application flow. They allow users to:
23
-
24
- - Monitor and audit tool usage
25
- - Enforce security policies
26
- - Inject additional context into conversations
27
- - Customize application behavior based on events
28
- - Integrate with external systems and services
29
- - Modify tool inputs or responses programmatically
30
-
31
- ## Hook Types
32
-
33
- Matilda Code supports four hook executor types:
34
-
35
- | Type | Description |
36
- | :--------- | :--------------------------------------------------------------------------------------------- |
37
- | `command` | Execute a shell command. Receives JSON via `stdin`, returns results via `stdout`. |
38
- | `http` | Send JSON as a `POST` request body to a specified URL. Returns results via HTTP response body. |
39
- | `function` | Directly call a registered JavaScript function (session-level hooks only). |
40
- | `prompt` | Use an LLM to evaluate hook input and return a decision. |
41
-
42
- ### Command Hooks
43
-
44
- Command hooks execute commands via child processes. Input JSON is passed through stdin, and output is returned via stdout.
45
-
46
- **Configuration:**
47
-
48
- | Field | Type | Required | Description |
49
- | :-------------- | :----------------------- | :------- | :------------------------------------------ |
50
- | `type` | `"command"` | Yes | Hook type |
51
- | `command` | `string` | Yes | Command to execute |
52
- | `name` | `string` | No | Hook name (for logging) |
53
- | `description` | `string` | No | Hook description |
54
- | `timeout` | `number` | No | Timeout in milliseconds, default 60000 |
55
- | `async` | `boolean` | No | Whether to run asynchronously in background |
56
- | `env` | `Record<string, string>` | No | Environment variables |
57
- | `shell` | `"bash" \| "powershell"` | No | Shell to use |
58
- | `statusMessage` | `string` | No | Status message displayed during execution |
59
-
60
- **Example:**
61
-
62
- ```json
63
- {
64
- "hooks": {
65
- "PreToolUse": [
66
- {
67
- "matcher": "WriteFile",
68
- "hooks": [
69
- {
70
- "type": "command",
71
- "command": "$MATILDA_PROJECT_DIR/.matilda/hooks/security-check.sh",
72
- "name": "security-check",
73
- "timeout": 10000
74
- }
75
- ]
76
- }
77
- ]
78
- }
79
- }
80
- ```
81
-
82
- ### HTTP Hooks
83
-
84
- HTTP hooks send hook input as POST requests to specified URLs. They support URL whitelists, DNS-level SSRF protection, environment variable interpolation, and other security features.
85
-
86
- **Configuration:**
87
-
88
- | Field | Type | Required | Description |
89
- | :--------------- | :----------------------- | :------- | :-------------------------------------------------------- |
90
- | `type` | `"http"` | Yes | Hook type |
91
- | `url` | `string` | Yes | Target URL |
92
- | `headers` | `Record<string, string>` | No | Request headers (supports env var interpolation) |
93
- | `allowedEnvVars` | `string[]` | No | Whitelist of environment variables allowed in URL/headers |
94
- | `timeout` | `number` | No | Timeout in seconds, default 600 |
95
- | `name` | `string` | No | Hook name (for logging) |
96
- | `statusMessage` | `string` | No | Status message displayed during execution |
97
- | `once` | `boolean` | No | Execute only once per event per session (HTTP hooks only) |
98
-
99
- **Security Features:**
100
-
101
- - **URL Whitelist**: Configure allowed URL patterns via `allowedUrls`
102
- - **SSRF Protection**: Blocks private IPs (10.x.x.x, 172.16-31.x.x, 192.168.x.x, etc.) but allows loopback addresses (127.0.0.1, ::1)
103
- - **DNS Validation**: Validates domain resolution before requests to prevent DNS rebinding attacks
104
- - **Environment Variable Interpolation**: `${VAR}` syntax, only allows variables in `allowedEnvVars` whitelist
105
-
106
- **Example:**
107
-
108
- ```json
109
- {
110
- "hooks": {
111
- "PreToolUse": [
112
- {
113
- "matcher": "*",
114
- "hooks": [
115
- {
116
- "type": "http",
117
- "url": "http://127.0.0.1:8080/hooks/pre-tool-use",
118
- "headers": {
119
- "Authorization": "Bearer ${HOOK_API_KEY}"
120
- },
121
- "allowedEnvVars": ["HOOK_API_KEY"],
122
- "timeout": 10,
123
- "name": "remote-security-check"
124
- }
125
- ]
126
- }
127
- ]
128
- }
129
- }
130
- ```
131
-
132
- ### Function Hooks
133
-
134
- Function hooks directly call registered JavaScript/TypeScript functions. They are used internally by the Skill system and are not currently exposed as a public API for end users.
135
-
136
- **Note**: For most use cases, use **command hooks** or **HTTP hooks** instead, which can be configured in settings files.
137
-
138
- ### Prompt Hooks
139
-
140
- Prompt hooks use an LLM to evaluate hook input and return a decision. This is useful for making intelligent decisions based on context, such as determining whether to allow or block an operation.
141
-
142
- **How it works:**
143
-
144
- 1. The hook input JSON is injected into your prompt using the `$ARGUMENTS` placeholder
145
- 2. The prompt is sent to an LLM (default: your current model)
146
- 3. The LLM returns a JSON response with the decision
147
- 4. Matilda Code processes the decision and continues or blocks execution accordingly
148
-
149
- **Configuration:**
150
-
151
- | Field | Type | Required | Description |
152
- | :-------------- | :--------- | :------- | :-------------------------------------------------- |
153
- | `type` | `"prompt"` | Yes | Hook type |
154
- | `prompt` | `string` | Yes | Prompt sent to LLM. Use `$ARGUMENTS` for hook input |
155
- | `model` | `string` | No | Model to use (defaults to your current model) |
156
- | `timeout` | `number` | No | Timeout in seconds, default 30 |
157
- | `name` | `string` | No | Hook name (for logging) |
158
- | `description` | `string` | No | Hook description |
159
- | `statusMessage` | `string` | No | Status message displayed during execution |
160
-
161
- **Response Format:**
162
-
163
- The LLM must return JSON with the following structure:
164
-
165
- ```json
166
- {
167
- "ok": true,
168
- "reason": "Explanation of the decision",
169
- "additionalContext": "Optional context to inject into the conversation"
170
- }
171
- ```
172
-
173
- | Field | Description |
174
- | :------------------ | :------------------------------------------------------------------------- |
175
- | `ok` | `true` to allow/continue, `false` to block/stop |
176
- | `reason` | Required when `ok` is `false`. Shown to the model to explain the block |
177
- | `additionalContext` | Optional. Additional context to inject into the conversation when allowing |
178
-
179
- **Supported Events:**
180
-
181
- Prompt hooks can be used with most hook events, including:
182
-
183
- - `PreToolUse` - Evaluate whether to allow a tool call
184
- - `PostToolUse` - Evaluate tool results and potentially inject context
185
- - `Stop` - Determine whether to continue or stop
186
- - `SubagentStop` - Evaluate subagent results
187
- - `UserPromptSubmit` - Evaluate or enrich user prompts
188
-
189
- **Example: Stop Hook**
190
-
191
- ```json
192
- {
193
- "hooks": {
194
- "Stop": [
195
- {
196
- "hooks": [
197
- {
198
- "type": "prompt",
199
- "prompt": "You are evaluating whether Matilda Code should stop working. Context: $ARGUMENTS\n\nAnalyze the conversation and determine if:\n1. All user-requested tasks are complete\n2. Any errors need to be addressed\n3. Follow-up work is needed\n\nRespond with JSON: {\"ok\": true} to allow stopping, or {\"ok\": false, \"reason\": \"your explanation\"} to continue working.",
200
- "timeout": 30
201
- }
202
- ]
203
- }
204
- ]
205
- }
206
- }
207
- ```
208
-
209
- When `ok` is `false`, Matilda Code will continue working and use the `reason` as context for the next response.
210
-
211
- **Example: PreToolUse Hook**
212
-
213
- ```json
214
- {
215
- "hooks": {
216
- "PreToolUse": [
217
- {
218
- "matcher": "Bash",
219
- "hooks": [
220
- {
221
- "type": "prompt",
222
- "prompt": "Evaluate this tool call for security concerns. Tool input: $ARGUMENTS\n\nCheck for:\n- Dangerous commands (rm -rf, curl | sh, etc.)\n- Unauthorized access attempts\n- Data exfiltration patterns\n\nRespond with {\"ok\": true} if safe, or {\"ok\": false, \"reason\": \"concern\"} if blocked.",
223
- "model": "sonnet",
224
- "timeout": 30,
225
- "name": "security-evaluator"
226
- }
227
- ]
228
- }
229
- ]
230
- }
231
- }
232
- ```
233
-
234
- ## Hook Events
235
-
236
- Hooks fire at specific points during a Matilda Code session. Different events support different matchers to filter trigger conditions.
237
-
238
- | Event | Triggered When | Matcher Target |
239
- | :------------------- | :---------------------------------------- | :-------------------------------------------------------- |
240
- | `PreToolUse` | Before tool execution | Tool name (`WriteFile`, `ReadFile`, `Bash`, etc.) |
241
- | `PostToolUse` | After successful tool execution | Tool name |
242
- | `PostToolUseFailure` | After tool execution fails | Tool name |
243
- | `UserPromptSubmit` | After user submits prompt | None (always fires) |
244
- | `SessionStart` | When session starts or resumes | Source (`startup`, `resume`, `clear`, `compact`) |
245
- | `SessionEnd` | When session ends | Reason (`clear`, `logout`, `prompt_input_exit`, etc.) |
246
- | `Stop` | When Claude prepares to conclude response | None (always fires) |
247
- | `SubagentStart` | When subagent starts | Agent type (`Bash`, `Explorer`, `Plan`, etc.) |
248
- | `SubagentStop` | When subagent stops | Agent type |
249
- | `PreCompact` | Before conversation compaction | Trigger (`manual`, `auto`) |
250
- | `Notification` | When notifications are sent | Type (`permission_prompt`, `idle_prompt`, `auth_success`) |
251
- | `PermissionRequest` | When permission dialog is shown | Tool name |
252
- | `TodoCreated` | When a new todo item is created | None (always fires) |
253
- | `TodoCompleted` | When a todo item is marked as completed | None (always fires) |
254
-
255
- ### Matcher Patterns
256
-
257
- `matcher` is a regular expression used to filter trigger conditions.
258
-
259
- | Event Type | Events | Matcher Support | Matcher Target |
260
- | :------------------ | :--------------------------------------------------------------------- | :-------------- | :------------------------------------------------------- |
261
- | Tool Events | `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest` | ✅ Regex | Tool name: `WriteFile`, `ReadFile`, `Bash`, etc. |
262
- | Subagent Events | `SubagentStart`, `SubagentStop` | ✅ Regex | Agent type: `Bash`, `Explorer`, etc. |
263
- | Session Events | `SessionStart` | ✅ Regex | Source: `startup`, `resume`, `clear`, `compact` |
264
- | Session Events | `SessionEnd` | ✅ Regex | Reason: `clear`, `logout`, `prompt_input_exit`, etc. |
265
- | Notification Events | `Notification` | ✅ Exact match | Type: `permission_prompt`, `idle_prompt`, `auth_success` |
266
- | Compact Events | `PreCompact` | ✅ Exact match | Trigger: `manual`, `auto` |
267
- | Todo Events | `TodoCreated`, `TodoCompleted` | ❌ No | N/A |
268
- | Prompt Events | `UserPromptSubmit` | ❌ No | N/A |
269
- | Stop Events | `Stop` | ❌ No | N/A |
270
-
271
- **Matcher Syntax:**
272
-
273
- - Empty string `""` or `"*"` matches all events of that type
274
- - Standard regex syntax supported (e.g., `^Bash$`, `Read.*`, `(WriteFile|Edit)`)
275
-
276
- **Examples:**
277
-
278
- ```json
279
- {
280
- "hooks": {
281
- "PreToolUse": [
282
- {
283
- "matcher": "^Bash$",
284
- "hooks": [
285
- {
286
- "type": "command",
287
- "command": "echo 'bash check' >> /tmp/hooks.log"
288
- }
289
- ]
290
- },
291
- {
292
- "matcher": "Write.*",
293
- "hooks": [
294
- {
295
- "type": "command",
296
- "command": "echo 'write check' >> /tmp/hooks.log"
297
- }
298
- ]
299
- },
300
- {
301
- "matcher": "*",
302
- "hooks": [
303
- { "type": "command", "command": "echo 'all tools' >> /tmp/hooks.log" }
304
- ]
305
- }
306
- ],
307
- "SubagentStart": [
308
- {
309
- "matcher": "^(Bash|Explorer)$",
310
- "hooks": [
311
- {
312
- "type": "command",
313
- "command": "echo 'subagent check' >> /tmp/hooks.log"
314
- }
315
- ]
316
- }
317
- ]
318
- }
319
- }
320
- ```
321
-
322
- ## Input/Output Rules
323
-
324
- ### Hook Input Structure
325
-
326
- All hooks receive standardized input in JSON format through stdin (command) or POST body (http).
327
-
328
- **Common Fields:**
329
-
330
- ```json
331
- {
332
- "session_id": "string",
333
- "transcript_path": "string",
334
- "cwd": "string",
335
- "hook_event_name": "string",
336
- "timestamp": "string"
337
- }
338
- ```
339
-
340
- Event-specific fields are added based on the hook type. When running in a subagent, `agent_id` and `agent_type` are additionally included.
341
-
342
- ### Hook Output Structure
343
-
344
- Hook output is returned via `stdout` (command) or HTTP response body (http) as JSON.
345
-
346
- **Exit Code Behavior (Command Hooks):**
347
-
348
- | Exit Code | Behavior |
349
- | :-------- | :------------------------------------------------------------------------------------ |
350
- | `0` | Success. Parse JSON in `stdout` to control behavior. |
351
- | `2` | **Blocking error**. Ignores `stdout`, passes `stderr` as error feedback to the model. |
352
- | Other | Non-blocking error. `stderr` only shown in debug mode, execution continues. |
353
-
354
- **Output Structure:**
355
-
356
- Hook output supports three categories of fields:
357
-
358
- 1. **Common Fields**: `continue`, `stopReason`, `suppressOutput`, `systemMessage`
359
- 2. **Top-level Decision**: `decision`, `reason` (used by some events)
360
- 3. **Event-specific Control**: `hookSpecificOutput` (must include `hookEventName`)
361
-
362
- ```json
363
- {
364
- "continue": true,
365
- "decision": "allow",
366
- "reason": "Operation approved",
367
- "hookSpecificOutput": {
368
- "hookEventName": "PreToolUse",
369
- "additionalContext": "Additional context information"
370
- }
371
- }
372
- ```
373
-
374
- ### Individual Hook Event Details
375
-
376
- #### PreToolUse
377
-
378
- **Purpose**: Executed before a tool is used to allow for permission checks, input validation, or context injection.
379
-
380
- **Event-specific fields**:
381
-
382
- ```json
383
- {
384
- "permission_mode": "default | plan | auto_edit | yolo",
385
- "tool_name": "name of the tool being executed",
386
- "tool_input": "object containing the tool's input parameters",
387
- "tool_use_id": "unique identifier for this tool use instance"
388
- }
389
- ```
390
-
391
- **Output Options**:
392
-
393
- - `hookSpecificOutput.permissionDecision`: "allow", "deny", or "ask" (REQUIRED)
394
- - `hookSpecificOutput.permissionDecisionReason`: explanation for the decision (REQUIRED)
395
- - `hookSpecificOutput.updatedInput`: modified tool input parameters to use instead of original
396
- - `hookSpecificOutput.additionalContext`: additional context information
397
-
398
- **Note**: While standard hook output fields like `decision` and `reason` are technically supported by the underlying class, the official interface expects the `hookSpecificOutput` with `permissionDecision` and `permissionDecisionReason`.
399
-
400
- **Example Output**:
401
-
402
- ```json
403
- {
404
- "hookSpecificOutput": {
405
- "hookEventName": "PreToolUse",
406
- "permissionDecision": "deny",
407
- "permissionDecisionReason": "Security policy blocks database writes",
408
- "additionalContext": "Current environment: production. Proceed with caution."
409
- }
410
- }
411
- ```
412
-
413
- #### PostToolUse
414
-
415
- **Purpose**: Executed after a tool completes successfully to process results, log outcomes, or inject additional context.
416
-
417
- **Event-specific fields**:
418
-
419
- ```json
420
- {
421
- "permission_mode": "default | plan | auto_edit | yolo",
422
- "tool_name": "name of the tool that was executed",
423
- "tool_input": "object containing the tool's input parameters",
424
- "tool_response": "object containing the tool's response",
425
- "tool_use_id": "unique identifier for this tool use instance"
426
- }
427
- ```
428
-
429
- **Output Options**:
430
-
431
- - `decision`: "allow", "deny", "block" (defaults to "allow" if not specified)
432
- - `reason`: reason for the decision
433
- - `hookSpecificOutput.additionalContext`: additional information to be included
434
-
435
- **Example Output**:
436
-
437
- ```json
438
- {
439
- "decision": "allow",
440
- "reason": "Tool executed successfully",
441
- "hookSpecificOutput": {
442
- "additionalContext": "File modification recorded in audit log"
443
- }
444
- }
445
- ```
446
-
447
- #### PostToolUseFailure
448
-
449
- **Purpose**: Executed when a tool execution fails to handle errors, send alerts, or record failures.
450
-
451
- **Event-specific fields**:
452
-
453
- ```json
454
- {
455
- "permission_mode": "default | plan | auto_edit | yolo",
456
- "tool_use_id": "unique identifier for the tool use",
457
- "tool_name": "name of the tool that failed",
458
- "tool_input": "object containing the tool's input parameters",
459
- "error": "error message describing the failure",
460
- "is_interrupt": "boolean indicating if failure was due to user interruption (optional)"
461
- }
462
- ```
463
-
464
- **Output Options**:
465
-
466
- - `hookSpecificOutput.additionalContext`: error handling information
467
- - Standard hook output fields
468
-
469
- **Example Output**:
470
-
471
- ```json
472
- {
473
- "hookSpecificOutput": {
474
- "additionalContext": "Error: File not found. Failure logged in monitoring system."
475
- }
476
- }
477
- ```
478
-
479
- #### UserPromptSubmit
480
-
481
- **Purpose**: Executed when the user submits a prompt to modify, validate, or enrich the input.
482
-
483
- **Event-specific fields**:
484
-
485
- ```json
486
- {
487
- "prompt": "the user's submitted prompt text"
488
- }
489
- ```
490
-
491
- **Output Options**:
492
-
493
- - `decision`: "allow", "deny", "block", or "ask"
494
- - `reason`: human-readable explanation for the decision
495
- - `hookSpecificOutput.additionalContext`: additional context to append to the prompt (optional)
496
-
497
- **Note**: Since UserPromptSubmitOutput extends HookOutput, all standard fields are available but only additionalContext in hookSpecificOutput is specifically defined for this event.
498
-
499
- **Example Output**:
500
-
501
- ```json
502
- {
503
- "decision": "allow",
504
- "reason": "Prompt reviewed and approved",
505
- "hookSpecificOutput": {
506
- "additionalContext": "Remember to follow company coding standards."
507
- }
508
- }
509
- ```
510
-
511
- #### SessionStart
512
-
513
- **Purpose**: Executed when a new session starts to perform initialization tasks.
514
-
515
- **Event-specific fields**:
516
-
517
- ```json
518
- {
519
- "permission_mode": "default | plan | auto_edit | yolo",
520
- "source": "startup | resume | clear | compact",
521
- "model": "the model being used",
522
- "agent_type": "the type of agent if applicable (optional)"
523
- }
524
- ```
525
-
526
- **Output Options**:
527
-
528
- - `hookSpecificOutput.additionalContext`: context to be available in the session
529
- - Standard hook output fields
530
-
531
- **Example Output**:
532
-
533
- ```json
534
- {
535
- "hookSpecificOutput": {
536
- "additionalContext": "Session started with security policies enabled."
537
- }
538
- }
539
- ```
540
-
541
- #### SessionEnd
542
-
543
- **Purpose**: Executed when a session ends to perform cleanup tasks.
544
-
545
- **Event-specific fields**:
546
-
547
- ```json
548
- {
549
- "reason": "clear | logout | prompt_input_exit | bypass_permissions_disabled | other"
550
- }
551
- ```
552
-
553
- **Output Options**:
554
-
555
- - Standard hook output fields (typically not used for blocking)
556
-
557
- #### Stop
558
-
559
- **Purpose**: Executed before Matilda concludes its response to provide final feedback or summaries.
560
-
561
- **Event-specific fields**:
562
-
563
- ```json
564
- {
565
- "stop_hook_active": "boolean indicating if stop hook is active",
566
- "last_assistant_message": "the last message from the assistant"
567
- }
568
- ```
569
-
570
- **Output Options**:
571
-
572
- - `decision`: "allow", "deny", "block", or "ask"
573
- - `reason`: human-readable explanation for the decision
574
- - `stopReason`: feedback to include in the stop response
575
- - `continue`: set to false to stop execution
576
- - `hookSpecificOutput.additionalContext`: additional context information
577
-
578
- **Note**: Since StopOutput extends HookOutput, all standard fields are available but the stopReason field is particularly relevant for this event.
579
-
580
- **Example Output**:
581
-
582
- ```json
583
- {
584
- "decision": "block",
585
- "reason": "Must be provided when Matilda Code is blocked from stopping"
586
- }
587
- ```
588
-
589
- #### StopFailure
590
-
591
- **Purpose**: Executed when the turn ends due to an API error (instead of Stop). This is a **fire-and-forget** event - hook output and exit codes are ignored.
592
-
593
- **Event-specific fields**:
594
-
595
- ```json
596
- {
597
- "error": "rate_limit | authentication_failed | billing_error | invalid_request | server_error | max_output_tokens | unknown",
598
- "error_details": "detailed error message (optional)",
599
- "last_assistant_message": "the last message from the assistant before the error (optional)"
600
- }
601
- ```
602
-
603
- **Matcher**: Matches against the `error` field. For example, `"matcher": "rate_limit"` will only trigger for rate limit errors.
604
-
605
- **Output Options**:
606
-
607
- - **None** - StopFailure is fire-and-forget. All hook output and exit codes are ignored.
608
-
609
- **Exit Code Handling**:
610
-
611
- | Exit Code | Behavior |
612
- | --------- | ------------------------- |
613
- | Any | Ignored (fire-and-forget) |
614
-
615
- **Example Configuration**:
616
-
617
- ```json
618
- {
619
- "hooks": {
620
- "StopFailure": [
621
- {
622
- "matcher": "rate_limit",
623
- "hooks": [
624
- {
625
- "type": "command",
626
- "command": "/path/to/rate-limit-alert.sh",
627
- "name": "rate-limit-alerter"
628
- }
629
- ]
630
- }
631
- ]
632
- }
633
- }
634
- ```
635
-
636
- **Use Cases**:
637
-
638
- - Rate limit monitoring and alerting
639
- - Authentication failure logging
640
- - Billing error notifications
641
- - Error statistics collection
642
-
643
- #### SubagentStart
644
-
645
- **Purpose**: Executed when a subagent (like the Task tool) is started to set up context or permissions.
646
-
647
- **Event-specific fields**:
648
-
649
- ```json
650
- {
651
- "permission_mode": "default | plan | auto_edit | yolo",
652
- "agent_id": "identifier for the subagent",
653
- "agent_type": "type of agent (Bash, Explorer, Plan, Custom, etc.)"
654
- }
655
- ```
656
-
657
- **Output Options**:
658
-
659
- - `hookSpecificOutput.additionalContext`: initial context for the subagent
660
- - Standard hook output fields
661
-
662
- **Example Output**:
663
-
664
- ```json
665
- {
666
- "hookSpecificOutput": {
667
- "additionalContext": "Subagent initialized with restricted permissions."
668
- }
669
- }
670
- ```
671
-
672
- #### SubagentStop
673
-
674
- **Purpose**: Executed when a subagent finishes to perform finalization tasks.
675
-
676
- **Event-specific fields**:
677
-
678
- ```json
679
- {
680
- "permission_mode": "default | plan | auto_edit | yolo",
681
- "stop_hook_active": "boolean indicating if stop hook is active",
682
- "agent_id": "identifier for the subagent",
683
- "agent_type": "type of agent",
684
- "agent_transcript_path": "path to the subagent's transcript",
685
- "last_assistant_message": "the last message from the subagent"
686
- }
687
- ```
688
-
689
- **Output Options**:
690
-
691
- - `decision`: "allow", "deny", "block", or "ask"
692
- - `reason`: human-readable explanation for the decision
693
-
694
- **Example Output**:
695
-
696
- ```json
697
- {
698
- "decision": "block",
699
- "reason": "Must be provided when Matilda Code is blocked from stopping"
700
- }
701
- ```
702
-
703
- #### PreCompact
704
-
705
- **Purpose**: Executed before conversation compaction to prepare or log the compaction.
706
-
707
- **Event-specific fields**:
708
-
709
- ```json
710
- {
711
- "trigger": "manual | auto",
712
- "custom_instructions": "custom instructions currently set"
713
- }
714
- ```
715
-
716
- **Output Options**:
717
-
718
- - `hookSpecificOutput.additionalContext`: context to include before compaction
719
- - Standard hook output fields
720
-
721
- **Example Output**:
722
-
723
- ```json
724
- {
725
- "hookSpecificOutput": {
726
- "additionalContext": "Compacting conversation to maintain optimal context window."
727
- }
728
- }
729
- ```
730
-
731
- #### PostCompact
732
-
733
- **Purpose**: Executed after conversation compaction completes to archive summaries or track usage.
734
-
735
- **Event-specific fields**:
736
-
737
- ```json
738
- {
739
- "trigger": "manual | auto",
740
- "compact_summary": "the summary generated by the compaction process"
741
- }
742
- ```
743
-
744
- **Matcher**: Matches against the `trigger` field. For example, `"matcher": "manual"` will only trigger for manual compaction via `/compact` command.
745
-
746
- **Output Options**:
747
-
748
- - `hookSpecificOutput.additionalContext`: additional context (for logging only)
749
- - Standard hook output fields (for logging only)
750
-
751
- **Note**: PostCompact is **not** in the official decision mode supported events list. The `decision` field and other control fields do not produce any control effects - they are only used for logging purposes.
752
-
753
- **Exit Code Handling**:
754
-
755
- | Exit Code | Behavior |
756
- | --------- | --------------------------------------------------------- |
757
- | 0 | Success - stdout shown to user in verbose mode |
758
- | Other | Non-blocking error - stderr shown to user in verbose mode |
759
-
760
- **Example Configuration**:
761
-
762
- ```json
763
- {
764
- "hooks": {
765
- "PostCompact": [
766
- {
767
- "matcher": "manual",
768
- "hooks": [
769
- {
770
- "type": "command",
771
- "command": "/path/to/save-compact-summary.sh",
772
- "name": "save-summary"
773
- }
774
- ]
775
- }
776
- ]
777
- }
778
- }
779
- ```
780
-
781
- **Use Cases**:
782
-
783
- - Summary archiving to files or databases
784
- - Usage statistics tracking
785
- - Context change monitoring
786
- - Audit logging for compaction operations
787
-
788
- #### Notification
789
-
790
- **Purpose**: Executed when notifications are sent to customize or intercept them.
791
-
792
- **Event-specific fields**:
793
-
794
- ```json
795
- {
796
- "message": "notification message content",
797
- "title": "notification title (optional)",
798
- "notification_type": "permission_prompt | idle_prompt | auth_success"
799
- }
800
- ```
801
-
802
- > **Note**: `elicitation_dialog` type is defined but not currently implemented.
803
-
804
- **Output Options**:
805
-
806
- - `hookSpecificOutput.additionalContext`: additional information to include
807
- - Standard hook output fields
808
-
809
- **Example Output**:
810
-
811
- ```json
812
- {
813
- "hookSpecificOutput": {
814
- "additionalContext": "Notification processed by monitoring system."
815
- }
816
- }
817
- ```
818
-
819
- #### PermissionRequest
820
-
821
- **Purpose**: Executed when permission dialogs are displayed to automate decisions or update permissions.
822
-
823
- **Event-specific fields**:
824
-
825
- ```json
826
- {
827
- "permission_mode": "default | plan | auto_edit | yolo",
828
- "tool_name": "name of the tool requesting permission",
829
- "tool_input": "object containing the tool's input parameters",
830
- "permission_suggestions": "array of suggested permissions (optional)"
831
- }
832
- ```
833
-
834
- **Output Options**:
835
-
836
- - `hookSpecificOutput.decision`: structured object with permission decision details:
837
- - `behavior`: "allow" or "deny"
838
- - `updatedInput`: modified tool input (optional)
839
- - `updatedPermissions`: modified permissions (optional)
840
- - `message`: message to show to user (optional)
841
- - `interrupt`: whether to interrupt the workflow (optional)
842
-
843
- **Example Output**:
844
-
845
- ```json
846
- {
847
- "hookSpecificOutput": {
848
- "decision": {
849
- "behavior": "allow",
850
- "message": "Permission granted based on security policy",
851
- "interrupt": false
852
- }
853
- }
854
- }
855
- ```
856
-
857
- #### TodoCreated
858
-
859
- **Purpose**: Executed when a new todo item is created via the `todo_write` tool. Allows validation, logging, or blocking of todo creation.
860
-
861
- Todo hooks run in two phases:
862
-
863
- - `validation`: runs before persistence. Use this phase for validation only; returning `block` or `deny` prevents the write.
864
- - `postWrite`: runs after persistence. Use this phase for side effects such as logging or syncing; `block` or `deny` is ignored in this phase.
865
-
866
- **Event-specific fields**:
867
-
868
- ```json
869
- {
870
- "todo_id": "unique identifier for the todo item",
871
- "todo_content": "content/description of the todo item",
872
- "todo_status": "pending | in_progress | completed",
873
- "all_todos": "array of all todo items in the current list",
874
- "phase": "validation | postWrite"
875
- }
876
- ```
877
-
878
- **Output Options**:
879
-
880
- - `decision`: "allow", "block", or "deny"
881
- - `reason`: human-readable explanation for the decision (required when blocking)
882
-
883
- **Blocking Behavior**:
884
-
885
- During the `validation` phase, when `decision` is `block` or `deny` (exit code 2), todo creation is prevented. The todo list remains unchanged, and the reason is provided as feedback to the model.
886
-
887
- During the `postWrite` phase, the todo has already been persisted. Hooks may still return output, but `block` / `deny` does not undo the write and should not be used for validation.
888
-
889
- **Example Output (Allow)**:
890
-
891
- ```json
892
- {
893
- "decision": "allow",
894
- "reason": "Todo content validated successfully"
895
- }
896
- ```
897
-
898
- **Example Output (Block)**:
899
-
900
- ```json
901
- {
902
- "decision": "block",
903
- "reason": "Todo content too short. Minimum 5 characters required."
904
- }
905
- ```
906
-
907
- **Example Hook Script**:
908
-
909
- ```bash
910
- #!/bin/bash
911
- # ~/.matilda/hooks/todo-validator.sh
912
- # Validates todo content before creation
913
-
914
- INPUT=$(cat)
915
- CONTENT=$(echo "$INPUT" | jq -r '.todo_content')
916
-
917
- # Check minimum length
918
- if [ ${#CONTENT} -lt 5 ]; then
919
- echo '{"decision": "block", "reason": "Todo content must be at least 5 characters"}'
920
- exit 2
921
- fi
922
-
923
- # Block test-related todos
924
- if [[ "$CONTENT" =~ "test" ]]; then
925
- echo '{"decision": "block", "reason": "Test todos are not allowed in production"}'
926
- exit 2
927
- fi
928
-
929
- echo '{"decision": "allow"}'
930
- exit 0
931
- ```
932
-
933
- **Example Configuration**:
934
-
935
- ```json
936
- {
937
- "hooks": {
938
- "TodoCreated": [
939
- {
940
- "hooks": [
941
- {
942
- "type": "command",
943
- "command": "$HOME/.matilda/hooks/todo-validator.sh",
944
- "name": "todo-validator",
945
- "timeout": 5000
946
- }
947
- ]
948
- }
949
- ]
950
- }
951
- }
952
- ```
953
-
954
- #### TodoCompleted
955
-
956
- **Purpose**: Executed when a todo item is marked as completed. Allows validation, logging, or blocking of todo completion.
957
-
958
- Todo hooks run in two phases:
959
-
960
- - `validation`: runs before persistence. Use this phase for validation only; returning `block` or `deny` prevents the write.
961
- - `postWrite`: runs after persistence. Use this phase for side effects such as logging or syncing; `block` or `deny` is ignored in this phase.
962
-
963
- **Event-specific fields**:
964
-
965
- ```json
966
- {
967
- "todo_id": "unique identifier for the todo item",
968
- "todo_content": "content/description of the todo item",
969
- "previous_status": "pending | in_progress (status before completion)",
970
- "all_todos": "array of all todo items in the current list",
971
- "phase": "validation | postWrite"
972
- }
973
- ```
974
-
975
- **Output Options**:
976
-
977
- - `decision`: "allow", "block", or "deny"
978
- - `reason`: human-readable explanation for the decision (required when blocking)
979
-
980
- **Blocking Behavior**:
981
-
982
- During the `validation` phase, when `decision` is `block` or `deny` (exit code 2), todo completion is prevented. The todo item remains in its previous status, and the reason is provided as feedback to the model.
983
-
984
- During the `postWrite` phase, the todo has already been persisted. Hooks may still return output, but `block` / `deny` does not undo the write and should not be used for validation.
985
-
986
- **Example Output (Allow)**:
987
-
988
- ```json
989
- {
990
- "decision": "allow",
991
- "reason": "Todo completion approved"
992
- }
993
- ```
994
-
995
- **Example Output (Block)**:
996
-
997
- ```json
998
- {
999
- "decision": "block",
1000
- "reason": "Cannot complete this todo until dependent tasks are finished."
1001
- }
1002
- ```
1003
-
1004
- **Example Hook Script**:
1005
-
1006
- ```bash
1007
- #!/bin/bash
1008
- # ~/.matilda/hooks/todo-completion-validator.sh
1009
- # Validates todo completion conditions
1010
-
1011
- INPUT=$(cat)
1012
- TODO_ID=$(echo "$INPUT" | jq -r '.todo_id')
1013
- ALL_TODOS=$(echo "$INPUT" | jq -r '.all_todos')
1014
-
1015
- # Check if there are incomplete dependent todos (example logic)
1016
- INCOMPLETE_COUNT=$(echo "$ALL_TODOS" | jq '[.[] | select(.status != "completed")] | length')
1017
-
1018
- if [ "$INCOMPLETE_COUNT" -gt 5 ]; then
1019
- echo '{"decision": "block", "reason": "Too many incomplete todos. Complete other tasks first."}'
1020
- exit 2
1021
- fi
1022
-
1023
- echo '{"decision": "allow"}'
1024
- exit 0
1025
- ```
1026
-
1027
- **Example Configuration**:
1028
-
1029
- ```json
1030
- {
1031
- "hooks": {
1032
- "TodoCompleted": [
1033
- {
1034
- "hooks": [
1035
- {
1036
- "type": "command",
1037
- "command": "$HOME/.matilda/hooks/todo-completion-validator.sh",
1038
- "name": "completion-validator",
1039
- "timeout": 5000
1040
- }
1041
- ]
1042
- }
1043
- ]
1044
- }
1045
- }
1046
- ```
1047
-
1048
- **Use Cases**:
1049
-
1050
- - **Logging**: Track todo creation and completion for audit or analytics
1051
- - **Validation**: Enforce content quality standards (minimum length, required keywords)
1052
- - **Workflow Control**: Block completion until prerequisites are met
1053
- - **Integration**: Sync todos with external task management systems (Jira, Trello, etc.)
1054
-
1055
- ## Hook Configuration
1056
-
1057
- Hooks are configured in Matilda Code settings, typically in `.matilda/settings.json` or user configuration files:
1058
-
1059
- ```json
1060
- {
1061
- "hooks": {
1062
- "PreToolUse": [
1063
- {
1064
- "matcher": "^Bash$",
1065
- "sequential": false,
1066
- "hooks": [
1067
- {
1068
- "type": "command",
1069
- "command": "/path/to/security-check.sh",
1070
- "name": "security-check",
1071
- "description": "Run security checks before tool execution",
1072
- "timeout": 30000
1073
- }
1074
- ]
1075
- }
1076
- ],
1077
- "SessionStart": [
1078
- {
1079
- "hooks": [
1080
- {
1081
- "type": "command",
1082
- "command": "echo 'Session started'",
1083
- "name": "session-init"
1084
- }
1085
- ]
1086
- }
1087
- ]
1088
- }
1089
- }
1090
- ```
1091
-
1092
- ## Hook Execution
1093
-
1094
- ### Parallel vs Sequential Execution
1095
-
1096
- - By default, hooks execute in parallel for better performance
1097
- - Use `sequential: true` in hook definition to enforce order-dependent execution
1098
- - Sequential hooks can modify input for subsequent hooks in the chain
1099
-
1100
- ### Async Hooks
1101
-
1102
- Only `command` type supports asynchronous execution. Setting `"async": true` runs the hook in the background without blocking the main flow.
1103
-
1104
- **Features:**
1105
-
1106
- - Cannot return decision control (operation has already occurred)
1107
- - Results are injected in the next conversation turn via `systemMessage` or `additionalContext`
1108
- - Suitable for auditing, logging, background testing, etc.
1109
-
1110
- **Example:**
1111
-
1112
- ```json
1113
- {
1114
- "hooks": {
1115
- "PostToolUse": [
1116
- {
1117
- "matcher": "WriteFile|Edit",
1118
- "hooks": [
1119
- {
1120
- "type": "command",
1121
- "command": "$MATILDA_PROJECT_DIR/.matilda/hooks/run-tests-async.sh",
1122
- "async": true,
1123
- "timeout": 300000
1124
- }
1125
- ]
1126
- }
1127
- ]
1128
- }
1129
- }
1130
- ```
1131
-
1132
- ```bash
1133
- #!/bin/bash
1134
- INPUT=$(cat)
1135
- FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
1136
- if [[ "$FILE_PATH" != *.ts && "$FILE_PATH" != *.js ]]; then exit 0; fi
1137
- RESULT=$(npm test 2>&1)
1138
- if [ $? -eq 0 ]; then
1139
- echo "{\"systemMessage\": \"Tests passed after editing $FILE_PATH\"}"
1140
- else
1141
- echo "{\"systemMessage\": \"Tests failed: $RESULT\"}"
1142
- fi
1143
- ```
1144
-
1145
- ### Security Model
1146
-
1147
- - Hooks run in the user's environment with user privileges
1148
- - Project-level hooks require trusted folder status
1149
- - Timeouts prevent hanging hooks (default: 60 seconds)
1150
-
1151
- ## Best Practices
1152
-
1153
- ### Example 1: Security Validation Hook
1154
-
1155
- A PreToolUse hook that logs and potentially blocks dangerous commands:
1156
-
1157
- **security_check.sh**
1158
-
1159
- ```bash
1160
- #!/bin/bash
1161
-
1162
- # Read input from stdin
1163
- INPUT=$(cat)
1164
-
1165
- # Parse the input to extract tool info
1166
- TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
1167
- TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')
1168
-
1169
- # Check for potentially dangerous operations
1170
- if echo "$TOOL_INPUT" | grep -qiE "(rm.*-rf|mv.*\/|chmod.*777)"; then
1171
- echo '{
1172
- "hookSpecificOutput": {
1173
- "hookEventName": "PreToolUse",
1174
- "permissionDecision": "deny",
1175
- "permissionDecisionReason": "Security policy blocks dangerous command"
1176
- }
1177
- }'
1178
- exit 2 # Blocking error
1179
- fi
1180
-
1181
- # Log the operation
1182
- echo "INFO: Tool $TOOL_NAME executed safely at $(date)" >> /var/log/matilda-security.log
1183
-
1184
- # Allow with additional context
1185
- echo '{
1186
- "hookSpecificOutput": {
1187
- "hookEventName": "PreToolUse",
1188
- "permissionDecision": "allow",
1189
- "permissionDecisionReason": "Security check passed",
1190
- "additionalContext": "Command approved by security policy"
1191
- }
1192
- }'
1193
- exit 0
1194
- ```
1195
-
1196
- Configure in `.matilda/settings.json`:
1197
-
1198
- ```json
1199
- {
1200
- "hooks": {
1201
- "PreToolUse": [
1202
- {
1203
- "hooks": [
1204
- {
1205
- "type": "command",
1206
- "command": "${SECURITY_CHECK_SCRIPT}",
1207
- "name": "security-checker",
1208
- "description": "Security validation for bash commands",
1209
- "timeout": 10000
1210
- }
1211
- ]
1212
- }
1213
- ]
1214
- }
1215
- }
1216
- ```
1217
-
1218
- ### Example 2: HTTP Audit Hook
1219
-
1220
- A PostToolUse HTTP hook that sends all tool execution records to a remote audit service:
1221
-
1222
- ```json
1223
- {
1224
- "hooks": {
1225
- "PostToolUse": [
1226
- {
1227
- "matcher": "*",
1228
- "hooks": [
1229
- {
1230
- "type": "http",
1231
- "url": "https://audit.example.com/api/tool-execution",
1232
- "headers": {
1233
- "Authorization": "Bearer ${AUDIT_API_TOKEN}",
1234
- "Content-Type": "application/json"
1235
- },
1236
- "allowedEnvVars": ["AUDIT_API_TOKEN"],
1237
- "timeout": 10,
1238
- "name": "audit-logger"
1239
- }
1240
- ]
1241
- }
1242
- ]
1243
- }
1244
- }
1245
- ```
1246
-
1247
- ### Example 3: User Prompt Validation Hook
1248
-
1249
- A UserPromptSubmit hook that validates user prompts for sensitive information and provides context for long prompts:
1250
-
1251
- **prompt_validator.py**
1252
-
1253
- ```python
1254
- import json
1255
- import sys
1256
- import re
1257
-
1258
- # Load input from stdin
1259
- try:
1260
- input_data = json.load(sys.stdin)
1261
- except json.JSONDecodeError as e:
1262
- print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
1263
- exit(1)
1264
-
1265
- user_prompt = input_data.get("prompt", "")
1266
-
1267
- # Sensitive words list
1268
- sensitive_words = ["password", "secret", "token", "api_key"]
1269
-
1270
- # Check for sensitive information
1271
- for word in sensitive_words:
1272
- if re.search(rf"\b{word}\b", user_prompt.lower()):
1273
- # Block prompts containing sensitive information
1274
- output = {
1275
- "decision": "block",
1276
- "reason": f"Prompt contains sensitive information '{word}'. Please remove sensitive content and resubmit.",
1277
- "hookSpecificOutput": {
1278
- "hookEventName": "UserPromptSubmit"
1279
- }
1280
- }
1281
- print(json.dumps(output))
1282
- exit(0)
1283
-
1284
- # Check prompt length and add warning context if too long
1285
- if len(user_prompt) > 1000:
1286
- output = {
1287
- "hookSpecificOutput": {
1288
- "hookEventName": "UserPromptSubmit",
1289
- "additionalContext": "Note: User submitted a long prompt. Please read carefully and ensure all requirements are understood."
1290
- }
1291
- }
1292
- print(json.dumps(output))
1293
- exit(0)
1294
-
1295
- # No processing needed for normal cases
1296
- exit(0)
1297
- ```
1298
-
1299
- ## Troubleshooting
1300
-
1301
- - Check application logs for hook execution details
1302
- - Verify hook script permissions and executability
1303
- - Ensure proper JSON formatting in hook outputs
1304
- - Use specific matcher patterns to avoid unintended hook execution
1305
- - Use `--debug` mode to see detailed hook matching and execution information
1306
- - Temporarily disable all hooks: add `"disableAllHooks": true` in settings