pentool 0.2.5__tar.gz → 0.2.7__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 (169) hide show
  1. {pentool-0.2.5 → pentool-0.2.7}/PKG-INFO +1 -1
  2. {pentool-0.2.5 → pentool-0.2.7}/pentool/__init__.py +1 -1
  3. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/license.py +41 -11
  4. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/app.py +5 -5
  5. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/proxy/screen.py +0 -24
  6. {pentool-0.2.5 → pentool-0.2.7}/pentool.egg-info/PKG-INFO +1 -1
  7. {pentool-0.2.5 → pentool-0.2.7}/pyproject.toml +1 -1
  8. {pentool-0.2.5 → pentool-0.2.7}/LICENSE +0 -0
  9. {pentool-0.2.5 → pentool-0.2.7}/README.md +0 -0
  10. {pentool-0.2.5 → pentool-0.2.7}/pentool/__main__.py +0 -0
  11. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/__init__.py +0 -0
  12. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/base_api.py +0 -0
  13. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/comparer_api.py +0 -0
  14. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/decoder_api.py +0 -0
  15. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/intruder_api.py +0 -0
  16. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/proxy_api.py +0 -0
  17. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/repeater_api.py +0 -0
  18. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/sequencer_api.py +0 -0
  19. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/spider_api.py +0 -0
  20. {pentool-0.2.5 → pentool-0.2.7}/pentool/api/target_api.py +0 -0
  21. {pentool-0.2.5 → pentool-0.2.7}/pentool/cli/__init__.py +0 -0
  22. {pentool-0.2.5 → pentool-0.2.7}/pentool/cli/main.py +0 -0
  23. {pentool-0.2.5 → pentool-0.2.7}/pentool/cli/project.py +0 -0
  24. {pentool-0.2.5 → pentool-0.2.7}/pentool/cli/proxy.py +0 -0
  25. {pentool-0.2.5 → pentool-0.2.7}/pentool/cli/scan.py +0 -0
  26. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/__init__.py +0 -0
  27. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/config.py +0 -0
  28. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/crash_reporter.py +0 -0
  29. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/database.py +0 -0
  30. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/event_bus.py +0 -0
  31. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/events.py +0 -0
  32. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/features.py +0 -0
  33. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/logging.py +0 -0
  34. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/plugin_manager.py +0 -0
  35. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/project.py +0 -0
  36. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/storage_interface.py +0 -0
  37. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/updater.py +0 -0
  38. {pentool-0.2.5 → pentool-0.2.7}/pentool/core/utils.py +0 -0
  39. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/__init__.py +0 -0
  40. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/comparer.py +0 -0
  41. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/decoder.py +0 -0
  42. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/intruder.py +0 -0
  43. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/match_replace.py +0 -0
  44. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/proxy.py +0 -0
  45. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/repeater.py +0 -0
  46. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/sequencer.py +0 -0
  47. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/spider.py +0 -0
  48. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/target.py +0 -0
  49. {pentool-0.2.5 → pentool-0.2.7}/pentool/modules/websocket_handler.py +0 -0
  50. {pentool-0.2.5 → pentool-0.2.7}/pentool/plugins/__init__.py +0 -0
  51. {pentool-0.2.5 → pentool-0.2.7}/pentool/plugins/builtin/__init__.py +0 -0
  52. {pentool-0.2.5 → pentool-0.2.7}/pentool/plugins/example_plugin.py +0 -0
  53. {pentool-0.2.5 → pentool-0.2.7}/pentool/plugins/example_plugin.tcss +0 -0
  54. {pentool-0.2.5 → pentool-0.2.7}/pentool/services/__init__.py +0 -0
  55. {pentool-0.2.5 → pentool-0.2.7}/pentool/services/base_service.py +0 -0
  56. {pentool-0.2.5 → pentool-0.2.7}/pentool/services/intruder_service.py +0 -0
  57. {pentool-0.2.5 → pentool-0.2.7}/pentool/services/proxy_service.py +0 -0
  58. {pentool-0.2.5 → pentool-0.2.7}/pentool/services/repeater_service.py +0 -0
  59. {pentool-0.2.5 → pentool-0.2.7}/pentool/services/scan_service.py +0 -0
  60. {pentool-0.2.5 → pentool-0.2.7}/pentool/storage/__init__.py +0 -0
  61. {pentool-0.2.5 → pentool-0.2.7}/pentool/storage/http_storage.py +0 -0
  62. {pentool-0.2.5 → pentool-0.2.7}/pentool/storage/large_body_handler.py +0 -0
  63. {pentool-0.2.5 → pentool-0.2.7}/pentool/storage/lru_cache.py +0 -0
  64. {pentool-0.2.5 → pentool-0.2.7}/pentool/t.py +0 -0
  65. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/__init__.py +0 -0
  66. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/constants.py +0 -0
  67. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/__init__.py +0 -0
  68. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/cert_dialog.py +0 -0
  69. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/cert_dialog.tcss +0 -0
  70. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/comment_dialog.py +0 -0
  71. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/comment_dialog.tcss +0 -0
  72. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/file_selector.py +0 -0
  73. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/file_selector.tcss +0 -0
  74. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/load_from_proxy.py +0 -0
  75. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/load_from_proxy.tcss +0 -0
  76. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/match_replace_dialog.py +0 -0
  77. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/match_replace_dialog.tcss +0 -0
  78. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/project_dialog.py +0 -0
  79. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/project_dialog.tcss +0 -0
  80. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/scope_dialog.py +0 -0
  81. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/dialogs/scope_dialog.tcss +0 -0
  82. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/messages.py +0 -0
  83. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/mixins/__init__.py +0 -0
  84. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/mixins/app_mixin.py +0 -0
  85. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/mixins/dialog_cancel.py +0 -0
  86. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/mixins/request_context_menu.py +0 -0
  87. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/project_manager.py +0 -0
  88. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/__init__.py +0 -0
  89. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/base.py +0 -0
  90. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/comparer/__init__.py +0 -0
  91. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/comparer/screen.py +0 -0
  92. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/comparer/screen.tcss +0 -0
  93. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/dashboard/__init__.py +0 -0
  94. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/dashboard/live_dashboard.py +0 -0
  95. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/dashboard/screen.py +0 -0
  96. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/dashboard/screen.tcss +0 -0
  97. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/decoder/__init__.py +0 -0
  98. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/decoder/screen.py +0 -0
  99. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/decoder/screen.tcss +0 -0
  100. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/extensions/__init__.py +0 -0
  101. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/extensions/screen.py +0 -0
  102. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/extensions/screen.tcss +0 -0
  103. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/intruder/__init__.py +0 -0
  104. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/intruder/screen.py +0 -0
  105. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/intruder/screen.tcss +0 -0
  106. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/proxy/__init__.py +0 -0
  107. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/proxy/screen.tcss +0 -0
  108. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/repeater/__init__.py +0 -0
  109. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/repeater/screen.py +0 -0
  110. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/repeater/screen.tcss +0 -0
  111. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/scanner_unavailable.py +0 -0
  112. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/sequencer/__init__.py +0 -0
  113. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/sequencer/screen.py +0 -0
  114. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/sequencer/screen.tcss +0 -0
  115. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/settings/__init__.py +0 -0
  116. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/settings/hotkeys.py +0 -0
  117. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/settings/hotkeys.tcss +0 -0
  118. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/settings/screen.py +0 -0
  119. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/settings/screen.tcss +0 -0
  120. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/spider/__init__.py +0 -0
  121. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/spider/screen.py +0 -0
  122. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/spider/screen.tcss +0 -0
  123. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/target/__init__.py +0 -0
  124. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/target/screen.py +0 -0
  125. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/target/screen.tcss +0 -0
  126. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/terminal/__init__.py +0 -0
  127. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/terminal/screen.py +0 -0
  128. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/screens/terminal/screen.tcss +0 -0
  129. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/__init__.py +0 -0
  130. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/activity_indicator.py +0 -0
  131. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/activity_indicator.tcss +0 -0
  132. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/context_menu.py +0 -0
  133. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/context_menu.tcss +0 -0
  134. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/filter_bar.py +0 -0
  135. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/filter_bar.tcss +0 -0
  136. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/inspector_panel.py +0 -0
  137. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/inspector_panel.tcss +0 -0
  138. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/menu.tcss +0 -0
  139. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/menu_bar.tcss +0 -0
  140. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/module_tabs.py +0 -0
  141. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/module_tabs.tcss +0 -0
  142. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/nice_checkbox.py +0 -0
  143. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/payload_drop_zone.py +0 -0
  144. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/payload_drop_zone.tcss +0 -0
  145. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/request_editor.py +0 -0
  146. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/request_editor.tcss +0 -0
  147. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/resize_handle.py +0 -0
  148. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/resize_handle.tcss +0 -0
  149. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/search_bar.py +0 -0
  150. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/search_bar.tcss +0 -0
  151. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/statusbar.py +0 -0
  152. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/statusbar.tcss +0 -0
  153. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/toolbar_button.py +0 -0
  154. {pentool-0.2.5 → pentool-0.2.7}/pentool/tui/widgets/toolbar_button.tcss +0 -0
  155. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/__init__.py +0 -0
  156. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/cert.py +0 -0
  157. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/coder.py +0 -0
  158. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/copy_as.py +0 -0
  159. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/diff.py +0 -0
  160. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/http_client.py +0 -0
  161. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/parser.py +0 -0
  162. {pentool-0.2.5 → pentool-0.2.7}/pentool/utils/terminal_check.py +0 -0
  163. {pentool-0.2.5 → pentool-0.2.7}/pentool.egg-info/SOURCES.txt +0 -0
  164. {pentool-0.2.5 → pentool-0.2.7}/pentool.egg-info/dependency_links.txt +0 -0
  165. {pentool-0.2.5 → pentool-0.2.7}/pentool.egg-info/entry_points.txt +0 -0
  166. {pentool-0.2.5 → pentool-0.2.7}/pentool.egg-info/requires.txt +0 -0
  167. {pentool-0.2.5 → pentool-0.2.7}/pentool.egg-info/top_level.txt +0 -0
  168. {pentool-0.2.5 → pentool-0.2.7}/setup.cfg +0 -0
  169. {pentool-0.2.5 → pentool-0.2.7}/tests/test_user_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pentool
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Modern Web Pentesting TUI - Professional security testing tool
5
5
  Author-email: Pentool Team <dev@pentool.pro>
6
6
  License: AGPL-3.0
@@ -1,6 +1,6 @@
1
1
  """Pentool — professional web security testing toolkit with Textual TUI."""
2
2
 
3
- __version__ = "0.2.5"
3
+ __version__ = "0.2.7"
4
4
  __author__ = "pentool"
5
5
 
6
6
 
@@ -648,6 +648,7 @@ async def download_pro_package(key: str, machine_id: str) -> bool:
648
648
  plat = _current_platform()
649
649
  try:
650
650
  import aiohttp
651
+ build_id: str | None = None
651
652
  async with aiohttp.ClientSession(
652
653
  timeout=aiohttp.ClientTimeout(total=60)
653
654
  ) as session:
@@ -659,6 +660,13 @@ async def download_pro_package(key: str, machine_id: str) -> bool:
659
660
  if resp.status != 200:
660
661
  return False
661
662
  archive_bytes = await resp.read()
663
+ # The Worker resolves the release/asset to serve this archive
664
+ # and knows its build_id at that point — it now echoes it back
665
+ # in this same response (see pentool-backend's /api/download
666
+ # handler) so we don't need a separate follow-up request just
667
+ # to learn it. Falls back to _fetch_pro_build_id() below if
668
+ # an older Worker deploy doesn't send the header yet.
669
+ build_id = resp.headers.get("X-Pro-Build-Id")
662
670
 
