ErisPulse 2.9.0.dev2__tar.gz → 2.10.0__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 (146) hide show
  1. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/PKG-INFO +3 -1
  2. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/README.pypi.md +2 -0
  3. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/pyproject.toml +1 -1
  4. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/create.py +84 -31
  5. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/init.py +17 -15
  6. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/types.py +27 -31
  7. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/constants.py +8 -0
  8. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/locales/en.py +14 -0
  9. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/locales/ja.py +14 -0
  10. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/locales/ru.py +14 -0
  11. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +14 -0
  12. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +14 -0
  13. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/utils/package_manager.py +7 -3
  14. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/utils/scaffold_text.py +62 -0
  15. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/__init__.py +16 -1
  16. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/adapter.py +13 -12
  17. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/client.py +25 -3
  18. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/errors.py +87 -0
  19. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/router.py +100 -12
  20. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/sql_base.py +11 -6
  21. erispulse-2.10.0/src/ErisPulse/Core/Bases/websocket.py +477 -0
  22. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/base.py +22 -19
  23. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/command.py +6 -4
  24. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/conversation.py +62 -13
  25. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/governance.py +10 -4
  26. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/overrides.py +64 -40
  27. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/__init__.py +27 -0
  28. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/adapter.py +44 -11
  29. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/client.py +35 -4
  30. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/config.py +149 -16
  31. erispulse-2.10.0/src/ErisPulse/Core/connections.py +555 -0
  32. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/constants.py +138 -1
  33. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/__init__.py +94 -19
  34. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/locales/en.py +31 -0
  35. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/locales/ja.py +31 -0
  36. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/locales/ru.py +31 -0
  37. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/locales/zh_cn.py +31 -0
  38. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/locales/zh_tw.py +31 -0
  39. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/lifecycle.py +10 -0
  40. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/logger.py +79 -8
  41. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/module.py +14 -0
  42. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/ownership.py +98 -30
  43. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/router.py +238 -53
  44. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/scope.py +3 -3
  45. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/shadow.py +15 -14
  46. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/text_match.py +3 -1
  47. erispulse-2.10.0/src/ErisPulse/Core/transcript.py +817 -0
  48. erispulse-2.10.0/src/ErisPulse/__init__.py +426 -0
  49. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/plugin_folder.py +5 -1
  50. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/__init__.py +16 -1
  51. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/sdk_initializer.py +9 -0
  52. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/tasks.py +232 -3
  53. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/troubleshoot.py +38 -30
  54. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/sdk.py +3 -1
  55. erispulse-2.9.0.dev2/src/ErisPulse/Core/Bases/websocket.py +0 -271
  56. erispulse-2.9.0.dev2/src/ErisPulse/Core/transcript.py +0 -426
  57. erispulse-2.9.0.dev2/src/ErisPulse/__init__.py +0 -108
  58. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/.gitignore +0 -0
  59. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/LICENSE +0 -0
  60. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/__init__.py +0 -0
  61. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/base.py +0 -0
  62. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/cli.py +0 -0
  63. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/__init__.py +0 -0
  64. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/config.py +0 -0
  65. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/doctor.py +0 -0
  66. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/install.py +0 -0
  67. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/language.py +0 -0
  68. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/list.py +0 -0
  69. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
  70. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/run.py +0 -0
  71. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/self_update.py +0 -0
  72. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
  73. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
  74. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/commands/version.py +0 -0
  75. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/console.py +0 -0
  76. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/hints.py +0 -0
  77. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
  78. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
  79. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/registry.py +0 -0
  80. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/utils/__init__.py +0 -0
  81. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/utils/config_wizard.py +0 -0
  82. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/utils/display.py +0 -0
  83. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/CLI/utils/interactive.py +0 -0
  84. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/api_dsl.py +0 -0
  85. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/config_schema.py +0 -0
  86. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/converter.py +0 -0
  87. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/i18n_schema.py +0 -0
  88. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/kv_builder.py +0 -0
  89. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/manager.py +0 -0
  90. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/model.py +0 -0
  91. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/module.py +0 -0
  92. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/send_builder.py +0 -0
  93. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/send_rules.py +0 -0
  94. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Bases/storage.py +0 -0
  95. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/__init__.py +0 -0
  96. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/command_args.py +0 -0
  97. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/interaction.py +0 -0
  98. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/message.py +0 -0
  99. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/message_builder.py +0 -0
  100. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/meta.py +0 -0
  101. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/notice.py +0 -0
  102. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/request.py +0 -0
  103. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/session_type.py +0 -0
  104. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/throttle.py +0 -0
  105. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/trace.py +0 -0
  106. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/Event/wrapper.py +0 -0
  107. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/assets/__init__.py +0 -0
  108. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/assets/error.css +0 -0
  109. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/assets/error.html +0 -0
  110. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/assets/root.css +0 -0
  111. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/assets/root.html +0 -0
  112. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/di.py +0 -0
  113. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/constants.py +0 -0
  114. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
  115. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/master.py +0 -0
  116. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/storage/__init__.py +0 -0
  117. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/storage/mysql.py +0 -0
  118. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/storage/postgres.py +0 -0
  119. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/Core/storage/sqlite.py +0 -0
  120. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/__main__.py +0 -0
  121. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/finders/__init__.py +0 -0
  122. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/finders/adapter.py +0 -0
  123. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/finders/bases/__init__.py +0 -0
  124. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/finders/bases/finder.py +0 -0
  125. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/finders/module.py +0 -0
  126. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/__init__.py +0 -0
  127. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/adapter.py +0 -0
  128. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/bases/__init__.py +0 -0
  129. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/bases/loader.py +0 -0
  130. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/module.py +0 -0
  131. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/strategy.py +0 -0
  132. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/loaders/strict.py +0 -0
  133. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/py.typed +0 -0
  134. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/config_schema.py +0 -0
  135. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/context.py +0 -0
  136. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/diagnostics.py +0 -0
  137. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/example_config.py +0 -0
  138. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/exceptions.py +0 -0
  139. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/file_watcher.py +0 -0
  140. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/frame_config.py +0 -0
  141. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/hints.py +0 -0
  142. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/memory.py +0 -0
  143. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/owner_cleanup.py +0 -0
  144. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/plugin_reload.py +0 -0
  145. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/proactive_gc.py +0 -0
  146. {erispulse-2.9.0.dev2 → erispulse-2.10.0}/src/ErisPulse/runtime/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ErisPulse
