drydock-cli 3.1.3__tar.gz → 3.1.4__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 (190) hide show
  1. {drydock_cli-3.1.3/drydock_cli.egg-info → drydock_cli-3.1.4}/PKG-INFO +13 -1
  2. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/README.md +12 -0
  3. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tui/app.py +56 -0
  4. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tui/widgets.py +1 -1
  5. {drydock_cli-3.1.3 → drydock_cli-3.1.4/drydock_cli.egg-info}/PKG-INFO +13 -1
  6. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/pyproject.toml +1 -1
  7. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/LICENSE +0 -0
  8. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/NOTICE +0 -0
  9. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/__init__.py +0 -0
  10. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/__main__.py +0 -0
  11. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/advisor.py +0 -0
  12. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/agent.py +0 -0
  13. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/bash_safety.py +0 -0
  14. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/budget.py +0 -0
  15. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/__init__.py +0 -0
  16. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/document-canvas.md +0 -0
  17. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-assess.md +0 -0
  18. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-cap.md +0 -0
  19. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-evidence.md +0 -0
  20. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-readiness.md +0 -0
  21. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-data.md +0 -0
  22. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-debug.md +0 -0
  23. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-finetune.md +0 -0
  24. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-metrics.md +0 -0
  25. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-rl.md +0 -0
  26. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-train.md +0 -0
  27. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/nist-ai-rmf.md +0 -0
  28. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/nist-csf.md +0 -0
  29. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-categorize.md +0 -0
  30. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-control.md +0 -0
  31. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-poam.md +0 -0
  32. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-review.md +0 -0
  33. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/stig-assess.md +0 -0
  34. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/builtin_skills/stig-remediate.md +0 -0
  35. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/cci.py +0 -0
  36. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/cli.py +0 -0
  37. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/compaction.py +0 -0
  38. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/config.py +0 -0
  39. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/detect.py +0 -0
  40. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/doccanvas.py +0 -0
  41. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/events.py +0 -0
  42. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/extract.py +0 -0
  43. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/fiar.py +0 -0
  44. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/gittools.py +0 -0
  45. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/graphrag.py +0 -0
  46. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/guards.py +0 -0
  47. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/loop_detect.py +0 -0
  48. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/mcp.py +0 -0
  49. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/phases.py +0 -0
  50. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/poam.py +0 -0
  51. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/progress.py +0 -0
  52. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/providers.py +0 -0
  53. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/recipes.py +0 -0
  54. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/recovery.py +0 -0
  55. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/resume.py +0 -0
  56. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/rmf.py +0 -0
  57. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/rmf_graph.py +0 -0
  58. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/skills.py +0 -0
  59. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/stig.py +0 -0
  60. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/subagents.py +0 -0
  61. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/suggest.py +0 -0
  62. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/task_state.py +0 -0
  63. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tool_policy.py +0 -0
  64. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tool_registry.py +0 -0
  65. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tool_result.py +0 -0
  66. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tool_select.py +0 -0
  67. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tool_validate.py +0 -0
  68. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tools/__init__.py +0 -0
  69. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/trajectory.py +0 -0
  70. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tui/__init__.py +0 -0
  71. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tui/approval.py +0 -0
  72. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tui/messages.py +0 -0
  73. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/tuning.py +0 -0
  74. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/verification.py +0 -0
  75. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock/web.py +0 -0
  76. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock_cli.egg-info/SOURCES.txt +0 -0
  77. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock_cli.egg-info/dependency_links.txt +0 -0
  78. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock_cli.egg-info/entry_points.txt +0 -0
  79. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock_cli.egg-info/requires.txt +0 -0
  80. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/drydock_cli.egg-info/top_level.txt +0 -0
  81. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/setup.cfg +0 -0
  82. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_advisor.py +0 -0
  83. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_approval.py +0 -0
  84. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_back_command.py +0 -0
  85. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_background.py +0 -0
  86. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_binary_output.py +0 -0
  87. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_crossplatform.py +0 -0
  88. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_output_bounding.py +0 -0
  89. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_process_group.py +0 -0
  90. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_safety.py +0 -0
  91. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_sanitize.py +0 -0
  92. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_shell.py +0 -0
  93. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_stdin.py +0 -0
  94. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_stop_partial.py +0 -0
  95. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_timeout_network.py +0 -0
  96. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_bash_timeout_param.py +0 -0
  97. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_budget.py +0 -0
  98. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_cci.py +0 -0
  99. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_cli_agents.py +0 -0
  100. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_compact_command.py +0 -0
  101. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_compaction.py +0 -0
  102. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_config.py +0 -0
  103. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_config_migration.py +0 -0
  104. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_context_limit_config.py +0 -0
  105. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_context_limit_issue25.py +0 -0
  106. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_criteria_coverage.py +0 -0
  107. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_cycling_detection.py +0 -0
  108. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_degenerate_argument.py +0 -0
  109. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_detect.py +0 -0
  110. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_dispatch.py +0 -0
  111. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_doccanvas.py +0 -0
  112. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_e2e_connected.py +0 -0
  113. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_edit_replace_all.py +0 -0
  114. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_effort_governor.py +0 -0
  115. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_empty_response.py +0 -0
  116. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_events.py +0 -0
  117. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_extract.py +0 -0
  118. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_failure_loop.py +0 -0
  119. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_fiar.py +0 -0
  120. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_first_run_setup.py +0 -0
  121. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_gittools.py +0 -0
  122. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_glob_edit_edges.py +0 -0
  123. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_graphify_example.py +0 -0
  124. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_graphrag.py +0 -0
  125. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_graphrag_quoted_path.py +0 -0
  126. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_graphrag_sqlite.py +0 -0
  127. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_grep_and_read_robust.py +0 -0
  128. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_guards_and_tools.py +0 -0
  129. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_hallucinated_tools.py +0 -0
  130. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_leaked_tool_call.py +0 -0
  131. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_loop_detect.py +0 -0
  132. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_mcp.py +0 -0
  133. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_model_registry.py +0 -0
  134. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_oneshot_unreachable.py +0 -0
  135. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_overthink_interrupt.py +0 -0
  136. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_phases.py +0 -0
  137. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_plan_autocontinue.py +0 -0
  138. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_poam.py +0 -0
  139. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_progress.py +0 -0
  140. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_providers_unreachable.py +0 -0
  141. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_read_index.py +0 -0
  142. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_recipes.py +0 -0
  143. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_recovery.py +0 -0
  144. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_recovery_config.py +0 -0
  145. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_recovery_integration.py +0 -0
  146. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_repeated_outcome.py +0 -0
  147. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_repetition_interrupt.py +0 -0
  148. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_resume_events.py +0 -0
  149. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_resume_restore.py +0 -0
  150. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_resume_snapshot.py +0 -0
  151. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_rmf.py +0 -0
  152. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_rmf_graph.py +0 -0
  153. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_rmf_stig_graph.py +0 -0
  154. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_rolling_plan.py +0 -0
  155. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_runaway_repetition.py +0 -0
  156. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_screenshot.py +0 -0
  157. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_server_probe.py +0 -0
  158. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_skills.py +0 -0
  159. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_sqlite_events.py +0 -0
  160. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_stall_retry.py +0 -0
  161. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_stig.py +0 -0
  162. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_stop.py +0 -0
  163. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_streaming_newlines.py +0 -0
  164. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_subagent.py +0 -0
  165. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_subagents.py +0 -0
  166. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_suggest.py +0 -0
  167. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_system_prompt_help.py +0 -0
  168. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_task_state.py +0 -0
  169. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_timeline.py +0 -0
  170. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_todo.py +0 -0
  171. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_arg_coercion.py +0 -0
  172. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_arg_coercion_more.py +0 -0
  173. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_arg_parsing.py +0 -0
  174. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_canonical.py +0 -0
  175. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_policy.py +0 -0
  176. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_result.py +0 -0
  177. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_select.py +0 -0
  178. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tool_validate.py +0 -0
  179. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tools_undo.py +0 -0
  180. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_trajectory.py +0 -0
  181. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tui.py +0 -0
  182. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_tuning.py +0 -0
  183. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_verification_gate.py +0 -0
  184. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_viewimage.py +0 -0
  185. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_vision_input.py +0 -0
  186. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_web_tools.py +0 -0
  187. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_windows_shell.py +0 -0
  188. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_worker_subagent.py +0 -0
  189. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_write_content_coerce.py +0 -0
  190. {drydock_cli-3.1.3 → drydock_cli-3.1.4}/tests/test_xccdf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 3.1.3
3
+ Version: 3.1.4
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
@@ -301,6 +301,18 @@ Redact every SSN and phone number in disclosure.md, then commit a release copy.
301
301
 
302
302
  Or run the bundled skill: `/document-canvas report.md redact all phone numbers`.
303
303
 
304
+ Prefer to drive it yourself? The **`/doc`** slash command runs the canvas deterministically
305
+ (no model), which is also the way to use it in the TUI regardless of what the model picks:
306
+
307
+ ```
308
+ /doc open report.md
309
+ /doc search report.md single-factor
310
+ /doc replace report.md single-factor authentication :: phishing-resistant MFA
311
+ /doc redact report.md SECRET-CODE-4471
312
+ /doc diff report.md # preview · /doc validate report.md
313
+ /doc commit report.md # write (keeps report.md.orig)
314
+ ```
315
+
304
316
  **Formats:** `.md` / `.markdown` / `.txt` are edited in place. `.pdf` / `.docx` are
305
317
  imported read-only (text extracted; edits written to a `<file>.canvas.md` sidecar so
306
318
  the binary original is never overwritten). Every edit is **staged** in a working copy
@@ -277,6 +277,18 @@ Redact every SSN and phone number in disclosure.md, then commit a release copy.
277
277
 
278
278
  Or run the bundled skill: `/document-canvas report.md redact all phone numbers`.
279
279
 
280
+ Prefer to drive it yourself? The **`/doc`** slash command runs the canvas deterministically
281
+ (no model), which is also the way to use it in the TUI regardless of what the model picks:
282
+
283
+ ```
284
+ /doc open report.md
285
+ /doc search report.md single-factor
286
+ /doc replace report.md single-factor authentication :: phishing-resistant MFA
287
+ /doc redact report.md SECRET-CODE-4471
288
+ /doc diff report.md # preview · /doc validate report.md
289
+ /doc commit report.md # write (keeps report.md.orig)
290
+ ```
291
+
280
292
  **Formats:** `.md` / `.markdown` / `.txt` are edited in place. `.pdf` / `.docx` are
281
293
  imported read-only (text extracted; edits written to a `<file>.canvas.md` sidecar so
282
294
  the binary original is never overwritten). Every edit is **staged** in a working copy
@@ -523,6 +523,60 @@ class DrydockApp(App):
523
523
  # markup=False so bracketed help/paths (e.g. "/model [name]") render literally.
524
524
  self._mount(Static(text, classes="assistant-msg", markup=False))
525
525
 
526
+ _DOC_USAGE = (
527
+ "Document Canvas — drive it by hand (deterministic, no model):\n"
528
+ " /doc open <path> open a doc (.md/.txt/.pdf/.docx)\n"
529
+ " /doc outline <name> headings\n"
530
+ " /doc search <name> <text> find blocks\n"
531
+ " /doc read <name> <block_id> read a block + neighbours\n"
532
+ " /doc replace <name> <query> :: <new> global search-and-replace\n"
533
+ " /doc redact <name> <text> verified redaction (red-boxing)\n"
534
+ " /doc diff|validate|commit|rollback <name>\n"
535
+ "(<name> is the filename shown by /doc open.)"
536
+ )
537
+
538
+ def _cmd_doc(self, arg: str) -> None:
539
+ """Human-driven Document Canvas — runs the Doc* tools directly so you can
540
+ use + verify the canvas in the TUI without the model choosing the tools."""
541
+ from drydock import tools as T
542
+ parts = arg.split(maxsplit=1)
543
+ sub = parts[0].lower() if parts else ""
544
+ rest = parts[1].strip() if len(parts) > 1 else ""
545
+ cfg = self.config
546
+ if sub == "open" and rest:
547
+ self._info(T.tool_docopen({"path": rest}, cfg))
548
+ return
549
+ np = rest.split(maxsplit=1)
550
+ name = np[0] if np else ""
551
+ tail = np[1].strip() if len(np) > 1 else ""
552
+ if not sub or not name:
553
+ self._info(self._DOC_USAGE)
554
+ return
555
+ if sub == "outline":
556
+ self._info(T.tool_docoutline({"name": name}, cfg))
557
+ elif sub == "search":
558
+ self._info(T.tool_docsearch({"name": name, "query": tail}, cfg))
559
+ elif sub == "read":
560
+ self._info(T.tool_docread({"name": name, "block_id": tail, "before": 1, "after": 1}, cfg))
561
+ elif sub == "replace":
562
+ if "::" not in tail:
563
+ self._info("usage: /doc replace <name> <query> :: <replacement>")
564
+ return
565
+ q, r = tail.split("::", 1)
566
+ self._info(T.tool_docreplace({"name": name, "query": q.strip(), "replacement": r.strip()}, cfg))
567
+ elif sub == "redact":
568
+ self._info(T.tool_docredact({"name": name, "query": tail}, cfg))
569
+ elif sub == "diff":
570
+ self._info(T.tool_docdiff({"name": name}, cfg))
571
+ elif sub == "validate":
572
+ self._info(T.tool_docvalidate({"name": name}, cfg))
573
+ elif sub == "commit":
574
+ self._info(T.tool_doccommit({"name": name}, cfg))
575
+ elif sub == "rollback":
576
+ self._info(T.tool_docrollback({"name": name}, cfg))
577
+ else:
578
+ self._info(self._DOC_USAGE)
579
+
526
580
  def _handle_slash(self, text: str) -> None:
527
581
  parts = text.split(maxsplit=1)
528
582
  cmd = parts[0].lower()
@@ -581,6 +635,8 @@ class DrydockApp(App):
581
635
  self._cmd_ask(arg, inject=True)
582
636
  elif cmd == "/graphrag":
583
637
  self._cmd_graphrag(arg)
638
+ elif cmd == "/doc":
639
+ self._cmd_doc(arg)
584
640
  elif cmd == "/status":
585
641
  t = self.state
586
642
  self._info(
@@ -154,7 +154,7 @@ class PromptHistory:
154
154
  SLASH_COMMANDS = [
155
155
  "/help", "/model", "/cwd", "/undo", "/back", "/stop", "/status",
156
156
  "/compact", "/context", "/shell", "/events", "/trace", "/resume", "/advisor", "/ask", "/ask!", "/graphrag", "/skills",
157
- "/loop", "/mcp", "/rmf", "/stig",
157
+ "/loop", "/mcp", "/rmf", "/stig", "/doc",
158
158
  "/clear", "/quit",
159
159
  ]
160
160
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 3.1.3
3
+ Version: 3.1.4
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
@@ -301,6 +301,18 @@ Redact every SSN and phone number in disclosure.md, then commit a release copy.
301
301
 
302
302
  Or run the bundled skill: `/document-canvas report.md redact all phone numbers`.
303
303
 
304
+ Prefer to drive it yourself? The **`/doc`** slash command runs the canvas deterministically
305
+ (no model), which is also the way to use it in the TUI regardless of what the model picks:
306
+
307
+ ```
308
+ /doc open report.md
309
+ /doc search report.md single-factor
310
+ /doc replace report.md single-factor authentication :: phishing-resistant MFA
311
+ /doc redact report.md SECRET-CODE-4471
312
+ /doc diff report.md # preview · /doc validate report.md
313
+ /doc commit report.md # write (keeps report.md.orig)
314
+ ```
315
+
304
316
  **Formats:** `.md` / `.markdown` / `.txt` are edited in place. `.pdf` / `.docx` are
305
317
  imported read-only (text extracted; edits written to a `<file>.canvas.md` sidecar so
306
318
  the binary original is never overwritten). Every edit is **staged** in a working copy
@@ -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.1.3"
10
+ version = "3.1.4"
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"
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