drydock-cli 3.0.89__tar.gz → 3.0.90__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 (105) hide show
  1. {drydock_cli-3.0.89/drydock_cli.egg-info → drydock_cli-3.0.90}/PKG-INFO +1 -1
  2. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tools/__init__.py +7 -0
  3. {drydock_cli-3.0.89 → drydock_cli-3.0.90/drydock_cli.egg-info}/PKG-INFO +1 -1
  4. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock_cli.egg-info/SOURCES.txt +1 -0
  5. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/pyproject.toml +1 -1
  6. drydock_cli-3.0.90/tests/test_bash_stdin.py +40 -0
  7. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/LICENSE +0 -0
  8. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/NOTICE +0 -0
  9. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/README.md +0 -0
  10. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/__init__.py +0 -0
  11. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/__main__.py +0 -0
  12. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/advisor.py +0 -0
  13. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/agent.py +0 -0
  14. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/bash_safety.py +0 -0
  15. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/__init__.py +0 -0
  16. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/rmf-categorize.md +0 -0
  17. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/rmf-control.md +0 -0
  18. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/rmf-poam.md +0 -0
  19. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/rmf-review.md +0 -0
  20. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/stig-assess.md +0 -0
  21. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/builtin_skills/stig-remediate.md +0 -0
  22. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/cci.py +0 -0
  23. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/cli.py +0 -0
  24. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/compaction.py +0 -0
  25. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/config.py +0 -0
  26. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/detect.py +0 -0
  27. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/extract.py +0 -0
  28. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/gittools.py +0 -0
  29. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/graphrag.py +0 -0
  30. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/guards.py +0 -0
  31. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/loop_detect.py +0 -0
  32. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/mcp.py +0 -0
  33. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/poam.py +0 -0
  34. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/providers.py +0 -0
  35. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/rmf.py +0 -0
  36. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/rmf_graph.py +0 -0
  37. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/skills.py +0 -0
  38. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/stig.py +0 -0
  39. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tool_registry.py +0 -0
  40. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tui/__init__.py +0 -0
  41. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tui/app.py +0 -0
  42. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tui/approval.py +0 -0
  43. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tui/messages.py +0 -0
  44. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tui/widgets.py +0 -0
  45. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/tuning.py +0 -0
  46. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock/web.py +0 -0
  47. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock_cli.egg-info/dependency_links.txt +0 -0
  48. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock_cli.egg-info/entry_points.txt +0 -0
  49. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock_cli.egg-info/requires.txt +0 -0
  50. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/drydock_cli.egg-info/top_level.txt +0 -0
  51. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/setup.cfg +0 -0
  52. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_advisor.py +0 -0
  53. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_approval.py +0 -0
  54. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_back_command.py +0 -0
  55. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_bash_background.py +0 -0
  56. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_bash_output_bounding.py +0 -0
  57. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_bash_process_group.py +0 -0
  58. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_bash_safety.py +0 -0
  59. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_bash_timeout_network.py +0 -0
  60. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_cci.py +0 -0
  61. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_cli_agents.py +0 -0
  62. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_compact_command.py +0 -0
  63. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_compaction.py +0 -0
  64. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_config.py +0 -0
  65. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_config_migration.py +0 -0
  66. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_context_limit_config.py +0 -0
  67. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_detect.py +0 -0
  68. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_dispatch.py +0 -0
  69. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_e2e_connected.py +0 -0
  70. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_empty_response.py +0 -0
  71. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_extract.py +0 -0
  72. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_failure_loop.py +0 -0
  73. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_first_run_setup.py +0 -0
  74. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_gittools.py +0 -0
  75. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_graphrag.py +0 -0
  76. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_guards_and_tools.py +0 -0
  77. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_hallucinated_tools.py +0 -0
  78. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_leaked_tool_call.py +0 -0
  79. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_loop_detect.py +0 -0
  80. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_mcp.py +0 -0
  81. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_oneshot_unreachable.py +0 -0
  82. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_plan_autocontinue.py +0 -0
  83. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_poam.py +0 -0
  84. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_providers_unreachable.py +0 -0
  85. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_read_index.py +0 -0
  86. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_rmf.py +0 -0
  87. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_rmf_graph.py +0 -0
  88. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_rmf_stig_graph.py +0 -0
  89. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_runaway_repetition.py +0 -0
  90. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_server_probe.py +0 -0
  91. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_skills.py +0 -0
  92. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_stig.py +0 -0
  93. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_stop.py +0 -0
  94. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_streaming_newlines.py +0 -0
  95. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_subagent.py +0 -0
  96. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_system_prompt_help.py +0 -0
  97. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_todo.py +0 -0
  98. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_tool_arg_parsing.py +0 -0
  99. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_tools_undo.py +0 -0
  100. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_tui.py +0 -0
  101. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_tuning.py +0 -0
  102. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_viewimage.py +0 -0
  103. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_vision_input.py +0 -0
  104. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_web_tools.py +0 -0
  105. {drydock_cli-3.0.89 → drydock_cli-3.0.90}/tests/test_xccdf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 3.0.89
3
+ Version: 3.0.90
4
4
  Summary: Drydock — a local, provider-agnostic terminal coding agent for local LLMs
5
5
  Author: Frank Bobe III
6
6
  License-Expression: Apache-2.0
@@ -911,6 +911,13 @@ def tool_bash(params: dict, config: dict) -> str:
911
911
  try:
912
912
  proc = subprocess.Popen(
913
913
  cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
914
+ # stdin=DEVNULL so a command that reads stdin gets immediate EOF
915
+ # (correct for a non-interactive tool) instead of inheriting the
916
+ # TUI's terminal — where it would steal the user's keystrokes or hang
917
+ # waiting for input Textual has captured. The agent still feeds input
918
+ # explicitly via a pipe/redirect (echo x | cmd, cmd < file), which
919
+ # overrides this.
920
+ stdin=subprocess.DEVNULL,
914
921
  text=True, cwd=config.get("cwd"), start_new_session=True,
915
922
  )
916
923
  config.setdefault("_abort", {})["proc"] = proc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 3.0.89
3
+ Version: 3.0.90
4
4
  Summary: Drydock — a local, provider-agnostic terminal coding agent for local LLMs
5
5
  Author: Frank Bobe III
6
6
  License-Expression: Apache-2.0
@@ -53,6 +53,7 @@ tests/test_bash_background.py
53
53
  tests/test_bash_output_bounding.py
54
54
  tests/test_bash_process_group.py
55
55
  tests/test_bash_safety.py
56
+ tests/test_bash_stdin.py
56
57
  tests/test_bash_timeout_network.py
57
58
  tests/test_cci.py
58
59
  tests/test_cli_agents.py
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
  # PyPI distribution name is drydock-cli (the established install name, continued
8
8
  # from the retired v2 fork); the import package + CLI command stay `drydock`.
9
9
  name = "drydock-cli"
10
- version = "3.0.89"
10
+ version = "3.0.90"
11
11
  description = "Drydock — a local, provider-agnostic terminal coding agent for local LLMs"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.11"
@@ -0,0 +1,40 @@
1
+ """tool_bash must NOT inherit the caller's stdin (in the TUI that's Textual's
2
+ terminal): a command that reads stdin should get immediate EOF, not hang waiting
3
+ for input or steal the user's keystrokes. The agent still feeds input explicitly
4
+ via a pipe/redirect, which overrides the DEVNULL stdin."""
5
+ from __future__ import annotations
6
+
7
+ import time
8
+
9
+ from drydock.tools import tool_bash
10
+
11
+
12
+ def _run(cmd, timeout=6):
13
+ t0 = time.monotonic()
14
+ out = tool_bash({"command": cmd, "timeout": timeout}, {"cwd": "/tmp"})
15
+ return time.monotonic() - t0, out
16
+
17
+
18
+ def test_stdin_reader_gets_eof_not_hang():
19
+ dt, out = _run("read x; echo \"got:[$x]\"")
20
+ assert dt < 2.0 and "got:[]" in out, "reading stdin should EOF instantly, not hang"
21
+
22
+
23
+ def test_cat_no_input_eofs():
24
+ dt, out = _run("cat && echo DONE")
25
+ assert dt < 2.0 and "DONE" in out
26
+
27
+
28
+ def test_python_input_raises_eoferror_cleanly():
29
+ _, out = _run('python3 -c "input()" 2>&1 | tail -1')
30
+ assert "EOFError" in out
31
+
32
+
33
+ def test_piped_input_still_works():
34
+ _, out = _run("echo hello | cat")
35
+ assert "hello" in out
36
+
37
+
38
+ def test_redirect_from_file_still_works():
39
+ _, out = _run("printf 'a\\nb\\n' > /tmp/ddin.txt; wc -l < /tmp/ddin.txt")
40
+ assert "2" in out
File without changes
File without changes
File without changes
File without changes