dominds 1.25.0 → 1.25.2

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 (230) hide show
  1. package/README.md +4 -3
  2. package/README.zh.md +4 -3
  3. package/dist/dialog-display-state.d.ts +3 -3
  4. package/dist/dialog-display-state.js +12 -8
  5. package/dist/dialog.d.ts +3 -3
  6. package/dist/dialog.js +42 -20
  7. package/dist/docs/design.md +4 -0
  8. package/dist/docs/design.zh.md +4 -0
  9. package/dist/docs/dlg-drive-algo.zh.md +5 -0
  10. package/dist/docs/roadmap.md +2 -0
  11. package/dist/docs/roadmap.zh.md +2 -0
  12. package/dist/llm/gen/mock.d.ts +2 -2
  13. package/dist/llm/gen/mock.js +2 -2
  14. package/dist/llm/kernel-driver/drive.js +41 -14
  15. package/dist/llm/kernel-driver/engine.d.ts +1 -1
  16. package/dist/llm/kernel-driver/idle-reminder-wake.js +1 -1
  17. package/dist/llm/kernel-driver/sideDialog.d.ts +1 -1
  18. package/dist/llm/kernel-driver/sideDialog.js +7 -3
  19. package/dist/llm/kernel-driver/tellask-special.js +1 -6
  20. package/dist/llm/kernel-driver/types.d.ts +1 -1
  21. package/dist/minds/system-prompt-parts.js +4 -4
  22. package/dist/persistence.d.ts +1 -7
  23. package/dist/persistence.js +186 -149
  24. package/dist/priming.js +116 -35
  25. package/dist/runtime/driver-messages.d.ts +1 -1
  26. package/dist/runtime/driver-messages.js +37 -19
  27. package/dist/server/api-routes.js +18 -0
  28. package/dist/server/server-core.d.ts +1 -0
  29. package/dist/server/server-core.js +11 -0
  30. package/dist/server/websocket-handler.js +2 -1
  31. package/dist/shared-reminders.d.ts +11 -3
  32. package/dist/shared-reminders.js +62 -34
  33. package/dist/team.js +4 -1
  34. package/dist/tool.d.ts +1 -1
  35. package/dist/tool.js +1 -1
  36. package/dist/tools/app-reminders.js +8 -2
  37. package/dist/tools/builtins.js +30 -0
  38. package/dist/tools/ctrl.js +34 -109
  39. package/dist/tools/fs.d.ts +2 -0
  40. package/dist/tools/fs.js +281 -2
  41. package/dist/tools/os.d.ts +11 -0
  42. package/dist/tools/os.js +26 -15
  43. package/dist/tools/picture.d.ts +1 -0
  44. package/dist/tools/picture.js +64 -1
  45. package/dist/tools/prompts/codex_inspect_and_patch_tools/en/tools.md +5 -0
  46. package/dist/tools/prompts/codex_inspect_and_patch_tools/zh/tools.md +5 -0
  47. package/dist/tools/prompts/control/en/errors.md +5 -19
  48. package/dist/tools/prompts/control/en/index.md +5 -4
  49. package/dist/tools/prompts/control/en/principles.md +23 -19
  50. package/dist/tools/prompts/control/en/scenarios.md +17 -11
  51. package/dist/tools/prompts/control/en/tools.md +4 -6
  52. package/dist/tools/prompts/control/zh/errors.md +5 -19
  53. package/dist/tools/prompts/control/zh/index.md +5 -4
  54. package/dist/tools/prompts/control/zh/principles.md +22 -19
  55. package/dist/tools/prompts/control/zh/scenarios.md +17 -11
  56. package/dist/tools/prompts/control/zh/tools.md +4 -6
  57. package/dist/tools/prompts/fs_read/en/errors.md +6 -0
  58. package/dist/tools/prompts/fs_read/en/index.md +17 -0
  59. package/dist/tools/prompts/fs_read/en/principles.md +5 -0
  60. package/dist/tools/prompts/fs_read/en/scenarios.md +3 -0
  61. package/dist/tools/prompts/fs_read/en/tools.md +11 -0
  62. package/dist/tools/prompts/fs_read/zh/errors.md +6 -0
  63. package/dist/tools/prompts/fs_read/zh/index.md +17 -0
  64. package/dist/tools/prompts/fs_read/zh/principles.md +5 -0
  65. package/dist/tools/prompts/fs_read/zh/scenarios.md +3 -0
  66. package/dist/tools/prompts/fs_read/zh/tools.md +11 -0
  67. package/dist/tools/prompts/os/en/index.md +1 -1
  68. package/dist/tools/prompts/os/en/principles.md +1 -1
  69. package/dist/tools/prompts/os/en/scenarios.md +21 -0
  70. package/dist/tools/prompts/os/en/tools.md +6 -0
  71. package/dist/tools/prompts/os/zh/index.md +1 -1
  72. package/dist/tools/prompts/os/zh/principles.md +1 -1
  73. package/dist/tools/prompts/os/zh/scenarios.md +21 -0
  74. package/dist/tools/prompts/os/zh/tools.md +6 -0
  75. package/dist/tools/prompts/personal_memory/en/index.md +1 -1
  76. package/dist/tools/prompts/personal_memory/en/principles.md +2 -2
  77. package/dist/tools/prompts/personal_memory/zh/index.md +1 -1
  78. package/dist/tools/prompts/personal_memory/zh/principles.md +2 -2
  79. package/dist/tools/registry.d.ts +6 -0
  80. package/dist/tools/ripgrep.d.ts +5 -0
  81. package/dist/tools/ripgrep.js +482 -1
  82. package/dist/tools/team_mgmt.js +8 -8
  83. package/dist/tools/txt.d.ts +34 -0
  84. package/dist/tools/txt.js +221 -1
  85. package/package.json +3 -3
  86. package/webapp/dist/assets/{_basePickBy-ZLV93S3E.js → _basePickBy-CbWZ8qnS.js} +3 -3
  87. package/webapp/dist/assets/_basePickBy-CbWZ8qnS.js.map +1 -0
  88. package/webapp/dist/assets/{_baseUniq-D0wSOJ06.js → _baseUniq-IY-Vfzx1.js} +2 -2
  89. package/webapp/dist/assets/_baseUniq-IY-Vfzx1.js.map +1 -0
  90. package/webapp/dist/assets/{arc-BHclbMTS.js → arc--U2Vks6y.js} +2 -2
  91. package/webapp/dist/assets/arc--U2Vks6y.js.map +1 -0
  92. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CK99gE_D.js → architectureDiagram-VXUJARFQ-DpryGqjy.js} +8 -26
  93. package/webapp/dist/assets/architectureDiagram-VXUJARFQ-DpryGqjy.js.map +1 -0
  94. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-fE5MBTEU.js → blockDiagram-VD42YOAC-TTufCfiE.js} +170 -187
  95. package/webapp/dist/assets/blockDiagram-VD42YOAC-TTufCfiE.js.map +1 -0
  96. package/webapp/dist/assets/{c4Diagram-IC4MRINW-BSLyPyoU.js → c4Diagram-YG6GDRKO-B4RPsw5H.js} +4 -4
  97. package/webapp/dist/assets/c4Diagram-YG6GDRKO-B4RPsw5H.js.map +1 -0
  98. package/webapp/dist/assets/{channel-DSvMpp-a.js → channel-DAtGYJHZ.js} +2 -2
  99. package/webapp/dist/assets/channel-DAtGYJHZ.js.map +1 -0
  100. package/webapp/dist/assets/{chunk-4BX2VUAB-OXEX170k.js → chunk-4BX2VUAB-JtO__vAF.js} +2 -2
  101. package/webapp/dist/assets/chunk-4BX2VUAB-JtO__vAF.js.map +1 -0
  102. package/webapp/dist/assets/{chunk-55IACEB6-BFQ_spQD.js → chunk-55IACEB6-JMRC8yG1.js} +2 -2
  103. package/webapp/dist/assets/chunk-55IACEB6-JMRC8yG1.js.map +1 -0
  104. package/webapp/dist/assets/{chunk-WL4C6EOR-PtH-blkK.js → chunk-B4BG7PRW-BDIpf8Iz.js} +121 -171
  105. package/webapp/dist/assets/chunk-B4BG7PRW-BDIpf8Iz.js.map +1 -0
  106. package/webapp/dist/assets/{chunk-NQ4KR5QH-B_ZhWMXR.js → chunk-DI55MBZ5-j9B4rifK.js} +7 -9
  107. package/webapp/dist/assets/chunk-DI55MBZ5-j9B4rifK.js.map +1 -0
  108. package/webapp/dist/assets/{chunk-FMBD7UC4-CbQ2BBPs.js → chunk-FMBD7UC4-DFXKLjHC.js} +2 -2
  109. package/webapp/dist/assets/chunk-FMBD7UC4-DFXKLjHC.js.map +1 -0
  110. package/webapp/dist/assets/{chunk-KX2RTZJC-BMd-daMY.js → chunk-QN33PNHL-BKzkeJ-b.js} +2 -2
  111. package/webapp/dist/assets/chunk-QN33PNHL-BKzkeJ-b.js.map +1 -0
  112. package/webapp/dist/assets/{chunk-QZHKN3VN-Cbf92xIw.js → chunk-QZHKN3VN-DiZd3UNl.js} +2 -2
  113. package/webapp/dist/assets/chunk-QZHKN3VN-DiZd3UNl.js.map +1 -0
  114. package/webapp/dist/assets/{chunk-JSJVCQXG-C4P1mjCL.js → chunk-TZMSLE5B-BaE4C244.js} +6 -14
  115. package/webapp/dist/assets/chunk-TZMSLE5B-BaE4C244.js.map +1 -0
  116. package/webapp/dist/assets/{classDiagram-VBA2DB6C-Dc3ncaD0.js → classDiagram-2ON5EDUG-CNF8ZohD.js} +6 -7
  117. package/webapp/dist/assets/classDiagram-2ON5EDUG-CNF8ZohD.js.map +1 -0
  118. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-Dc3ncaD0.js → classDiagram-v2-WZHVMYZB-CNF8ZohD.js} +6 -7
  119. package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-CNF8ZohD.js.map +1 -0
  120. package/webapp/dist/assets/{clone-E9Ad85BC.js → clone-Nq0Ko0Gv.js} +2 -2
  121. package/webapp/dist/assets/clone-Nq0Ko0Gv.js.map +1 -0
  122. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-B-nj0o74.js → cose-bilkent-S5V4N54A-uHPLSeKv.js} +2 -2
  123. package/webapp/dist/assets/cose-bilkent-S5V4N54A-uHPLSeKv.js.map +1 -0
  124. package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
  125. package/webapp/dist/assets/{dagre-KLK3FWXG-CyJYNIbm.js → dagre-6UL2VRFP-C1awWpU3.js} +7 -7
  126. package/webapp/dist/assets/dagre-6UL2VRFP-C1awWpU3.js.map +1 -0
  127. package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
  128. package/webapp/dist/assets/{diagram-E7M64L7V-C8eweQ7b.js → diagram-PSM6KHXK-Bf69p76M.js} +10 -10
  129. package/webapp/dist/assets/diagram-PSM6KHXK-Bf69p76M.js.map +1 -0
  130. package/webapp/dist/assets/{diagram-IFDJBPK2-DMdygRl0.js → diagram-QEK2KX5R-Bvlbx8Jp.js} +8 -9
  131. package/webapp/dist/assets/diagram-QEK2KX5R-Bvlbx8Jp.js.map +1 -0
  132. package/webapp/dist/assets/{diagram-P4PSJMXO-BQDZHb0a.js → diagram-S2PKOQOG-CGjGalBu.js} +8 -8
  133. package/webapp/dist/assets/diagram-S2PKOQOG-CGjGalBu.js.map +1 -0
  134. package/webapp/dist/assets/{erDiagram-INFDFZHY-C1HaXN6E.js → erDiagram-Q2GNP2WA-Ds3qhwkG.js} +75 -96
  135. package/webapp/dist/assets/erDiagram-Q2GNP2WA-Ds3qhwkG.js.map +1 -0
  136. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-24nNqQyo.js → flowDiagram-NV44I4VS-B1wDG_l5.js} +81 -98
  137. package/webapp/dist/assets/flowDiagram-NV44I4VS-B1wDG_l5.js.map +1 -0
  138. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BWPOFaLV.js → ganttDiagram-JELNMOA3-BwuYt2bO.js} +3 -28
  139. package/webapp/dist/assets/ganttDiagram-JELNMOA3-BwuYt2bO.js.map +1 -0
  140. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-D7_L-p_Y.js → gitGraphDiagram-V2S2FVAM-B2Tw773z.js} +46 -38
  141. package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-B2Tw773z.js.map +1 -0
  142. package/webapp/dist/assets/graph-CS_H7jBi.js +425 -0
  143. package/webapp/dist/assets/graph-CS_H7jBi.js.map +1 -0
  144. package/webapp/dist/assets/{index-CDCDAfqP.js → index-arD81Nnh.js} +1086 -1044
  145. package/webapp/dist/assets/{index-CDCDAfqP.js.map → index-arD81Nnh.js.map} +1 -1
  146. package/webapp/dist/assets/{index-BQoNJEGT.css → index-yycTJNYb.css} +1 -1
  147. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CvaBM5j6.js → infoDiagram-HS3SLOUP-C9_JKYhm.js} +7 -7
  148. package/webapp/dist/assets/infoDiagram-HS3SLOUP-C9_JKYhm.js.map +1 -0
  149. package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
  150. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-TQR6_teO.js → journeyDiagram-XKPGCS4Q-BhZggYOL.js} +5 -5
  151. package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-BhZggYOL.js.map +1 -0
  152. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-B-BOuC-U.js → kanban-definition-3W4ZIXB7-B-R2Xm4Y.js} +3 -5
  153. package/webapp/dist/assets/kanban-definition-3W4ZIXB7-B-R2Xm4Y.js.map +1 -0
  154. package/webapp/dist/assets/{layout-B8yqIqbx.js → layout-BzMatxDa.js} +5 -5
  155. package/webapp/dist/assets/layout-BzMatxDa.js.map +1 -0
  156. package/webapp/dist/assets/{linear-CoLfiZKK.js → linear-BuuJkw_U.js} +2 -2
  157. package/webapp/dist/assets/linear-BuuJkw_U.js.map +1 -0
  158. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-P70BMIHI.js → mindmap-definition-VGOIOE7T-BR7oDKBR.js} +5 -7
  159. package/webapp/dist/assets/mindmap-definition-VGOIOE7T-BR7oDKBR.js.map +1 -0
  160. package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
  161. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DsS_4dTB.js → pieDiagram-ADFJNKIX--QWeT2vZ.js} +8 -8
  162. package/webapp/dist/assets/pieDiagram-ADFJNKIX--QWeT2vZ.js.map +1 -0
  163. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DoM9PEq-.js → quadrantDiagram-AYHSOK5B-BpqtmN3r.js} +3 -3
  164. package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-BpqtmN3r.js.map +1 -0
  165. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-Bn3lYMMI.js → requirementDiagram-UZGBJVZJ-CIXjIi4F.js} +6 -16
  166. package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-CIXjIi4F.js.map +1 -0
  167. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-97kCegRT.js → sankeyDiagram-TZEHDZUN-DJIt7SRz.js} +2 -2
  168. package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-DJIt7SRz.js.map +1 -0
  169. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DXqjQjf6.js → sequenceDiagram-WL72ISMW-BpDK1ROT.js} +201 -601
  170. package/webapp/dist/assets/sequenceDiagram-WL72ISMW-BpDK1ROT.js.map +1 -0
  171. package/webapp/dist/assets/{stateDiagram-RAJIS63D-DQcTPKWP.js → stateDiagram-FKZM4ZOC-BoKGfmHf.js} +9 -9
  172. package/webapp/dist/assets/stateDiagram-FKZM4ZOC-BoKGfmHf.js.map +1 -0
  173. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DHmxRVJn.js → stateDiagram-v2-4FDKWEC3--haXC2JK.js} +5 -5
  174. package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3--haXC2JK.js.map +1 -0
  175. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BlovQQ4B.js → timeline-definition-IT6M3QCI-BmSg3Hjf.js} +3 -3
  176. package/webapp/dist/assets/timeline-definition-IT6M3QCI-BmSg3Hjf.js.map +1 -0
  177. package/webapp/dist/assets/{treemap-KZPCXAKY-CGu93c9S.js → treemap-GDKQZRPO-D9OuyDVA.js} +24 -37
  178. package/webapp/dist/assets/treemap-GDKQZRPO-D9OuyDVA.js.map +1 -0
  179. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BKa1DxVq.js → xychartDiagram-PRI3JC2R-CVqSvO_S.js} +4 -4
  180. package/webapp/dist/assets/xychartDiagram-PRI3JC2R-CVqSvO_S.js.map +1 -0
  181. package/webapp/dist/index.html +2 -2
  182. package/webapp/dist/assets/_basePickBy-ZLV93S3E.js.map +0 -1
  183. package/webapp/dist/assets/_baseUniq-D0wSOJ06.js.map +0 -1
  184. package/webapp/dist/assets/arc-BHclbMTS.js.map +0 -1
  185. package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-CK99gE_D.js.map +0 -1
  186. package/webapp/dist/assets/blockDiagram-WCTKOSBZ-fE5MBTEU.js.map +0 -1
  187. package/webapp/dist/assets/c4Diagram-IC4MRINW-BSLyPyoU.js.map +0 -1
  188. package/webapp/dist/assets/channel-DSvMpp-a.js.map +0 -1
  189. package/webapp/dist/assets/chunk-4BX2VUAB-OXEX170k.js.map +0 -1
  190. package/webapp/dist/assets/chunk-55IACEB6-BFQ_spQD.js.map +0 -1
  191. package/webapp/dist/assets/chunk-FMBD7UC4-CbQ2BBPs.js.map +0 -1
  192. package/webapp/dist/assets/chunk-JSJVCQXG-C4P1mjCL.js.map +0 -1
  193. package/webapp/dist/assets/chunk-KX2RTZJC-BMd-daMY.js.map +0 -1
  194. package/webapp/dist/assets/chunk-NQ4KR5QH-B_ZhWMXR.js.map +0 -1
  195. package/webapp/dist/assets/chunk-QZHKN3VN-Cbf92xIw.js.map +0 -1
  196. package/webapp/dist/assets/chunk-WL4C6EOR-PtH-blkK.js.map +0 -1
  197. package/webapp/dist/assets/classDiagram-VBA2DB6C-Dc3ncaD0.js.map +0 -1
  198. package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-Dc3ncaD0.js.map +0 -1
  199. package/webapp/dist/assets/clone-E9Ad85BC.js.map +0 -1
  200. package/webapp/dist/assets/cose-bilkent-S5V4N54A-B-nj0o74.js.map +0 -1
  201. package/webapp/dist/assets/dagre-KLK3FWXG-CyJYNIbm.js.map +0 -1
  202. package/webapp/dist/assets/diagram-E7M64L7V-C8eweQ7b.js.map +0 -1
  203. package/webapp/dist/assets/diagram-IFDJBPK2-DMdygRl0.js.map +0 -1
  204. package/webapp/dist/assets/diagram-P4PSJMXO-BQDZHb0a.js.map +0 -1
  205. package/webapp/dist/assets/erDiagram-INFDFZHY-C1HaXN6E.js.map +0 -1
  206. package/webapp/dist/assets/flowDiagram-PKNHOUZH-24nNqQyo.js.map +0 -1
  207. package/webapp/dist/assets/ganttDiagram-A5KZAMGK-BWPOFaLV.js.map +0 -1
  208. package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-D7_L-p_Y.js.map +0 -1
  209. package/webapp/dist/assets/graph-OHu4dL2n.js +0 -782
  210. package/webapp/dist/assets/graph-OHu4dL2n.js.map +0 -1
  211. package/webapp/dist/assets/infoDiagram-LFFYTUFH-CvaBM5j6.js.map +0 -1
  212. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-DB1l2Uue.js +0 -966
  213. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-DB1l2Uue.js.map +0 -1
  214. package/webapp/dist/assets/journeyDiagram-4ABVD52K-TQR6_teO.js.map +0 -1
  215. package/webapp/dist/assets/kanban-definition-K7BYSVSG-B-BOuC-U.js.map +0 -1
  216. package/webapp/dist/assets/layout-B8yqIqbx.js.map +0 -1
  217. package/webapp/dist/assets/linear-CoLfiZKK.js.map +0 -1
  218. package/webapp/dist/assets/mindmap-definition-YRQLILUH-P70BMIHI.js.map +0 -1
  219. package/webapp/dist/assets/pieDiagram-SKSYHLDU-DsS_4dTB.js.map +0 -1
  220. package/webapp/dist/assets/quadrantDiagram-337W2JSQ-DoM9PEq-.js.map +0 -1
  221. package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-Bn3lYMMI.js.map +0 -1
  222. package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-97kCegRT.js.map +0 -1
  223. package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-DXqjQjf6.js.map +0 -1
  224. package/webapp/dist/assets/stateDiagram-RAJIS63D-DQcTPKWP.js.map +0 -1
  225. package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-DHmxRVJn.js.map +0 -1
  226. package/webapp/dist/assets/timeline-definition-YZTLITO2-BlovQQ4B.js.map +0 -1
  227. package/webapp/dist/assets/treemap-KZPCXAKY-CGu93c9S.js.map +0 -1
  228. package/webapp/dist/assets/vennDiagram-LZ73GAT5-Do1jprrz.js +0 -2487
  229. package/webapp/dist/assets/vennDiagram-LZ73GAT5-Do1jprrz.js.map +0 -1
  230. package/webapp/dist/assets/xychartDiagram-JWTSCODW-BKa1DxVq.js.map +0 -1
@@ -30,6 +30,12 @@
30
30
  - `scrollbackLines`(可选):滚动回看里保留的最近输出行数
31
31
  - `timeoutSeconds`(可选):超时秒数;超时后转为守护进程追踪
32
32
 
33
+ **Windows 提示:**
34
+
35
+ - 默认 `cmd.exe` 路径下,优先使用不带空格的正斜杠路径,如 `D:/path/to/file`
36
+ - 复杂 PowerShell 命令建议显式传 `shell: 'powershell.exe'` 或 `shell: 'pwsh'`;系统会自动用编码方式传递命令,避免引号和反斜杠歧义
37
+ - 不要依赖 `cmd /c "..."`
38
+
33
39
  **返回:**
34
40
 
35
41
  ```yaml
@@ -36,7 +36,7 @@ Key notes:
36
36
  - Personal memory is automatically isolated on disk under `.minds/memory/individual/<member-id>/...`.
37
37
  - Your `path` must NOT include your member id (do not write `<member-id>/...`).
38
38
  - If you have zero memory files yet, just call `add_personal_memory` — the directory will be created automatically.
39
- - If the content is a role's long-lived responsibilities/methods/examples, put it in `persona / knowhow / pitfalls` instead; if it should synchronize the team's current effective state, key decisions, next steps, or still-active blockers, use Taskdoc `progress`, the quasi-real-time task bulletin board; if it is only a personal/current-dialog short-term working set or continuation detail, use reminders instead.
39
+ - If the content is a role's long-lived responsibilities/methods/examples, put it in `persona / knowhow / pitfalls` instead; if it should synchronize the team's current effective state, key decisions, next steps, or still-active blockers, use Taskdoc `progress`, the quasi-real-time task bulletin board; if it is only current-task/current-dialog short-term current work or continuation detail, use reminders instead.
40
40
 
41
41
  Tool list:
42
42
 
@@ -73,7 +73,7 @@ The `personal_memory` toolset uses a **path key-value storage** model:
73
73
  - Boundary with skills: workspace-coupled facts, paths, local contracts, and responsibility-area indexes belong in `personal_memory`; workspace-independent operating methods, checklists, triggers, and boundaries belong in skills. If both appear in one experience, split them so skills do not hide repo facts that can go stale.
74
74
  - Do not store task progress or daily state here:
75
75
  - Information that must synchronize the team's current effective state, key decisions, next step, or still-active blockers belongs in Taskdoc `progress`, the quasi-real-time task bulletin board
76
- - Personal or current-dialog short-term working set details belong in reminders
76
+ - Current-task or current-dialog short-term current-work details belong in reminders
77
77
 
78
78
  ### 3. Recommended Boundaries
79
79
 
@@ -81,7 +81,7 @@ The `personal_memory` toolset uses a **path key-value storage** model:
81
81
  - **A member’s own reusable long-lived experience and working index**: `personal_memory`
82
82
  - **Reusable operating guidance / checklists / triggers and boundaries**: `skills`
83
83
  - **Taskdoc `progress`**: the team-shared quasi-real-time task bulletin board for current effective state, key decisions, next steps, and still-active blockers
84
- - **reminders**: personal or current-dialog short-term working set, continuation package, and easy-to-lose volatile details
84
+ - **reminders**: current-task or current-dialog short-term current work, continuation package, and easy-to-lose volatile details
85
85
  - **Team-shared long-lived conventions / invariants / consensus rules**: `team_memory`
86
86
 
87
87
  > Note: If the main purpose of the information is to let the team quickly synchronize on where things stand now, which decisions are in effect, what is next, or which blockers still hold, it belongs in Taskdoc `progress`, not in `personal_memory`.
@@ -36,7 +36,7 @@ personal_memory 是 Dominds 的**个人记忆工具集**,用于管理智能体
36
36
  - 个人记忆会自动隔离到磁盘路径:`.minds/memory/individual/<member-id>/...`。
37
37
  - `path` 不应包含你的成员 id(不要写 `<member-id>/...`)。
38
38
  - 如果你还没有任何个人记忆条目,直接调用 `add_personal_memory` 即可:目录会由系统自动创建。
39
- - 如果你想写的是角色长期职责/方法/正反例,请改去 `persona / knowhow / pitfalls`;如果你想向全队同步当前有效状态、关键决策、下一步或仍成立阻塞,请改去 Taskdoc `progress` 这一准实时任务公告牌;如果只是个人/当前对话短期工作集与接续细节,请改去 reminders。
39
+ - 如果你想写的是角色长期职责/方法/正反例,请改去 `persona / knowhow / pitfalls`;如果你想向全队同步当前有效状态、关键决策、下一步或仍成立阻塞,请改去 Taskdoc `progress` 这一准实时任务公告牌;如果只是当前任务/当前对话短期手头工作与接续细节,请改去 reminders。
40
40
 
41
41
  ## 快速导航
42
42
 
@@ -73,7 +73,7 @@ personal_memory 工具集采用**路径键值存储**模型:
73
73
  - 与 skills 的边界:工作区关联强的事实、路径、局部契约、职责域索引写进 `personal_memory`;独立于工作区内容的操作方法、检查清单、触发条件与边界写进 skill。若两者混在一起,请拆开维护,避免 skill 藏着容易过期的仓库事实。
74
74
  - 不要把任务进度/当天状态写进个人记忆:
75
75
  - 需要向全队同步的当前有效状态、关键决策、下一步与仍成立阻塞,用 Taskdoc `progress` 这一准实时任务公告牌
76
- - 只供个人/当前对话短期持有的接续细节、临时 bridge 信息与工作集,用 reminders
76
+ - 只供当前任务/当前对话短期持有的接续细节、临时 bridge 信息与手头工作提示,用 reminders
77
77
 
78
78
  ### 3. 推荐边界
79
79
 
@@ -81,7 +81,7 @@ personal_memory 工具集采用**路径键值存储**模型:
81
81
  - **成员自己的长期可复用经验与个人工作索引**:`personal_memory`
82
82
  - **可复用操作指引 / 检查清单 / 触发条件与边界**:`skills`
83
83
  - **Taskdoc `progress`**:全队共享的准实时任务公告牌,承接当前有效状态、关键决策、下一步与仍成立阻塞
84
- - **reminders**:个人/当前对话短期工作集、接续包、容易丢的临时细节
84
+ - **reminders**:当前任务/当前对话短期手头工作、接续包、容易丢的临时细节
85
85
  - **团队共享的长期约定 / 不变量 / 共识原则**:`team_memory`
86
86
 
87
87
  > 注:如果信息的主要目的,是让全队快速同步“现在到哪了、哪些决策已生效、下一步是什么、哪些阻塞仍成立”,它更适合进入 Taskdoc `progress` 这一准实时公告牌,而不是 `personal_memory`。
@@ -17,6 +17,12 @@ export type ToolsetMeta = {
17
17
  * system according to dialog scope rather than granted by team config.
18
18
  */
19
19
  assignable?: boolean;
20
+ /**
21
+ * Whether wildcard toolset expansion (`toolsets: ['*']`) may include this
22
+ * toolset. Defaults to true. Use false for explicitly grantable toolsets that
23
+ * should not be mass-assigned by wildcard baselines.
24
+ */
25
+ wildcardAssignable?: boolean;
20
26
  descriptionI18n?: I18nText;
21
27
  /**
22
28
  * Toolset-level prompt injected into the agent system prompt when the member
@@ -1,6 +1,11 @@
1
1
  import type { FuncTool } from '../tool';
2
2
  export declare const ripgrepFilesTool: FuncTool;
3
+ export declare const fsRipgrepFilesTool: FuncTool;
3
4
  export declare const ripgrepCountTool: FuncTool;
5
+ export declare const fsRipgrepCountTool: FuncTool;
4
6
  export declare const ripgrepSnippetsTool: FuncTool;
7
+ export declare const fsRipgrepSnippetsTool: FuncTool;
5
8
  export declare const ripgrepFixedTool: FuncTool;
9
+ export declare const fsRipgrepFixedTool: FuncTool;
6
10
  export declare const ripgrepSearchTool: FuncTool;
11
+ export declare const fsRipgrepSearchTool: FuncTool;
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.ripgrepSearchTool = exports.ripgrepFixedTool = exports.ripgrepSnippetsTool = exports.ripgrepCountTool = exports.ripgrepFilesTool = void 0;
39
+ exports.fsRipgrepSearchTool = exports.ripgrepSearchTool = exports.fsRipgrepFixedTool = exports.ripgrepFixedTool = exports.fsRipgrepSnippetsTool = exports.ripgrepSnippetsTool = exports.fsRipgrepCountTool = exports.ripgrepCountTool = exports.fsRipgrepFilesTool = exports.ripgrepFilesTool = void 0;
40
40
  /**
41
41
  * Module: tools/ripgrep
42
42
  *
@@ -629,6 +629,39 @@ function baseRgArgs(options, member) {
629
629
  globCompatibilityWarnings: filters.globCompatibilityWarnings,
630
630
  };
631
631
  }
632
+ function fsBaseRgArgs(options) {
633
+ const args = ['--no-messages', '--color=never'];
634
+ if (options.includeHidden)
635
+ args.push('--hidden');
636
+ if (options.followSymlinks)
637
+ args.push('--follow');
638
+ if (options.caseMode === 'smart')
639
+ args.push('--smart-case');
640
+ if (options.caseMode === 'sensitive')
641
+ args.push('--case-sensitive');
642
+ if (options.caseMode === 'insensitive')
643
+ args.push('--ignore-case');
644
+ if (options.fixedStrings)
645
+ args.push('--fixed-strings');
646
+ const simple = process.platform === 'win32'
647
+ ? extractSimpleExtensionGlobs(options.globs)
648
+ : { typeArgs: [], extensionFilters: [], passthroughGlobs: options.globs };
649
+ args.push(...simple.typeArgs);
650
+ for (const glob of simple.passthroughGlobs) {
651
+ args.push('--glob', glob);
652
+ }
653
+ const globCompatibilityWarnings = process.platform === 'win32' && simple.passthroughGlobs.length > 0
654
+ ? [
655
+ 'Some complex globs were passed through to rg --glob. On Windows, simple extension filters are translated to --type, but complex globs may still be affected by ripgrep glob/path compatibility.',
656
+ ]
657
+ : [];
658
+ return {
659
+ args,
660
+ postFilter: (relPath) => simple.extensionFilters.length === 0 ||
661
+ simple.extensionFilters.some((ext) => relPath.toLowerCase().endsWith(`.${ext}`)),
662
+ globCompatibilityWarnings,
663
+ };
664
+ }
632
665
  function buildRipgrepDiagnostics(run, filterPlan, returnedMatches) {
633
666
  const diagnostics = [];
634
667
  if (run.partialPathFailure) {
@@ -980,6 +1013,95 @@ exports.ripgrepFilesTool = {
980
1013
  return await runRipgrepFiles(caller, pattern, searchPath, options);
981
1014
  },
982
1015
  };
1016
+ async function runFsRipgrepFiles(pattern, searchPath, options) {
1017
+ const filterPlan = fsBaseRgArgs(options);
1018
+ const args = [
1019
+ ...filterPlan.args,
1020
+ '--files-with-matches',
1021
+ '--',
1022
+ pattern,
1023
+ normalizeRipgrepSearchPath(searchPath),
1024
+ ];
1025
+ try {
1026
+ let totalFiles = 0;
1027
+ const results = [];
1028
+ const run = await runRgLines(args, (line) => {
1029
+ if (!filterPlan.postFilter(line))
1030
+ return;
1031
+ totalFiles++;
1032
+ if (results.length < options.maxFiles)
1033
+ results.push({ path: line });
1034
+ });
1035
+ const diagnostics = buildRipgrepDiagnostics(run, filterPlan, totalFiles > 0);
1036
+ const truncated = totalFiles > options.maxFiles;
1037
+ const summary = totalFiles === 0
1038
+ ? formatRipgrepNoMatchesSummary(run.partialPathFailure)
1039
+ : truncated
1040
+ ? `Found ${totalFiles} files; showing first ${options.maxFiles} (truncated=true).${run.partialPathFailure ? ` ${RIPGREP_PARTIAL_PATH_FAILURE_SUMMARY}` : ''}`
1041
+ : `Found ${totalFiles} files.${run.partialPathFailure ? ` ${RIPGREP_PARTIAL_PATH_FAILURE_SUMMARY}` : ''}`;
1042
+ const yaml = [
1043
+ `status: ${run.partialPathFailure ? 'partial_failure' : 'ok'}`,
1044
+ `pattern: ${yamlQuote(pattern)}`,
1045
+ `mode: fs_files`,
1046
+ `path: ${yamlQuote(searchPath)}`,
1047
+ ...(options.globs.length > 0 ? [`globs: ${yamlFlowStringArray(options.globs)}`] : []),
1048
+ `case: ${options.caseMode}`,
1049
+ `fixed_strings: ${options.fixedStrings}`,
1050
+ `regex: ${!options.fixedStrings}`,
1051
+ `truncated: ${truncated}`,
1052
+ `limits:`,
1053
+ ` max_files: ${options.maxFiles}`,
1054
+ `totals:`,
1055
+ ` files_matched: ${totalFiles}`,
1056
+ `diagnostics:`,
1057
+ ` partial_path_failure: ${run.partialPathFailure}`,
1058
+ ` messages: ${yamlFlowStringArray(diagnostics)}`,
1059
+ `summary: ${yamlQuote(summary)}`,
1060
+ `results:`,
1061
+ ...results.map((r) => ` - path: ${yamlQuote(r.path)}`),
1062
+ ].join('\n');
1063
+ return run.partialPathFailure ? (0, tool_1.toolPartialFailure)(formatYamlCodeBlock(yaml)) : okYaml(yaml);
1064
+ }
1065
+ catch (error) {
1066
+ return failYaml([
1067
+ `status: error`,
1068
+ `pattern: ${yamlQuote(pattern)}`,
1069
+ `mode: fs_files`,
1070
+ `path: ${yamlQuote(searchPath)}`,
1071
+ `error: FAILED`,
1072
+ `summary: ${yamlQuote(error instanceof Error ? error.message : String(error))}`,
1073
+ ].join('\n'));
1074
+ }
1075
+ }
1076
+ exports.fsRipgrepFilesTool = {
1077
+ type: 'func',
1078
+ name: 'fs_ripgrep_files',
1079
+ description: 'Search local filesystem file paths containing a pattern without restricting paths to rtws (rg-backed).',
1080
+ descriptionI18n: {
1081
+ en: 'Search local filesystem file paths containing a pattern without restricting paths to rtws (rg-backed).',
1082
+ zh: '搜索本机文件系统中包含匹配内容的文件路径,不限制路径必须位于 rtws 内(rg 驱动)。',
1083
+ },
1084
+ parameters: exports.ripgrepFilesTool.parameters,
1085
+ argsValidation: 'dominds',
1086
+ call: async (_dlg, _caller, args) => {
1087
+ const pattern = requireNonEmptyStringArg(args, 'pattern');
1088
+ const searchPath = optionalStringArg(args, 'path') ?? '.';
1089
+ const globs = parseRipgrepGlobsArg(args);
1090
+ const caseMode = parseRipgrepCaseModeArg(args, 'smart');
1091
+ const fixedStrings = optionalBooleanArg(args, 'fixed_strings') ?? false;
1092
+ const includeHidden = optionalBooleanArg(args, 'include_hidden') ?? false;
1093
+ const followSymlinks = optionalBooleanArg(args, 'follow_symlinks') ?? false;
1094
+ const maxFiles = optionalPositiveIntegerArg(args, 'max_files') ?? 50;
1095
+ return await runFsRipgrepFiles(pattern, searchPath, {
1096
+ globs,
1097
+ caseMode,
1098
+ fixedStrings,
1099
+ includeHidden,
1100
+ followSymlinks,
1101
+ maxFiles,
1102
+ });
1103
+ },
1104
+ };
983
1105
  async function runRipgrepCount(caller, pattern, searchPath, options) {
984
1106
  const forbiddenPath = detectForbiddenRipgrepSearchPath(caller, searchPath);
985
1107
  if (forbiddenPath) {
@@ -1104,6 +1226,106 @@ exports.ripgrepCountTool = {
1104
1226
  return await runRipgrepCount(caller, pattern, searchPath, options);
1105
1227
  },
1106
1228
  };
1229
+ async function runFsRipgrepCount(pattern, searchPath, options) {
1230
+ const filterPlan = fsBaseRgArgs(options);
1231
+ const args = [
1232
+ ...filterPlan.args,
1233
+ '--count-matches',
1234
+ '--',
1235
+ pattern,
1236
+ normalizeRipgrepSearchPath(searchPath),
1237
+ ];
1238
+ try {
1239
+ let totalFiles = 0;
1240
+ let totalMatches = 0;
1241
+ const results = [];
1242
+ const run = await runRgLines(args, (line) => {
1243
+ const idx = line.lastIndexOf(':');
1244
+ if (idx <= 0)
1245
+ return;
1246
+ const p = line.slice(0, idx);
1247
+ if (!filterPlan.postFilter(p))
1248
+ return;
1249
+ const rawCount = line.slice(idx + 1);
1250
+ const count = Number.parseInt(rawCount, 10);
1251
+ if (!Number.isFinite(count))
1252
+ return;
1253
+ totalFiles++;
1254
+ totalMatches += count;
1255
+ if (results.length < options.maxFiles)
1256
+ results.push({ path: p, count });
1257
+ });
1258
+ const diagnostics = buildRipgrepDiagnostics(run, filterPlan, totalMatches > 0);
1259
+ const truncated = totalFiles > options.maxFiles;
1260
+ const summary = totalMatches === 0
1261
+ ? formatRipgrepNoMatchesSummary(run.partialPathFailure)
1262
+ : truncated
1263
+ ? `Counted ${totalMatches} matches in ${totalFiles} files; showing first ${options.maxFiles} files (truncated=true).${run.partialPathFailure ? ` ${RIPGREP_PARTIAL_PATH_FAILURE_SUMMARY}` : ''}`
1264
+ : `Counted ${totalMatches} matches in ${totalFiles} files.${run.partialPathFailure ? ` ${RIPGREP_PARTIAL_PATH_FAILURE_SUMMARY}` : ''}`;
1265
+ const yaml = [
1266
+ `status: ${run.partialPathFailure ? 'partial_failure' : 'ok'}`,
1267
+ `pattern: ${yamlQuote(pattern)}`,
1268
+ `mode: fs_count`,
1269
+ `path: ${yamlQuote(searchPath)}`,
1270
+ ...(options.globs.length > 0 ? [`globs: ${yamlFlowStringArray(options.globs)}`] : []),
1271
+ `case: ${options.caseMode}`,
1272
+ `fixed_strings: ${options.fixedStrings}`,
1273
+ `regex: ${!options.fixedStrings}`,
1274
+ `truncated: ${truncated}`,
1275
+ `limits:`,
1276
+ ` max_files: ${options.maxFiles}`,
1277
+ `totals:`,
1278
+ ` files_matched: ${totalFiles}`,
1279
+ ` matches: ${totalMatches}`,
1280
+ `diagnostics:`,
1281
+ ` partial_path_failure: ${run.partialPathFailure}`,
1282
+ ` messages: ${yamlFlowStringArray(diagnostics)}`,
1283
+ `summary: ${yamlQuote(summary)}`,
1284
+ `results:`,
1285
+ ...results.map((r) => ` - path: ${yamlQuote(r.path)}\n count: ${r.count}`),
1286
+ ].join('\n');
1287
+ return run.partialPathFailure ? (0, tool_1.toolPartialFailure)(formatYamlCodeBlock(yaml)) : okYaml(yaml);
1288
+ }
1289
+ catch (error) {
1290
+ return failYaml([
1291
+ `status: error`,
1292
+ `pattern: ${yamlQuote(pattern)}`,
1293
+ `mode: fs_count`,
1294
+ `path: ${yamlQuote(searchPath)}`,
1295
+ `error: FAILED`,
1296
+ `summary: ${yamlQuote(error instanceof Error ? error.message : String(error))}`,
1297
+ ].join('\n'));
1298
+ }
1299
+ }
1300
+ exports.fsRipgrepCountTool = {
1301
+ type: 'func',
1302
+ name: 'fs_ripgrep_count',
1303
+ description: 'Count local filesystem matches per file without restricting paths to rtws (rg-backed).',
1304
+ descriptionI18n: {
1305
+ en: 'Count local filesystem matches per file without restricting paths to rtws (rg-backed).',
1306
+ zh: '统计本机文件系统中每个文件的匹配数量,不限制路径必须位于 rtws 内(rg 驱动)。',
1307
+ },
1308
+ parameters: exports.ripgrepCountTool.parameters,
1309
+ argsValidation: 'dominds',
1310
+ call: async (_dlg, _caller, args) => {
1311
+ const pattern = requireNonEmptyStringArg(args, 'pattern');
1312
+ const searchPath = optionalStringArg(args, 'path') ?? '.';
1313
+ const globs = parseRipgrepGlobsArg(args);
1314
+ const caseMode = parseRipgrepCaseModeArg(args, 'smart');
1315
+ const fixedStrings = optionalBooleanArg(args, 'fixed_strings') ?? false;
1316
+ const includeHidden = optionalBooleanArg(args, 'include_hidden') ?? false;
1317
+ const followSymlinks = optionalBooleanArg(args, 'follow_symlinks') ?? false;
1318
+ const maxFiles = optionalPositiveIntegerArg(args, 'max_files') ?? 200;
1319
+ return await runFsRipgrepCount(pattern, searchPath, {
1320
+ globs,
1321
+ caseMode,
1322
+ fixedStrings,
1323
+ includeHidden,
1324
+ followSymlinks,
1325
+ maxFiles,
1326
+ });
1327
+ },
1328
+ };
1107
1329
  async function runRipgrepSnippets(caller, pattern, searchPath, options) {
1108
1330
  const forbiddenPath = detectForbiddenRipgrepSearchPath(caller, searchPath);
1109
1331
  if (forbiddenPath) {
@@ -1237,6 +1459,113 @@ exports.ripgrepSnippetsTool = {
1237
1459
  return await runRipgrepSnippets(caller, pattern, searchPath, options);
1238
1460
  },
1239
1461
  };
1462
+ async function runFsRipgrepSnippets(pattern, searchPath, options) {
1463
+ const filterPlan = fsBaseRgArgs(options);
1464
+ const args = [
1465
+ ...filterPlan.args,
1466
+ '--vimgrep',
1467
+ '--',
1468
+ pattern,
1469
+ normalizeRipgrepSearchPath(searchPath),
1470
+ ];
1471
+ try {
1472
+ let totalMatches = 0;
1473
+ const fileSet = new Set();
1474
+ const results = [];
1475
+ const fileCache = new Map();
1476
+ const run = await runRgLines(args, async (line) => {
1477
+ const first = line.indexOf(':');
1478
+ if (first <= 0)
1479
+ return;
1480
+ const second = line.indexOf(':', first + 1);
1481
+ if (second <= first)
1482
+ return;
1483
+ const third = line.indexOf(':', second + 1);
1484
+ if (third <= second)
1485
+ return;
1486
+ const filePath = line.slice(0, first);
1487
+ const lineStr = line.slice(first + 1, second);
1488
+ const colStr = line.slice(second + 1, third);
1489
+ const text = line.slice(third + 1);
1490
+ const ln = Number.parseInt(lineStr, 10);
1491
+ const col = Number.parseInt(colStr, 10);
1492
+ if (!Number.isFinite(ln) || !Number.isFinite(col))
1493
+ return;
1494
+ if (!filterPlan.postFilter(filePath))
1495
+ return;
1496
+ totalMatches++;
1497
+ fileSet.add(filePath);
1498
+ if (results.length >= options.maxResults)
1499
+ return;
1500
+ let lines = fileCache.get(filePath);
1501
+ if (!lines) {
1502
+ lines = await loadFileLines(filePath).catch(() => []);
1503
+ fileCache.set(filePath, lines);
1504
+ }
1505
+ const idx0 = ln - 1;
1506
+ const before = lines.slice(Math.max(0, idx0 - options.contextBefore), idx0);
1507
+ const after = lines.slice(idx0 + 1, idx0 + 1 + options.contextAfter);
1508
+ results.push({ path: filePath, line: ln, col, match: text, before, after });
1509
+ });
1510
+ const diagnostics = buildRipgrepDiagnostics(run, filterPlan, totalMatches > 0);
1511
+ return formatRipgrepSnippetYaml({
1512
+ pattern,
1513
+ searchPath,
1514
+ globs: options.globs,
1515
+ caseMode: options.caseMode,
1516
+ fixedStrings: options.fixedStrings,
1517
+ maxResults: options.maxResults,
1518
+ fileCount: fileSet.size,
1519
+ totalMatches,
1520
+ partialPathFailure: run.partialPathFailure,
1521
+ diagnostics,
1522
+ results,
1523
+ });
1524
+ }
1525
+ catch (error) {
1526
+ return failYaml([
1527
+ `status: error`,
1528
+ `pattern: ${yamlQuote(pattern)}`,
1529
+ `mode: fs_snippets`,
1530
+ `path: ${yamlQuote(searchPath)}`,
1531
+ `error: FAILED`,
1532
+ `summary: ${yamlQuote(error instanceof Error ? error.message : String(error))}`,
1533
+ ].join('\n'));
1534
+ }
1535
+ }
1536
+ exports.fsRipgrepSnippetsTool = {
1537
+ type: 'func',
1538
+ name: 'fs_ripgrep_snippets',
1539
+ description: 'Search local filesystem snippets with line/col without restricting paths to rtws (rg-backed).',
1540
+ descriptionI18n: {
1541
+ en: 'Search local filesystem snippets with line/col without restricting paths to rtws (rg-backed).',
1542
+ zh: '搜索本机文件系统并显示带行列的匹配片段,不限制路径必须位于 rtws 内(rg 驱动)。',
1543
+ },
1544
+ parameters: exports.ripgrepSnippetsTool.parameters,
1545
+ argsValidation: 'dominds',
1546
+ call: async (_dlg, _caller, args) => {
1547
+ const pattern = requireNonEmptyStringArg(args, 'pattern');
1548
+ const searchPath = optionalStringArg(args, 'path') ?? '.';
1549
+ const globs = parseRipgrepGlobsArg(args);
1550
+ const caseMode = parseRipgrepCaseModeArg(args, 'smart');
1551
+ const fixedStrings = optionalBooleanArg(args, 'fixed_strings') ?? false;
1552
+ const includeHidden = optionalBooleanArg(args, 'include_hidden') ?? false;
1553
+ const followSymlinks = optionalBooleanArg(args, 'follow_symlinks') ?? false;
1554
+ const maxResults = optionalPositiveIntegerArg(args, 'max_results') ?? 50;
1555
+ const contextBefore = optionalNonNegativeIntegerArg(args, 'context_before') ?? 1;
1556
+ const contextAfter = optionalNonNegativeIntegerArg(args, 'context_after') ?? 1;
1557
+ return await runFsRipgrepSnippets(pattern, searchPath, {
1558
+ globs,
1559
+ caseMode,
1560
+ fixedStrings,
1561
+ includeHidden,
1562
+ followSymlinks,
1563
+ maxResults,
1564
+ contextBefore,
1565
+ contextAfter,
1566
+ });
1567
+ },
1568
+ };
1240
1569
  exports.ripgrepFixedTool = {
1241
1570
  type: 'func',
1242
1571
  name: 'ripgrep_fixed',
@@ -1300,6 +1629,53 @@ exports.ripgrepFixedTool = {
1300
1629
  return await runRipgrepSnippets(caller, literal, searchPath, options);
1301
1630
  },
1302
1631
  };
1632
+ exports.fsRipgrepFixedTool = {
1633
+ type: 'func',
1634
+ name: 'fs_ripgrep_fixed',
1635
+ description: 'Fixed-string ripgrep convenience tool for local filesystem search without restricting paths to rtws.',
1636
+ descriptionI18n: {
1637
+ en: 'Fixed-string ripgrep convenience tool for local filesystem search without restricting paths to rtws.',
1638
+ zh: '本机文件系统固定字符串 ripgrep 便捷工具,不限制路径必须位于 rtws 内。',
1639
+ },
1640
+ parameters: exports.ripgrepFixedTool.parameters,
1641
+ argsValidation: 'dominds',
1642
+ call: async (_dlg, _caller, args) => {
1643
+ const literal = requireNonEmptyStringArg(args, 'literal');
1644
+ const searchPath = optionalStringArg(args, 'path') ?? '.';
1645
+ const modeRaw = optionalStringArg(args, 'mode') ?? 'snippets';
1646
+ if (modeRaw !== 'files' && modeRaw !== 'snippets' && modeRaw !== 'count') {
1647
+ throw new Error("Invalid arguments: `mode` must be one of: 'files', 'snippets', 'count'");
1648
+ }
1649
+ const globs = parseRipgrepGlobsArg(args);
1650
+ const caseMode = parseRipgrepCaseModeArg(args, 'smart');
1651
+ const includeHidden = optionalBooleanArg(args, 'include_hidden') ?? false;
1652
+ const followSymlinks = optionalBooleanArg(args, 'follow_symlinks') ?? false;
1653
+ const base = {
1654
+ globs,
1655
+ caseMode,
1656
+ fixedStrings: true,
1657
+ includeHidden,
1658
+ followSymlinks,
1659
+ };
1660
+ if (modeRaw === 'files') {
1661
+ const maxFiles = optionalPositiveIntegerArg(args, 'max_files') ?? 50;
1662
+ return await runFsRipgrepFiles(literal, searchPath, { ...base, maxFiles });
1663
+ }
1664
+ if (modeRaw === 'count') {
1665
+ const maxFiles = optionalPositiveIntegerArg(args, 'max_files') ?? 200;
1666
+ return await runFsRipgrepCount(literal, searchPath, { ...base, maxFiles });
1667
+ }
1668
+ const maxResults = optionalPositiveIntegerArg(args, 'max_results') ?? 50;
1669
+ const contextBefore = optionalNonNegativeIntegerArg(args, 'context_before') ?? 1;
1670
+ const contextAfter = optionalNonNegativeIntegerArg(args, 'context_after') ?? 1;
1671
+ return await runFsRipgrepSnippets(literal, searchPath, {
1672
+ ...base,
1673
+ maxResults,
1674
+ contextBefore,
1675
+ contextAfter,
1676
+ });
1677
+ },
1678
+ };
1303
1679
  const DISALLOWED_RG_ARGS = new Set(['--pre', '--pre-glob']);
1304
1680
  async function runRipgrepSearch(caller, pattern, searchPath, rawRgArgs) {
1305
1681
  const forbiddenPath = detectForbiddenRipgrepSearchPath(caller, searchPath);
@@ -1423,3 +1799,108 @@ exports.ripgrepSearchTool = {
1423
1799
  return await runRipgrepSearch(caller, pattern, searchPath, rgArgs);
1424
1800
  },
1425
1801
  };
1802
+ async function runFsRipgrepSearch(pattern, searchPath, rawRgArgs) {
1803
+ for (const tok of rawRgArgs) {
1804
+ if (DISALLOWED_RG_ARGS.has(tok)) {
1805
+ return failYaml(`status: error\nerror: DISALLOWED_ARG\nsummary: ${yamlQuote(`Disallowed rg arg: ${tok}`)}`);
1806
+ }
1807
+ if (tok === '--json' ||
1808
+ tok === '--count' ||
1809
+ tok === '--count-matches' ||
1810
+ tok === '--files-with-matches' ||
1811
+ tok === '--files') {
1812
+ return failYaml(`status: error\nerror: DISALLOWED_ARG\nsummary: ${yamlQuote(`Disallowed rg output arg: ${tok}`)}`);
1813
+ }
1814
+ }
1815
+ const options = {
1816
+ ...defaultBaseOptions(),
1817
+ fixedStrings: false,
1818
+ maxResults: 50,
1819
+ contextBefore: 1,
1820
+ contextAfter: 1,
1821
+ };
1822
+ const filterPlan = fsBaseRgArgs(options);
1823
+ const rawArgsPlan = buildRawRipgrepArgsPlan(rawRgArgs);
1824
+ const rgArgs = [
1825
+ ...filterPlan.args,
1826
+ ...rawArgsPlan.args,
1827
+ '--vimgrep',
1828
+ '--',
1829
+ pattern,
1830
+ normalizeRipgrepSearchPath(searchPath),
1831
+ ];
1832
+ try {
1833
+ let totalMatches = 0;
1834
+ const fileSet = new Set();
1835
+ const results = [];
1836
+ const run = await runRgLines(rgArgs, (line) => {
1837
+ const first = line.indexOf(':');
1838
+ if (first <= 0)
1839
+ return;
1840
+ const secondColon = line.indexOf(':', first + 1);
1841
+ if (secondColon <= first)
1842
+ return;
1843
+ const thirdColon = line.indexOf(':', secondColon + 1);
1844
+ if (thirdColon <= secondColon)
1845
+ return;
1846
+ const filePath = line.slice(0, first);
1847
+ const lineStr = line.slice(first + 1, secondColon);
1848
+ const colStr = line.slice(secondColon + 1, thirdColon);
1849
+ const text = line.slice(thirdColon + 1);
1850
+ const ln = Number.parseInt(lineStr, 10);
1851
+ const col = Number.parseInt(colStr, 10);
1852
+ if (!Number.isFinite(ln) || !Number.isFinite(col))
1853
+ return;
1854
+ if (!rawArgsPlan.postFilter(filePath))
1855
+ return;
1856
+ totalMatches++;
1857
+ fileSet.add(filePath);
1858
+ if (results.length < options.maxResults)
1859
+ results.push({ path: filePath, line: ln, col, match: text });
1860
+ });
1861
+ const diagnostics = [
1862
+ ...buildRipgrepDiagnostics(run, filterPlan, totalMatches > 0),
1863
+ ...rawArgsPlan.globCompatibilityWarnings,
1864
+ ];
1865
+ return formatRipgrepSnippetYaml({
1866
+ pattern,
1867
+ searchPath,
1868
+ globs: [],
1869
+ caseMode: 'smart',
1870
+ fixedStrings: false,
1871
+ maxResults: options.maxResults,
1872
+ fileCount: fileSet.size,
1873
+ totalMatches,
1874
+ partialPathFailure: run.partialPathFailure,
1875
+ diagnostics,
1876
+ results,
1877
+ });
1878
+ }
1879
+ catch (error) {
1880
+ return failYaml([
1881
+ `status: error`,
1882
+ `pattern: ${yamlQuote(pattern)}`,
1883
+ `mode: fs_snippets`,
1884
+ `path: ${yamlQuote(searchPath)}`,
1885
+ `error: FAILED`,
1886
+ `summary: ${yamlQuote(error instanceof Error ? error.message : String(error))}`,
1887
+ ].join('\n'));
1888
+ }
1889
+ }
1890
+ exports.fsRipgrepSearchTool = {
1891
+ type: 'func',
1892
+ name: 'fs_ripgrep_search',
1893
+ description: 'Escape hatch: run rg-style local filesystem search without restricting paths to rtws. Output is normalized to YAML snippets mode.',
1894
+ descriptionI18n: {
1895
+ en: 'Escape hatch: run rg-style local filesystem search without restricting paths to rtws. Output is normalized to YAML snippets mode.',
1896
+ zh: '逃生舱:运行本机文件系统 rg 风格搜索,不限制路径必须位于 rtws 内。输出归一为 YAML snippets 模式。',
1897
+ },
1898
+ parameters: exports.ripgrepSearchTool.parameters,
1899
+ argsValidation: 'dominds',
1900
+ call: async (_dlg, _caller, args) => {
1901
+ const pattern = requireNonEmptyStringArg(args, 'pattern');
1902
+ const searchPath = optionalStringArg(args, 'path') ?? '.';
1903
+ const rgArgs = optionalStringArrayArg(args, 'rg_args') ?? [];
1904
+ return await runFsRipgrepSearch(pattern, searchPath, rgArgs);
1905
+ },
1906
+ };