3
- Version: 2.9.0-dev.2
3
+ Version: 2.10.0
4
4
  Summary: Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署
5
5
  Project-URL: Homepage, https://github.com/ErisPulse/ErisPulse
6
6
  Project-URL: Documentation, https://www.erisdev.com#docs
@@ -95,6 +95,8 @@ It ships with a flexible plugin system, hot reload, a visual Dashboard, an AI Bu
95
95
  pip install ErisPulse
96
96
  ```
97
97
 
98
+ For a global `epsdk` CLI without any virtual environment, use `uv tool install ErisPulse` instead.
99
+
98
100
  ### Option 2 — Docker (recommended for production)
99
101
 
100
102
  ```bash
@@ -42,6 +42,8 @@ It ships with a flexible plugin system, hot reload, a visual Dashboard, an AI Bu
42
42
  pip install ErisPulse
43
43
  ```
44
44
 
45
+ For a global `epsdk` CLI without any virtual environment, use `uv tool install ErisPulse` instead.
46
+
45
47
  ### Option 2 — Docker (recommended for production)
46
48
 
47
49
  ```bash
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ErisPulse"
7
- version = "2.9.0-dev.2"
7
+ version = "2.10.0"
8
8
  description = "Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署"
9
9
  readme = "README.pypi.md"
10
10
  requires-python = ">=3.10"
@@ -41,6 +41,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41
41
  SOFTWARE.
42
42
  """
43
43
 
44
+ # 生成模块/适配器模板的最低 SDK 地板(写入模板 min_sdk_version 字段)。
45
+ # 模板示例使用 args=/options=(2.9 特性);pip 默认不解析预发布版本,
46
+ # 该地板不得高于已发布的正式版本,否则生成的组件会因依赖装不上或
47
+ # 加载器按 PEP 440 拒载(与 CLI/constants.py 的 INIT_ERISPULSE_DEPENDENCY 同步升版)。
48
+ _TEMPLATE_MIN_SDK_VERSION = "2.9.0"
49
+
44
50
  _MODULE_PYPROJECT = """[project]
45
51
  name = "ErisPulse-{name}"
46
52
  version = "1.0.0"
@@ -72,10 +78,19 @@ _MODULE_INIT = """from .Core import Main
72
78
 
73
79
  _MODULE_CORE = """from dataclasses import dataclass, field
74
80
 
75
- from ErisPulse import SDK
76
- from ErisPulse.Core.Bases import BaseConfig, BaseI18n, BaseModule, I18nKey, ModuleMeta
77
- from ErisPulse.Core.Event import Event, command, message, notice
78
- from ErisPulse.Core.i18n import i18n
81
+ from ErisPulse import (
82
+ SDK,
83
+ BaseConfig,
84
+ BaseI18n,
85
+ BaseModule,
86
+ Event,
87
+ I18nKey,
88
+ ModuleMeta,
89
+ command,
90
+ i18n,
91
+ message,
92
+ notice,
93
+ )
79
94
 
80
95
 
81
96
  class Main(BaseModule):
@@ -92,12 +107,6 @@ class Main(BaseModule):
92
107
  :ivar advanced_threshold: 高级阈值(docstring :ivar: 声明即为字段描述,无需 metadata)
93
108
  \"\"\"
94
109
 
95
- enabled: bool = field(
96
- default=True,
97
- metadata={{
98
- \"description\": {{\"i18n\": \"module.{name}.enabled\", \"default\": \"Enable module\"}},
99
- }},
100
- )
101
110
  # example 字段:默认不写入 config.toml(仅记录在 config.full.example,用户按需启用)
102
111
  advanced_threshold: int = field(
103
112
  default=100,
@@ -117,15 +126,6 @@ class Main(BaseModule):
117
126
  ru=\"Модуль {name}\",
118
127
  zh_TW=\"{name} 模組\",
119
128
  )
120
- enabled: I18nKey = I18nKey(
121
- key=\"module.{name}.enabled\",
122
- default=\"Enable module\",
123
- zh_CN=\"是否启用模块\",
124
- en=\"Enable module\",
125
- ja=\"モジュールを有効にする\",
126
- ru=\"Включить модуль\",
127
- zh_TW=\"啟用模組\",
128
- )
129
129
  hello_help: I18nKey = I18nKey(
130
130
  key=\"module.{name}.command.hello.help\",
131
131
  default=\"Send a greeting message\",
@@ -144,6 +144,42 @@ class Main(BaseModule):
144
144
  ru=\"Привет от {name}!\",
145
145
  zh_TW=\"來自 {name} 的問候!\",
146
146
  )
