pi-coding-master 0.2.7

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 (304) hide show
  1. package/README.md +50 -0
  2. package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py +80 -0
  3. package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py.CHANGELOG +1 -0
  4. package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py.SPEC +3 -0
  5. package/core/god.agent.capability/hands.dev.writeissue/issue.ts +209 -0
  6. package/core/god.agent.capability/hands.dev.writeissue/issue.ts.SPEC +26 -0
  7. package/core/god.agent.capability/hands.files.changewatcher/watcher.ts +44 -0
  8. package/core/god.agent.capability/hands.files.changewatcher/watcher.ts.SPEC +25 -0
  9. package/core/god.pi.mod/cli/pi-completion.zsh +21 -0
  10. package/core/god.pi.mod/cli/pi-completion.zsh.CHANGELOG +1 -0
  11. package/core/god.pi.mod/cli/pi-people.sh +264 -0
  12. package/core/god.pi.mod/cli/pi-people.sh.LESSON +10 -0
  13. package/core/god.pi.mod/cli/pi-people.sh.SPEC +31 -0
  14. package/core/god.pi.mod/paths.ts +47 -0
  15. package/core/god.pi.mod/tui.mods.blockrender/blockrender.js +90 -0
  16. package/core/god.pi.mod/tui.mods.blockrender/blockrender.js.SPEC +29 -0
  17. package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts +154 -0
  18. package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.CHANGELOG +10 -0
  19. package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.LESSON +12 -0
  20. package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.SPEC +26 -0
  21. package/core/god.pi.mod/tui.mods.footer.budget/footer-cny.CHANGELOG +39 -0
  22. package/core/god.pi.mod/tui.mods.viewmode/view_mode-thinking.patch +55 -0
  23. package/core/god.pi.mod/tui.mods.viewmode/view_mode-tools.patch +19 -0
  24. package/core/god.pi.mod/tui.mods.viewmode/view_mode-tools.patch.CHANGELOG +1 -0
  25. package/core/god.pi.mod/tui.mods.viewmode/view_mode.ts +50 -0
  26. package/core/god.pi.mod/tui.mods.viewmode/view_mode.ts.SPEC +12 -0
  27. package/core/god.pi.mod/tui.variants.userterminal/user_terminal.CHANGELOG +10 -0
  28. package/core/god.pi.mod/tui.variants.userterminal/user_terminal.ts +66 -0
  29. package/core/god.pi.mod/tui.variants.userterminal/user_terminal.ts.SPEC +31 -0
  30. package/core/index.ts +3 -0
  31. package/core/individual.bio.gene/dna.coded/coded.dna +257 -0
  32. package/core/individual.bio.gene/dna.coded/coded.dna.CHANGELOG +12 -0
  33. package/core/individual.bio.gene/dna.coded/coded.dna.SPEC +11 -0
  34. package/core/individual.bio.gene/dna.coded/core.dna +110 -0
  35. package/core/individual.bio.gene/dna.promotor/promotor.dna +117 -0
  36. package/core/individual.bio.gene/dna.promotor/promotor.dna.CHANGELOG +4 -0
  37. package/core/individual.bio.gene/dna.promotor/promotor.dna.SPEC +7 -0
  38. package/core/individual.bio.gene/dna.transpiler/transpiler.ts +395 -0
  39. package/core/individual.bio.gene/dna.transpiler/transpiler.ts.CHANGELOG +7 -0
  40. package/core/individual.bio.gene/dna.transpiler/transpiler.ts.SPEC +28 -0
  41. package/core/individual.bio.gene/gene.README +19 -0
  42. package/core/individual.bio.gene/rna/rna.json +536 -0
  43. package/core/individual.bio.gene/rna/rna.json.CHANGELOG +2 -0
  44. package/core/individual.bio.gene/rna/rna.json.SPEC +8 -0
  45. package/core/individual.bio.organs/blood.runtime/messages.ts +236 -0
  46. package/core/individual.bio.organs/blood.runtime/runtime.ts +173 -0
  47. package/core/individual.bio.organs/blood.runtime/runtime.ts.CHANGELOG +5 -0
  48. package/core/individual.bio.organs/blood.runtime/runtime.ts.SPEC +32 -0
  49. package/core/individual.bio.organs/brain.amygdala/amygdala.ts +25 -0
  50. package/core/individual.bio.organs/brain.amygdala/amygdala.ts.COMMENT +3 -0
  51. package/core/individual.bio.organs/brain.amygdala/amygdala.ts.SPEC +9 -0
  52. package/core/individual.bio.organs/brain.hippocampus/hippocampus-launcher.sh.template +108 -0
  53. package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts +166 -0
  54. package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.CHANGELOG +12 -0
  55. package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.LESSON +22 -0
  56. package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.SPEC +16 -0
  57. package/core/individual.bio.organs/brain.hippocampus/memory.ts +879 -0
  58. package/core/individual.bio.organs/brain.hippocampus/memory.ts.CHANGELOG +66 -0
  59. package/core/individual.bio.organs/brain.hippocampus/memory.ts.LESSON +25 -0
  60. package/core/individual.bio.organs/brain.hippocampus/memory.ts.SPEC +46 -0
  61. package/core/individual.bio.organs/brain.hippocampus/sleep.ts +139 -0
  62. package/core/individual.bio.organs/brain.hippocampus/sleep.ts.CHANGELOG +11 -0
  63. package/core/individual.bio.organs/brain.hippocampus/sleep.ts.SPEC +16 -0
  64. package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.SPEC +44 -0
  65. package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts +73 -0
  66. package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts.CHANGELOG +3 -0
  67. package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts.SPEC +24 -0
  68. package/core/individual.bio.organs/brain.prefrontal.drafting/index.ts.CHANGELOG +3 -0
  69. package/core/individual.bio.organs/brain.prefrontal.drafting/main.ts +13 -0
  70. package/core/individual.bio.organs/brain.prefrontal.drafting/main.ts.SPEC +17 -0
  71. package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts +94 -0
  72. package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts.LESSON +13 -0
  73. package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts.SPEC +20 -0
  74. package/core/individual.bio.organs/brain.senses.subconscious/feed-format.SPEC +56 -0
  75. package/core/individual.bio.organs/brain.senses.subconscious/index.ts.CHANGELOG +13 -0
  76. package/core/individual.bio.organs/brain.senses.subconscious/spawner.ts +130 -0
  77. package/core/individual.bio.organs/brain.senses.subconscious/spawner.ts.SPEC +13 -0
  78. package/core/individual.bio.organs/brain.senses.subconscious/subconscious.ts +280 -0
  79. package/core/individual.bio.organs/brain.senses.subconscious/subconscious.ts.CHANGELOG +7 -0
  80. package/core/individual.bio.organs/brain.senses.subconscious/tools.ts +180 -0
  81. package/core/individual.bio.organs/brain.senses.subconscious/tools.ts.SPEC +3 -0
  82. package/core/individual.bio.organs/ears.listen/config.json +9 -0
  83. package/core/individual.bio.organs/ears.listen/config.json.CHANGELOG +1 -0
  84. package/core/individual.bio.organs/ears.listen/config.json.SPEC +3 -0
  85. package/core/individual.bio.organs/ears.listen/ears.ts.CHANGELOG +48 -0
  86. package/core/individual.bio.organs/ears.listen/ears_recorder.py.CHANGELOG +6 -0
  87. package/core/individual.bio.organs/ears.listen/index.ts +1 -0
  88. package/core/individual.bio.organs/ears.listen/index.ts.SPEC +16 -0
  89. package/core/individual.bio.organs/ears.listen/listen.ts +208 -0
  90. package/core/individual.bio.organs/ears.listen/listen.ts.SPEC +3 -0
  91. package/core/individual.bio.organs/ears.listen/listen_recorder.py +445 -0
  92. package/core/individual.bio.organs/ears.listen/listen_recorder.py.SPEC +7 -0
  93. package/core/individual.bio.organs/ears.listen/python_protogen/__init__.py +0 -0
  94. package/core/individual.bio.organs/ears.listen/python_protogen/common/__init__.py +0 -0
  95. package/core/individual.bio.organs/ears.listen/python_protogen/common/events_pb2.py +38 -0
  96. package/core/individual.bio.organs/ears.listen/python_protogen/common/events_pb2_grpc.py +24 -0
  97. package/core/individual.bio.organs/ears.listen/python_protogen/common/rpcmeta_pb2.py +42 -0
  98. package/core/individual.bio.organs/ears.listen/python_protogen/common/rpcmeta_pb2_grpc.py +24 -0
  99. package/core/individual.bio.organs/ears.listen/python_protogen/products/__init__.py +0 -0
  100. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/__init__.py +0 -0
  101. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/__init__.py +0 -0
  102. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/ast_service_pb2.py +45 -0
  103. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/ast_service_pb2_grpc.py +97 -0
  104. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/__init__.py +0 -0
  105. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/au_base_pb2.py +80 -0
  106. package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/au_base_pb2_grpc.py +24 -0
  107. package/core/individual.bio.organs/hands.fileactions/authorize.TRUST +1 -0
  108. package/core/individual.bio.organs/hands.fileactions/authorize.ts +70 -0
  109. package/core/individual.bio.organs/hands.fileactions/authorize.ts.CHANGELOG +1 -0
  110. package/core/individual.bio.organs/hands.fileactions/authorize.ts.SPEC +3 -0
  111. package/core/individual.bio.organs/hands.fileactions/dir.README +13 -0
  112. package/core/individual.bio.organs/hands.fileactions/file_rules.json +23 -0
  113. package/core/individual.bio.organs/hands.fileactions/fileactions.README +12 -0
  114. package/core/individual.bio.organs/hands.fileactions/fileactions.ts +540 -0
  115. package/core/individual.bio.organs/hands.fileactions/fileactions.ts.CHANGELOG +25 -0
  116. package/core/individual.bio.organs/hands.fileactions/fileactions.ts.SPEC +30 -0
  117. package/core/individual.bio.organs/hands.fileactions/filewatch.ts +66 -0
  118. package/core/individual.bio.organs/hands.fileactions/filewatch.ts.SPEC +3 -0
  119. package/core/individual.bio.organs/hands.main/main.ts +18 -0
  120. package/core/individual.bio.organs/hands.main/main.ts.SPEC +20 -0
  121. package/core/individual.bio.organs/hands.sensitive/sensitive.ts +24 -0
  122. package/core/individual.bio.organs/hands.sensitive/sensitive.ts.CHANGELOG +2 -0
  123. package/core/individual.bio.organs/hands.sensitive/sensitive.ts.SPEC +3 -0
  124. package/core/individual.bio.organs/heart.interrupt/agent_start-loader-flicker.patch +13 -0
  125. package/core/individual.bio.organs/heart.interrupt/interactive-mode-loader.patch +11 -0
  126. package/core/individual.bio.organs/heart.interrupt/runner_esc.patch +10 -0
  127. package/core/individual.bio.organs/heart.interrupt/runner_esc.patch.SPEC +9 -0
  128. package/core/individual.bio.organs/heart.kernel/kernel.ts +253 -0
  129. package/core/individual.bio.organs/heart.kernel/kernel.ts.CHANGELOG +13 -0
  130. package/core/individual.bio.organs/heart.kernel/kernel.ts.SPEC +23 -0
  131. package/core/individual.bio.organs/heart.main/heart.main.CHANGELOG +43 -0
  132. package/core/individual.bio.organs/heart.main/heartbeat.ts +494 -0
  133. package/core/individual.bio.organs/heart.main/heartbeat.ts.LESSON +43 -0
  134. package/core/individual.bio.organs/heart.main/main.ts +8 -0
  135. package/core/individual.bio.organs/heart.main/main.ts.SPEC +19 -0
  136. package/core/individual.bio.organs/heart.main/process.ts +122 -0
  137. package/core/individual.bio.organs/heart.main/process.ts.CHANGELOG +2 -0
  138. package/core/individual.bio.organs/heart.main/process.ts.SPEC +24 -0
  139. package/core/individual.bio.organs/heart.main/remove_timeout.patch +110 -0
  140. package/core/individual.bio.organs/heart.main/stop.ts.CHANGELOG +3 -0
  141. package/core/individual.bio.organs/heart.main/stop.ts.SPEC +28 -0
  142. package/core/individual.bio.organs/mouth.speak/index.ts +1 -0
  143. package/core/individual.bio.organs/mouth.speak/index.ts.CHANGELOG +1 -0
  144. package/core/individual.bio.organs/mouth.speak/index.ts.SPEC +6 -0
  145. package/core/individual.bio.organs/mouth.speak/mouth.ts.CHANGELOG +15 -0
  146. package/core/individual.bio.organs/mouth.speak/mouth_recorder.py.CHANGELOG +1 -0
  147. package/core/individual.bio.organs/mouth.speak/speak.ts +180 -0
  148. package/core/individual.bio.organs/mouth.speak/speak.ts.SPEC +3 -0
  149. package/core/individual.bio.organs/mouth.speak/speak_recorder.py +35 -0
  150. package/core/individual.bio.organs/mouth.speak/speak_recorder.py.SPEC +3 -0
  151. package/core/individual.bio.organs/organs.README +110 -0
  152. package/core/package-lock.json +18 -0
  153. package/core/package.json +35 -0
  154. package/core/prompts/prompts.json +77 -0
  155. package/core/prompts/prompts.ts +44 -0
  156. package/core/prompts/prompts.ts.SPEC +9 -0
  157. package/core/society.world/.gitkeep +0 -0
  158. package/core/society.world/accessibility.claudecode/message-service.cjs +217 -0
  159. package/core/society.world/accessibility.claudecode/message-service.cjs.SPEC +7 -0
  160. package/core/society.world/accessibility.claudecode/send.ts +34 -0
  161. package/core/society.world/dollar.distribution.ubi/ubi.ts +55 -0
  162. package/core/society.world/dollar.main/dollar-service.cjs +185 -0
  163. package/core/society.world/dollar.main/main.ts +116 -0
  164. package/core/society.world/dollar.transaction/transaction.ts +71 -0
  165. package/core/society.world/space/space.ts +206 -0
  166. package/core/society.world/space/space.ts.SPEC +30 -0
  167. package/core/technology.laptop/#agent.macos.BLUEPRINT +278 -0
  168. package/core/technology.phone/apps.preinstalled/albums.FUTURE/albums.ts +69 -0
  169. package/core/technology.phone/apps.preinstalled/albums.FUTURE/albums.ts.SPEC +15 -0
  170. package/core/technology.phone/apps.preinstalled/calendar/calendar.ts +406 -0
  171. package/core/technology.phone/apps.preinstalled/calendar/calendar.ts.SPEC +22 -0
  172. package/core/technology.phone/apps.preinstalled/calendar/holiday-calendar.ts +529 -0
  173. package/core/technology.phone/apps.preinstalled/clock/clock.ts +132 -0
  174. package/core/technology.phone/apps.preinstalled/clock/clock.ts.SPEC +11 -0
  175. package/core/technology.phone/apps.preinstalled/contacts.FUTURE/contacts.ts +300 -0
  176. package/core/technology.phone/apps.preinstalled/contacts.FUTURE/contacts.ts.SPEC +22 -0
  177. package/core/technology.phone/apps.preinstalled/developer.FUTURE/developer.ts +22 -0
  178. package/core/technology.phone/apps.preinstalled/developer.FUTURE/developer.ts.SPEC +15 -0
  179. package/core/technology.phone/apps.preinstalled/notes/notes.ts +239 -0
  180. package/core/technology.phone/apps.preinstalled/notes/notes.ts.SPEC +21 -0
  181. package/core/technology.phone/apps.preinstalled/polymarket/polymarket.ts +261 -0
  182. package/core/technology.phone/apps.preinstalled/polymarket/polymarket.ts.SPEC +7 -0
  183. package/core/technology.phone/apps.preinstalled/reminder/reminder.ts +404 -0
  184. package/core/technology.phone/apps.preinstalled/reminder/reminder.ts.SPEC +25 -0
  185. package/core/technology.phone/apps.preinstalled/siri.FUTURE/siri.ts +22 -0
  186. package/core/technology.phone/apps.preinstalled/siri.FUTURE/siri.ts.SPEC +15 -0
  187. package/core/technology.phone/apps.preinstalled/spotlight/spotlight.ts +29 -0
  188. package/core/technology.phone/apps.preinstalled/spotlight/spotlight.ts.SPEC +7 -0
  189. package/core/technology.phone/apps.preinstalled/steam/chess.ts +230 -0
  190. package/core/technology.phone/apps.preinstalled/steam/snake.ts +100 -0
  191. package/core/technology.phone/apps.preinstalled/steam/snake.ts.SPEC +7 -0
  192. package/core/technology.phone/apps.preinstalled/steam/spy-cmd.ts +4 -0
  193. package/core/technology.phone/apps.preinstalled/steam/spy-tool.ts +56 -0
  194. package/core/technology.phone/apps.preinstalled/steam/spy.ts +302 -0
  195. package/core/technology.phone/apps.preinstalled/steam/steam.ts +299 -0
  196. package/core/technology.phone/apps.preinstalled/weather/weather.ts +50 -0
  197. package/core/technology.phone/apps.preinstalled/weather/weather.ts.SPEC +9 -0
  198. package/core/technology.phone/apps.preinstalled/wechat/imessage.ts +423 -0
  199. package/core/technology.phone/apps.preinstalled/wechat/imessage.ts.SPEC +24 -0
  200. package/core/technology.phone/apps.system/appstore/appstore.ts +22 -0
  201. package/core/technology.phone/apps.system/appstore/appstore.ts.SPEC +15 -0
  202. package/core/technology.phone/apps.system/finder.FUTURE/finder.ts +64 -0
  203. package/core/technology.phone/apps.system/finder.FUTURE/finder.ts.SPEC +8 -0
  204. package/core/technology.phone/apps.system/safari/safari-app.ts +146 -0
  205. package/core/technology.phone/apps.system/safari/safari.ts.SPEC +24 -0
  206. package/core/technology.phone/apps.system/settings/settings.ts +126 -0
  207. package/core/technology.phone/apps.system/settings/settings.ts.SPEC +17 -0
  208. package/core/technology.phone/apps.system/tips/tips.ts +22 -0
  209. package/core/technology.phone/apps.system/tips/tips.ts.SPEC +15 -0
  210. package/core/technology.phone/apps.thirdparty/alipay/alipay.ts +148 -0
  211. package/core/technology.phone/apps.thirdparty/alipay/alipay.ts.SPEC +7 -0
  212. package/core/technology.phone/apps.thirdparty/bilibili/bilibili-app.ts +33 -0
  213. package/core/technology.phone/apps.thirdparty/bilibili/bilibili.ts +142 -0
  214. package/core/technology.phone/apps.thirdparty/bilibili/bilibili.ts.SPEC +22 -0
  215. package/core/technology.phone/apps.thirdparty/wechatread/wechatread.ts +80 -0
  216. package/core/technology.phone/apps.thirdparty/wechatread/wechatread.ts.SPEC +15 -0
  217. package/core/technology.phone/index.ts +1 -0
  218. package/core/technology.phone/package.json +2 -0
  219. package/core/technology.phone/system.homepage/homepage.ts +247 -0
  220. package/core/technology.phone/system.homepage/homepage.ts.SPEC +22 -0
  221. package/core/technology.phone/system.kernel/kernel.ts +264 -0
  222. package/core/technology.phone/system.kernel/kernel.ts.SPEC +7 -0
  223. package/core/technology.phone/system.notifications/notifications.ts +87 -0
  224. package/core/technology.phone/system.notifications/notifications.ts.SPEC +7 -0
  225. package/core/technology.phone/system.share/share.ts +46 -0
  226. package/core/technology.phone/system.share/share.ts.SPEC +7 -0
  227. package/core/technology.server/browser-service.cjs +152 -0
  228. package/core/technology.server/data/cookies/arxiv.json +30 -0
  229. package/core/technology.server/data/cookies/bili.json +184 -0
  230. package/core/technology.server/data/cookies/default.json +30 -0
  231. package/core/technology.server/data/cookies/news.json +113 -0
  232. package/core/technology.server/data/cookies/s1.json +45 -0
  233. package/core/technology.server/data/cookies/safari.json +184 -0
  234. package/core/technology.server/data/cookies/safari2.json +1 -0
  235. package/core/technology.server/data/cookies/safaridbg.json +1 -0
  236. package/core/technology.server/data/cookies/search.json +45 -0
  237. package/core/technology.server/data/cookies/sw.json +30 -0
  238. package/core/technology.server/data/cookies/t1.json +1 -0
  239. package/core/technology.server/data/cookies/testread.json +1 -0
  240. package/core/technology.server/data/cookies/video1.json +113 -0
  241. package/core/technology.server/data/cookies/yt.json +170 -0
  242. package/core/technology.server/data/cookies/yt2.json +113 -0
  243. package/core/technology.server/pikipedia/#pikipedia.BLUEPRINT +106 -0
  244. package/core/technology.server/playleft.cjs +247 -0
  245. package/core/technology.server/search-proxy.py +76 -0
  246. package/core/technology.server/server.README +59 -0
  247. package/deploy/dist-overrides/cli/cli.js +18 -0
  248. package/deploy/dist-overrides/core/extensions/loader.js +518 -0
  249. package/deploy/dist-overrides/core/package-manager.js +2081 -0
  250. package/deploy/dist-overrides/core/system-prompt.js +109 -0
  251. package/deploy/dist-overrides/core/system-prompt.js.LESSON +17 -0
  252. package/deploy/dist-overrides/core/tools/bash.js +353 -0
  253. package/deploy/dist-overrides/core/tools/bash.js.CHANGELOG +2 -0
  254. package/deploy/dist-overrides/core/tools/edit-diff.js +345 -0
  255. package/deploy/dist-overrides/core/tools/edit.js +315 -0
  256. package/deploy/dist-overrides/core/tools/edit.js.CHANGELOG +1 -0
  257. package/deploy/dist-overrides/core/tools/file-mutation-queue.js +52 -0
  258. package/deploy/dist-overrides/core/tools/find.js +298 -0
  259. package/deploy/dist-overrides/core/tools/find.js.CHANGELOG +1 -0
  260. package/deploy/dist-overrides/core/tools/grep.js +305 -0
  261. package/deploy/dist-overrides/core/tools/grep.js.CHANGELOG +1 -0
  262. package/deploy/dist-overrides/core/tools/index.js +112 -0
  263. package/deploy/dist-overrides/core/tools/ls-guard.js +4 -0
  264. package/deploy/dist-overrides/core/tools/ls.js +170 -0
  265. package/deploy/dist-overrides/core/tools/ls.js.CHANGELOG +1 -0
  266. package/deploy/dist-overrides/core/tools/output-accumulator.js +184 -0
  267. package/deploy/dist-overrides/core/tools/path-utils.js +99 -0
  268. package/deploy/dist-overrides/core/tools/prompts-reader.js +53 -0
  269. package/deploy/dist-overrides/core/tools/read.js +392 -0
  270. package/deploy/dist-overrides/core/tools/read.js.CHANGELOG +1 -0
  271. package/deploy/dist-overrides/core/tools/render-utils.js +65 -0
  272. package/deploy/dist-overrides/core/tools/tool-definition-wrapper.js +34 -0
  273. package/deploy/dist-overrides/core/tools/truncate.js +215 -0
  274. package/deploy/dist-overrides/core/tools/write.js +203 -0
  275. package/deploy/dist-overrides/core/tools/write.js.CHANGELOG +1 -0
  276. package/deploy/dist-overrides/dist-overrides.README +18 -0
  277. package/deploy/dist-overrides/main.js +665 -0
  278. package/deploy/dist-overrides/modes/interactive/components/assistant-message.js +139 -0
  279. package/deploy/dist-overrides/modes/interactive/components/footer.js +326 -0
  280. package/deploy/dist-overrides/modes/interactive/components/model-selector.js +285 -0
  281. package/deploy/dist-overrides/modes/interactive/components/tool-execution.js +383 -0
  282. package/deploy/dist-overrides/modes/interactive/components/tool-execution.js.CHANGELOG +3 -0
  283. package/deploy/dist-overrides/modes/interactive/interactive-mode.js +4781 -0
  284. package/deploy/dist-overrides/pi-ai/providers/anthropic.js +931 -0
  285. package/deploy/dist-overrides/pi-ai/providers/openai-completions.js +1007 -0
  286. package/deploy/dist-overrides/pi-ai/providers/openai-completions.js.LESSON +15 -0
  287. package/deploy/dist-overrides/pi-tui/components/loader.js +69 -0
  288. package/deploy/dist-overrides/pi-tui/components/markdown.js +646 -0
  289. package/deploy/dist-overrides/pi-tui/components/text.js +92 -0
  290. package/deploy/dist-overrides/pi-tui/custom-message.js +75 -0
  291. package/deploy/dist-overrides/pi-tui/tui.js +1266 -0
  292. package/deploy/dist-overrides/pi-tui/utils.js +1060 -0
  293. package/deploy/dist-overrides/vendor.REMOVED/jiti/lib/jiti.mjs +3 -0
  294. package/deploy/install.sh +186 -0
  295. package/deploy/install.sh.CHANGELOG +6 -0
  296. package/deploy/lint/lint-naming.ts +202 -0
  297. package/deploy/scripts/apply.js +18 -0
  298. package/deploy/scripts/build-github.sh +219 -0
  299. package/deploy/scripts/build-phone.sh +24 -0
  300. package/deploy/scripts/check-deploy.sh +42 -0
  301. package/deploy/scripts/migrate-context.sh +72 -0
  302. package/deploy/scripts/patch-pi-dist.js +39 -0
  303. package/deploy/scripts/uninstall.sh +34 -0
  304. package/package.json +18 -0
@@ -0,0 +1,52 @@
1
+ import { realpath } from "node:fs/promises";
2
+ import { resolve } from "node:path";
3
+ const fileMutationQueues = new Map();
4
+ let registrationQueue = Promise.resolve();
5
+ function isMissingPathError(error) {
6
+ return (typeof error === "object" &&
7
+ error !== null &&
8
+ "code" in error &&
9
+ (error.code === "ENOENT" || error.code === "ENOTDIR"));
10
+ }
11
+ async function getMutationQueueKey(filePath) {
12
+ const resolvedPath = resolve(filePath);
13
+ try {
14
+ return await realpath(resolvedPath);
15
+ }
16
+ catch (error) {
17
+ if (isMissingPathError(error)) {
18
+ return resolvedPath;
19
+ }
20
+ throw error;
21
+ }
22
+ }
23
+ /**
24
+ * Serialize file mutation operations targeting the same file.
25
+ * Operations for different files still run in parallel.
26
+ */
27
+ export async function withFileMutationQueue(filePath, fn) {
28
+ const registration = registrationQueue.then(async () => {
29
+ const key = await getMutationQueueKey(filePath);
30
+ const currentQueue = fileMutationQueues.get(key) ?? Promise.resolve();
31
+ let releaseNext;
32
+ const nextQueue = new Promise((resolveQueue) => {
33
+ releaseNext = resolveQueue;
34
+ });
35
+ const chainedQueue = currentQueue.then(() => nextQueue);
36
+ fileMutationQueues.set(key, chainedQueue);
37
+ return { key, currentQueue, chainedQueue, releaseNext };
38
+ });
39
+ registrationQueue = registration.then(() => undefined, () => undefined);
40
+ const { key, currentQueue, chainedQueue, releaseNext } = await registration;
41
+ await currentQueue;
42
+ try {
43
+ return await fn();
44
+ }
45
+ finally {
46
+ releaseNext();
47
+ if (fileMutationQueues.get(key) === chainedQueue) {
48
+ fileMutationQueues.delete(key);
49
+ }
50
+ }
51
+ }
52
+ //# sourceMappingURL=file-mutation-queue.js.map
@@ -0,0 +1,298 @@
1
+ import { createInterface } from "node:readline";
2
+ import { Text } from "@earendil-works/pi-tui";
3
+ import { spawn } from "child_process";
4
+ import path from "path";
5
+ import { Type } from "typebox";
6
+ import { getToolPrompt } from "./prompts-reader.js";
7
+ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
8
+ import { ensureTool } from "../../utils/tools-manager.js";
9
+ import { pathExists, resolveToCwd } from "./path-utils.js";
10
+ import { getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
11
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
12
+ import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
13
+ function toPosixPath(value) {
14
+ return value.split(path.sep).join("/");
15
+ }
16
+ const findSchema = Type.Object({
17
+ pattern: Type.String({
18
+ messageDescription: "Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'",
19
+ }),
20
+ path: Type.Optional(Type.String({ messageDescription: "Directory to search in (default: current directory)" })),
21
+ limit: Type.Optional(Type.Number({ messageDescription: "Maximum number of results (default: 1000)" })),
22
+ });
23
+ const DEFAULT_LIMIT = 1000;
24
+ const defaultFindOperations = {
25
+ exists: pathExists,
26
+ // This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.
27
+ glob: () => [],
28
+ };
29
+ function formatFindCall(args, theme) {
30
+ const pattern = str(args?.pattern);
31
+ const rawPath = str(args?.path);
32
+ const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
33
+ const limit = args?.limit;
34
+ const invalidArg = invalidArgText(theme);
35
+ let text = `${theme.fg("toolTitle", "● " + theme.bold("Find"))}` +
36
+ " " +
37
+ (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) +
38
+ theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
39
+ if (limit !== undefined) {
40
+ text += theme.fg("toolOutput", ` (limit ${limit})`);
41
+ }
42
+ return text;
43
+ }
44
+ function formatFindResult(result, options, theme, showImages) {
45
+ const output = getTextOutput(result, showImages).trim();
46
+ let text = "";
47
+ if (output) {
48
+ const lines = output.split("\n");
49
+ const maxLines = options.expanded ? lines.length : 20;
50
+ const displayLines = lines.slice(0, maxLines);
51
+ const remaining = lines.length - maxLines;
52
+ text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
53
+ if (remaining > 0) {
54
+ text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
55
+ }
56
+ }
57
+ const resultLimit = result.details?.resultLimitReached;
58
+ const truncation = result.details?.truncation;
59
+ if (resultLimit || truncation?.truncated) {
60
+ const warnings = [];
61
+ if (resultLimit)
62
+ warnings.push(`${resultLimit} results limit`);
63
+ if (truncation?.truncated)
64
+ warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
65
+ text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
66
+ }
67
+ return text;
68
+ }
69
+ export function createFindToolDefinition(cwd, options) {
70
+ const customOps = options?.operations;
71
+ return {
72
+ name: "find",
73
+ label: "find",
74
+ messageDescription: (getToolPrompt('find', 'messageDescription') || '').replace('{{DEFAULT_LIMIT}}', String(DEFAULT_LIMIT)).replace('{{DEFAULT_MAX_BYTES_KB}}', String(DEFAULT_MAX_BYTES / 1024)),
75
+ promptSnippet: getToolPrompt('find', 'snippet'),
76
+ parameters: findSchema,
77
+ async execute(_toolCallId, { pattern, path: searchDir, limit }, signal, _onUpdate, _ctx) {
78
+ return new Promise((resolve, reject) => {
79
+ if (signal?.aborted) {
80
+ reject(new Error("Operation aborted"));
81
+ return;
82
+ }
83
+ let settled = false;
84
+ let stopChild;
85
+ const settle = (fn) => {
86
+ if (settled)
87
+ return;
88
+ settled = true;
89
+ signal?.removeEventListener("abort", onAbort);
90
+ stopChild = undefined;
91
+ fn();
92
+ };
93
+ const onAbort = () => {
94
+ stopChild?.();
95
+ settle(() => reject(new Error("Operation aborted")));
96
+ };
97
+ signal?.addEventListener("abort", onAbort, { once: true });
98
+ (async () => {
99
+ try {
100
+ const searchPath = resolveToCwd(searchDir || ".", cwd);
101
+ const effectiveLimit = limit ?? DEFAULT_LIMIT;
102
+ const ops = customOps ?? defaultFindOperations;
103
+ // If custom operations provide glob(), use that instead of fd.
104
+ if (customOps?.glob) {
105
+ if (!(await ops.exists(searchPath))) {
106
+ settle(() => reject(new Error(`Path not found: ${searchPath}`)));
107
+ return;
108
+ }
109
+ if (signal?.aborted) {
110
+ settle(() => reject(new Error("Operation aborted")));
111
+ return;
112
+ }
113
+ const results = await ops.glob(pattern, searchPath, {
114
+ ignore: ["**/node_modules/**", "**/.git/**"],
115
+ limit: effectiveLimit,
116
+ });
117
+ if (signal?.aborted) {
118
+ settle(() => reject(new Error("Operation aborted")));
119
+ return;
120
+ }
121
+ if (results.length === 0) {
122
+ settle(() => resolve({
123
+ content: [{ type: "text", text: "No files found matching pattern" }],
124
+ details: undefined,
125
+ }));
126
+ return;
127
+ }
128
+ // Relativize paths against the search root for stable output.
129
+ const relativized = results.map((p) => {
130
+ if (p.startsWith(searchPath))
131
+ return toPosixPath(p.slice(searchPath.length + 1));
132
+ return toPosixPath(path.relative(searchPath, p));
133
+ });
134
+ const resultLimitReached = relativized.length >= effectiveLimit;
135
+ const rawOutput = relativized.join("\n");
136
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
137
+ let resultOutput = truncation.content;
138
+ const details = {};
139
+ const notices = [];
140
+ if (resultLimitReached) {
141
+ notices.push(`${effectiveLimit} results limit reached`);
142
+ details.resultLimitReached = effectiveLimit;
143
+ }
144
+ if (truncation.truncated) {
145
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
146
+ details.truncation = truncation;
147
+ }
148
+ if (notices.length > 0) {
149
+ resultOutput += `\n\n[${notices.join(". ")}]`;
150
+ }
151
+ settle(() => resolve({
152
+ content: [{ type: "text", text: resultOutput }],
153
+ details: Object.keys(details).length > 0 ? details : undefined,
154
+ }));
155
+ return;
156
+ }
157
+ // Default implementation uses fd.
158
+ const fdPath = await ensureTool("fd", true);
159
+ if (signal?.aborted) {
160
+ settle(() => reject(new Error("Operation aborted")));
161
+ return;
162
+ }
163
+ if (!fdPath) {
164
+ settle(() => reject(new Error("fd is not available and could not be downloaded")));
165
+ return;
166
+ }
167
+ // Build fd arguments. --no-require-git makes fd apply hierarchical .gitignore
168
+ // semantics whether or not the search path is inside a git repository, without
169
+ // leaking sibling-directory rules the way --ignore-file (a global source) would.
170
+ const args = [
171
+ "--glob",
172
+ "--color=never",
173
+ "--hidden",
174
+ "--no-require-git",
175
+ "--max-results",
176
+ String(effectiveLimit),
177
+ ];
178
+ // fd --glob matches against the basename unless --full-path is set; in --full-path
179
+ // mode it matches against the absolute candidate path, so a path-containing
180
+ // pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.
181
+ let effectivePattern = pattern;
182
+ if (pattern.includes("/")) {
183
+ args.push("--full-path");
184
+ if (!pattern.startsWith("/") && !pattern.startsWith("**/") && pattern !== "**") {
185
+ effectivePattern = `**/${pattern}`;
186
+ }
187
+ }
188
+ args.push("--", effectivePattern, searchPath);
189
+ const child = spawn(fdPath, args, { stdio: ["ignore", "pipe", "pipe"] });
190
+ const rl = createInterface({ input: child.stdout });
191
+ let stderr = "";
192
+ const lines = [];
193
+ stopChild = () => {
194
+ if (!child.killed) {
195
+ child.kill();
196
+ }
197
+ };
198
+ const cleanup = () => {
199
+ rl.close();
200
+ };
201
+ child.stderr?.on("data", (chunk) => {
202
+ stderr += chunk.toString();
203
+ });
204
+ rl.on("line", (line) => {
205
+ lines.push(line);
206
+ });
207
+ child.on("error", (error) => {
208
+ cleanup();
209
+ settle(() => reject(new Error(`Failed to run fd: ${error.message}`)));
210
+ });
211
+ child.on("close", (code) => {
212
+ cleanup();
213
+ if (signal?.aborted) {
214
+ settle(() => reject(new Error("Operation aborted")));
215
+ return;
216
+ }
217
+ const output = lines.join("\n");
218
+ if (code !== 0) {
219
+ const errorMsg = stderr.trim() || `fd exited with code ${code}`;
220
+ if (!output) {
221
+ settle(() => reject(new Error(errorMsg)));
222
+ return;
223
+ }
224
+ }
225
+ if (!output) {
226
+ settle(() => resolve({
227
+ content: [{ type: "text", text: "No files found matching pattern" }],
228
+ details: undefined,
229
+ }));
230
+ return;
231
+ }
232
+ const relativized = [];
233
+ for (const rawLine of lines) {
234
+ const line = rawLine.replace(/\r$/, "").trim();
235
+ if (!line)
236
+ continue;
237
+ const hadTrailingSlash = line.endsWith("/") || line.endsWith("\\");
238
+ let relativePath = line;
239
+ if (line.startsWith(searchPath)) {
240
+ relativePath = line.slice(searchPath.length + 1);
241
+ }
242
+ else {
243
+ relativePath = path.relative(searchPath, line);
244
+ }
245
+ if (hadTrailingSlash && !relativePath.endsWith("/"))
246
+ relativePath += "/";
247
+ relativized.push(toPosixPath(relativePath));
248
+ }
249
+ const resultLimitReached = relativized.length >= effectiveLimit;
250
+ const rawOutput = relativized.join("\n");
251
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
252
+ let resultOutput = truncation.content;
253
+ const details = {};
254
+ const notices = [];
255
+ if (resultLimitReached) {
256
+ notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);
257
+ details.resultLimitReached = effectiveLimit;
258
+ }
259
+ if (truncation.truncated) {
260
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
261
+ details.truncation = truncation;
262
+ }
263
+ if (notices.length > 0) {
264
+ resultOutput += `\n\n[${notices.join(". ")}]`;
265
+ }
266
+ settle(() => resolve({
267
+ content: [{ type: "text", text: resultOutput }],
268
+ details: Object.keys(details).length > 0 ? details : undefined,
269
+ }));
270
+ });
271
+ }
272
+ catch (e) {
273
+ if (signal?.aborted) {
274
+ settle(() => reject(new Error("Operation aborted")));
275
+ return;
276
+ }
277
+ const error = e instanceof Error ? e : new Error(String(e));
278
+ settle(() => reject(error));
279
+ }
280
+ })();
281
+ });
282
+ },
283
+ renderCall(args, theme, context) {
284
+ const text = context.lastComponent ?? new Text("", 0, 0);
285
+ text.setText(formatFindCall(args, theme));
286
+ return text;
287
+ },
288
+ renderResult(result, options, theme, context) {
289
+ const text = context.lastComponent ?? new Text("", 2, 0);
290
+ text.setText(formatFindResult(result, options, theme, context.showImages));
291
+ return text;
292
+ },
293
+ };
294
+ }
295
+ export function createFindTool(cwd, options) {
296
+ return wrapToolDefinition(createFindToolDefinition(cwd, options));
297
+ }
298
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ [2026-06-19] 工具名首字母大写
@@ -0,0 +1,305 @@
1
+ import { readFile as fsReadFile, stat as fsStat } from "node:fs/promises";
2
+ import { createInterface } from "node:readline";
3
+ import { Text } from "@earendil-works/pi-tui";
4
+ import { spawn } from "child_process";
5
+ import path from "path";
6
+ import { Type } from "typebox";
7
+ import { getToolPrompt } from "./prompts-reader.js";
8
+ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
9
+ import { ensureTool } from "../../utils/tools-manager.js";
10
+ import { resolveToCwd } from "./path-utils.js";
11
+ import { getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
12
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
13
+ import { DEFAULT_MAX_BYTES, formatSize, GREP_MAX_LINE_LENGTH, truncateHead, truncateLine, } from "./truncate.js";
14
+ const grepSchema = Type.Object({
15
+ pattern: Type.String({ messageDescription: "Search pattern (regex or literal string)" }),
16
+ path: Type.Optional(Type.String({ messageDescription: "Directory or file to search (default: current directory)" })),
17
+ glob: Type.Optional(Type.String({ messageDescription: "Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'" })),
18
+ ignoreCase: Type.Optional(Type.Boolean({ messageDescription: "Case-insensitive search (default: false)" })),
19
+ literal: Type.Optional(Type.Boolean({ messageDescription: "Treat pattern as literal string instead of regex (default: false)" })),
20
+ context: Type.Optional(Type.Number({ messageDescription: "Number of lines to show before and after each match (default: 0)" })),
21
+ limit: Type.Optional(Type.Number({ messageDescription: "Maximum number of matches to return (default: 100)" })),
22
+ });
23
+ const DEFAULT_LIMIT = 100;
24
+ const defaultGrepOperations = {
25
+ isDirectory: async (p) => (await fsStat(p)).isDirectory(),
26
+ readFile: (p) => fsReadFile(p, "utf-8"),
27
+ };
28
+ function formatGrepCall(args, theme) {
29
+ const pattern = str(args?.pattern);
30
+ const rawPath = str(args?.path);
31
+ const path = rawPath !== null ? shortenPath(rawPath || ".") : null;
32
+ const glob = str(args?.glob);
33
+ const limit = args?.limit;
34
+ const invalidArg = invalidArgText(theme);
35
+ let text = `${theme.fg("toolTitle", "● " + theme.bold("Grep"))}` +
36
+ " " +
37
+ (pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) +
38
+ theme.fg("toolOutput", ` in ${path === null ? invalidArg : path}`);
39
+ if (glob)
40
+ text += theme.fg("toolOutput", ` (${glob})`);
41
+ if (limit !== undefined)
42
+ text += theme.fg("toolOutput", ` limit ${limit}`);
43
+ return text;
44
+ }
45
+ function formatGrepResult(result, options, theme, showImages) {
46
+ const output = getTextOutput(result, showImages).trim();
47
+ let text = "";
48
+ if (output) {
49
+ const lines = output.split("\n");
50
+ const maxLines = options.expanded ? lines.length : 15;
51
+ const displayLines = lines.slice(0, maxLines);
52
+ const remaining = lines.length - maxLines;
53
+ text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
54
+ if (remaining > 0) {
55
+ text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("app.tools.expand", "to expand")}${theme.fg("muted", ")")}`;
56
+ }
57
+ }
58
+ const matchLimit = result.details?.matchLimitReached;
59
+ const truncation = result.details?.truncation;
60
+ const linesTruncated = result.details?.linesTruncated;
61
+ if (matchLimit || truncation?.truncated || linesTruncated) {
62
+ const warnings = [];
63
+ if (matchLimit)
64
+ warnings.push(`${matchLimit} matches limit`);
65
+ if (truncation?.truncated)
66
+ warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);
67
+ if (linesTruncated)
68
+ warnings.push("some lines truncated");
69
+ text += `\n${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
70
+ }
71
+ return text;
72
+ }
73
+ export function createGrepToolDefinition(cwd, options) {
74
+ const customOps = options?.operations;
75
+ return {
76
+ name: "grep",
77
+ label: "grep",
78
+ messageDescription: (getToolPrompt('grep', 'messageDescription') || '').replace('{{DEFAULT_LIMIT}}', String(DEFAULT_LIMIT)).replace('{{DEFAULT_MAX_BYTES_KB}}', String(DEFAULT_MAX_BYTES / 1024)).replace('{{GREP_MAX_LINE_LENGTH}}', String(GREP_MAX_LINE_LENGTH)),
79
+ promptSnippet: getToolPrompt('grep', 'snippet'),
80
+ parameters: grepSchema,
81
+ async execute(_toolCallId, { pattern, path: searchDir, glob, ignoreCase, literal, context, limit, }, signal, _onUpdate, _ctx) {
82
+ return new Promise((resolve, reject) => {
83
+ if (signal?.aborted) {
84
+ reject(new Error("Operation aborted"));
85
+ return;
86
+ }
87
+ let settled = false;
88
+ const settle = (fn) => {
89
+ if (!settled) {
90
+ settled = true;
91
+ fn();
92
+ }
93
+ };
94
+ (async () => {
95
+ try {
96
+ const rgPath = await ensureTool("rg", true);
97
+ if (!rgPath) {
98
+ settle(() => reject(new Error("ripgrep (rg) is not available and could not be downloaded")));
99
+ return;
100
+ }
101
+ const searchPath = resolveToCwd(searchDir || ".", cwd);
102
+ const ops = customOps ?? defaultGrepOperations;
103
+ let isDirectory;
104
+ try {
105
+ isDirectory = await ops.isDirectory(searchPath);
106
+ }
107
+ catch {
108
+ settle(() => reject(new Error(`Path not found: ${searchPath}`)));
109
+ return;
110
+ }
111
+ const contextValue = context && context > 0 ? context : 0;
112
+ const effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);
113
+ const formatPath = (filePath) => {
114
+ if (isDirectory) {
115
+ const relative = path.relative(searchPath, filePath);
116
+ if (relative && !relative.startsWith("..")) {
117
+ return relative.replace(/\\/g, "/");
118
+ }
119
+ }
120
+ return path.basename(filePath);
121
+ };
122
+ const fileCache = new Map();
123
+ const getFileLines = async (filePath) => {
124
+ let lines = fileCache.get(filePath);
125
+ if (!lines) {
126
+ try {
127
+ const content = await ops.readFile(filePath);
128
+ lines = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
129
+ }
130
+ catch {
131
+ lines = [];
132
+ }
133
+ fileCache.set(filePath, lines);
134
+ }
135
+ return lines;
136
+ };
137
+ const args = ["--json", "--line-number", "--color=never", "--hidden"];
138
+ if (ignoreCase)
139
+ args.push("--ignore-case");
140
+ if (literal)
141
+ args.push("--fixed-strings");
142
+ if (glob)
143
+ args.push("--glob", glob);
144
+ args.push("--", pattern, searchPath);
145
+ const child = spawn(rgPath, args, { stdio: ["ignore", "pipe", "pipe"] });
146
+ const rl = createInterface({ input: child.stdout });
147
+ let stderr = "";
148
+ let matchCount = 0;
149
+ let matchLimitReached = false;
150
+ let linesTruncated = false;
151
+ let aborted = false;
152
+ let killedDueToLimit = false;
153
+ const outputLines = [];
154
+ const cleanup = () => {
155
+ rl.close();
156
+ signal?.removeEventListener("abort", onAbort);
157
+ };
158
+ const stopChild = (dueToLimit = false) => {
159
+ if (!child.killed) {
160
+ killedDueToLimit = dueToLimit;
161
+ child.kill();
162
+ }
163
+ };
164
+ const onAbort = () => {
165
+ aborted = true;
166
+ stopChild();
167
+ };
168
+ signal?.addEventListener("abort", onAbort, { once: true });
169
+ child.stderr?.on("data", (chunk) => {
170
+ stderr += chunk.toString();
171
+ });
172
+ const formatBlock = async (filePath, lineNumber) => {
173
+ const relativePath = formatPath(filePath);
174
+ const lines = await getFileLines(filePath);
175
+ if (!lines.length)
176
+ return [`${relativePath}:${lineNumber}: (unable to read file)`];
177
+ const block = [];
178
+ const start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;
179
+ const end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;
180
+ for (let current = start; current <= end; current++) {
181
+ const lineText = lines[current - 1] ?? "";
182
+ const sanitized = lineText.replace(/\r/g, "");
183
+ const isMatchLine = current === lineNumber;
184
+ // Truncate long lines so grep output stays compact.
185
+ const { text: truncatedText, wasTruncated } = truncateLine(sanitized);
186
+ if (wasTruncated)
187
+ linesTruncated = true;
188
+ if (isMatchLine)
189
+ block.push(`${relativePath}:${current}: ${truncatedText}`);
190
+ else
191
+ block.push(`${relativePath}-${current}- ${truncatedText}`);
192
+ }
193
+ return block;
194
+ };
195
+ // Collect matches during streaming, then format them after rg exits.
196
+ const matches = [];
197
+ rl.on("line", (line) => {
198
+ if (!line.trim() || matchCount >= effectiveLimit)
199
+ return;
200
+ let event;
201
+ try {
202
+ event = JSON.parse(line);
203
+ }
204
+ catch {
205
+ return;
206
+ }
207
+ if (event.type === "match") {
208
+ matchCount++;
209
+ const filePath = event.data?.path?.text;
210
+ const lineNumber = event.data?.line_number;
211
+ const lineText = event.data?.lines?.text;
212
+ if (filePath && typeof lineNumber === "number")
213
+ matches.push({ filePath, lineNumber, lineText });
214
+ if (matchCount >= effectiveLimit) {
215
+ matchLimitReached = true;
216
+ stopChild(true);
217
+ }
218
+ }
219
+ });
220
+ child.on("error", (error) => {
221
+ cleanup();
222
+ settle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));
223
+ });
224
+ child.on("close", async (code) => {
225
+ cleanup();
226
+ if (aborted) {
227
+ settle(() => reject(new Error("Operation aborted")));
228
+ return;
229
+ }
230
+ if (!killedDueToLimit && code !== 0 && code !== 1) {
231
+ const errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;
232
+ settle(() => reject(new Error(errorMsg)));
233
+ return;
234
+ }
235
+ if (matchCount === 0) {
236
+ settle(() => resolve({ content: [{ type: "text", text: "No matches found" }], details: undefined }));
237
+ return;
238
+ }
239
+ // Format matches after streaming finishes so custom readFile() backends can be async.
240
+ for (const match of matches) {
241
+ if (contextValue === 0 && match.lineText !== undefined) {
242
+ const relativePath = formatPath(match.filePath);
243
+ const sanitized = match.lineText
244
+ .replace(/\r\n/g, "\n")
245
+ .replace(/\r/g, "")
246
+ .replace(/\n$/, "");
247
+ const { text: truncatedText, wasTruncated } = truncateLine(sanitized);
248
+ if (wasTruncated)
249
+ linesTruncated = true;
250
+ outputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);
251
+ }
252
+ else {
253
+ const block = await formatBlock(match.filePath, match.lineNumber);
254
+ outputLines.push(...block);
255
+ }
256
+ }
257
+ const rawOutput = outputLines.join("\n");
258
+ // Apply byte truncation. There is no line limit here because the match limit already capped rows.
259
+ const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
260
+ let output = truncation.content;
261
+ const details = {};
262
+ // Build actionable notices for truncation and match limits.
263
+ const notices = [];
264
+ if (matchLimitReached) {
265
+ notices.push(`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);
266
+ details.matchLimitReached = effectiveLimit;
267
+ }
268
+ if (truncation.truncated) {
269
+ notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
270
+ details.truncation = truncation;
271
+ }
272
+ if (linesTruncated) {
273
+ notices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`);
274
+ details.linesTruncated = true;
275
+ }
276
+ if (notices.length > 0)
277
+ output += `\n\n[${notices.join(". ")}]`;
278
+ settle(() => resolve({
279
+ content: [{ type: "text", text: output }],
280
+ details: Object.keys(details).length > 0 ? details : undefined,
281
+ }));
282
+ });
283
+ }
284
+ catch (err) {
285
+ settle(() => reject(err));
286
+ }
287
+ })();
288
+ });
289
+ },
290
+ renderCall(args, theme, context) {
291
+ const text = context.lastComponent ?? new Text("", 0, 0);
292
+ text.setText(formatGrepCall(args, theme));
293
+ return text;
294
+ },
295
+ renderResult(result, options, theme, context) {
296
+ const text = context.lastComponent ?? new Text("", 2, 0);
297
+ text.setText(formatGrepResult(result, options, theme, context.showImages));
298
+ return text;
299
+ },
300
+ };
301
+ }
302
+ export function createGrepTool(cwd, options) {
303
+ return wrapToolDefinition(createGrepToolDefinition(cwd, options));
304
+ }
305
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ [2026-06-19] 工具名首字母大写