drydock-cli 3.1.2__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.2/drydock_cli.egg-info → drydock_cli-3.1.4}/PKG-INFO +54 -1
  2. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/README.md +53 -0
  3. drydock_cli-3.1.4/drydock/builtin_skills/document-canvas.md +40 -0
  4. drydock_cli-3.1.4/drydock/doccanvas.py +525 -0
  5. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tools/__init__.py +376 -0
  6. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tui/app.py +56 -0
  7. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tui/widgets.py +2 -2
  8. {drydock_cli-3.1.2 → drydock_cli-3.1.4/drydock_cli.egg-info}/PKG-INFO +54 -1
  9. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock_cli.egg-info/SOURCES.txt +3 -0
  10. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/pyproject.toml +1 -1
  11. drydock_cli-3.1.4/tests/test_doccanvas.py +252 -0
  12. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_skills.py +1 -0
  13. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/LICENSE +0 -0
  14. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/NOTICE +0 -0
  15. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/__init__.py +0 -0
  16. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/__main__.py +0 -0
  17. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/advisor.py +0 -0
  18. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/agent.py +0 -0
  19. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/bash_safety.py +0 -0
  20. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/budget.py +0 -0
  21. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/__init__.py +0 -0
  22. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-assess.md +0 -0
  23. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-cap.md +0 -0
  24. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-evidence.md +0 -0
  25. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/fiar-readiness.md +0 -0
  26. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-data.md +0 -0
  27. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-debug.md +0 -0
  28. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-finetune.md +0 -0
  29. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-metrics.md +0 -0
  30. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-rl.md +0 -0
  31. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/ml-train.md +0 -0
  32. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/nist-ai-rmf.md +0 -0
  33. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/nist-csf.md +0 -0
  34. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-categorize.md +0 -0
  35. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-control.md +0 -0
  36. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-poam.md +0 -0
  37. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/rmf-review.md +0 -0
  38. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/stig-assess.md +0 -0
  39. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/builtin_skills/stig-remediate.md +0 -0
  40. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/cci.py +0 -0
  41. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/cli.py +0 -0
  42. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/compaction.py +0 -0
  43. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/config.py +0 -0
  44. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/detect.py +0 -0
  45. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/events.py +0 -0
  46. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/extract.py +0 -0
  47. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/fiar.py +0 -0
  48. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/gittools.py +0 -0
  49. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/graphrag.py +0 -0
  50. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/guards.py +0 -0
  51. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/loop_detect.py +0 -0
  52. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/mcp.py +0 -0
  53. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/phases.py +0 -0
  54. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/poam.py +0 -0
  55. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/progress.py +0 -0
  56. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/providers.py +0 -0
  57. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/recipes.py +0 -0
  58. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/recovery.py +0 -0
  59. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/resume.py +0 -0
  60. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/rmf.py +0 -0
  61. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/rmf_graph.py +0 -0
  62. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/skills.py +0 -0
  63. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/stig.py +0 -0
  64. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/subagents.py +0 -0
  65. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/suggest.py +0 -0
  66. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/task_state.py +0 -0
  67. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tool_policy.py +0 -0
  68. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tool_registry.py +0 -0
  69. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tool_result.py +0 -0
  70. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tool_select.py +0 -0
  71. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tool_validate.py +0 -0
  72. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/trajectory.py +0 -0
  73. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tui/__init__.py +0 -0
  74. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tui/approval.py +0 -0
  75. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tui/messages.py +0 -0
  76. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/tuning.py +0 -0
  77. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/verification.py +0 -0
  78. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock/web.py +0 -0
  79. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock_cli.egg-info/dependency_links.txt +0 -0
  80. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock_cli.egg-info/entry_points.txt +0 -0
  81. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock_cli.egg-info/requires.txt +0 -0
  82. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/drydock_cli.egg-info/top_level.txt +0 -0
  83. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/setup.cfg +0 -0
  84. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_advisor.py +0 -0
  85. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_approval.py +0 -0
  86. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_back_command.py +0 -0
  87. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_background.py +0 -0
  88. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_binary_output.py +0 -0
  89. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_crossplatform.py +0 -0
  90. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_output_bounding.py +0 -0
  91. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_process_group.py +0 -0
  92. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_safety.py +0 -0
  93. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_sanitize.py +0 -0
  94. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_shell.py +0 -0
  95. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_stdin.py +0 -0
  96. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_stop_partial.py +0 -0
  97. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_timeout_network.py +0 -0
  98. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_bash_timeout_param.py +0 -0
  99. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_budget.py +0 -0
  100. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_cci.py +0 -0
  101. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_cli_agents.py +0 -0
  102. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_compact_command.py +0 -0
  103. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_compaction.py +0 -0
  104. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_config.py +0 -0
  105. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_config_migration.py +0 -0
  106. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_context_limit_config.py +0 -0
  107. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_context_limit_issue25.py +0 -0
  108. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_criteria_coverage.py +0 -0
  109. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_cycling_detection.py +0 -0
  110. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_degenerate_argument.py +0 -0
  111. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_detect.py +0 -0
  112. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_dispatch.py +0 -0
  113. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_e2e_connected.py +0 -0
  114. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_edit_replace_all.py +0 -0
  115. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_effort_governor.py +0 -0
  116. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_empty_response.py +0 -0
  117. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_events.py +0 -0
  118. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_extract.py +0 -0
  119. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_failure_loop.py +0 -0
  120. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_fiar.py +0 -0
  121. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_first_run_setup.py +0 -0
  122. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_gittools.py +0 -0
  123. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_glob_edit_edges.py +0 -0
  124. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_graphify_example.py +0 -0
  125. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_graphrag.py +0 -0
  126. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_graphrag_quoted_path.py +0 -0
  127. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_graphrag_sqlite.py +0 -0
  128. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_grep_and_read_robust.py +0 -0
  129. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_guards_and_tools.py +0 -0
  130. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_hallucinated_tools.py +0 -0
  131. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_leaked_tool_call.py +0 -0
  132. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_loop_detect.py +0 -0
  133. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_mcp.py +0 -0
  134. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_model_registry.py +0 -0
  135. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_oneshot_unreachable.py +0 -0
  136. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_overthink_interrupt.py +0 -0
  137. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_phases.py +0 -0
  138. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_plan_autocontinue.py +0 -0
  139. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_poam.py +0 -0
  140. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_progress.py +0 -0
  141. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_providers_unreachable.py +0 -0
  142. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_read_index.py +0 -0
  143. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_recipes.py +0 -0
  144. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_recovery.py +0 -0
  145. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_recovery_config.py +0 -0
  146. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_recovery_integration.py +0 -0
  147. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_repeated_outcome.py +0 -0
  148. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_repetition_interrupt.py +0 -0
  149. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_resume_events.py +0 -0
  150. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_resume_restore.py +0 -0
  151. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_resume_snapshot.py +0 -0
  152. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_rmf.py +0 -0
  153. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_rmf_graph.py +0 -0
  154. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_rmf_stig_graph.py +0 -0
  155. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_rolling_plan.py +0 -0
  156. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_runaway_repetition.py +0 -0
  157. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_screenshot.py +0 -0
  158. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_server_probe.py +0 -0
  159. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_sqlite_events.py +0 -0
  160. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_stall_retry.py +0 -0
  161. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_stig.py +0 -0
  162. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_stop.py +0 -0
  163. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_streaming_newlines.py +0 -0
  164. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_subagent.py +0 -0
  165. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_subagents.py +0 -0
  166. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_suggest.py +0 -0
  167. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_system_prompt_help.py +0 -0
  168. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_task_state.py +0 -0
  169. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_timeline.py +0 -0
  170. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_todo.py +0 -0
  171. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_arg_coercion.py +0 -0
  172. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_arg_coercion_more.py +0 -0
  173. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_arg_parsing.py +0 -0
  174. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_canonical.py +0 -0
  175. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_policy.py +0 -0
  176. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_result.py +0 -0
  177. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_select.py +0 -0
  178. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tool_validate.py +0 -0
  179. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tools_undo.py +0 -0
  180. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_trajectory.py +0 -0
  181. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tui.py +0 -0
  182. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_tuning.py +0 -0
  183. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_verification_gate.py +0 -0
  184. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_viewimage.py +0 -0
  185. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_vision_input.py +0 -0
  186. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_web_tools.py +0 -0
  187. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_windows_shell.py +0 -0
  188. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_worker_subagent.py +0 -0
  189. {drydock_cli-3.1.2 → drydock_cli-3.1.4}/tests/test_write_content_coerce.py +0 -0
  190. {drydock_cli-3.1.2 → 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.2
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
@@ -267,6 +267,59 @@ exports the open findings to a deterministic **eMASS POA&M CSV** — Control (fr
267
267
  the CCI map), Vulnerability Description, `POA&M Status=Ongoing`, Milestone (the
268
268
  Fix Text), and Severity (CAT I/II/III → High/Moderate/Low) — no LLM, stdlib only.
269
269
 
270
+ ### Document Canvas — editing documents far larger than the context window
271
+
272
+ Edit a 300-, 800-, 1000-page document the way you edit a large codebase: **search,
273
+ open a small region, apply a hash-guarded patch, validate, commit** — the model
274
+ never loads the whole document into context. Drydock parses the source into
275
+ addressable **blocks** with stable ids (`sec-0004`, `para-0182`, …) and content
276
+ hashes, and gives the model these tools:
277
+
278
+ | Tool | What it does |
279
+ |---|---|
280
+ | `DocOpen` | Parse a document into the canvas and show its outline |
281
+ | `DocOutline` / `DocSearch` / `DocRead` | Navigate + read small windows (never the whole file) |
282
+ | `DocReplace` | Global search-and-replace across the whole document in one pass |
283
+ | `DocPatch` | Hash-guarded, transactional edit of a block (replace / insert / delete) |
284
+ | `DocRedact` | Permanently remove text and **verify** it can't be recovered ("red boxing") |
285
+ | `DocDiff` / `DocValidate` | Preview staged changes; run structural + phrase checks |
286
+ | `DocCommit` / `DocRollback` | Write the source (original kept as `<file>.orig`) or discard |
287
+
288
+ **You don't call these tools yourself — you describe the task in plain English** and
289
+ the model drives them (just like Read/Edit/Bash). It picks the canvas over
290
+ `Read`/`Edit` automatically for documents too big to hold in context. For example,
291
+ type into the TUI:
292
+
293
+ ```
294
+ Open report.md and change every "single-factor authentication" to
295
+ "phishing-resistant MFA", then validate and commit.
296
+
297
+ Find the definition of "serendipity" in dictionary.pdf.
298
+
299
+ Redact every SSN and phone number in disclosure.md, then commit a release copy.
300
+ ```
301
+
302
+ Or run the bundled skill: `/document-canvas report.md redact all phone numbers`.
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
+
316
+ **Formats:** `.md` / `.markdown` / `.txt` are edited in place. `.pdf` / `.docx` are
317
+ imported read-only (text extracted; edits written to a `<file>.canvas.md` sidecar so
318
+ the binary original is never overwritten). Every edit is **staged** in a working copy
319
+ and hash-guarded, so the model can never clobber stale content; `DocCommit` writes the
320
+ file and preserves the untouched original as `<file>.orig`. Redaction is the one
321
+ **blocking** check — it refuses if the removed text would still be recoverable.
322
+
270
323
  ## Install
271
324
 
272
325
  ```bash
@@ -243,6 +243,59 @@ exports the open findings to a deterministic **eMASS POA&M CSV** — Control (fr
243
243
  the CCI map), Vulnerability Description, `POA&M Status=Ongoing`, Milestone (the
244
244
  Fix Text), and Severity (CAT I/II/III → High/Moderate/Low) — no LLM, stdlib only.
245
245
 
246
+ ### Document Canvas — editing documents far larger than the context window
247
+
248
+ Edit a 300-, 800-, 1000-page document the way you edit a large codebase: **search,
249
+ open a small region, apply a hash-guarded patch, validate, commit** — the model
250
+ never loads the whole document into context. Drydock parses the source into
251
+ addressable **blocks** with stable ids (`sec-0004`, `para-0182`, …) and content
252
+ hashes, and gives the model these tools:
253
+
254
+ | Tool | What it does |
255
+ |---|---|
256
+ | `DocOpen` | Parse a document into the canvas and show its outline |
257
+ | `DocOutline` / `DocSearch` / `DocRead` | Navigate + read small windows (never the whole file) |
258
+ | `DocReplace` | Global search-and-replace across the whole document in one pass |
259
+ | `DocPatch` | Hash-guarded, transactional edit of a block (replace / insert / delete) |
260
+ | `DocRedact` | Permanently remove text and **verify** it can't be recovered ("red boxing") |
261
+ | `DocDiff` / `DocValidate` | Preview staged changes; run structural + phrase checks |
262
+ | `DocCommit` / `DocRollback` | Write the source (original kept as `<file>.orig`) or discard |
263
+
264
+ **You don't call these tools yourself — you describe the task in plain English** and
265
+ the model drives them (just like Read/Edit/Bash). It picks the canvas over
266
+ `Read`/`Edit` automatically for documents too big to hold in context. For example,
267
+ type into the TUI:
268
+
269
+ ```
270
+ Open report.md and change every "single-factor authentication" to
271
+ "phishing-resistant MFA", then validate and commit.
272
+
273
+ Find the definition of "serendipity" in dictionary.pdf.
274
+
275
+ Redact every SSN and phone number in disclosure.md, then commit a release copy.
276
+ ```
277
+
278
+ Or run the bundled skill: `/document-canvas report.md redact all phone numbers`.
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
+
292
+ **Formats:** `.md` / `.markdown` / `.txt` are edited in place. `.pdf` / `.docx` are
293
+ imported read-only (text extracted; edits written to a `<file>.canvas.md` sidecar so
294
+ the binary original is never overwritten). Every edit is **staged** in a working copy
295
+ and hash-guarded, so the model can never clobber stale content; `DocCommit` writes the
296
+ file and preserves the untouched original as `<file>.orig`. Redaction is the one
297
+ **blocking** check — it refuses if the removed text would still be recoverable.
298
+
246
299
  ## Install
247
300
 
248
301
  ```bash
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: document-canvas
3
+ description: Edit a large document (md/txt) via the Document Canvas — search, patch, validate, commit, without loading it all
4
+ ---
5
+ Edit the document as a CANVAS — never load the whole thing into context. Target
6
+ for this task: $ARGS
7
+
8
+ Work like a programmer editing a large codebase. Address blocks by their stable
9
+ id (para-0182, sec-0004, …), not by line numbers or page numbers.
10
+
11
+ 1. **Open.** Call DocOpen with the file path. Read the outline it returns to
12
+ understand the structure. (The document name is the filename.)
13
+
14
+ 2. **Locate — don't read everything.** Use DocSearch to find the blocks relevant
15
+ to the change (exact text, or regex:true for patterns like requirement numbers).
16
+ Use DocOutline to navigate the hierarchy. Only the blocks you open enter context.
17
+
18
+ 3. **Read the target region.** Call DocRead on each candidate block with a small
19
+ `before`/`after` window so you understand its context. Note each target's
20
+ content **hash** — you must pass it back as `expected_hash`.
21
+
22
+ 4. **Patch — hash-guarded, staged.** Call DocPatch with op (replace / insert_before
23
+ / insert_after / delete), target_id, the `expected_hash` from DocRead, and
24
+ new_text plus a short `reason`. Patches are STAGED in a working copy — the source
25
+ file is NOT changed yet. If a hash is stale the patch is rejected; re-DocRead and
26
+ retry. For several related edits, pass a `patches` list so they apply atomically.
27
+
28
+ 5. **Preview.** Call DocDiff to see every staged change as a unified diff. Confirm
29
+ you changed only what you intended and did not over-edit neighbouring text.
30
+
31
+ 6. **Validate.** Call DocValidate (pass `prohibited` for terms that must be gone and
32
+ `required` for terms that must remain). Resolve any ⚠ findings before committing.
33
+
34
+ 7. **Commit.** Only when the diff and validation look right, call DocCommit. It
35
+ writes the source file and preserves the untouched original as <file>.orig. Use
36
+ DocRollback to discard staged edits instead.
37
+
38
+ For a global change (e.g. a terminology update), search for ALL occurrences, then
39
+ process them in small batches — you do not need every passage in context at once.
40
+ Report which blocks you changed and the final validation result.