147
+ roll_help: I18nKey = I18nKey(
148
+ key=\"module.{name}.command.roll.help\",
149
+ default=\"Roll dice: count [sides]\",
150
+ zh_CN=\"掷骰子:次数 [面数]\",
151
+ en=\"Roll dice: count [sides]\",
152
+ ja=\"サイコロを振る: 回数 [面数]\",
153
+ ru=\"Бросить кости: количество [граней]\",
154
+ zh_TW=\"擲骰子:次數 [面數]\",
155
+ )
156
+ roll_reply: I18nKey = I18nKey(
157
+ key=\"module.{name}.command.roll.reply\",
158
+ default=\"Rolled {{count}}d{{sides}}, total: {{total}}{{detail}}\",
159
+ zh_CN=\"掷了 {{count}} 次 {{sides}} 面骰,总点数:{{total}}{{detail}}\",
160
+ en=\"Rolled {{count}}d{{sides}}, total: {{total}}{{detail}}\",
161
+ ja=\"{{sides}}面ダイスを {{count}} 回振った合計: {{total}}{{detail}}\",
162
+ ru=\"Бросков {{count}}d{{sides}}, сумма: {{total}}{{detail}}\",
163
+ zh_TW=\"擲了 {{count}} 次 {{sides}} 面骰,總點數:{{total}}{{detail}}\",
164
+ )
165
+ roll_detail: I18nKey = I18nKey(
166
+ key=\"module.{name}.command.roll.detail\",
167
+ default=\" (verbose: {{count}} rolls of {{sides}}-sided dice)\",
168
+ zh_CN=\"(详细模式:{{count}} 次 {{sides}} 面骰)\",
169
+ en=\" (verbose: {{count}} rolls of {{sides}}-sided dice)\",
170
+ ja=\"(詳細モード: {{sides}}面ダイスを {{count}} 回)\",
171
+ ru=\" (подробно: {{count}} бросков {{sides}}-гранного кубика)\",
172
+ zh_TW=\"(詳細模式:{{count}} 次 {{sides}} 面骰)\",
173
+ )
174
+ signin_reply: I18nKey = I18nKey(
175
+ key=\"module.{name}.command.signin.reply\",
176
+ default=\"Signed in!\",
177
+ zh_CN=\"签到成功\",
178
+ en=\"Signed in!\",
179
+ ja=\"チェックイン完了!\",
180
+ ru=\"Готово, вы отмечены!\",
181
+ zh_TW=\"簽到成功\",
182
+ )
147
183
 
148
184
  def __init__(self, sdk: SDK = None):
149
185
  # sdk 由框架在实例化时自动注入(无需手动导入兜底)
@@ -167,7 +203,7 @@ class Main(BaseModule):
167
203
  version=\"0.1.0\",
168
204
  author=\"ErisDev\",
169
205
  # 最低 SDK 版本(可选):不满足时框架在加载期明确报错并跳过本模块
170
- min_sdk_version=\"2.8.0\",
206
+ min_sdk_version=\"{min_sdk}\",
171
207
  group=\"default\",
