chattool 7.0.1__tar.gz → 7.0.3__tar.gz

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 (201) hide show
  1. {chattool-7.0.1/src/chattool.egg-info → chattool-7.0.3}/PKG-INFO +11 -1
  2. {chattool-7.0.1 → chattool-7.0.3}/README.md +10 -0
  3. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/__init__.py +1 -1
  4. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/serve/cli.py +8 -0
  5. chattool-7.0.3/src/chattool/serve/local.py +109 -0
  6. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/pypi/main.py +36 -23
  7. {chattool-7.0.1 → chattool-7.0.3/src/chattool.egg-info}/PKG-INFO +11 -1
  8. {chattool-7.0.1 → chattool-7.0.3}/src/chattool.egg-info/SOURCES.txt +1 -0
  9. {chattool-7.0.1 → chattool-7.0.3}/LICENSE +0 -0
  10. {chattool-7.0.1 → chattool-7.0.3}/MANIFEST.in +0 -0
  11. {chattool-7.0.1 → chattool-7.0.3}/pyproject.toml +0 -0
  12. {chattool-7.0.1 → chattool-7.0.3}/scripts/migrate_chattool_envs_to_chatarch.py +0 -0
  13. {chattool-7.0.1 → chattool-7.0.3}/setup.cfg +0 -0
  14. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/_all.py +0 -0
  15. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/client/__init__.py +0 -0
  16. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/client/cert_client.py +0 -0
  17. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/client/main.py +0 -0
  18. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/client/svg2gif_client.py +0 -0
  19. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/__init__.py +0 -0
  20. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/aliyun.py +0 -0
  21. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/azure.py +0 -0
  22. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/base.py +0 -0
  23. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/browser.py +0 -0
  24. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/crs.py +0 -0
  25. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/elements.py +0 -0
  26. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/feishu.py +0 -0
  27. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/github.py +0 -0
  28. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/huggingface.py +0 -0
  29. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/liblib.py +0 -0
  30. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/openai.py +0 -0
  31. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/pollinations.py +0 -0
  32. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/siliconflow.py +0 -0
  33. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/skills.py +0 -0
  34. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/tencent.py +0 -0
  35. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/tongyi.py +0 -0
  36. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/tplink.py +0 -0
  37. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/config/zulip.py +0 -0
  38. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/const.py +0 -0
  39. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/docker/__init__.py +0 -0
  40. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/docker/cli.py +0 -0
  41. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/docker/elements.py +0 -0
  42. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/docker/main.py +0 -0
  43. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/__init__.py +0 -0
  44. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/__init__.py +0 -0
  45. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/cli.py +0 -0
  46. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/client.py +0 -0
  47. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/daily.py +0 -0
  48. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/harvest.py +0 -0
  49. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/models.py +0 -0
  50. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/presets.py +0 -0
  51. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/arxiv/query.py +0 -0
  52. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/cli.py +0 -0
  53. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/github/__init__.py +0 -0
  54. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/github/client.py +0 -0
  55. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/github/models.py +0 -0
  56. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/wordpress/__init__.py +0 -0
  57. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/wordpress/client.py +0 -0
  58. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/explore/wordpress/models.py +0 -0
  59. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/interaction/__init__.py +0 -0
  60. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/interaction/command_schema.py +0 -0
  61. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/interaction/policy.py +0 -0
  62. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/interaction/warnings.py +0 -0
  63. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/llm/__init__.py +0 -0
  64. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/llm/chattype.py +0 -0
  65. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/llm/response.py +0 -0
  66. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/mcp/__init__.py +0 -0
  67. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/mcp/catalog.py +0 -0
  68. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/mcp/cli.py +0 -0
  69. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/mcp/server.py +0 -0
  70. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/serve/__init__.py +0 -0
  71. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/serve/capture.py +0 -0
  72. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/serve/cert_server.py +0 -0
  73. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/serve/lark_serve.py +0 -0
  74. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/serve/svg2gif.py +0 -0
  75. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/__init__.py +0 -0
  76. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/alias.py +0 -0
  77. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/hermes/install.sh +0 -0
  78. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/nvm.sh +0 -0
  79. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/README.md +0 -0
  80. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/commands/chatloop-help.md +0 -0
  81. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/commands/chatloop-project.md +0 -0
  82. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/commands/chatloop-status.md +0 -0
  83. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/commands/chatloop-stop.md +0 -0
  84. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/commands/chatloop.md +0 -0
  85. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/plugins/chatloop/index.ts +0 -0
  86. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/assets/opencode_chatloop/plugins/chatloop/package.json +0 -0
  87. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/cc_connect.py +0 -0
  88. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/chrome.py +0 -0
  89. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/claude.py +0 -0
  90. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/cli.py +0 -0
  91. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/codex.py +0 -0
  92. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/docker.py +0 -0
  93. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/elements.py +0 -0
  94. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/frp.py +0 -0
  95. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/hermes.py +0 -0
  96. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/lark_cli.py +0 -0
  97. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/mode_prompt.py +0 -0
  98. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/nodejs.py +0 -0
  99. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/opencode.py +0 -0
  100. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/opencode_chatloop.py +0 -0
  101. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/__init__.py +0 -0
  102. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/cli.py +0 -0
  103. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/core.py +0 -0
  104. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/options.py +0 -0
  105. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/render.py +0 -0
  106. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/templates/default/en/AGENTS.md +0 -0
  107. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/templates/default/en/projects/README.md +0 -0
  108. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/templates/default/zh/AGENTS.md +0 -0
  109. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace/templates/default/zh/projects/README.md +0 -0
  110. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/workspace.py +0 -0
  111. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/setup/zsh.py +0 -0
  112. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/skill/__init__.py +0 -0
  113. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/skill/cli.py +0 -0
  114. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/skill/interaction.py +0 -0
  115. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/skill/platforms.py +0 -0
  116. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/skill/validation.py +0 -0
  117. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/__init__.py +0 -0
  118. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/__init__.py +0 -0
  119. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/base.py +0 -0
  120. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/cli.py +0 -0
  121. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/playwright_impl.py +0 -0
  122. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/selenium.py +0 -0
  123. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/test_browser.py +0 -0
  124. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/test_module.py +0 -0
  125. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/test_remote.py +0 -0
  126. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/browser/xhs_qrcode.py +0 -0
  127. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cc/__init__.py +0 -0
  128. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cc/cli.py +0 -0
  129. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cert/__init__.py +0 -0
  130. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cert/acme_dns_tiny.py +0 -0
  131. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cert/cert_server.py +0 -0
  132. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cert/cert_updater.py +0 -0
  133. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cert/cli.py +0 -0
  134. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/cert/email.py +0 -0
  135. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/crs/__init__.py +0 -0
  136. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/crs/api.py +0 -0
  137. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/crs/cli.py +0 -0
  138. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/__init__.py +0 -0
  139. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/aliyun.py +0 -0
  140. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/base.py +0 -0
  141. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/cli.py +0 -0
  142. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/domain_utils.py +0 -0
  143. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/ip_updater.py +0 -0
  144. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/mcp.py +0 -0
  145. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/tencent.py +0 -0
  146. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/dns/utils.py +0 -0
  147. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/__init__.py +0 -0
  148. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/api.py +0 -0
  149. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/cli.py +0 -0
  150. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/client.py +0 -0
  151. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/commands.py +0 -0
  152. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/render.py +0 -0
  153. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/github/requests.py +0 -0
  154. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/__init__.py +0 -0
  155. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/base.py +0 -0
  156. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/cli.py +0 -0
  157. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/helpers.py +0 -0
  158. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/huggingface.py +0 -0
  159. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/liblib.py +0 -0
  160. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/pollinations.py +0 -0
  161. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/siliconflow.py +0 -0
  162. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/image/tongyi.py +0 -0
  163. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/interact.py +0 -0
  164. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/__init__.py +0 -0
  165. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/bot.py +0 -0
  166. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/cli.py +0 -0
  167. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/context.py +0 -0
  168. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/docx_blocks.py +0 -0
  169. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/elements.py +0 -0
  170. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/markdown_blocks.py +0 -0
  171. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/lark/session.py +0 -0
  172. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/network/__init__.py +0 -0
  173. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/network/cli.py +0 -0
  174. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/network/link_check.py +0 -0
  175. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/network/mcp.py +0 -0
  176. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/network/scanner.py +0 -0
  177. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/network/service_urls.py +0 -0
  178. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/nginx/__init__.py +0 -0
  179. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/nginx/cli.py +0 -0
  180. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/nginx/templates.py +0 -0
  181. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/pypi/__init__.py +0 -0
  182. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/pypi/cli.py +0 -0
  183. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/tplogin.py +0 -0
  184. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/tplogin_cli.py +0 -0
  185. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/zulip/__init__.py +0 -0
  186. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/zulip/cli.py +0 -0
  187. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/zulip/client.py +0 -0
  188. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/zulip/legacy.py +0 -0
  189. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/tools/zulip/mcp.py +0 -0
  190. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/__init__.py +0 -0
  191. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/basic.py +0 -0
  192. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/custom_logger.py +0 -0
  193. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/fastobj.py +0 -0
  194. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/httpclient.py +0 -0
  195. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/pathing.py +0 -0
  196. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/test_helpers.py +0 -0
  197. {chattool-7.0.1 → chattool-7.0.3}/src/chattool/utils/urltool.py +0 -0
  198. {chattool-7.0.1 → chattool-7.0.3}/src/chattool.egg-info/dependency_links.txt +0 -0
  199. {chattool-7.0.1 → chattool-7.0.3}/src/chattool.egg-info/entry_points.txt +0 -0
  200. {chattool-7.0.1 → chattool-7.0.3}/src/chattool.egg-info/requires.txt +0 -0
  201. {chattool-7.0.1 → chattool-7.0.3}/src/chattool.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chattool
3
- Version: 7.0.1
3
+ Version: 7.0.3
4
4
  Summary: Toolkit for Chat API
5
5
  Author-email: Rex Wang <1073853456@qq.com>
6
6
  License: MIT license
@@ -248,6 +248,16 @@ chattool explore arxiv get
248
248
 
249
249
  交互终端里,`chattool explore arxiv get` 缺少 arXiv ID 时会自动补问。
250
250
 
251
+ ### 本地服务 (`chattool serve`)
252
+
253
+ ```bash
254
+ chattool serve local ./cli-tree.html --host 127.0.0.1 --port 8765
255
+ chattool serve local ./reports --html cli-tree.html --port 8765
256
+ chattool serve local . --html index.html --dry-run
257
+ ```
258
+
259
+ `serve local` 可用本地端口打开 HTML 文件或目录;省略目标时默认使用当前目录,`-i` 会进入统一交互补问。
260
+
251
261
  ### 其他工具
252
262
 
253
263
  | 工具 | 命令 | 说明 |
@@ -158,6 +158,16 @@ chattool explore arxiv get
158
158
 
159
159
  交互终端里,`chattool explore arxiv get` 缺少 arXiv ID 时会自动补问。
160
160
 
161
+ ### 本地服务 (`chattool serve`)
162
+
163
+ ```bash
164
+ chattool serve local ./cli-tree.html --host 127.0.0.1 --port 8765
165
+ chattool serve local ./reports --html cli-tree.html --port 8765
166
+ chattool serve local . --html index.html --dry-run
167
+ ```
168
+
169
+ `serve local` 可用本地端口打开 HTML 文件或目录;省略目标时默认使用当前目录,`-i` 会进入统一交互补问。
170
+
161
171
  ### 其他工具