663
671
  async with session.post(
664
672
  f"{_LICENSE_API_BASE}/api/download",
@@ -685,12 +693,25 @@ async def download_pro_package(key: str, machine_id: str) -> bool:
685
693
  # check_and_update_pro_package() can tell "nothing changed" from "a
686
694
  # new build was published" without re-downloading the archive just
687
695
  # to compare it.
688
- try:
689
- build_id = await _fetch_pro_build_id(plat)
690
- if build_id:
691
- _write_pro_meta(build_id)
692
- except Exception:
693
- pass # non-fatal — worst case, next check just re-downloads once more
696
+ #
697
+ # Writing this is what makes the extracted package "trusted" —
698
+ # is_pro_package_compatible() refuses to load it otherwise. Getting
699
+ # here means the archive already extracted successfully, so this
700
+ # must not silently no-op: if the Worker didn't send the header
701
+ # (old deploy) AND the fallback /api/pro/version call also fails
702
+ # (flaky network), fall back to recording the current FREE version
703
+ # with a synthetic build_id rather than leaving .build_meta.json
704
+ # unwritten — a fully-installed, working PRO package should never be
705
+ # stuck showing "doesn't record which version" just because one
706
+ # extra network round-trip hiccupped after the real work was done.
707
+ if not build_id:
708
+ try:
709
+ build_id = await _fetch_pro_build_id(plat)
710
+ except Exception:
711
+ build_id = None
712
+ if not build_id:
713
+ build_id = f"unknown:{time.time()}"
714
+ _write_pro_meta(build_id)
694
715
 
695
716
  return True
696
717
  except Exception:
@@ -771,15 +792,24 @@ async def check_and_update_pro_package() -> "ProSyncResult":
771
792
 
772
793
  meta = _read_pro_meta()
773
794
  local_build_id = meta.get("build_id", "")
774
-
775
- if local_build_id == remote_build_id:
776
- _compatible, warning = is_pro_package_compatible()
777
- return ProSyncResult(updated=False, warning=warning)
795
+ _compatible, _warning = is_pro_package_compatible()
796
+
797
+ # Even if the build_id hasn't changed (no new release published since),
798
+ # a package already marked incompatible (e.g. free_version never got
799
+ # recorded, from before the /api/download build_id-header fix) must
800
+ # still be re-downloaded — otherwise this function forever reports the
801
+ # same "doesn't record which version" warning and never actually heals
802
+ # it, since download_pro_package() is only reached below when the
803
+ # build_id differs. A once-broken install with a matching build_id
804
+ # would never take that path without this check.
805
+ if local_build_id == remote_build_id and _compatible:
806
+ return ProSyncResult(updated=False, warning="")
778
807
 
779
808
  updated = await download_pro_package(info.license_key, info.machine_id)
780
809
  if updated:
781
810
  return ProSyncResult(updated=True, warning="")
782
811
 
783
- # Download of the newer build failed — warn if what's left on disk is stale.
812
+ # Download of the newer/repaired build failed — warn if what's left on
813
+ # disk is stale.
784
814
  _compatible, warning = is_pro_package_compatible()
785
815
  return ProSyncResult(updated=False, warning=warning)
@@ -681,7 +681,7 @@ class PentoolApp(App):
681
681
  pass
682
682
 
683
683
  def action_repeater_send(self) -> None:
684
- """Ctrl+Space / ctrl-at — отправить запрос в Repeater независимо от глубины фокуса."""
684
+ """Ctrl+Space / ctrl-at — send the request to Repeater regardless of focus depth."""
685
685
  if self._active_module != "repeater":
686
686
  return
687
687
  try:
@@ -725,8 +725,8 @@ class PentoolApp(App):
725
725
  lic = get_session_license()
726
726
  if not (lic.valid and lic.has_feature("scanner_pro")):
727
727
  self.notify(
728
- "🔒 Scanner — платная функция.\n"
729
- "Активируйте: pentool license trial",
728
+ "🔒 Scanner — paid feature.\n"
729
+ "Activate: pentool license trial",
730
730
  severity="warning",
731
731
  timeout=5,
732
732
  )
@@ -751,7 +751,7 @@ class PentoolApp(App):
751
751
  return self._proxy_api
752
752
 
753
753
  def flash(self, message: str, severity: str = "information", timeout: float = 2.5) -> None:
754
- """Краткое сообщение справа в строке модулей (tooltip2)."""
754
+ """Short message on the right side of the module bar (tooltip2)."""
755
755
  try:
756
756
  self.query_one("#module-tabs", ModuleTabs).flash(message, severity, timeout)
757
757
  except Exception:
@@ -810,7 +810,7 @@ class PentoolApp(App):
810
810
  # ProjectManager._do_switch) — the other screens may still be
811
811
  # reloading, but that's independent of Proxy.
812
812
  self.notify(
813
- "Проект ещё открывается — подождите пару секунд перед запуском Proxy",
813
+ "Project is still opening — wait a couple of seconds before starting Proxy",
814
814
  severity="warning",
815
815
  timeout=4,
816
816
  )
@@ -1860,7 +1860,6 @@ class ProxyScreen(RequestContextMenuMixin, AppMixin, Widget):
1860
1860
  ("send_repeater", "Send to Repeater"),
1861
1861
  ("send_intruder", "Send to Intruder"),
1862
1862
  ("send_scanner", "Send to Scanner"),
1863
- ("send_target", "Send to Target"),
1864
1863
  ("-", ""),
1865
1864
  ("mark_req", "Mark color"),
1866
1865
  ("edit_comment", "View/Edit Comment"),
@@ -1923,8 +1922,6 @@ class ProxyScreen(RequestContextMenuMixin, AppMixin, Widget):
1923
1922
  if host:
1924
1923
  from pentool.tui.messages import SendHostToScanner
1925
1924
  self.app.post_message(SendHostToScanner(host))
1926
- elif action == "send_target":
1927
- self._send_to_target()
1928
1925
  elif action == "mark_req":
1929
1926
  self._mark_dialog()
1930
1927
  elif action == "edit_comment":
@@ -1990,27 +1987,6 @@ class ProxyScreen(RequestContextMenuMixin, AppMixin, Widget):
1990
1987
  def _sync_target_host_scope(self, host: str, in_scope: bool) -> None:
1991
1988
  self.app.post_message(SyncScopeToTarget(host, in_scope)) # type: ignore[attr-defined]
1992
1989
 
1993
- def _send_to_target(self) -> None:
1994
- if self._selected_req_id is None:
1995
- return
1996
- self.run_worker(self._do_send_to_target())
1997
-
1998
- async def _do_send_to_target(self) -> None:
1999
- if self._proxy_service is None or not self._proxy_service.is_storage_ready() or self._selected_req_id is None:
2000
- return
2001
- entry = await self._proxy_service.get_full_entry(self._selected_req_id)
2002
- if entry is None:
2003
- return
2004
- from pentool.utils.parser import ParsedRequest
2005
- parsed = ParsedRequest(
2006
- method=entry.get("method", "GET"),
2007
- url=entry.get("url", ""),
2008
- headers=entry.get("request_headers") or {},
2009
- body=entry.get("request_body", "") or "",
2010
- )
2011
- self.app.post_message(SendToTarget(parsed))
2012
- self.app.notify("Added to Target", severity="information", timeout=2)
2013
-
2014
1990
  # ── Colors available for marking requests ─────────────────────────────────
2015
1991
 
2016
1992
  _COLOR_OPTIONS: list[tuple[str, str]] = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pentool
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Modern Web Pentesting TUI - Professional security testing tool
5
5
  Author-email: Pentool Team <dev@pentool.pro>
6
6
  License: AGPL-3.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pentool"
7
- version = "0.2.5"
7
+ version = "0.2.7"
8
8
  description = "Modern Web Pentesting TUI - Professional security testing tool"
9
9
  authors = [
10
10
  {name = "Pentool Team", email = "dev@pentool.pro"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes