dominds 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/LICENSE +157 -0
  2. package/README.md +250 -0
  3. package/README.zh.md +161 -0
  4. package/dist/access-control.js +253 -0
  5. package/dist/cli/create.js +263 -0
  6. package/dist/cli/read.js +84 -0
  7. package/dist/cli/tui.js +199 -0
  8. package/dist/cli/webui.js +169 -0
  9. package/dist/cli.js +227 -0
  10. package/dist/dialog-factory.js +53 -0
  11. package/dist/dialog-global-registry.js +68 -0
  12. package/dist/dialog-instance-registry.js +78 -0
  13. package/dist/dialog-run-state.js +198 -0
  14. package/dist/dialog.js +1024 -0
  15. package/dist/evt-registry.js +103 -0
  16. package/dist/index.js +8 -0
  17. package/dist/llm/client.js +69 -0
  18. package/dist/llm/defaults.yaml +386 -0
  19. package/dist/llm/driver.js +3214 -0
  20. package/dist/llm/gen/anthropic.js +611 -0
  21. package/dist/llm/gen/codex.js +375 -0
  22. package/dist/llm/gen/mock.js +326 -0
  23. package/dist/llm/gen/openai.js +470 -0
  24. package/dist/llm/gen/registry.js +26 -0
  25. package/dist/llm/gen.js +2 -0
  26. package/dist/llm/tools-projection.js +37 -0
  27. package/dist/log.js +228 -0
  28. package/dist/mcp/config.js +230 -0
  29. package/dist/mcp/sdk-client.js +129 -0
  30. package/dist/mcp/server-runtime.js +57 -0
  31. package/dist/mcp/stdio-client.js +280 -0
  32. package/dist/mcp/supervisor.js +979 -0
  33. package/dist/mcp/tool-names.js +109 -0
  34. package/dist/minds/builtin/cmdr/persona.md +3 -0
  35. package/dist/minds/builtin/dijiang/knowledge.md +287 -0
  36. package/dist/minds/builtin/dijiang/persona.md +7 -0
  37. package/dist/minds/builtin/fuxi/persona.en.md +59 -0
  38. package/dist/minds/builtin/fuxi/persona.zh.md +49 -0
  39. package/dist/minds/builtin/pangu/persona.en.md +78 -0
  40. package/dist/minds/builtin/pangu/persona.zh.md +71 -0
  41. package/dist/minds/load.js +617 -0
  42. package/dist/minds/minds-i18n.js +131 -0
  43. package/dist/minds/system-prompt.js +281 -0
  44. package/dist/persistence.js +3128 -0
  45. package/dist/problems.js +109 -0
  46. package/dist/server/api-routes.js +1031 -0
  47. package/dist/server/auth.js +180 -0
  48. package/dist/server/mime-types.js +32 -0
  49. package/dist/server/prompts-routes.js +543 -0
  50. package/dist/server/server-core.js +235 -0
  51. package/dist/server/setup-routes.js +697 -0
  52. package/dist/server/static-server.js +132 -0
  53. package/dist/server/websocket-handler.js +1011 -0
  54. package/dist/server.js +164 -0
  55. package/dist/shared/async-fifo-mutex.js +36 -0
  56. package/dist/shared/diligence.js +20 -0
  57. package/dist/shared/dotenv.js +144 -0
  58. package/dist/shared/evt.js +195 -0
  59. package/dist/shared/i18n/driver-messages.js +267 -0
  60. package/dist/shared/i18n/text.js +9 -0
  61. package/dist/shared/i18n/tool-result-messages.js +51 -0
  62. package/dist/shared/rtws-cli.js +73 -0
  63. package/dist/shared/runtime-language.js +47 -0
  64. package/dist/shared/team-mgmt-manual.js +116 -0
  65. package/dist/shared/types/context-health.js +2 -0
  66. package/dist/shared/types/dialog.js +11 -0
  67. package/dist/shared/types/i18n.js +2 -0
  68. package/dist/shared/types/index.js +26 -0
  69. package/dist/shared/types/language.js +40 -0
  70. package/dist/shared/types/problems.js +2 -0
  71. package/dist/shared/types/prompts.js +2 -0
  72. package/dist/shared/types/q4h.js +7 -0
  73. package/dist/shared/types/run-state.js +8 -0
  74. package/dist/shared/types/setup.js +2 -0
  75. package/dist/shared/types/storage.js +10 -0
  76. package/dist/shared/types/tellask.js +8 -0
  77. package/dist/shared/types/tools-registry.js +2 -0
  78. package/dist/shared/types/wire.js +12 -0
  79. package/dist/shared/utils/fmt.js +9 -0
  80. package/dist/shared/utils/html.js +20 -0
  81. package/dist/shared/utils/id.js +18 -0
  82. package/dist/shared/utils/inter-dialog-format.js +101 -0
  83. package/dist/shared/utils/time.js +13 -0
  84. package/dist/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  85. package/dist/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  86. package/dist/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  87. package/dist/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  88. package/dist/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  89. package/dist/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  90. package/dist/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  91. package/dist/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  92. package/dist/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  93. package/dist/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  94. package/dist/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  95. package/dist/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  96. package/dist/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  97. package/dist/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  98. package/dist/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  99. package/dist/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  100. package/dist/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  101. package/dist/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  102. package/dist/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  103. package/dist/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  104. package/dist/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  105. package/dist/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  106. package/dist/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  107. package/dist/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  108. package/dist/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  109. package/dist/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  110. package/dist/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  111. package/dist/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  112. package/dist/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  113. package/dist/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  114. package/dist/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  115. package/dist/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  116. package/dist/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  117. package/dist/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  118. package/dist/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  119. package/dist/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  120. package/dist/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  121. package/dist/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  122. package/dist/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  123. package/dist/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  124. package/dist/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  125. package/dist/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  126. package/dist/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  127. package/dist/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  128. package/dist/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  129. package/dist/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  130. package/dist/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  131. package/dist/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  132. package/dist/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  133. package/dist/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  134. package/dist/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  135. package/dist/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  136. package/dist/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  137. package/dist/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  138. package/dist/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  139. package/dist/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  140. package/dist/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  141. package/dist/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  142. package/dist/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  143. package/dist/static/assets/_baseUniq-Crfl3d5Y.js +661 -0
  144. package/dist/static/assets/_baseUniq-Crfl3d5Y.js.map +1 -0
  145. package/dist/static/assets/arc-CbA_x9GD.js +132 -0
  146. package/dist/static/assets/arc-CbA_x9GD.js.map +1 -0
  147. package/dist/static/assets/architectureDiagram-VXUJARFQ-lcFS8ZQJ.js +8685 -0
  148. package/dist/static/assets/architectureDiagram-VXUJARFQ-lcFS8ZQJ.js.map +1 -0
  149. package/dist/static/assets/blockDiagram-VD42YOAC-B3Q36qRc.js +3608 -0
  150. package/dist/static/assets/blockDiagram-VD42YOAC-B3Q36qRc.js.map +1 -0
  151. package/dist/static/assets/c4Diagram-YG6GDRKO-Mt-aq3VH.js +2482 -0
  152. package/dist/static/assets/c4Diagram-YG6GDRKO-Mt-aq3VH.js.map +1 -0
  153. package/dist/static/assets/channel-BVr1Yke-.js +8 -0
  154. package/dist/static/assets/channel-BVr1Yke-.js.map +1 -0
  155. package/dist/static/assets/chunk-4BX2VUAB-qCIn5Iic.js +17 -0
  156. package/dist/static/assets/chunk-4BX2VUAB-qCIn5Iic.js.map +1 -0
  157. package/dist/static/assets/chunk-55IACEB6-q172NeCV.js +14 -0
  158. package/dist/static/assets/chunk-55IACEB6-q172NeCV.js.map +1 -0
  159. package/dist/static/assets/chunk-B4BG7PRW-CMJmtYzq.js +1827 -0
  160. package/dist/static/assets/chunk-B4BG7PRW-CMJmtYzq.js.map +1 -0
  161. package/dist/static/assets/chunk-DI55MBZ5-DiuwwZPL.js +1916 -0
  162. package/dist/static/assets/chunk-DI55MBZ5-DiuwwZPL.js.map +1 -0
  163. package/dist/static/assets/chunk-FMBD7UC4-06sqZTTn.js +20 -0
  164. package/dist/static/assets/chunk-FMBD7UC4-06sqZTTn.js.map +1 -0
  165. package/dist/static/assets/chunk-QN33PNHL-CnpBNkpP.js +25 -0
  166. package/dist/static/assets/chunk-QN33PNHL-CnpBNkpP.js.map +1 -0
  167. package/dist/static/assets/chunk-QZHKN3VN-CNgjMR-e.js +18 -0
  168. package/dist/static/assets/chunk-QZHKN3VN-CNgjMR-e.js.map +1 -0
  169. package/dist/static/assets/chunk-TZMSLE5B-BxtzW6--.js +109 -0
  170. package/dist/static/assets/chunk-TZMSLE5B-BxtzW6--.js.map +1 -0
  171. package/dist/static/assets/classDiagram-2ON5EDUG-29huvmn-.js +23 -0
  172. package/dist/static/assets/classDiagram-2ON5EDUG-29huvmn-.js.map +1 -0
  173. package/dist/static/assets/classDiagram-v2-WZHVMYZB-29huvmn-.js +23 -0
  174. package/dist/static/assets/classDiagram-v2-WZHVMYZB-29huvmn-.js.map +1 -0
  175. package/dist/static/assets/clone-D2OgLSSn.js +9 -0
  176. package/dist/static/assets/clone-D2OgLSSn.js.map +1 -0
  177. package/dist/static/assets/cose-bilkent-S5V4N54A-BNegDCxl.js +4943 -0
  178. package/dist/static/assets/cose-bilkent-S5V4N54A-BNegDCxl.js.map +1 -0
  179. package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js +30240 -0
  180. package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -0
  181. package/dist/static/assets/dagre-6UL2VRFP-f1XrTRSn.js +695 -0
  182. package/dist/static/assets/dagre-6UL2VRFP-f1XrTRSn.js.map +1 -0
  183. package/dist/static/assets/defaultLocale-DVr69WTU.js +207 -0
  184. package/dist/static/assets/defaultLocale-DVr69WTU.js.map +1 -0
  185. package/dist/static/assets/diagram-PSM6KHXK-8w1WbeDi.js +849 -0
  186. package/dist/static/assets/diagram-PSM6KHXK-8w1WbeDi.js.map +1 -0
  187. package/dist/static/assets/diagram-QEK2KX5R-CF4wtMmR.js +303 -0
  188. package/dist/static/assets/diagram-QEK2KX5R-CF4wtMmR.js.map +1 -0
  189. package/dist/static/assets/diagram-S2PKOQOG-8p3Avgn2.js +213 -0
  190. package/dist/static/assets/diagram-S2PKOQOG-8p3Avgn2.js.map +1 -0
  191. package/dist/static/assets/erDiagram-Q2GNP2WA-BMKLxlM9.js +1159 -0
  192. package/dist/static/assets/erDiagram-Q2GNP2WA-BMKLxlM9.js.map +1 -0
  193. package/dist/static/assets/favicon-Cmg5RbCj.svg +8 -0
  194. package/dist/static/assets/flowDiagram-NV44I4VS-CgEuPNK2.js +2332 -0
  195. package/dist/static/assets/flowDiagram-NV44I4VS-CgEuPNK2.js.map +1 -0
  196. package/dist/static/assets/ganttDiagram-JELNMOA3-bJkDCf-9.js +3681 -0
  197. package/dist/static/assets/ganttDiagram-JELNMOA3-bJkDCf-9.js.map +1 -0
  198. package/dist/static/assets/gitGraphDiagram-NY62KEGX-4QE9kesp.js +1206 -0
  199. package/dist/static/assets/gitGraphDiagram-NY62KEGX-4QE9kesp.js.map +1 -0
  200. package/dist/static/assets/graph-CS0Pmm7c.js +597 -0
  201. package/dist/static/assets/graph-CS0Pmm7c.js.map +1 -0
  202. package/dist/static/assets/index-BS6HnGzC.js +112303 -0
  203. package/dist/static/assets/index-BS6HnGzC.js.map +1 -0
  204. package/dist/static/assets/index-DaIsSzC_.css +483 -0
  205. package/dist/static/assets/infoDiagram-WHAUD3N6-ypBcKfUs.js +34 -0
  206. package/dist/static/assets/infoDiagram-WHAUD3N6-ypBcKfUs.js.map +1 -0
  207. package/dist/static/assets/init-ZxktEp_H.js +17 -0
  208. package/dist/static/assets/init-ZxktEp_H.js.map +1 -0
  209. package/dist/static/assets/journeyDiagram-XKPGCS4Q-QnrxDowJ.js +1255 -0
  210. package/dist/static/assets/journeyDiagram-XKPGCS4Q-QnrxDowJ.js.map +1 -0
  211. package/dist/static/assets/kanban-definition-3W4ZIXB7-CfvEc4z5.js +1048 -0
  212. package/dist/static/assets/kanban-definition-3W4ZIXB7-CfvEc4z5.js.map +1 -0
  213. package/dist/static/assets/layout-8TGxpm23.js +2218 -0
  214. package/dist/static/assets/layout-8TGxpm23.js.map +1 -0
  215. package/dist/static/assets/linear-BATBPQQv.js +341 -0
  216. package/dist/static/assets/linear-BATBPQQv.js.map +1 -0
  217. package/dist/static/assets/min-B3oVH3AC.js +42 -0
  218. package/dist/static/assets/min-B3oVH3AC.js.map +1 -0
  219. package/dist/static/assets/mindmap-definition-VGOIOE7T-L7VLwwF8.js +1127 -0
  220. package/dist/static/assets/mindmap-definition-VGOIOE7T-L7VLwwF8.js.map +1 -0
  221. package/dist/static/assets/ordinal-CxptdPJm.js +77 -0
  222. package/dist/static/assets/ordinal-CxptdPJm.js.map +1 -0
  223. package/dist/static/assets/pieDiagram-ADFJNKIX-CFW3zIhM.js +241 -0
  224. package/dist/static/assets/pieDiagram-ADFJNKIX-CFW3zIhM.js.map +1 -0
  225. package/dist/static/assets/quadrantDiagram-AYHSOK5B-B7ssen3E.js +1338 -0
  226. package/dist/static/assets/quadrantDiagram-AYHSOK5B-B7ssen3E.js.map +1 -0
  227. package/dist/static/assets/requirementDiagram-UZGBJVZJ-D0v5BArv.js +1162 -0
  228. package/dist/static/assets/requirementDiagram-UZGBJVZJ-D0v5BArv.js.map +1 -0
  229. package/dist/static/assets/sankeyDiagram-TZEHDZUN-B7slncJe.js +1195 -0
  230. package/dist/static/assets/sankeyDiagram-TZEHDZUN-B7slncJe.js.map +1 -0
  231. package/dist/static/assets/sequenceDiagram-WL72ISMW-oXU2lRh_.js +3875 -0
  232. package/dist/static/assets/sequenceDiagram-WL72ISMW-oXU2lRh_.js.map +1 -0
  233. package/dist/static/assets/stateDiagram-FKZM4ZOC-CFYsEd0x.js +452 -0
  234. package/dist/static/assets/stateDiagram-FKZM4ZOC-CFYsEd0x.js.map +1 -0
  235. package/dist/static/assets/stateDiagram-v2-4FDKWEC3-C0UWaNA7.js +22 -0
  236. package/dist/static/assets/stateDiagram-v2-4FDKWEC3-C0UWaNA7.js.map +1 -0
  237. package/dist/static/assets/timeline-definition-IT6M3QCI-C3KODUrh.js +1223 -0
  238. package/dist/static/assets/timeline-definition-IT6M3QCI-C3KODUrh.js.map +1 -0
  239. package/dist/static/assets/treemap-KMMF4GRG-DAGDLhj2.js +18753 -0
  240. package/dist/static/assets/treemap-KMMF4GRG-DAGDLhj2.js.map +1 -0
  241. package/dist/static/assets/xychartDiagram-PRI3JC2R-C0J9iwTO.js +1888 -0
  242. package/dist/static/assets/xychartDiagram-PRI3JC2R-C0J9iwTO.js.map +1 -0
  243. package/dist/static/index.html +71 -0
  244. package/dist/static/testing/dom-observation-utils.js +425 -0
  245. package/dist/static/testing/e2e-test-helper.js +3119 -0
  246. package/dist/team.js +1160 -0
  247. package/dist/tellask.js +431 -0
  248. package/dist/tool.js +150 -0
  249. package/dist/tools/apply-patch.js +542 -0
  250. package/dist/tools/builtins.js +196 -0
  251. package/dist/tools/context-health.js +177 -0
  252. package/dist/tools/ctrl.js +478 -0
  253. package/dist/tools/diag.js +583 -0
  254. package/dist/tools/env.js +184 -0
  255. package/dist/tools/fs.js +818 -0
  256. package/dist/tools/mcp.js +138 -0
  257. package/dist/tools/mem.js +349 -0
  258. package/dist/tools/os.js +751 -0
  259. package/dist/tools/prompts/team_mgmt.en.md +70 -0
  260. package/dist/tools/prompts/team_mgmt.zh.md +70 -0
  261. package/dist/tools/prompts/ws_mod.en.md +86 -0
  262. package/dist/tools/prompts/ws_mod.zh.md +87 -0
  263. package/dist/tools/registry-snapshot.js +31 -0
  264. package/dist/tools/registry.js +121 -0
  265. package/dist/tools/ripgrep.js +678 -0
  266. package/dist/tools/team-mgmt.js +3300 -0
  267. package/dist/tools/txt.js +3178 -0
  268. package/dist/utils/id.js +72 -0
  269. package/dist/utils/task-doc.js +236 -0
  270. package/dist/utils/task-package.js +522 -0
  271. package/dist/utils/taskdoc-search.js +280 -0
  272. package/dist/utils/taskdoc.js +400 -0
  273. package/package.json +69 -0