162
172
 
163
173
  | 工具 | 命令 | 说明 |
@@ -4,7 +4,7 @@ import importlib
4
4
 
5
5
  __author__ = """Rex Wang"""
6
6
  __email__ = "1073853456@qq.com"
7
- __version__ = "7.0.1"
7
+ __version__ = "7.0.3"
8
8
 
9
9
  from dotenv import load_dotenv
10
10
 
@@ -27,6 +27,12 @@ def _load_lark():
27
27
  return command
28
28
 
29
29
 
30
+ def _load_local():
31
+ command = _load_attr("chattool.serve.local", "local")
32
+ command.short_help = "Serve a local directory or HTML file."
33
+ return command
34
+
35
+
30
36
  def _load_svg2gif():
31
37
  command = _load_attr("chattool.serve.svg2gif", "svg2gif_app")
32
38
  command.short_help = "Run the SVG-to-GIF conversion service."
@@ -44,6 +50,7 @@ serve_cli._lazy_commands.update(
44
50
  "capture": _load_capture,
45
51
  "cert": _load_cert,
46
52
  "lark": _load_lark,
53
+ "local": _load_local,
47
54
  "svg2gif": _load_svg2gif,
48
55
  }
49
56
  )
@@ -52,6 +59,7 @@ serve_cli._lazy_command_help.update(
52
59
  "capture": "Run the screenshot capture server.",
53
60
  "cert": "Run the certificate service.",
54
61
  "lark": "Run the Lark webhook service.",
62
+ "local": "Serve a local directory or HTML file.",
55
63
  "svg2gif": "Run the SVG-to-GIF conversion service.",
56
64
  }
