drydock-cli 3.0.101__tar.gz → 3.0.102__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.
- {drydock_cli-3.0.101/drydock_cli.egg-info → drydock_cli-3.0.102}/PKG-INFO +1 -1
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tools/__init__.py +10 -3
- {drydock_cli-3.0.101 → drydock_cli-3.0.102/drydock_cli.egg-info}/PKG-INFO +1 -1
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock_cli.egg-info/SOURCES.txt +1 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/pyproject.toml +1 -1
- drydock_cli-3.0.102/tests/test_glob_edit_edges.py +28 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/LICENSE +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/NOTICE +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/README.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/__init__.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/__main__.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/advisor.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/agent.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/bash_safety.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/__init__.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/rmf-categorize.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/rmf-control.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/rmf-poam.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/rmf-review.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/stig-assess.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/builtin_skills/stig-remediate.md +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/cci.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/cli.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/compaction.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/config.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/detect.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/extract.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/gittools.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/graphrag.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/guards.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/loop_detect.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/mcp.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/poam.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/providers.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/rmf.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/rmf_graph.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/skills.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/stig.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tool_registry.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tui/__init__.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tui/app.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tui/approval.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tui/messages.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tui/widgets.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/tuning.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock/web.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock_cli.egg-info/dependency_links.txt +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock_cli.egg-info/entry_points.txt +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock_cli.egg-info/requires.txt +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/drydock_cli.egg-info/top_level.txt +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/setup.cfg +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_advisor.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_approval.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_back_command.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_background.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_binary_output.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_output_bounding.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_process_group.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_safety.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_sanitize.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_shell.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_stdin.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_stop_partial.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_timeout_network.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_bash_timeout_param.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_cci.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_cli_agents.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_compact_command.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_compaction.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_config.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_config_migration.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_context_limit_config.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_detect.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_dispatch.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_e2e_connected.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_edit_replace_all.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_empty_response.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_extract.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_failure_loop.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_first_run_setup.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_gittools.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_graphify_example.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_graphrag.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_grep_and_read_robust.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_guards_and_tools.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_hallucinated_tools.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_leaked_tool_call.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_loop_detect.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_mcp.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_oneshot_unreachable.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_plan_autocontinue.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_poam.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_providers_unreachable.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_read_index.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_rmf.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_rmf_graph.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_rmf_stig_graph.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_runaway_repetition.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_server_probe.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_skills.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_stig.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_stop.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_streaming_newlines.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_subagent.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_system_prompt_help.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_todo.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_tool_arg_coercion.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_tool_arg_parsing.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_tools_undo.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_tui.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_tuning.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_viewimage.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_vision_input.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_web_tools.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_write_content_coerce.py +0 -0
- {drydock_cli-3.0.101 → drydock_cli-3.0.102}/tests/test_xccdf.py +0 -0
|
@@ -833,6 +833,11 @@ def tool_edit(params: dict, config: dict) -> str:
|
|
|
833
833
|
# crashing with a TypeError in the substring search / replace.
|
|
834
834
|
old = _as_text(params.get("old_string", ""))
|
|
835
835
|
new = _as_text(params.get("new_string", ""))
|
|
836
|
+
if old == "":
|
|
837
|
+
# An empty old_string matches between every char (count = len+1) → the
|
|
838
|
+
# generic "found N times" is baffling. Say what's actually wrong.
|
|
839
|
+
return ("Error: old_string is empty. Edit replaces existing text — give the "
|
|
840
|
+
"exact text to find. To create a file or add to the end, use Write.")
|
|
836
841
|
if has_conflict_markers(new):
|
|
837
842
|
return conflict_marker_refusal(fp)
|
|
838
843
|
# If a directory was passed, try to infer the intended file (avoids a
|
|
@@ -1138,8 +1143,10 @@ def tool_bash(params: dict, config: dict) -> str:
|
|
|
1138
1143
|
|
|
1139
1144
|
|
|
1140
1145
|
def tool_glob(params: dict, config: dict) -> str:
|
|
1141
|
-
pattern = params
|
|
1142
|
-
|
|
1146
|
+
pattern = _as_str_arg(params.get("pattern"))
|
|
1147
|
+
if not pattern:
|
|
1148
|
+
return "Error: Glob needs a 'pattern' (e.g. '**/*.py')."
|
|
1149
|
+
base = _as_str_arg(params.get("path")) or config.get("cwd") or "."
|
|
1143
1150
|
try:
|
|
1144
1151
|
matches = sorted(_glob.glob(os.path.join(base, pattern), recursive=True))
|
|
1145
1152
|
if not matches:
|
|
@@ -1154,7 +1161,7 @@ def tool_glob(params: dict, config: dict) -> str:
|
|
|
1154
1161
|
def tool_grep(params: dict, config: dict) -> str:
|
|
1155
1162
|
pattern = _as_str_arg(params.get("pattern"))
|
|
1156
1163
|
path = _as_str_arg(params.get("path")) or config.get("cwd") or "."
|
|
1157
|
-
include = params.get("include", "")
|
|
1164
|
+
include = _as_str_arg(params.get("include", ""))
|
|
1158
1165
|
try:
|
|
1159
1166
|
cmd = ["grep", "-rn", "--color=never"]
|
|
1160
1167
|
if include:
|
|
@@ -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.
|
|
10
|
+
version = "3.0.102"
|
|
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,28 @@
|
|
|
1
|
+
"""More edge cases from probing: Glob must not crash on a missing/list pattern,
|
|
2
|
+
and an empty Edit old_string should say what's wrong (not the baffling generic
|
|
3
|
+
'found N times')."""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from drydock.tools import tool_glob, tool_edit
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_glob_missing_pattern_is_error_not_crash():
|
|
10
|
+
out = tool_glob({}, {"cwd": "/tmp"})
|
|
11
|
+
assert out.startswith("Error:") and "pattern" in out
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_glob_list_pattern_unwrapped(tmp_path):
|
|
15
|
+
(tmp_path / "a.py").write_text("x")
|
|
16
|
+
out = tool_glob({"pattern": ["*.py"], "path": str(tmp_path)}, {"cwd": str(tmp_path)})
|
|
17
|
+
assert "a.py" in out
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_glob_no_matches(tmp_path):
|
|
21
|
+
out = tool_glob({"pattern": "*.nope", "path": str(tmp_path)}, {"cwd": str(tmp_path)})
|
|
22
|
+
assert out.strip() == "(no matches)"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_edit_empty_old_string_clear_error(tmp_path):
|
|
26
|
+
f = tmp_path / "e.txt"; f.write_text("hello\n")
|
|
27
|
+
out = tool_edit({"file_path": str(f), "old_string": "", "new_string": "X"}, {"cwd": str(tmp_path)})
|
|
28
|
+
assert "empty" in out.lower() and f.read_text() == "hello\n"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|