@@ -0,0 +1,542 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.applyPatchTool = void 0;
7
+ /**
8
+ * Module: tools/apply-patch
9
+ *
10
+ * Codex-style `apply_patch` function tool.
11
+ * - Accepts the Codex CLI patch format (`*** Begin Patch` ... `*** End Patch`)
12
+ * - Applies edits to the current workspace (rtws)
13
+ * - Enforces Dominds directory access control (`read_dirs`/`write_dirs` + deny lists)
14
+ */
15
+ const node_fs_1 = require("node:fs");
16
+ const node_path_1 = __importDefault(require("node:path"));
17
+ const access_control_1 = require("../access-control");
18
+ const runtime_language_1 = require("../shared/runtime-language");
19
+ const BEGIN_PATCH_MARKER = '*** Begin Patch';
20
+ const END_PATCH_MARKER = '*** End Patch';
21
+ const ADD_FILE_MARKER = '*** Add File: ';
22
+ const DELETE_FILE_MARKER = '*** Delete File: ';
23
+ const UPDATE_FILE_MARKER = '*** Update File: ';
24
+ const MOVE_TO_MARKER = '*** Move to: ';
25
+ const EOF_MARKER = '*** End of File';
26
+ const CHANGE_CONTEXT_MARKER = '@@ ';
27
+ const EMPTY_CHANGE_CONTEXT_MARKER = '@@';
28
+ function parseApplyPatchArgs(args) {
29
+ const patchValue = args['patch'];
30
+ if (typeof patchValue !== 'string' || patchValue.trim() === '') {
31
+ throw new Error('apply_patch.patch must be a non-empty string');
32
+ }
33
+ return { patch: patchValue };
34
+ }
35
+ function assertRelativePath(input, label) {
36
+ if (node_path_1.default.isAbsolute(input) || /^[a-zA-Z]:[\\/]/.test(input)) {
37
+ throw new Error(`${label} must be a relative path: ${input}`);
38
+ }
39
+ }
40
+ function resolveInWorkspace(workspaceRoot, relPath, label) {
41
+ assertRelativePath(relPath, label);
42
+ const resolved = node_path_1.default.resolve(workspaceRoot, relPath);
43
+ const root = node_path_1.default.resolve(workspaceRoot);
44
+ if (resolved === root)
45
+ return resolved;
46
+ const prefix = root.endsWith(node_path_1.default.sep) ? root : root + node_path_1.default.sep;
47
+ if (!resolved.startsWith(prefix)) {
48
+ throw new Error(`${label} escapes workspace root: ${relPath}`);
49
+ }
50
+ return resolved;
51
+ }
52
+ function splitLines(text) {
53
+ return text.split(/\r?\n/);
54
+ }
55
+ function tryStripHeredocWrapper(lines) {
56
+ if (lines.length < 4)
57
+ return null;
58
+ const firstRaw = lines[0];
59
+ const lastRaw = lines[lines.length - 1];
60
+ if (firstRaw === undefined || lastRaw === undefined)
61
+ return null;
62
+ const first = firstRaw.trim();
63
+ const last = lastRaw.trim();
64
+ if (first !== '<<EOF' && first !== "<<'EOF'" && first !== '<<\"EOF\"') {
65
+ return null;
66
+ }
67
+ if (!last.endsWith('EOF')) {
68
+ return null;
69
+ }
70
+ return lines.slice(1, lines.length - 1);
71
+ }
72
+ function ensurePatchBoundariesStrict(lines) {
73
+ const firstLine = lines.length > 0 ? lines[0] : undefined;
74
+ const lastLine = lines.length > 0 ? lines[lines.length - 1] : undefined;
75
+ const first = typeof firstLine === 'string' ? firstLine.trim() : '';
76
+ const last = typeof lastLine === 'string' ? lastLine.trim() : '';
77
+ if (first !== BEGIN_PATCH_MARKER) {
78
+ throw new Error(`Invalid patch: The first line of the patch must be '${BEGIN_PATCH_MARKER}'`);
79
+ }
80
+ if (last !== END_PATCH_MARKER) {
81
+ throw new Error(`Invalid patch: The last line of the patch must be '${END_PATCH_MARKER}'`);
82
+ }
83
+ return { inner: lines.slice(1, lines.length - 1) };
84
+ }
85
+ function normalizePatchText(patch) {
86
+ const rawLines = splitLines(patch.trim());
87
+ try {
88
+ const strict = ensurePatchBoundariesStrict(rawLines);
89
+ return [BEGIN_PATCH_MARKER, ...strict.inner, END_PATCH_MARKER].join('\n');
90
+ }
91
+ catch (strictErr) {
92
+ const heredocLines = tryStripHeredocWrapper(rawLines);
93
+ if (heredocLines === null) {
94
+ const message = strictErr instanceof Error ? strictErr.message : String(strictErr);
95
+ throw new Error(message);
96
+ }
97
+ const strict = ensurePatchBoundariesStrict(heredocLines);
98
+ return [BEGIN_PATCH_MARKER, ...strict.inner, END_PATCH_MARKER].join('\n');
99
+ }
100
+ }
101
+ function seekSequence(lines, pattern, start, eof) {
102
+ if (pattern.length === 0)
103
+ return start;
104
+ if (pattern.length > lines.length)
105
+ return null;
106
+ const searchStart = eof && lines.length >= pattern.length ? lines.length - pattern.length : start;
107
+ const maxStart = lines.length - pattern.length;
108
+ const exactMatchAt = (idx) => {
109
+ for (let j = 0; j < pattern.length; j++) {
110
+ const lhs = lines[idx + j];
111
+ const rhs = pattern[j];
112
+ if (lhs !== rhs)
113
+ return false;
114
+ }
115
+ return true;
116
+ };
117
+ for (let i = searchStart; i <= maxStart; i++) {
118
+ if (exactMatchAt(i))
119
+ return i;
120
+ }
121
+ for (let i = searchStart; i <= maxStart; i++) {
122
+ let ok = true;
123
+ for (let j = 0; j < pattern.length; j++) {
124
+ const lhs = lines[i + j] ?? '';
125
+ const rhs = pattern[j] ?? '';
126
+ if (lhs.trimEnd() !== rhs.trimEnd()) {
127
+ ok = false;
128
+ break;
129
+ }
130
+ }
131
+ if (ok)
132
+ return i;
133
+ }
134
+ for (let i = searchStart; i <= maxStart; i++) {
135
+ let ok = true;
136
+ for (let j = 0; j < pattern.length; j++) {
137
+ const lhs = lines[i + j] ?? '';
138
+ const rhs = pattern[j] ?? '';
139
+ if (lhs.trim() !== rhs.trim()) {
140
+ ok = false;
141
+ break;
142
+ }
143
+ }
144
+ if (ok)
145
+ return i;
146
+ }
147
+ const normalize = (s) => {
148
+ const trimmed = s.trim();
149
+ let out = '';
150
+ for (const ch of trimmed) {
151
+ switch (ch) {
152
+ case '\u2010':
153
+ case '\u2011':
154
+ case '\u2012':
155
+ case '\u2013':
156
+ case '\u2014':
157
+ case '\u2015':
158
+ case '\u2212':
159
+ out += '-';
160
+ break;
161
+ case '\u2018':
162
+ case '\u2019':
163
+ case '\u201A':
164
+ case '\u201B':
165
+ out += "'";
166
+ break;
167
+ case '\u201C':
168
+ case '\u201D':
169
+ case '\u201E':
170
+ case '\u201F':
171
+ out += '"';
172
+ break;
173
+ case '\u00A0':
174
+ case '\u2002':
175
+ case '\u2003':
176
+ case '\u2004':
177
+ case '\u2005':
178
+ case '\u2006':
179
+ case '\u2007':
180
+ case '\u2008':
181
+ case '\u2009':
182
+ case '\u200A':
183
+ case '\u202F':
184
+ case '\u205F':
185
+ case '\u3000':
186
+ out += ' ';
187
+ break;
188
+ default:
189
+ out += ch;
190
+ }
191
+ }
192
+ return out;
193
+ };
194
+ for (let i = searchStart; i <= maxStart; i++) {
195
+ let ok = true;
196
+ for (let j = 0; j < pattern.length; j++) {
197
+ const lhs = normalize(lines[i + j] ?? '');
198
+ const rhs = normalize(pattern[j] ?? '');
199
+ if (lhs !== rhs) {
200
+ ok = false;
201
+ break;
202
+ }
203
+ }
204
+ if (ok)
205
+ return i;
206
+ }
207
+ return null;
208
+ }
209
+ function parseUpdateFileChunk(lines, lineNumber, allowMissingContext) {
210
+ if (lines.length === 0) {
211
+ throw new Error(`Invalid hunk at line ${lineNumber}: Update hunk does not contain any lines`);
212
+ }
213
+ const firstLine = lines[0] ?? '';
214
+ const firstTrimmed = firstLine.trim();
215
+ let changeContext = null;
216
+ let startIndex = 0;
217
+ if (firstTrimmed === EMPTY_CHANGE_CONTEXT_MARKER) {
218
+ startIndex = 1;
219
+ }
220
+ else if (firstTrimmed.startsWith(CHANGE_CONTEXT_MARKER)) {
221
+ changeContext = firstTrimmed.slice(CHANGE_CONTEXT_MARKER.length);
222
+ startIndex = 1;
223
+ }
224
+ else {
225
+ if (!allowMissingContext) {
226
+ throw new Error(`Invalid hunk at line ${lineNumber}: Expected update hunk to start with a @@ context marker, got: '${firstLine}'`);
227
+ }
228
+ startIndex = 0;
229
+ }
230
+ if (startIndex >= lines.length) {
231
+ throw new Error(`Invalid hunk at line ${lineNumber + 1}: Update hunk does not contain any lines`);
232
+ }
233
+ const oldLines = [];
234
+ const newLines = [];
235
+ let isEndOfFile = false;
236
+ let parsedLines = 0;
237
+ for (let i = startIndex; i < lines.length; i++) {
238
+ const line = lines[i] ?? '';
239
+ const lineTrimmed = line.trim();
240
+ if (lineTrimmed === EOF_MARKER) {
241
+ if (parsedLines === 0) {
242
+ throw new Error(`Invalid hunk at line ${lineNumber + 1}: Update hunk does not contain any lines`);
243
+ }
244
+ isEndOfFile = true;
245
+ parsedLines += 1;
246
+ break;
247
+ }
248
+ if (line.length === 0) {
249
+ oldLines.push('');
250
+ newLines.push('');
251
+ parsedLines += 1;
252
+ continue;
253
+ }
254
+ const firstChar = line[0];
255
+ if (firstChar === ' ') {
256
+ const rest = line.slice(1);
257
+ oldLines.push(rest);
258
+ newLines.push(rest);
259
+ parsedLines += 1;
260
+ continue;
261
+ }
262
+ if (firstChar === '+') {
263
+ newLines.push(line.slice(1));
264
+ parsedLines += 1;
265
+ continue;
266
+ }
267
+ if (firstChar === '-') {
268
+ oldLines.push(line.slice(1));
269
+ parsedLines += 1;
270
+ continue;
271
+ }
272
+ if (parsedLines === 0) {
273
+ throw new Error(`Invalid hunk at line ${lineNumber + 1}: Unexpected line found in update hunk: '${line}'. Every line should start with ' ' (context line), '+' (added line), or '-' (removed line)`);
274
+ }
275
+ break;
276
+ }
277
+ return {
278
+ chunk: { changeContext, oldLines, newLines, isEndOfFile },
279
+ consumed: parsedLines + startIndex,
280
+ };
281
+ }
282
+ function parseOneHunk(lines, lineNumber) {
283
+ const firstLineRaw = lines.length > 0 ? lines[0] : undefined;
284
+ const firstLineTrimmed = typeof firstLineRaw === 'string' ? firstLineRaw.trim() : '';
285
+ if (firstLineTrimmed.startsWith(ADD_FILE_MARKER)) {
286
+ const relPath = firstLineTrimmed.slice(ADD_FILE_MARKER.length);
287
+ if (relPath.trim() === '') {
288
+ throw new Error(`Invalid hunk at line ${lineNumber}: Add file path is empty`);
289
+ }
290
+ let contents = '';
291
+ let consumed = 1;
292
+ for (let i = 1; i < lines.length; i++) {
293
+ const line = lines[i];
294
+ if (typeof line !== 'string')
295
+ break;
296
+ if (line.startsWith('+')) {
297
+ contents += line.slice(1) + '\n';
298
+ consumed += 1;
299
+ continue;
300
+ }
301
+ break;
302
+ }
303
+ return { hunk: { kind: 'add_file', relPath, contents }, consumed };
304
+ }
305
+ if (firstLineTrimmed.startsWith(DELETE_FILE_MARKER)) {
306
+ const relPath = firstLineTrimmed.slice(DELETE_FILE_MARKER.length);
307
+ if (relPath.trim() === '') {
308
+ throw new Error(`Invalid hunk at line ${lineNumber}: Delete file path is empty`);
309
+ }
310
+ return { hunk: { kind: 'delete_file', relPath }, consumed: 1 };
311
+ }
312
+ if (firstLineTrimmed.startsWith(UPDATE_FILE_MARKER)) {
313
+ const relPath = firstLineTrimmed.slice(UPDATE_FILE_MARKER.length);
314
+ if (relPath.trim() === '') {
315
+ throw new Error(`Invalid hunk at line ${lineNumber}: Update file path is empty`);
316
+ }
317
+ let consumed = 1;
318
+ let remaining = lines.slice(1);
319
+ let moveToRelPath = null;
320
+ if (remaining.length > 0) {
321
+ const moveCandidateRaw = remaining[0];
322
+ const moveCandidate = typeof moveCandidateRaw === 'string' ? moveCandidateRaw.trim() : '';
323
+ if (moveCandidate.startsWith(MOVE_TO_MARKER)) {
324
+ moveToRelPath = moveCandidate.slice(MOVE_TO_MARKER.length);
325
+ if (moveToRelPath.trim() === '') {
326
+ throw new Error(`Invalid hunk at line ${lineNumber + consumed}: Move-to path is empty`);
327
+ }
328
+ remaining = remaining.slice(1);
329
+ consumed += 1;
330
+ }
331
+ }
332
+ const chunks = [];
333
+ while (remaining.length > 0) {
334
+ const first = remaining[0];
335
+ const firstStr = typeof first === 'string' ? first : '';
336
+ if (firstStr.trim() === '') {
337
+ remaining = remaining.slice(1);
338
+ consumed += 1;
339
+ continue;
340
+ }
341
+ if (firstStr.trimStart().startsWith('***')) {
342
+ break;
343
+ }
344
+ const allowMissingContext = chunks.length === 0;
345
+ const parsed = parseUpdateFileChunk(remaining, lineNumber + consumed, allowMissingContext);
346
+ chunks.push(parsed.chunk);
347
+ remaining = remaining.slice(parsed.consumed);
348
+ consumed += parsed.consumed;
349
+ }
350
+ if (chunks.length === 0) {
351
+ throw new Error(`Invalid hunk at line ${lineNumber}: Update file hunk for path '${relPath}' is empty`);
352
+ }
353
+ return { hunk: { kind: 'update_file', relPath, moveToRelPath, chunks }, consumed };
354
+ }
355
+ throw new Error(`Invalid hunk at line ${lineNumber}: '${firstLineTrimmed}' is not a valid hunk header. Valid hunk headers: '*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}'`);
356
+ }
357
+ function parsePatch(patch) {
358
+ const normalized = normalizePatchText(patch);
359
+ const lines = splitLines(normalized);
360
+ const { inner } = ensurePatchBoundariesStrict(lines);
361
+ const hunks = [];
362
+ let idx = 0;
363
+ let lineNumber = 2;
364
+ while (idx < inner.length) {
365
+ const slice = inner.slice(idx);
366
+ const parsed = parseOneHunk(slice, lineNumber);
367
+ hunks.push(parsed.hunk);
368
+ idx += parsed.consumed;
369
+ lineNumber += parsed.consumed;
370
+ }
371
+ return hunks;
372
+ }
373
+ function applyReplacements(originalLines, replacements) {
374
+ const lines = [...originalLines];
375
+ const sorted = [...replacements].sort((a, b) => b[0] - a[0]);
376
+ for (const [startIdx, oldLen, newSegment] of sorted) {
377
+ for (let i = 0; i < oldLen; i++) {
378
+ if (startIdx < lines.length) {
379
+ lines.splice(startIdx, 1);
380
+ }
381
+ }
382
+ if (newSegment.length > 0) {
383
+ lines.splice(startIdx, 0, ...newSegment);
384
+ }
385
+ }
386
+ return lines;
387
+ }
388
+ function computeReplacements(originalLines, sourceLabel, chunks) {
389
+ const replacements = [];
390
+ let lineIndex = 0;
391
+ for (const chunk of chunks) {
392
+ if (chunk.changeContext !== null) {
393
+ const ctxIdx = seekSequence(originalLines, [chunk.changeContext], lineIndex, false);
394
+ if (ctxIdx === null) {
395
+ throw new Error(`Failed to find context '${chunk.changeContext}' in ${sourceLabel}`);
396
+ }
397
+ lineIndex = ctxIdx + 1;
398
+ }
399
+ if (chunk.oldLines.length === 0) {
400
+ const last = originalLines.length > 0 ? originalLines[originalLines.length - 1] : undefined;
401
+ const insertionIdx = last === '' ? originalLines.length - 1 : originalLines.length;
402
+ replacements.push([insertionIdx, 0, [...chunk.newLines]]);
403
+ continue;
404
+ }
405
+ let pattern = chunk.oldLines;
406
+ let found = seekSequence(originalLines, pattern, lineIndex, chunk.isEndOfFile);
407
+ let newSlice = chunk.newLines;
408
+ if (found === null && pattern.length > 0 && pattern[pattern.length - 1] === '') {
409
+ pattern = pattern.slice(0, pattern.length - 1);
410
+ if (newSlice.length > 0 && newSlice[newSlice.length - 1] === '') {
411
+ newSlice = newSlice.slice(0, newSlice.length - 1);
412
+ }
413
+ found = seekSequence(originalLines, pattern, lineIndex, chunk.isEndOfFile);
414
+ }
415
+ if (found === null) {
416
+ throw new Error(`Failed to find expected lines in ${sourceLabel}:\n${chunk.oldLines.join('\n')}`);
417
+ }
418
+ replacements.push([found, pattern.length, [...newSlice]]);
419
+ lineIndex = found + pattern.length;
420
+ }
421
+ return replacements.sort((a, b) => a[0] - b[0]);
422
+ }
423
+ async function deriveNewContentsFromChunks(absPath, chunks) {
424
+ let originalContents;
425
+ try {
426
+ originalContents = await node_fs_1.promises.readFile(absPath, 'utf8');
427
+ }
428
+ catch (err) {
429
+ const msg = err instanceof Error ? err.message : String(err);
430
+ throw new Error(`Failed to read file to update ${absPath}: ${msg}`);
431
+ }
432
+ const originalLines = originalContents.split('\n');
433
+ if (originalLines.length > 0 && originalLines[originalLines.length - 1] === '') {
434
+ originalLines.pop();
435
+ }
436
+ const replacements = computeReplacements(originalLines, absPath, chunks);
437
+ const newLines = applyReplacements([...originalLines], replacements);
438
+ if (newLines.length === 0 || newLines[newLines.length - 1] !== '') {
439
+ newLines.push('');
440
+ }
441
+ return newLines.join('\n');
442
+ }
443
+ function printSummary(summary) {
444
+ const parts = [];
445
+ if (summary.added.length > 0) {
446
+ parts.push(`Added:\n- ${summary.added.join('\n- ')}`);
447
+ }
448
+ if (summary.modified.length > 0) {
449
+ parts.push(`Modified:\n- ${summary.modified.join('\n- ')}`);
450
+ }
451
+ if (summary.deleted.length > 0) {
452
+ parts.push(`Deleted:\n- ${summary.deleted.join('\n- ')}`);
453
+ }
454
+ if (parts.length === 0) {
455
+ return 'No files were modified.';
456
+ }
457
+ return parts.join('\n\n');
458
+ }
459
+ function ensureReadAccess(caller, relPath) {
460
+ const language = (0, runtime_language_1.getWorkLanguage)();
461
+ if (!(0, access_control_1.hasReadAccess)(caller, relPath)) {
462
+ throw new Error((0, access_control_1.getAccessDeniedMessage)('read', relPath, language));
463
+ }
464
+ }
465
+ function ensureWriteAccess(caller, relPath) {
466
+ const language = (0, runtime_language_1.getWorkLanguage)();
467
+ if (!(0, access_control_1.hasWriteAccess)(caller, relPath)) {
468
+ throw new Error((0, access_control_1.getAccessDeniedMessage)('write', relPath, language));
469
+ }
470
+ }
471
+ async function applyHunksToWorkspace(caller, hunks) {
472
+ if (hunks.length === 0) {
473
+ throw new Error('No files were modified.');
474
+ }
475
+ const workspaceRoot = process.cwd();
476
+ const added = [];
477
+ const modified = [];
478
+ const deleted = [];
479
+ for (const hunk of hunks) {
480
+ switch (hunk.kind) {
481
+ case 'add_file': {
482
+ ensureWriteAccess(caller, hunk.relPath);
483
+ const abs = resolveInWorkspace(workspaceRoot, hunk.relPath, 'apply_patch path');
484
+ const parent = node_path_1.default.dirname(abs);
485
+ await node_fs_1.promises.mkdir(parent, { recursive: true });
486
+ await node_fs_1.promises.writeFile(abs, hunk.contents, 'utf8');
487
+ added.push(hunk.relPath);
488
+ break;
489
+ }
490
+ case 'delete_file': {
491
+ ensureWriteAccess(caller, hunk.relPath);
492
+ const abs = resolveInWorkspace(workspaceRoot, hunk.relPath, 'apply_patch path');
493
+ await node_fs_1.promises.unlink(abs);
494
+ deleted.push(hunk.relPath);
495
+ break;
496
+ }
497
+ case 'update_file': {
498
+ ensureReadAccess(caller, hunk.relPath);
499
+ ensureWriteAccess(caller, hunk.relPath);
500
+ const srcAbs = resolveInWorkspace(workspaceRoot, hunk.relPath, 'apply_patch path');
501
+ const newContents = await deriveNewContentsFromChunks(srcAbs, hunk.chunks);
502
+ if (hunk.moveToRelPath !== null) {
503
+ ensureWriteAccess(caller, hunk.moveToRelPath);
504
+ const destAbs = resolveInWorkspace(workspaceRoot, hunk.moveToRelPath, 'apply_patch move target');
505
+ const parent = node_path_1.default.dirname(destAbs);
506
+ await node_fs_1.promises.mkdir(parent, { recursive: true });
507
+ await node_fs_1.promises.writeFile(destAbs, newContents, 'utf8');
508
+ await node_fs_1.promises.unlink(srcAbs);
509
+ modified.push(hunk.moveToRelPath);
510
+ break;
511
+ }
512
+ await node_fs_1.promises.writeFile(srcAbs, newContents, 'utf8');
513
+ modified.push(hunk.relPath);
514
+ break;
515
+ }
516
+ default: {
517
+ const _exhaustive = hunk;
518
+ return _exhaustive;
519
+ }
520
+ }
521
+ }
522
+ return { added, modified, deleted };
523
+ }
524
+ exports.applyPatchTool = {
525
+ type: 'func',
526
+ name: 'apply_patch',
527
+ description: 'Apply a Codex-style apply_patch formatted patch to the workspace. Enforces Dominds directory allow/deny lists.',
528
+ parameters: {
529
+ type: 'object',
530
+ additionalProperties: false,
531
+ required: ['patch'],
532
+ properties: {
533
+ patch: { type: 'string' },
534
+ },
535
+ },
536
+ async call(_dlg, caller, args) {
537
+ const parsed = parseApplyPatchArgs(args);
538
+ const hunks = parsePatch(parsed.patch);
539
+ const summary = await applyHunksToWorkspace(caller, hunks);
540
+ return printSummary(summary);
541
+ },
542
+ };