drydock-cli 3.0.16__tar.gz → 3.0.17__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 (48) hide show
  1. {drydock_cli-3.0.16/drydock_cli.egg-info → drydock_cli-3.0.17}/PKG-INFO +1 -1
  2. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/__init__.py +1 -1
  3. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tools/__init__.py +10 -4
  4. {drydock_cli-3.0.16 → drydock_cli-3.0.17/drydock_cli.egg-info}/PKG-INFO +1 -1
  5. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock_cli.egg-info/SOURCES.txt +1 -0
  6. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/pyproject.toml +1 -1
  7. drydock_cli-3.0.17/tests/test_todo.py +38 -0
  8. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/LICENSE +0 -0
  9. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/NOTICE +0 -0
  10. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/README.md +0 -0
  11. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/__main__.py +0 -0
  12. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/agent.py +0 -0
  13. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/bash_safety.py +0 -0
  14. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/cli.py +0 -0
  15. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/compaction.py +0 -0
  16. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/config.py +0 -0
  17. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/detect.py +0 -0
  18. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/guards.py +0 -0
  19. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/loop_detect.py +0 -0
  20. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/providers.py +0 -0
  21. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tool_registry.py +0 -0
  22. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tui/__init__.py +0 -0
  23. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tui/app.py +0 -0
  24. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tui/approval.py +0 -0
  25. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tui/messages.py +0 -0
  26. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tui/widgets.py +0 -0
  27. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock/tuning.py +0 -0
  28. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock_cli.egg-info/dependency_links.txt +0 -0
  29. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock_cli.egg-info/entry_points.txt +0 -0
  30. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock_cli.egg-info/requires.txt +0 -0
  31. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/drydock_cli.egg-info/top_level.txt +0 -0
  32. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/setup.cfg +0 -0
  33. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_approval.py +0 -0
  34. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_back_command.py +0 -0
  35. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_bash_safety.py +0 -0
  36. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_compaction.py +0 -0
  37. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_config.py +0 -0
  38. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_detect.py +0 -0
  39. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_guards_and_tools.py +0 -0
  40. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_hallucinated_tools.py +0 -0
  41. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_leaked_tool_call.py +0 -0
  42. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_loop_detect.py +0 -0
  43. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_plan_autocontinue.py +0 -0
  44. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_providers_unreachable.py +0 -0
  45. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_subagent.py +0 -0
  46. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_tools_undo.py +0 -0
  47. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_tui.py +0 -0
  48. {drydock_cli-3.0.16 → drydock_cli-3.0.17}/tests/test_tuning.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 3.0.16
3
+ Version: 3.0.17
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
@@ -7,4 +7,4 @@ try:
7
7
  __version__ = _version("drydock-cli")
8
8
  except PackageNotFoundError:
9
9
  # Running from source before install (e.g. PYTHONPATH dev runs).
10
- __version__ = "3.0.16"
10
+ __version__ = "3.0.17"
@@ -496,10 +496,16 @@ _TODO_DONE = {"x", "X", "✓"}
496
496
  _TODO_DOING = {"~", "-", "/", "*"}
497
497
 
498
498
 
499
- def parse_todo(tasks: str) -> list[tuple[str, str]]:
500
- """Parse a plain-text checklist into (text, status) pairs. Each non-empty
501
- line is one task, optionally prefixed with [x] done / [~] in_progress /
502
- [ ] pending. Deliberately forgiving (a bare line counts as pending)."""
499
+ def parse_todo(tasks) -> list[tuple[str, str]]:
500
+ """Parse a checklist into (text, status) pairs. Each non-empty line is one
501
+ task, optionally prefixed with [x] done / [~] in_progress / [ ] pending.
502
+ Deliberately forgiving: a bare line counts as pending, and `tasks` may be a
503
+ newline-joined string OR a list of lines (the model sometimes sends a JSON
504
+ array instead of one string — handle both rather than crash the TUI)."""
505
+ if isinstance(tasks, (list, tuple)):
506
+ tasks = "\n".join(str(t) for t in tasks)
507
+ elif tasks is not None and not isinstance(tasks, str):
508
+ tasks = str(tasks)
503
509
  out: list[tuple[str, str]] = []
504
510
  for raw in (tasks or "").splitlines():
505
511
  line = raw.strip().lstrip("-*•").strip()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 3.0.16
3
+ Version: 3.0.17
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
@@ -40,6 +40,7 @@ tests/test_loop_detect.py
40
40
  tests/test_plan_autocontinue.py
41
41
  tests/test_providers_unreachable.py
42
42
  tests/test_subagent.py
43
+ tests/test_todo.py
43
44
  tests/test_tools_undo.py
44
45
  tests/test_tui.py
45
46
  tests/test_tuning.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.16"
10
+ version = "3.0.17"
11
11
  description = "Drydock — a local, provider-agnostic terminal coding agent for local LLMs"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.12"
@@ -0,0 +1,38 @@
1
+ """Tests for the `todo` checklist tool and its forgiving parser."""
2
+ from __future__ import annotations
3
+
4
+ from drydock.tools import parse_todo, tool_todo
5
+
6
+
7
+ def test_parse_todo_basic_statuses():
8
+ items = parse_todo("[x] done one\n[~] doing two\n[ ] pending three")
9
+ assert items == [
10
+ ("done one", "done"),
11
+ ("doing two", "in_progress"),
12
+ ("pending three", "pending"),
13
+ ]
14
+
15
+
16
+ def test_parse_todo_accepts_list_input():
17
+ # The model sometimes sends a JSON array instead of one newline string —
18
+ # this must NOT crash (it took down the whole TUI before).
19
+ items = parse_todo([
20
+ "[~] Explore existing tests and run them",
21
+ "[ ] Add edge-case tests",
22
+ "[ ] Verify all tests pass",
23
+ ])
24
+ assert [s for _, s in items] == ["in_progress", "pending", "pending"]
25
+ assert items[0][0] == "Explore existing tests and run them"
26
+
27
+
28
+ def test_parse_todo_none_and_empty():
29
+ assert parse_todo(None) == []
30
+ assert parse_todo("") == []
31
+ assert parse_todo([]) == []
32
+
33
+
34
+ def test_tool_todo_accepts_list(tmp_path):
35
+ cfg: dict = {}
36
+ out = tool_todo({"tasks": ["[ ] a", "[x] b"]}, cfg)
37
+ assert "2 tasks" in out and "1 done" in out
38
+ assert len(cfg["_todo"]) == 2
File without changes
File without changes
File without changes
File without changes