172
208
  tags=[\"{name}\"],
173
209
  # 对外服务白名单(可选):声明后其他模块可经 sdk.module.call() 调用这些方法;
@@ -225,6 +261,20 @@ class Main(BaseModule):
225
261
  async def hello_command(event: Event):
226
262
  await event.reply(i18n.t(\"module.{name}.command.hello.reply\"))
227
263
 
264
+ # {text[module.roll_hint]}
265
+ @command(
266
+ \"roll\",
267
+ args=\"<count:int> [sides:int=6]\",
268
+ options={{\"verbose\": \"-v/--verbose\"}},
269
+ help=i18n.t(\"module.{name}.command.roll.help\"),
270
+ )
271
+ async def roll_command(event: Event, count: int, sides: int = 6, verbose: bool = False):
272
+ import random
273
+
274
+ total = sum(random.randint(1, sides) for _ in range(count))
275
+ detail = i18n.t(\"module.{name}.command.roll.detail\", count=count, sides=sides) if verbose else \"\"
276
+ await event.reply(i18n.t(\"module.{name}.command.roll.reply\", count=count, sides=sides, total=total, detail=detail))
277
+
228
278
  async def _register_message_handlers(self):
229
279
  @message.on_private_message()
230
280
  async def private_message_handler(event: Event):
@@ -235,9 +285,9 @@ class Main(BaseModule):
235
285
  pass
236
286
 
237
287
  # 消息装饰器支持 pattern(glob 通配符)/ regex(正则),不匹配则不触发
238
- @message.on_message(pattern=\"签到*\")
288
+ @message.on_message(pattern=\"{text[module.signin_pattern]}\")
239
289
  async def signin_handler(event: Event):
240
- await event.reply(\"签到成功\")
290
+ await event.reply(i18n.t(\"module.{name}.command.signin.reply\"))
241
291
 
242
292
  @notice.on_friend_add()
243
293
  async def friend_add_handler(event: Event):
@@ -283,10 +333,7 @@ _ADAPTER_CORE = """import asyncio
283
333
  import json
284
334
  from dataclasses import dataclass, field
285
335
  from typing import ClassVar
286
- from ErisPulse.Core import BaseAdapter
287
- from ErisPulse.Core.Bases import BaseConfig, BaseI18n, I18nKey
288
- from ErisPulse.Core import router
289
- from ErisPulse.Core.i18n import i18n
336
+ from ErisPulse import BaseAdapter, BaseConfig, BaseI18n, I18nKey, router, i18n
290
337
 
291
338
 
292
339
  class {name}(BaseAdapter):
@@ -294,7 +341,7 @@ class {name}(BaseAdapter):
294
341
  {text[adapter.doc]}
295
342
  \"\"\"
296
343
 
297
- # 依赖声明(可选,ErisPulse 2.8.0+):
344
+ # 依赖声明(可选,ErisPulse 2.9.0+):
298
345
  # depends = {{"adapters": [], "modules": []}} # 硬依赖:缺失时跳过启动
299
346
  # optional_modules = [] # 软依赖:就绪/丢失时收到
300
347
  # # on_dependency_ready/lost 回调
@@ -302,7 +349,7 @@ class {name}(BaseAdapter):
302
349
  optional_modules: ClassVar[list] = []
303
350
 
304
351
  # 声明所需最低 SDK 版本:不满足时框架在加载期明确报错并跳过本适配器(可选)
305
- min_sdk_version = "2.8.0"
352
+ min_sdk_version = "{min_sdk}"
306
353
 
307
354
  # {text[adapter.config_hint]}
308
355
  @dataclass
@@ -461,6 +508,11 @@ class {name}(BaseAdapter):
461
508
  async def _ws_handler(self, websocket):
462
509
  bot_id = self._get_bot_id()
463
510
 
511
+ # 连接已由框架自动登记进连接池(ErisPulse.connections):
512
+ # meta 供跨模块查看,join_group 后可被 connections.broadcast 定向推送
513
+ websocket.meta["bot_id"] = bot_id
514
+ websocket.join_group(f"bot:{{bot_id}}")
515
+
464
516
  await self.emit_meta("connect", bot_id, user_name="{name}")
465
517
  self.logger.info("{text[adapter.log.bot_connected]}")
466
518
 
@@ -484,7 +536,7 @@ class {name}(BaseAdapter):
484
536
 
485
537
  async def call_api(self, endpoint: str, **params):
486
538
  \"\"\"Call platform API\"\"\"
487
- from ErisPulse.Core import client
539
+ from ErisPulse import client
488
540
 
489
541
  cfg = self.cfg
490
542
  headers = {{"Authorization": "Bearer " + cfg.token}}
@@ -848,7 +900,7 @@ class CreateCommand(Command):
848
900
 
849
901
  (pkg_dir / "__init__.py").write_text(_MODULE_INIT, encoding="utf-8")
850
902
  (pkg_dir / "Core.py").write_text(
851
- _MODULE_CORE.format(name=name, text=_scaffold_text(name)),
903
+ _MODULE_CORE.format(name=name, text=_scaffold_text(name), min_sdk=_TEMPLATE_MIN_SDK_VERSION),
852
904
  encoding="utf-8",
853
905
  )
854
906
  (project_dir / "pyproject.toml").write_text(
@@ -921,7 +973,7 @@ class CreateCommand(Command):
921
973
 
922
974
  (plugin_dir / "__init__.py").write_text(_MODULE_INIT, encoding="utf-8")
923
975
  (plugin_dir / "Core.py").write_text(
924
- _MODULE_CORE.format(name=name, text=_scaffold_text(name)),
976
+ _MODULE_CORE.format(name=name, text=_scaffold_text(name), min_sdk=_TEMPLATE_MIN_SDK_VERSION),
925
977
  encoding="utf-8",
926
978
  )
927
979
 
@@ -1000,6 +1052,7 @@ class CreateCommand(Command):
1000
1052
  converter_name=converter_name,
1001
1053
  entry_key=entry_key,
1002
1054
  text=_scaffold_text(name),
1055
+ min_sdk=_TEMPLATE_MIN_SDK_VERSION,
1003
1056
  ),
1004
1057
  encoding="utf-8",
1005
1058
  )
@@ -15,6 +15,7 @@ from rich.text import Text
15
15
 
16
16
  from ..base import Command
17
17
  from ..console import console
18
+ from ..constants import INIT_ERISPULSE_DEPENDENCY
18
19
  from ..i18n import i18n
19
20
  from ..utils import PackageManager
20
21
  from ..utils.display import _input, prompt_validated, section_header
@@ -26,6 +27,7 @@ from ..utils.package_manager import (
26
27
  uv_add,
27
28
  warn_if_uv_isolated,
28
29
  )
30
+ from ..utils.scaffold_text import ScaffoldText
29
31
 
30
32
 
31
33
  def _validate_project_name(name: str) -> bool:
@@ -192,6 +194,9 @@ class InitCommand(Command):
192
194
  console.print(f"[success] {i18n.t('cli.init.created_dir', name=project_name)}[/]")
193
195
 
194
196
  try:
197
+ # 生成物文案(config 注释 / main docstring / .gitignore 分节 /
198
+ # README)跟随 CLI 语言;缺失键回退英文
199
+ st = ScaffoldText()
195
200
  for dir_name in ["config", "logs"]:
196
201
  (project_path / dir_name).mkdir(exist_ok=True)
197
202
  # SSL 证书默认目录:跟随项目运行目录走,配置里用相对路径引用
@@ -201,15 +206,14 @@ class InitCommand(Command):
201
206
  ssl_file = ssl_dir / ssl_name
202
207
  if not ssl_file.exists():
203
208
  ssl_file.write_text(
204
- "# 将你的证书/密钥 PEM 内容粘贴到本文件,或在配置中改用 ssl_cert/ssl_key 内联填写\n",
209
+ st.t("init.ssl_placeholder") + "\n",
205
210
  encoding="utf-8",
206
211
  )
207
212
 
208
213
  config_file = project_path / "config" / "config.toml"
209
214
  if not config_file.exists():
210
215
  with config_file.open("w", encoding="utf-8") as f:
211
- f.write("# ErisPulse 配置文件\n")
212
- f.write("# 完整配置示例请参考 config.full.example\n\n")
216
+ f.write(st.t("init.config_toml_header") + "\n\n")
213
217
  f.write("[ErisPulse.server]\n")
214
218
  f.write('host = "0.0.0.0"\n')
215
219
  f.write("port = 8000\n\n")
@@ -224,9 +228,7 @@ class InitCommand(Command):
224
228
  main_file = project_path / "main.py"
225
229
  if not main_file.exists():
226
230
  with main_file.open("w", encoding="utf-8") as f:
227
- f.write(f'"""\n{display_name} 主程序\n\n')
228
- f.write("这是 ErisPulse 自动生成的主程序文件\n")
229
- f.write('"""\n\n')
231
+ f.write(st.t("init.main_docstring", display_name=display_name) + "\n")
230
232
  f.write("import asyncio\n")
231
233
  f.write("from ErisPulse import sdk\n\n")
232
234
  f.write("async def main():\n")
@@ -245,7 +247,7 @@ class InitCommand(Command):
245
247
  f.write('description = "ErisPulse project"\n')
246
248
  f.write('requires-python = ">=3.10"\n')
247
249
  f.write("dependencies = [\n")
248
- f.write(' "erispulse>=2.8.3",\n')
250
+ f.write(f' "{INIT_ERISPULSE_DEPENDENCY}",\n')
249
251
  for adapter in adapter_list or []:
250
252
  f.write(f' "{adapter}",\n')
251
253
  f.write("]\n")
@@ -265,13 +267,13 @@ class InitCommand(Command):
265
267
  "*.egg-info/\n"
266
268
  ".eggs/\n"
267
269
  "\n"
268
- "# 虚拟环境与本地环境\n"
270
+ f"{st.t('init.gitignore_section_venv')}\n"
269
271
  ".venv/\n"
270
272
  "venv/\n"
271
273
  "env/\n"
272
274
  ".env\n"
273
275
  "\n"
274
- "# 工具缓存\n"
276
+ f"{st.t('init.gitignore_section_cache')}\n"
275
277
  ".pytest_cache/\n"
276
278
  ".mypy_cache/\n"
277
279
  ".ruff_cache/\n"
@@ -279,11 +281,11 @@ class InitCommand(Command):
279
281
  "coverage.xml\n"
280
282
  "htmlcov/\n"
281
283
  "\n"
282
- "# ErisPulse 运行时数据(配置与日志含敏感信息,不入库)\n"
284
+ f"{st.t('init.gitignore_section_runtime')}\n"
283
285
  "config/\n"
284
286
  "logs/\n"
285
287
  "\n"
286
- "# 编辑器与系统文件\n"
288
+ f"{st.t('init.gitignore_section_editor')}\n"
287
289
  ".idea/\n"
288
290
  ".vscode/\n"
289
291
  "*.swp\n"
@@ -295,14 +297,14 @@ class InitCommand(Command):
295
297
  readme_file = project_path / "README.md"
296
298
  if not readme_file.exists():
297
299
  with readme_file.open("w", encoding="utf-8") as f:
298
- f.write(f"# {display_name}\n\nErisPulse 项目。\n\n```bash\nepsdk run\n```\n")
300
+ f.write(st.t("init.readme_body", display_name=display_name))
299
301
  console.print(f"[success] {i18n.t('cli.init.readme_created')}[/]")
300
302
 
301
303
  # ---- 虚拟环境与依赖安装 ----
302
304
  if create_venv:
303
305
  console.print(f"[info] {i18n.t('cli.init.venv_creating')}[/]")
304
306
  venv_python = None
305
- if uv_add(project_path, ["erispulse>=2.8.3"]):
307
+ if uv_add(project_path, [INIT_ERISPULSE_DEPENDENCY]):
306
308
  # uv add 自动创建 .venv、安装依赖并写入 pyproject 依赖清单
307
309
  venv_python = resolve_target_python(project_path)[0]
308
310
  console.print(f"[success] {i18n.t('cli.init.venv_created')}[/]")
@@ -312,8 +314,8 @@ class InitCommand(Command):
312
314
  if venv_python:
313
315
  console.print(f"[success] {i18n.t('cli.init.venv_created')}[/]")
314
316
  pm = PackageManager(python_executable=venv_python)
315
- if pm.install_package(["erispulse>=2.8.3"]):
316
- append_pyproject_dependencies(project_path, ["erispulse>=2.8.3"])
317
+ if pm.install_package([INIT_ERISPULSE_DEPENDENCY]):
318
+ append_pyproject_dependencies(project_path, [INIT_ERISPULSE_DEPENDENCY])
317
319
  console.print(f"[success] {i18n.t('cli.init.deps_installed')}[/]")
318
320
  else:
319
321
  console.print(
@@ -26,32 +26,31 @@ from ..i18n import i18n
26
26
  # 生成文件名(带前导下划线,避免与用户业务模块冲突)
27
27
  STUB_FILENAME = "_ep_types.py"
28
28
 
29
- # 存根文件头部说明
30
- _STUB_HEADER = '''"""
31
- ErisPulse 类型存根(自动生成,请勿手动编辑)
32
-
33
- 由 `epsdk types` 命令根据已安装的模块/适配器生成。
34
- 仅导出类型供用户代码作为变量标注使用,**不提供任何运行时实例**。
35
- 所有导入都在 ``TYPE_CHECKING`` 下,运行时零开销、零行为改变。
36
-
37
- 使用方式:
38
- from _ep_types import MyModule, Yunhu
39
- from ErisPulse import sdk
40
-
41
- # 用导入的类型标注变量,即可获得 IDE 补全
42
- my_mod: MyModule = sdk.module.get("MyModule")
43
- my_mod.hello() # ← IDE 能补全 hello
44
-
45
- my_adapter: Yunhu = sdk.adapter.get("yunhu")
46
- await my_adapter.Send.To("group", "123").Board(...) # ← 补全平台特有方法
47
-
48
- 说明:
49
- - 类型名采用 entry-point 名的 PascalCase 形式(如 ``yunhu`` → ``Yunhu``),
50
- 与传入 ``sdk.adapter.get()`` / ``sdk.module.get()`` 的名称对应
51
- - 存根仅用于静态类型检查,不含运行时实现
52
- - 安装/卸载模块/适配器后请重新生成:``epsdk types``
53
- """
54
- '''
29
+ def _stub_header() -> str:
30
+ """{!--< internal-use >!--} 渲染存根文件头部说明(当前语言)"""
31
+ return (
32
+ '"""\n'
33
+ f"{i18n.t('cli.types.stub_title')}\n"
34
+ "\n"
35
+ f"{i18n.t('cli.types.stub_intro')}\n"
36
+ "\n"
37
+ f"{i18n.t('cli.types.stub_usage_title')}:\n"
38
+ " from _ep_types import MyModule, Yunhu\n"
39
+ " from ErisPulse import sdk\n"
40
+ "\n"
41
+ f" {i18n.t('cli.types.stub_usage_comment')}\n"
42
+ ' my_mod: MyModule = sdk.module.get("MyModule")\n'
43
+ f" my_mod.hello() {i18n.t('cli.types.stub_usage_module_hint')}\n"
44
+ "\n"
45
+ ' my_adapter: Yunhu = sdk.adapter.get("yunhu")\n'
46
+ f" await my_adapter.Send.To(\"group\", \"123\").Board(...) {i18n.t('cli.types.stub_usage_adapter_hint')}\n"
47
+ "\n"
48
+ f"{i18n.t('cli.types.stub_notes_title')}:\n"
49
+ f" - {i18n.t('cli.types.stub_note_naming')}\n"
50
+ f" - {i18n.t('cli.types.stub_note_static_only')}\n"
51
+ f" - {i18n.t('cli.types.stub_note_regen')}\n"
52
+ '"""\n'
53
+ )
55
54
 
56
55
  # 排除内省的方法名(来自基类、Python 内置、下划线开头)
57
56
  _EXCLUDE_METHOD_NAMES = frozenset({
@@ -491,14 +490,11 @@ class TypesCommand(Command):
491
490
  :param modules_info: 模块信息
492
491
  :return: 存根文件内容
493
492
  """
494
- lines = [_STUB_HEADER.rstrip(), ""]
493
+ lines = [_stub_header().rstrip(), ""]
495
494
  lines.append("from typing import TYPE_CHECKING")
496
495
  lines.append("")
497
496
  lines.append("if TYPE_CHECKING:")
498
- lines.append(" # 以下类型导入仅在 IDE / 类型检查器中生效,不会被运行时执行。")
499
- lines.append(" # 在用户代码中通过 ``from _ep_types import XxxModule`` 获取类型,")
500
- lines.append(" # 配合 ``my_mod: XxxModule = sdk.module.get('XxxModule')`` 获得补全。")
501
- lines.append("")
497
+ lines.append(f" # {i18n.t('cli.types.stub_typing_comment')}")
502
498
 
503
499
  export_names: list[str] = []
504
500
  seen_imports: set[str] = set() # 去重完全相同的导入语句
@@ -55,8 +55,16 @@ RUN_RESTART_PAUSE_SECS: float = 0.5
55
55
  # 修改影响: 数值越小越早提示,越大越保守(0/负数禁用提示)。
56
56
  RUN_PERSISTENT_CRASH_HINT_THRESHOLD: int = 3
57
57
 
58
+ # init 生成项目对框架本体的依赖下限(pip 依赖声明,非 SDK 加载期检查)。
59
+ # 使用位置: CLI/commands/init.py -> pyproject.toml 生成 / uv_add / pm.install_package /
60
+ # append_pyproject_dependencies 四处。
61
+ # 修改影响: 真实 pip 依赖——pip 默认不解析预发布版本,该下限不得高于已发布的
62
+ # 正式版本(与 create.py 的 _TEMPLATE_MIN_SDK_VERSION 同步升版)。
63
+ INIT_ERISPULSE_DEPENDENCY: str = "erispulse>=2.9.0"
64
+
58
65
  __all__ = [
59
66
  "ADAPTER_ENTRY_POINT_GROUP",
67
+ "INIT_ERISPULSE_DEPENDENCY",
60
68
  "RUN_CRASH_BACKOFF_MAX_SECS",
61
69
  "RUN_CRASH_BACKOFF_PER_CRASH_SECS",
62
70
  "RUN_RESTART_PAUSE_SECS",
@@ -426,6 +426,9 @@ TRANSLATIONS = {
426
426
  "cli.display.enter_number": "Please enter a number",
427
427
  # ==================== package_manager utils ====================
428
428
  "cli.package.ssl_error": "SSL verification failed: {error}",
429
+ "cli.package.uv_venv_failed": "uv venv failed: {error}",
430
+ "cli.package.python_venv_failed": "python -m venv failed: {error}",
431
+ "cli.package.pyproject_writeback_failed": "Failed to write dependencies back to pyproject.toml: {error}",
429
432
  "cli.package.ssl_error_proxy_hint": " Proxy detected, please ensure the proxy is configured correctly or try setting the HTTPS_PROXY environment variable",
430
433
  "cli.package.fetch_remote_failed": "Failed to fetch remote package list, please check your network connection or proxy settings",
431
434
  "cli.package.proxy_detected": " Proxy detected: {proxy}",
@@ -549,4 +552,15 @@ TRANSLATIONS = {
549
552
  "cli.types.usage_hint": "Import types in your code and use them as variable annotations for IDE completion:",
550
553
  "cli.types.usage_example": "from _ep_types import MyModule # then: my_mod: MyModule = sdk.module.get('MyModule')",
551
554
  "cli.types.introspect_failed": "Failed to introspect target environment: {error}",
555
+ "cli.types.stub_title": "ErisPulse type stub (auto-generated, do not edit manually)",
556
+ "cli.types.stub_intro": "Generated by the `epsdk types` command from installed modules/adapters.\nExports types only, for variable annotations in user code — **provides no runtime instances**.\nAll imports are under ``TYPE_CHECKING``: zero runtime cost, zero behavior change.",
557
+ "cli.types.stub_usage_title": "Usage",
558
+ "cli.types.stub_usage_comment": "# annotate variables with the imported types to get IDE completion",
559
+ "cli.types.stub_usage_module_hint": "# ← IDE completes hello",
560
+ "cli.types.stub_usage_adapter_hint": "# ← completes platform-specific methods",
561
+ "cli.types.stub_notes_title": "Notes",
562
+ "cli.types.stub_note_naming": "Type names are the PascalCase form of entry-point names (e.g. ``yunhu`` → ``Yunhu``), matching the names passed to ``sdk.adapter.get()`` / ``sdk.module.get()``",
563
+ "cli.types.stub_note_static_only": "The stub is for static type checking only and contains no runtime implementation",
564
+ "cli.types.stub_note_regen": "Regenerate after installing/uninstalling modules or adapters: ``epsdk types``",
565
+ "cli.types.stub_typing_comment": "The type imports below only take effect in IDEs / type checkers and are never executed at runtime; in user code, get types via ``from _ep_types import XxxModule`` and use them as variable annotations for completion",
552
566
  }
@@ -426,6 +426,9 @@ TRANSLATIONS = {
426
426
  "cli.display.enter_number": "数字を入力してください",
427
427
  # ==================== package_manager ユーティリティ ====================
428
428
  "cli.package.ssl_error": "SSL 検証失敗: {error}",
429
+ "cli.package.uv_venv_failed": "uv venv に失敗しました: {error}",
430
+ "cli.package.python_venv_failed": "python -m venv に失敗しました: {error}",
431
+ "cli.package.pyproject_writeback_failed": "pyproject.toml への依存関係の書き戻しに失敗しました: {error}",
429
432
  "cli.package.ssl_error_proxy_hint": " プロキシが検出されました。プロキシ設定が正しいことを確認するか、HTTPS_PROXY 環境変数を設定してください",
430
433
  "cli.package.fetch_remote_failed": "リモートパッケージリストを取得できませんでした。ネットワーク接続またはプロキシ設定を確認してください",
431
434
  "cli.package.proxy_detected": " プロキシを検出: {proxy}",
@@ -549,4 +552,15 @@ TRANSLATIONS = {
549
552
  "cli.types.usage_hint": "コードに型をインポートして変数アノテーションとして使用すると、IDE 補完が利用できます:",
550
553
  "cli.types.usage_example": "from _ep_types import MyModule # 次に: my_mod: MyModule = sdk.module.get('MyModule')",
551
554
  "cli.types.introspect_failed": "対象環境のイントロスペクションに失敗: {error}",
555
+ "cli.types.stub_title": "ErisPulse 型スタブ(自動生成、手動編集禁止)",
556
+ "cli.types.stub_intro": "インストール済みのモジュール/アダプタから `epsdk types` コマンドにより生成されました。\nユーザーコードの変数アノテーション用に型のみをエクスポートし、**実行時インスタンスは提供しません**。\nすべてのインポートは ``TYPE_CHECKING`` 配下にあり、実行時のオーバーヘッドと動作変更はゼロです。",
557
+ "cli.types.stub_usage_title": "使用方法",
558
+ "cli.types.stub_usage_comment": "# インポートした型で変数をアノテートすると IDE 補全が効きます",
559
+ "cli.types.stub_usage_module_hint": "# ← IDE が hello を補完します",
560
+ "cli.types.stub_usage_adapter_hint": "# ← プラットフォーム固有メソッドを補完します",
561
+ "cli.types.stub_notes_title": "説明",
562
+ "cli.types.stub_note_naming": "型名は entry-point 名の PascalCase 形式(例: ``yunhu`` → ``Yunhu``)で、``sdk.adapter.get()`` / ``sdk.module.get()`` に渡す名前に対応します",
563
+ "cli.types.stub_note_static_only": "スタブは静的型検査専用で、実行時実装を含みません",
564
+ "cli.types.stub_note_regen": "モジュール/アダプタのインストール/アンインストール後は再生成してください: ``epsdk types``",
565
+ "cli.types.stub_typing_comment": "以下の型インポートは IDE / 型チェッカーでのみ有効で、実行時には実行されません。ユーザーコードでは ``from _ep_types import XxxModule`` で型を取得し変数アノテーションに使うと補完が効きます",
552
566
  }
@@ -426,6 +426,9 @@ TRANSLATIONS = {
426
426
  "cli.display.enter_number": "Пожалуйста, введите номер",
427
427
  # ==================== утилиты package_manager ====================
428
428
  "cli.package.ssl_error": "Ошибка проверки SSL: {error}",
429
+ "cli.package.uv_venv_failed": "Сбой uv venv: {error}",
430
+ "cli.package.python_venv_failed": "Сбой python -m venv: {error}",
431
+ "cli.package.pyproject_writeback_failed": "Не удалось записать зависимости обратно в pyproject.toml: {error}",
429
432
  "cli.package.ssl_error_proxy_hint": " Обнаружен прокси. Убедитесь, что прокси настроен правильно, или попробуйте задать переменную окружения HTTPS_PROXY",
430
433
  "cli.package.fetch_remote_failed": "Не удалось получить список удалённых пакетов. Проверьте сетевое подключение или настройки прокси",
431
434
  "cli.package.proxy_detected": " Обнаружен прокси: {proxy}",
@@ -549,4 +552,15 @@ TRANSLATIONS = {
549
552
  "cli.types.usage_hint": "Импортируйте типы в коде и используйте как аннотации переменных для автодополнения IDE:",
550
553
  "cli.types.usage_example": "from _ep_types import MyModule # затем: my_mod: MyModule = sdk.module.get('MyModule')",
551
554
  "cli.types.introspect_failed": "Ошибка интроспекции целевой среды: {error}",
555
+ "cli.types.stub_title": "Заглушка типов ErisPulse (сгенерирована автоматически, вручную не редактировать)",
556
+ "cli.types.stub_intro": "Сгенерирована командой `epsdk types` по установленным модулям/адаптерам.\nЭкспортирует только типы для аннотаций переменных в коде пользователя — **экземпляры времени выполнения не предоставляет**.\nВсе импорты находятся под ``TYPE_CHECKING``: нулевые накладные расходы и нулевое изменение поведения во время выполнения.",
557
+ "cli.types.stub_usage_title": "Использование",
558
+ "cli.types.stub_usage_comment": "# аннотируйте переменные импортированными типами, чтобы получить автодополнение в IDE",
559
+ "cli.types.stub_usage_module_hint": "# ← IDE дополнит hello",
560
+ "cli.types.stub_usage_adapter_hint": "# ← дополнит методы, специфичные для платформы",
561
+ "cli.types.stub_notes_title": "Примечания",
562
+ "cli.types.stub_note_naming": "Имена типов — форма PascalCase имён entry-point (например, ``yunhu`` → ``Yunhu``) и соответствуют именам, передаваемым в ``sdk.adapter.get()`` / ``sdk.module.get()``",
563
+ "cli.types.stub_note_static_only": "Заглушка предназначена только для статической проверки типов и не содержит реализации времени выполнения",
564
+ "cli.types.stub_note_regen": "После установки/удаления модулей или адаптеров перегенерируйте: ``epsdk types``",
565
+ "cli.types.stub_typing_comment": "Импорты типов ниже действуют только в IDE / проверщиках типов и никогда не выполняются во время выполнения; в коде пользователя получайте типы через ``from _ep_types import XxxModule`` и используйте их в аннотациях переменных для автодополнения",
552
566
  }
@@ -426,6 +426,9 @@ TRANSLATIONS = {
426
426
  "cli.display.enter_number": "请输入数字序号",
427
427
  # ==================== package_manager 工具 ====================
428
428
  "cli.package.ssl_error": "SSL 验证失败: {error}",
429
+ "cli.package.uv_venv_failed": "uv venv 失败:{error}",
430
+ "cli.package.python_venv_failed": "python -m venv 失败:{error}",
431
+ "cli.package.pyproject_writeback_failed": "pyproject.toml 依赖回写失败:{error}",
429
432
  "cli.package.ssl_error_proxy_hint": " 检测到代理,请确保代理配置正确或尝试设置 HTTPS_PROXY 环境变量",
430
433
  "cli.package.fetch_remote_failed": "无法获取远程包列表,请检查网络连接或代理设置",
431
434
  "cli.package.proxy_detected": " 检测到代理: {proxy}",
@@ -549,4 +552,15 @@ TRANSLATIONS = {
549
552
  "cli.types.usage_hint": "在代码中导入类型并作为变量标注,即可获得 IDE 补全:",
550
553
  "cli.types.usage_example": "from _ep_types import MyModule # 然后写 my_mod: MyModule = sdk.module.get('MyModule')",
551
554
  "cli.types.introspect_failed": "内省目标环境失败: {error}",
555
+ "cli.types.stub_title": "ErisPulse 类型存根(自动生成,请勿手动编辑)",
556
+ "cli.types.stub_intro": "由 `epsdk types` 命令根据已安装的模块/适配器生成。\n仅导出类型供用户代码作为变量标注使用,**不提供任何运行时实例**。\n所有导入都在 ``TYPE_CHECKING`` 下,运行时零开销、零行为改变。",
557
+ "cli.types.stub_usage_title": "使用方式",
558
+ "cli.types.stub_usage_comment": "# 用导入的类型标注变量,即可获得 IDE 补全",
559
+ "cli.types.stub_usage_module_hint": "# ← IDE 能补全 hello",
560
+ "cli.types.stub_usage_adapter_hint": "# ← 补全平台特有方法",
561
+ "cli.types.stub_notes_title": "说明",
562
+ "cli.types.stub_note_naming": "类型名采用 entry-point 名的 PascalCase 形式(如 ``yunhu`` → ``Yunhu``),与传入 ``sdk.adapter.get()`` / ``sdk.module.get()`` 的名称对应",
563
+ "cli.types.stub_note_static_only": "存根仅用于静态类型检查,不含运行时实现",
564
+ "cli.types.stub_note_regen": "安装/卸载模块/适配器后请重新生成:``epsdk types``",
565
+ "cli.types.stub_typing_comment": "以下类型导入仅在 IDE / 类型检查器中生效,不会被运行时执行;用户代码中经 ``from _ep_types import XxxModule`` 获取类型并用于变量标注即可获得补全",
552
566
  }
@@ -426,6 +426,9 @@ TRANSLATIONS = {
426
426
  "cli.display.enter_number": "請輸入數字序號",
427
427
  # ==================== package_manager 工具 ====================
428
428
  "cli.package.ssl_error": "SSL 驗證失敗: {error}",
429
+ "cli.package.uv_venv_failed": "uv venv 失敗:{error}",
430
+ "cli.package.python_venv_failed": "python -m venv 失敗:{error}",
431
+ "cli.package.pyproject_writeback_failed": "pyproject.toml 依賴回寫失敗:{error}",
429
432
  "cli.package.ssl_error_proxy_hint": " 偵測到代理,請確保代理設定正確或嘗試設定 HTTPS_PROXY 環境變數",
430
433
  "cli.package.fetch_remote_failed": "無法取得遠端包列表,請檢查網路連線或代理設定",
431
434
  "cli.package.proxy_detected": " 偵測到代理: {proxy}",
@@ -549,4 +552,15 @@ TRANSLATIONS = {
549
552
  "cli.types.usage_hint": "在程式碼中匯入型別並作為變數標注,即可獲得 IDE 補全:",
550
553
  "cli.types.usage_example": "from _ep_types import MyModule # 然後寫 my_mod: MyModule = sdk.module.get('MyModule')",
551
554
  "cli.types.introspect_failed": "內省目標環境失敗: {error}",
555
+ "cli.types.stub_title": "ErisPulse 類型存根(自動產生,請勿手動編輯)",
556
+ "cli.types.stub_intro": "由 `epsdk types` 命令根據已安裝的模組/適配器產生。\n僅匯出類型供使用者程式碼作為變數標註使用,**不提供任何執行時實例**。\n所有匯入都在 ``TYPE_CHECKING`` 下,執行時零開銷、零行為改變。",
557
+ "cli.types.stub_usage_title": "使用方式",
558
+ "cli.types.stub_usage_comment": "# 用匯入的類型標註變數,即可獲得 IDE 補全",
559
+ "cli.types.stub_usage_module_hint": "# ← IDE 能補全 hello",
560
+ "cli.types.stub_usage_adapter_hint": "# ← 補全平台特有方法",
561
+ "cli.types.stub_notes_title": "說明",
562
+ "cli.types.stub_note_naming": "類型名採用 entry-point 名的 PascalCase 形式(如 ``yunhu`` → ``Yunhu``),與傳入 ``sdk.adapter.get()`` / ``sdk.module.get()`` 的名稱對應",
563
+ "cli.types.stub_note_static_only": "存根僅用於靜態類型檢查,不含執行時實作",
564
+ "cli.types.stub_note_regen": "安裝/卸載模組/適配器後請重新產生:``epsdk types``",
565
+ "cli.types.stub_typing_comment": "以下類型匯入僅在 IDE / 類型檢查器中生效,不會被執行時執行;使用者程式碼中經 ``from _ep_types import XxxModule`` 取得類型並用於變數標註即可獲得補全",
552
566
  }