57
65
  )
@@ -0,0 +1,109 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from urllib.parse import quote
5
+
6
+ import click
7
+
8
+ from chattool.interaction.command_schema import (
9
+ CommandField,
10
+ CommandSchema,
11
+ add_interactive_option,
12
+ resolve_command_inputs,
13
+ )
14
+
15
+
16
+ LOCAL_SCHEMA = CommandSchema(
17
+ name="serve-local",
18
+ fields=(
19
+ CommandField(
20
+ "target",
21
+ prompt="HTML file or directory",
22
+ kind="path",
23
+ default=".",
24
+ prompt_if_missing=True,
25
+ ),
26
+ ),
27
+ )
28
+
29
+
30
+ def resolve_local_target(target: str | None, html_name: str | None) -> dict[str, str]:
31
+ """Resolve a directory or HTML file into a static root and URL path."""
32
+
33
+ raw_target = Path(target or ".").expanduser()
34
+ target_path = raw_target.resolve()
35
+
36
+ if target_path.is_file():
37
+ if html_name:
38
+ raise click.UsageError("--html can only be used when TARGET is a directory.")
39
+ root = target_path.parent
40
+ html_path = target_path
41
+ elif target_path.is_dir():
42
+ root = target_path
43
+ html_path = (root / (html_name or "index.html")).resolve()
44
+ try:
45
+ html_path.relative_to(root)
46
+ except ValueError as exc:
47
+ raise click.UsageError("--html must resolve inside TARGET directory.") from exc
48
+ else:
49
+ raise click.UsageError(f"TARGET does not exist: {raw_target}")
50
+
51
+ if not html_path.exists():
52
+ raise click.UsageError(f"HTML file does not exist: {html_path}")
53
+ if not html_path.is_file():
54
+ raise click.UsageError(f"HTML path is not a file: {html_path}")
55
+
56
+ return {
57
+ "root": str(root),
58
+ "html": str(html_path),
59
+ "path": "/" + quote(str(html_path.relative_to(root)).replace("\\", "/")),
60
+ }
61
+
62
+
63
+ @click.command(name="local")
64
+ @click.argument("target", required=False)
65
+ @click.option("--html", "html_name", default=None, help="HTML file inside TARGET directory. Defaults to index.html.")
66
+ @click.option("--host", default="127.0.0.1", show_default=True, help="Bind host.")
67
+ @click.option("--port", default=8765, show_default=True, type=int, help="Bind port.")
68
+ @click.option("--open/--no-open", "open_browser", default=True, show_default=True, help="Open the URL in a browser.")
69
+ @click.option("--dry-run", is_flag=True, help="Print resolved server info without starting the server.")
70
+ @add_interactive_option
71
+ def local(
72
+ target: str | None,
73
+ html_name: str | None,
74
+ host: str,
75
+ port: int,
76
+ open_browser: bool,
77
+ dry_run: bool,
78
+ interactive: bool | None,
79
+ ) -> None:
80
+ """Serve a local directory or HTML file over HTTP."""
81
+
82
+ values = resolve_command_inputs(
83
+ schema=LOCAL_SCHEMA,
84
+ provided={"target": target},
85
+ interactive=interactive,
86
+ usage="Usage: chattool serve local [TARGET] [--html FILE] [--host HOST] [--port PORT] [-i|-I]",
87
+ )
88
+ resolved = resolve_local_target(values["target"], html_name)
89
+ url = f"http://{host}:{port}{resolved['path']}"
90
+ click.echo(f"Root: {resolved['root']}")
91
+ click.echo(f"HTML: {resolved['html']}")
92
+ click.echo(f"URL: {url}")
93
+ if dry_run:
94
+ return
95
+
96
+ import http.server
97
+ import socketserver
98
+ import webbrowser
99
+ from functools import partial
100
+
101
+ handler = partial(http.server.SimpleHTTPRequestHandler, directory=resolved["root"])
102
+ with socketserver.TCPServer((host, port), handler) as httpd:
103
+ click.echo("Press Ctrl+C to stop.")
104
+ if open_browser:
105
+ webbrowser.open(url)
106
+ try:
107
+ httpd.serve_forever()
108
+ except KeyboardInterrupt:
109
+ click.echo("\nStopped.")
@@ -339,6 +339,8 @@ def _build_chatarch_pyproject_content(
339
339
  email: str | None,
340
340
  include_mkdocs: bool = True,
341
341
  ) -> str:
342
+ repo_slug = _chatarch_repo_slug(package_name)
343
+ docs_url = _chatarch_docs_url(package_name)
342
344
  lines = [
343
345
  "[build-system]",
344
346
  'requires = ["setuptools>=61.0", "wheel"]',
@@ -368,6 +370,16 @@ def _build_chatarch_pyproject_content(
368
370
  ' "Programming Language :: Python :: 3",',
369
371
  ' "Operating System :: OS Independent",',
370
372
  "]",
373
+ "",
374
+ "[project.urls]",
375
+ f'Homepage = "https://github.com/{_toml_escape(repo_slug)}"',
376
+ f'Repository = "https://github.com/{_toml_escape(repo_slug)}"',
377
+ ]
378
+ )
379
+ if include_mkdocs:
380
+ lines.append(f'Documentation = "{_toml_escape(docs_url)}"')
381
+ lines.extend(
382
+ [
371
383
  "",
372
384
  "[project.scripts]",
373
385
  f'{module_name} = "{module_name}.cli:main"',
@@ -395,9 +407,19 @@ def _build_chatarch_pyproject_content(
395
407
  return "\n".join(lines)
396
408
 
397
409
 
410
+ def _chatarch_repo_slug(package_name: str) -> str:
411
+ return f"ChatArch/{package_name}"
412
+
413
+
414
+ def _chatarch_docs_url(package_name: str) -> str:
415
+ return f"https://ChatArch.github.io/{package_name}"
416
+
417
+
398
418
  def _chatarch_badge_block(
399
419
  package_name: str, *, include_mkdocs: bool, include_workflows: bool
400
420
  ) -> str:
421
+ repo_slug = _chatarch_repo_slug(package_name)
422
+ docs_url = _chatarch_docs_url(package_name)
401
423
  lines = [
402
424
  '<div align="center">',
403
425
  f' <a href="https://pypi.python.org/pypi/{package_name}">',
@@ -407,15 +429,15 @@ def _chatarch_badge_block(
407
429
  if include_workflows:
408
430
  lines.extend(
409
431
  [
410
- ' <a href="https://github.com/OWNER/REPO/actions/workflows/ci.yml">',
411
- ' <img src="https://github.com/OWNER/REPO/actions/workflows/ci.yml/badge.svg" alt="Tests" />',
432
+ f' <a href="https://github.com/{repo_slug}/actions/workflows/ci.yml">',
433
+ f' <img src="https://github.com/{repo_slug}/actions/workflows/ci.yml/badge.svg" alt="Tests" />',
412
434
  " </a>",
413
435
  ]
414
436
  )
415
437
  if include_mkdocs:
416
438
  lines.extend(
417
439
  [
418
- ' <a href="https://OWNER.github.io/REPO">',
440
+ f' <a href="{docs_url}">',
419
441
  ' <img src="https://img.shields.io/badge/docs-mkdocs-blue.svg" alt="Documentation" />',
420
442
  " </a>",
421
443
  ]
@@ -707,12 +729,14 @@ def _build_chatarch_docs_index_en(package_name: str) -> str:
707
729
 
708
730
 
709
731
  def _build_chatarch_mkdocs_yml(package_name: str) -> str:
732
+ repo_slug = _chatarch_repo_slug(package_name)
733
+ docs_url = _chatarch_docs_url(package_name)
710
734
  return (
711
735
  textwrap.dedent(
712
736
  f"""
713
737
  site_name: {package_name} 文档
714
- site_url: https://OWNER.github.io/REPO
715
- repo_url: https://github.com/OWNER/REPO
738
+ site_url: {docs_url}
739
+ repo_url: https://github.com/{repo_slug}
716
740
  theme:
717
741
  name: material
718
742
  language: zh
@@ -940,9 +964,8 @@ def scaffold_package(
940
964
 
941
965
  on:
942
966
  push:
943
- branches:
944
- - main
945
- - master
967
+ tags:
968
+ - "v*"
946
969
  workflow_dispatch:
947
970
 
948
971
  permissions:
@@ -981,15 +1004,14 @@ def scaffold_package(
981
1004
  print(f"version={version}", file=output)
982
1005
  print(f"tag=v{version}", file=output)
983
1006
  PY
984
- - name: Check release tag
985
- id: tag
1007
+ - name: Check tag matches package version
1008
+ if: github.event_name == 'push'
986
1009
  env:
987
1010
  RELEASE_TAG: ${{ steps.meta.outputs.tag }}
988
1011
  run: |
989
- if git ls-remote --exit-code --tags origin "refs/tags/${RELEASE_TAG}" >/dev/null 2>&1; then
990
- echo "exists=true" >> "$GITHUB_OUTPUT"
991
- else
992
- echo "exists=false" >> "$GITHUB_OUTPUT"
1012
+ if [ "${GITHUB_REF_NAME}" != "${RELEASE_TAG}" ]; then
1013
+ echo "Tag ${GITHUB_REF_NAME} does not match package version ${RELEASE_TAG}."
1014
+ exit 1
993
1015
  fi
994
1016
  - name: Check PyPI version
995
1017
  id: pypi
@@ -1018,15 +1040,6 @@ def scaffold_package(
1018
1040
  with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
1019
1041
  print(f"exists={exists}", file=output)
1020
1042
  PY
1021
- - name: Create release tag
1022
- if: steps.pypi.outputs.exists == 'false' && steps.tag.outputs.exists == 'false'
1023
- env:
1024
- RELEASE_TAG: ${{ steps.meta.outputs.tag }}
1025
- run: |
1026
- git config user.name github-actions[bot]
1027
- git config user.email 41898282+github-actions[bot]@users.noreply.github.com
1028
- git tag -a "${RELEASE_TAG}" -m "Release ${RELEASE_TAG}"
1029
- git push origin "${RELEASE_TAG}"
1030
1043
  - name: Stop when version is already on PyPI
1031
1044
  if: steps.pypi.outputs.exists == 'true'
1032
1045
  run: echo "{package_name} ${{ steps.meta.outputs.version }} is already on PyPI; skipping publish."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chattool
3
- Version: 7.0.1
3
+ Version: 7.0.3
4
4
  Summary: Toolkit for Chat API
5
5
  Author-email: Rex Wang <1073853456@qq.com>
6
6
  License: MIT license
@@ -248,6 +248,16 @@ chattool explore arxiv get
248
248
 
249
249
  交互终端里,`chattool explore arxiv get` 缺少 arXiv ID 时会自动补问。
250
250
 
251
+ ### 本地服务 (`chattool serve`)
252
+
253
+ ```bash
254
+ chattool serve local ./cli-tree.html --host 127.0.0.1 --port 8765
255
+ chattool serve local ./reports --html cli-tree.html --port 8765
256
+ chattool serve local . --html index.html --dry-run
257
+ ```
258
+
259
+ `serve local` 可用本地端口打开 HTML 文件或目录;省略目标时默认使用当前目录,`-i` 会进入统一交互补问。
260
+
251
261
  ### 其他工具
252
262
 
253
263
  | 工具 | 命令 | 说明 |
@@ -71,6 +71,7 @@ src/chattool/serve/capture.py
71
71
  src/chattool/serve/cert_server.py
72
72
  src/chattool/serve/cli.py
73
73
  src/chattool/serve/lark_serve.py
74
+ src/chattool/serve/local.py
74
75
  src/chattool/serve/svg2gif.py
75
76
  src/chattool/setup/__init__.py
76
77
  src/chattool/setup/alias.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes