langchain-agentx-cli 0.2.0__tar.gz → 0.2.1__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 (134) hide show
  1. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/PKG-INFO +1 -1
  2. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/__init__.py +1 -1
  3. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/clipboard.py +82 -24
  4. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/PKG-INFO +1 -1
  5. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/pyproject.toml +1 -1
  6. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/LICENSE +0 -0
  7. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/README.md +0 -0
  8. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/__main__.py +0 -0
  9. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/app.py +0 -0
  10. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/bootstrap.py +0 -0
  11. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/bridge/__init__.py +0 -0
  12. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/bridge/session_bridge.py +0 -0
  13. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/cli.py +0 -0
  14. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/__init__.py +0 -0
  15. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/__init__.py +0 -0
  16. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/clear.py +0 -0
  17. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/compact.py +0 -0
  18. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/help.py +0 -0
  19. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/model.py +0 -0
  20. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/quit.py +0 -0
  21. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/builtin/theme.py +0 -0
  22. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/parser.py +0 -0
  23. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/providers/__init__.py +0 -0
  24. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/providers/sdk_commands.py +0 -0
  25. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/commands/registry.py +0 -0
  26. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/completion/__init__.py +0 -0
  27. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/completion/base.py +0 -0
  28. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/completion/command_source.py +0 -0
  29. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/completion/history_source.py +0 -0
  30. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/config.py +0 -0
  31. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/history/__init__.py +0 -0
  32. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/history/store.py +0 -0
  33. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/keybindings/__init__.py +0 -0
  34. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/keybindings/bindings.py +0 -0
  35. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/llm_config.py +0 -0
  36. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/permissions/__init__.py +0 -0
  37. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/permissions/factory.py +0 -0
  38. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/permissions/policy.py +0 -0
  39. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/prompts/__init__.py +0 -0
  40. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/prompts/assembler.py +0 -0
  41. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/prompts/sections.py +0 -0
  42. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/prompts/system_prompt.py +0 -0
  43. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/screens/__init__.py +0 -0
  44. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/screens/repl.py +0 -0
  45. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/session_factory.py +0 -0
  46. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/session_options.py +0 -0
  47. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/state/__init__.py +0 -0
  48. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/state/task_store.py +0 -0
  49. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/__init__.py +0 -0
  50. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/colors.py +0 -0
  51. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/detection.py +0 -0
  52. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/manager.py +0 -0
  53. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/settings.py +0 -0
  54. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/system_theme.py +0 -0
  55. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/themes.py +0 -0
  56. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/theme/watcher.py +0 -0
  57. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tools/__init__.py +0 -0
  58. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tools/registry.py +0 -0
  59. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/__init__.py +0 -0
  60. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/message_selection.py +0 -0
  61. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/__init__.py +0 -0
  62. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/cache.py +0 -0
  63. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/component_manager.py +0 -0
  64. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/config.py +0 -0
  65. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/consumer.py +0 -0
  66. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/dialog.py +0 -0
  67. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/inject.py +0 -0
  68. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/models.py +0 -0
  69. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/presenters/__init__.py +0 -0
  70. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/presenters/base.py +0 -0
  71. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/presenters/bash.py +0 -0
  72. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/presenters/fallback.py +0 -0
  73. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/presenters/file.py +0 -0
  74. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/permissions/queue.py +0 -0
  75. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/tui/safe_screen.py +0 -0
  76. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/welcome.py +0 -0
  77. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/__init__.py +0 -0
  78. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/compact_progress.py +0 -0
  79. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/completion_overlay.py +0 -0
  80. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/input_area.py +0 -0
  81. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/message_events.py +0 -0
  82. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/message_list.py +0 -0
  83. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/messages/__init__.py +0 -0
  84. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/messages/assistant_message.py +0 -0
  85. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/messages/error_message.py +0 -0
  86. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/messages/rendering.py +0 -0
  87. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/messages/thinking_message.py +0 -0
  88. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/pending_permission.py +0 -0
  89. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/permission_inline.py +0 -0
  90. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/permission_keybindings.py +0 -0
  91. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/spinner.py +0 -0
  92. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/task_panel.py +0 -0
  93. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/__init__.py +0 -0
  94. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/agent/__init__.py +0 -0
  95. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/agent/widget.py +0 -0
  96. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/ask_user_question/__init__.py +0 -0
  97. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/ask_user_question/widget.py +0 -0
  98. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/base.py +0 -0
  99. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/bash/__init__.py +0 -0
  100. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/bash/widget.py +0 -0
  101. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/batch_edit/__init__.py +0 -0
  102. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/batch_edit/widget.py +0 -0
  103. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/edit/__init__.py +0 -0
  104. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/edit/widget.py +0 -0
  105. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/glob/__init__.py +0 -0
  106. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/glob/widget.py +0 -0
  107. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/grep/__init__.py +0 -0
  108. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/grep/widget.py +0 -0
  109. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/helpers.py +0 -0
  110. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/read/__init__.py +0 -0
  111. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/read/widget.py +0 -0
  112. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/skill/__init__.py +0 -0
  113. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/skill/widget.py +0 -0
  114. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/user_message/__init__.py +0 -0
  115. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/user_message/widget.py +0 -0
  116. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/webfetch/__init__.py +0 -0
  117. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/webfetch/widget.py +0 -0
  118. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/websearch/__init__.py +0 -0
  119. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/websearch/widget.py +0 -0
  120. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/write/__init__.py +0 -0
  121. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli/widgets/tools/write/widget.py +0 -0
  122. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/SOURCES.txt +0 -0
  123. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/dependency_links.txt +0 -0
  124. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/entry_points.txt +0 -0
  125. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/not-zip-safe +0 -0
  126. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/requires.txt +0 -0
  127. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/langchain_agentx_cli.egg-info/top_level.txt +0 -0
  128. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/setup.cfg +0 -0
  129. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/tests/test_app_interrupt.py +0 -0
  130. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/tests/test_repl_commands.py +0 -0
  131. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/tests/test_repl_submit_flow.py +0 -0
  132. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/tests/test_repl_ui.py +0 -0
  133. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/tests/test_smoke.py +0 -0
  134. {langchain_agentx_cli-0.2.0 → langchain_agentx_cli-0.2.1}/tests/test_welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langchain-agentx-cli
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Terminal CLI/TUI for AgentX: migrate Claude Code Ink UI, backed by langchain-agentx-python SDK.
5
5
  Author: GoodMood2008
6
6
  License: Apache-2.0
@@ -1,3 +1,3 @@
1
1
  """langchain_agentx_cli:依托 langchain_agentx_python SDK 的终端 CLI/TUI(CC Ink 迁移)。"""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.1"
@@ -53,9 +53,11 @@ def _wrap_for_multiplexer(sequence: str) -> str:
53
53
  def _write_osc52_to_tty(sequence: str) -> bool:
54
54
  """直接写入终端 fd,对齐 CC 写 stdout 的行为。
55
55
 
56
+ 修复:改进 OSC 52 写入的可靠性和兼容性。
57
+
56
58
  CC (Ink) 通过 process.stdout.write(raw) 发送 OSC 52。
57
- Textual 接管了 sys.stdout 但底层 fd 1 仍连接终端。
58
- 直接用 os.write(1, ...) 绕过 Python IO 层。
59
+ 优先使用 Python IO 层(sys.stdout/sys.stderr),因为它能正确
60
+ 处理各种终端环境(包括管道/重定向)。
59
61
 
60
62
  Args:
61
63
  sequence: OSC 52 序列(已包装 tmux/screen)
@@ -63,32 +65,54 @@ def _write_osc52_to_tty(sequence: str) -> bool:
63
65
  Returns:
64
66
  是否成功写入
65
67
  """
66
- encoded = sequence.encode("utf-8")
68
+ # 方法 1:sys.stdout(对齐 CC 的 process.stdout.write)
69
+ # 某些环境下 os.write(1) 会失败但 sys.stdout.write 能工作
70
+ try:
71
+ sys.stdout.write(sequence)
72
+ sys.stdout.flush()
73
+ return True
74
+ except Exception:
75
+ pass
76
+
77
+ # 方法 2:sys.stderr(备选输出流)
78
+ try:
79
+ sys.stderr.write(sequence)
80
+ sys.stderr.flush()
81
+ return True
82
+ except Exception:
83
+ pass
67
84
 
68
- # 对齐 CC:写 stdout fd(网页终端通常只监听 stdout)
85
+ # 方法 3:写 stdout fd(绕过 Python IO 层)
86
+ # 某些环境下这会失败,所以放在后面
87
+ encoded = sequence.encode("utf-8")
69
88
  try:
70
89
  os.write(1, encoded)
90
+ os.fsync(1)
71
91
  return True
72
92
  except OSError:
73
93
  pass
74
94
 
75
- # 回退:/dev/tty
95
+ # 方法 4:stderr fd
96
+ try:
97
+ os.write(2, encoded)
98
+ os.fsync(2)
99
+ return True
100
+ except OSError:
101
+ pass
102
+
103
+ # 方法 5:/dev/tty(直接与终端通信)
76
104
  try:
77
105
  fd = os.open("/dev/tty", os.O_WRONLY)
78
106
  try:
79
107
  os.write(fd, encoded)
108
+ os.fsync(fd)
80
109
  return True
81
110
  finally:
82
111
  os.close(fd)
83
112
  except OSError:
84
113
  pass
85
114
 
86
- # 最后回退:stderr
87
- try:
88
- os.write(2, encoded)
89
- return True
90
- except OSError:
91
- return False
115
+ return False
92
116
 
93
117
 
94
118
  def _detect_linux_copy_command() -> Literal["wl-copy", "xclip", "xsel"] | None:
@@ -124,7 +148,12 @@ def _detect_linux_copy_command() -> Literal["wl-copy", "xclip", "xsel"] | None:
124
148
 
125
149
 
126
150
  def _copy_native(text: str) -> bool:
127
- """使用系统工具写入剪贴板(对齐 CC copyNative)。"""
151
+ """使用系统工具写入剪贴板(对齐 CC copyNative)。
152
+
153
+ 修复 Linux 下 PRIMARY/CLIPBOARD 选择不匹配问题:
154
+ - 同时写入 PRIMARY 和 CLIPBOARD 选择
155
+ - 确保鼠标选中粘贴(中键)和 Ctrl+V 粘贴都能工作
156
+ """
128
157
  # SSH 环境下不使用 native copy(会写入远程剪贴板)
129
158
  if os.environ.get("SSH_CONNECTION"):
130
159
  return False
@@ -150,17 +179,35 @@ def _copy_native(text: str) -> bool:
150
179
  )
151
180
  return True
152
181
  if cmd == "xclip":
182
+ # 修复:同时写入 PRIMARY 和 CLIPBOARD
183
+ # PRIMARY: 鼠标选中自动复制(中键粘贴)
184
+ # CLIPBOARD: Ctrl+C/V 粘贴
185
+ subprocess.run(
186
+ ["xclip", "-selection", "primary"],
187
+ input=text.encode(),
188
+ timeout=2,
189
+ check=False,
190
+ )
153
191
  subprocess.run(
154
192
  ["xclip", "-selection", "clipboard"],
155
193
  input=text.encode(),
156
194
  timeout=2,
195
+ check=False,
157
196
  )
158
197
  return True
159
198
  if cmd == "xsel":
199
+ # 同时写入 PRIMARY 和 CLIPBOARD
200
+ subprocess.run(
201
+ ["xsel", "--primary", "--input"],
202
+ input=text.encode(),
203
+ timeout=2,
204
+ check=False,
205
+ )
160
206
  subprocess.run(
161
207
  ["xsel", "--clipboard", "--input"],
162
208
  input=text.encode(),
163
209
  timeout=2,
210
+ check=False,
164
211
  )
165
212
  return True
166
213
  return False
@@ -186,7 +233,7 @@ def copy_text(text: str) -> tuple[bool, str | None]:
186
233
  复制文本到剪贴板(对齐 CC setClipboard)。
187
234
 
188
235
  策略:
189
- 1. Native copy (pbcopy/xclip/wl-copy/clip.exe) - 仅当非 SSH 且有 DISPLAY
236
+ 1. Native copy (pbcopy/xclip/wl-copy/clip.exe) - 同时写入 PRIMARY/CLIPBOARD
190
237
  2. OSC 52 - 直接写入 stdout(对齐 CC,支持 OrcaTerm 等网页终端)
191
238
 
192
239
  Args:
@@ -212,25 +259,36 @@ def copy_text(text: str) -> tuple[bool, str | None]:
212
259
  if osc52_ok or native_ok:
213
260
  return True, None
214
261
 
215
- # 诊断失败原因
262
+ # 诊断失败原因(更详细的错误信息)
216
263
  reasons = []
217
- if platform.system().lower() == "linux":
264
+ system = platform.system().lower()
265
+
266
+ if system == "linux":
267
+ # 检查 DISPLAY/WAYLAND_DISPLAY
268
+ has_display = bool(os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"))
218
269
  if os.environ.get("SSH_CONNECTION"):
219
- reasons.append("SSH 环境无法使用 xclip/xsel")
220
- elif not (os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY")):
221
- reasons.append("无 DISPLAY/WAYLAND_DISPLAY 环境变量")
270
+ reasons.append("SSH 环境无法使用 xclip/xsel(需使用 OSC 52)")
271
+ elif not has_display:
272
+ reasons.append("无 DISPLAY/WAYLAND_DISPLAY(需安装 xclip: sudo yum install xclip)")
222
273
  else:
223
274
  cmd = _detect_linux_copy_command()
224
275
  if cmd:
225
- reasons.append(f"{cmd} 存在但调用失败")
276
+ reasons.append(f"{cmd} 调用失败")
226
277
  else:
227
- reasons.append("未安装 xclip/wl-copy/xsel(sudo yum install xclip)")
278
+ reasons.append("未安装 xclip/wl-copy/xsel")
228
279
 
280
+ # 终端复用器诊断
229
281
  if os.environ.get("TMUX"):
230
- reasons.append("tmux 环境可能不支持 OSC 52")
282
+ reasons.append("tmux: set-clipboard on(允许 OSC 52")
231
283
  elif os.environ.get("STY"):
232
- reasons.append("screen 环境可能不支持 OSC 52")
233
- else:
234
- reasons.append("终端可能不支持 OSC 52")
284
+ reasons.append("screen: altscreen on(允许 OSC 52")
285
+
286
+ # 如果没有 terminal multiplexer,检查终端类型
287
+ if not (os.environ.get("TMUX") or os.environ.get("STY")):
288
+ term = os.environ.get("TERM", "")
289
+ if "xterm" in term or "screen" in term:
290
+ reasons.append("终端可能不支持 OSC 52")
291
+ else:
292
+ reasons.append("建议使用支持 OSC 52 的终端(如 iTerm2、WezTerm)")
235
293
 
236
294
  return False, ",".join(reasons)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langchain-agentx-cli
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Terminal CLI/TUI for AgentX: migrate Claude Code Ink UI, backed by langchain-agentx-python SDK.
5
5
  Author: GoodMood2008
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "langchain-agentx-cli"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "Terminal CLI/TUI for AgentX: migrate Claude Code Ink UI, backed by langchain-agentx-python SDK."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"