reprompt-cli 2.2.0__tar.gz → 2.2.1__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 (316) hide show
  1. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/CHANGELOG.md +7 -0
  2. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/PKG-INFO +2 -2
  3. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/README.md +1 -1
  4. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/pyproject.toml +1 -1
  5. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/cli.py +34 -9
  6. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/mcp.py +128 -1
  7. reprompt_cli-2.2.1/tests/test_file_input.py +107 -0
  8. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_mcp.py +69 -2
  9. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/uv.lock +1 -1
  10. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.editorconfig +0 -0
  11. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  12. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  13. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  14. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  15. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  16. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/dependabot.yml +0 -0
  17. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/workflows/ci.yml +0 -0
  18. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/workflows/publish.yml +0 -0
  19. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.gitignore +0 -0
  20. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.pre-commit-config.yaml +0 -0
  21. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.pre-commit-hooks.yaml +0 -0
  22. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.testmondata-shm +0 -0
  23. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.testmondata-wal +0 -0
  24. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/CODE_OF_CONDUCT.md +0 -0
  25. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/CONTRIBUTING.md +0 -0
  26. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/LICENSE +0 -0
  27. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/SECURITY.md +0 -0
  28. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/Screenshot 2026-03-24 at 09.45.03.png +0 -0
  29. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/action.yml +0 -0
  30. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/demo.gif +0 -0
  31. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-128.png +0 -0
  32. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-16.png +0 -0
  33. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-256.png +0 -0
  34. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-32.png +0 -0
  35. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-48.png +0 -0
  36. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-512.png +0 -0
  37. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-96.png +0 -0
  38. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon.svg +0 -0
  39. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-128.png +0 -0
  40. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-16.png +0 -0
  41. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-256.png +0 -0
  42. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-32.png +0 -0
  43. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-48.png +0 -0
  44. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-512.png +0 -0
  45. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-96.png +0 -0
  46. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon.svg +0 -0
  47. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-128.png +0 -0
  48. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-16.png +0 -0
  49. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-256.png +0 -0
  50. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-32.png +0 -0
  51. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-48.png +0 -0
  52. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-512.png +0 -0
  53. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-96.png +0 -0
  54. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon.svg +0 -0
  55. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-128.png +0 -0
  56. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-16.png +0 -0
  57. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-256.png +0 -0
  58. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-32.png +0 -0
  59. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-48.png +0 -0
  60. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-512.png +0 -0
  61. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-96.png +0 -0
  62. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon.svg +0 -0
  63. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/generate.sh +0 -0
  64. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/superpowers/specs/2026-03-24-v14-command-consolidation-design.md +0 -0
  65. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/superpowers/specs/2026-03-25-v1.5-dashboard-design.md +0 -0
  66. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/scripts/generate_demo_data.py +0 -0
  67. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/__init__.py +0 -0
  68. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/__init__.py +0 -0
  69. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/aider.py +0 -0
  70. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/base.py +0 -0
  71. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/chatgpt.py +0 -0
  72. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/claude_chat.py +0 -0
  73. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/claude_code.py +0 -0
  74. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/cline.py +0 -0
  75. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/codex.py +0 -0
  76. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/cursor.py +0 -0
  77. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/filters.py +0 -0
  78. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/gemini.py +0 -0
  79. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/openclaw.py +0 -0
  80. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/__init__.py +0 -0
  81. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/handler.py +0 -0
  82. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/host.py +0 -0
  83. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/manifest.py +0 -0
  84. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/protocol.py +0 -0
  85. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/commands/__init__.py +0 -0
  86. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/commands/telemetry.py +0 -0
  87. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/commands/wrapped.py +0 -0
  88. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/config.py +0 -0
  89. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/__init__.py +0 -0
  90. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/agent.py +0 -0
  91. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/analyzer.py +0 -0
  92. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/build.py +0 -0
  93. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/check.py +0 -0
  94. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/compress.py +0 -0
  95. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/conversation.py +0 -0
  96. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/cost.py +0 -0
  97. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/dashboard.py +0 -0
  98. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/dedup.py +0 -0
  99. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/digest.py +0 -0
  100. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/distill.py +0 -0
  101. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/effectiveness.py +0 -0
  102. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/explain.py +0 -0
  103. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/extractors.py +0 -0
  104. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/extractors_zh.py +0 -0
  105. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/insights.py +0 -0
  106. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/lang_detect.py +0 -0
  107. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/library.py +0 -0
  108. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/lint.py +0 -0
  109. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/merge_view.py +0 -0
  110. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/models.py +0 -0
  111. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/persona.py +0 -0
  112. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/pipeline.py +0 -0
  113. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/privacy.py +0 -0
  114. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/privacy_scan.py +0 -0
  115. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/prompt_dna.py +0 -0
  116. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/recommend.py +0 -0
  117. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/repetition.py +0 -0
  118. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/rewrite.py +0 -0
  119. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/scorer.py +0 -0
  120. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/segmenter.py +0 -0
  121. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/session_meta.py +0 -0
  122. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/session_quality.py +0 -0
  123. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/session_type.py +0 -0
  124. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/style.py +0 -0
  125. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/suggestions.py +0 -0
  126. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/templates.py +0 -0
  127. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/timeutil.py +0 -0
  128. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/trends.py +0 -0
  129. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/wrapped.py +0 -0
  130. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/demo.py +0 -0
  131. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/__init__.py +0 -0
  132. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/base.py +0 -0
  133. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/local_embed.py +0 -0
  134. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/ollama.py +0 -0
  135. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/openai_embed.py +0 -0
  136. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/tfidf.py +0 -0
  137. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/mcp_main.py +0 -0
  138. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/__init__.py +0 -0
  139. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/agent_terminal.py +0 -0
  140. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/build_terminal.py +0 -0
  141. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/chartjs.min.js +0 -0
  142. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/check_terminal.py +0 -0
  143. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/compress_terminal.py +0 -0
  144. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/dashboard_terminal.py +0 -0
  145. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/distill_terminal.py +0 -0
  146. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/explain_terminal.py +0 -0
  147. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/export.py +0 -0
  148. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/html_report.py +0 -0
  149. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/json_out.py +0 -0
  150. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/markdown.py +0 -0
  151. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/projects_terminal.py +0 -0
  152. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/repetition_terminal.py +0 -0
  153. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/rewrite_terminal.py +0 -0
  154. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/sessions_terminal.py +0 -0
  155. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/terminal.py +0 -0
  156. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/wrapped_html.py +0 -0
  157. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/wrapped_terminal.py +0 -0
  158. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/py.typed +0 -0
  159. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/sharing/__init__.py +0 -0
  160. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/sharing/client.py +0 -0
  161. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/sharing/clipboard.py +0 -0
  162. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/storage/__init__.py +0 -0
  163. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/storage/db.py +0 -0
  164. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/__init__.py +0 -0
  165. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/collector.py +0 -0
  166. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/consent.py +0 -0
  167. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/events.py +0 -0
  168. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/prompt.py +0 -0
  169. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/queue.py +0 -0
  170. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/sender.py +0 -0
  171. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/__init__.py +0 -0
  172. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/conftest.py +0 -0
  173. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/aider_chat_history.md +0 -0
  174. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/chatgpt_conversations.json +0 -0
  175. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/claude_chat_export.json +0 -0
  176. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/claude_session.jsonl +0 -0
  177. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/cline_task/api_conversation_history.json +0 -0
  178. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/export/default_export.md +0 -0
  179. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/export/full_export.md +0 -0
  180. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/gemini_session.json +0 -0
  181. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/openclaw_session.jsonl +0 -0
  182. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_aider.py +0 -0
  183. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_chatgpt.py +0 -0
  184. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_claude.py +0 -0
  185. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_claude_chat.py +0 -0
  186. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_cline.py +0 -0
  187. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_gemini.py +0 -0
  188. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_openclaw.py +0 -0
  189. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_agent.py +0 -0
  190. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_agent_cli.py +0 -0
  191. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_analyzer.py +0 -0
  192. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_cli.py +0 -0
  193. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_e2e.py +0 -0
  194. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_handler.py +0 -0
  195. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_integration.py +0 -0
  196. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_manifest.py +0 -0
  197. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_protocol.py +0 -0
  198. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_build.py +0 -0
  199. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_build_cli.py +0 -0
  200. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_build_output.py +0 -0
  201. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_check.py +0 -0
  202. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_check_cli.py +0 -0
  203. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cli.py +0 -0
  204. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cli_deprecations.py +0 -0
  205. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cli_library_effectiveness.py +0 -0
  206. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_clipboard.py +0 -0
  207. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_codex_adapter.py +0 -0
  208. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compare_best_worst.py +0 -0
  209. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress.py +0 -0
  210. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_cli.py +0 -0
  211. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_dna.py +0 -0
  212. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_html.py +0 -0
  213. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_insights.py +0 -0
  214. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_config.py +0 -0
  215. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_conversation.py +0 -0
  216. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_copy_flag.py +0 -0
  217. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cost.py +0 -0
  218. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_coverage_boost.py +0 -0
  219. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cursor_adapter.py +0 -0
  220. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_dashboard.py +0 -0
  221. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db.py +0 -0
  222. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_digest.py +0 -0
  223. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_effectiveness.py +0 -0
  224. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_session_quality.py +0 -0
  225. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_trends.py +0 -0
  226. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_dedup.py +0 -0
  227. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_demo.py +0 -0
  228. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_deprecated_commands.py +0 -0
  229. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_digest.py +0 -0
  230. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_digest_cli.py +0 -0
  231. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_distill.py +0 -0
  232. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_distill_cli.py +0 -0
  233. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_distill_weights.py +0 -0
  234. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_e2e.py +0 -0
  235. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_effectiveness.py +0 -0
  236. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_embeddings_local.py +0 -0
  237. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_embeddings_ollama.py +0 -0
  238. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_embeddings_openai.py +0 -0
  239. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_empty_state.py +0 -0
  240. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_explain.py +0 -0
  241. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_explain_cli.py +0 -0
  242. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_export.py +0 -0
  243. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_export_cli.py +0 -0
  244. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_export_snapshot.py +0 -0
  245. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors.py +0 -0
  246. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors_routing.py +0 -0
  247. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors_zh.py +0 -0
  248. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors_zh_e2e.py +0 -0
  249. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_html_report.py +0 -0
  250. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_import_cli.py +0 -0
  251. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_import_e2e.py +0 -0
  252. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_init_cli.py +0 -0
  253. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_insights.py +0 -0
  254. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_insights_cli.py +0 -0
  255. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_insights_expanded.py +0 -0
  256. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_install_hook.py +0 -0
  257. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_lang_detect.py +0 -0
  258. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_library.py +0 -0
  259. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_lint.py +0 -0
  260. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_lint_cli.py +0 -0
  261. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_markdown.py +0 -0
  262. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_merge_view.py +0 -0
  263. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_models.py +0 -0
  264. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_output.py +0 -0
  265. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_parse_conversation_base.py +0 -0
  266. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_parse_conversation_chatgpt.py +0 -0
  267. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_parse_conversation_claude.py +0 -0
  268. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_persona.py +0 -0
  269. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_pipeline.py +0 -0
  270. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy.py +0 -0
  271. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_cli.py +0 -0
  272. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_e2e.py +0 -0
  273. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_output.py +0 -0
  274. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_scan.py +0 -0
  275. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_projects.py +0 -0
  276. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_prompt_dna.py +0 -0
  277. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_public_api.py +0 -0
  278. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_recommend.py +0 -0
  279. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_repetition.py +0 -0
  280. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_repetition_cli.py +0 -0
  281. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_repetition_output.py +0 -0
  282. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_rewrite.py +0 -0
  283. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_schema_version.py +0 -0
  284. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_score_cli.py +0 -0
  285. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_scorer.py +0 -0
  286. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_segmenter.py +0 -0
  287. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_session_quality.py +0 -0
  288. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_session_type.py +0 -0
  289. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_sessions_cli.py +0 -0
  290. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_sessions_output.py +0 -0
  291. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_share_e2e.py +0 -0
  292. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_sharing_client.py +0 -0
  293. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_source_filter.py +0 -0
  294. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_style.py +0 -0
  295. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_style_trends.py +0 -0
  296. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_suggestions.py +0 -0
  297. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_cli.py +0 -0
  298. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_collector.py +0 -0
  299. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_consent.py +0 -0
  300. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_e2e.py +0 -0
  301. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_events.py +0 -0
  302. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_prompt.py +0 -0
  303. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_queue.py +0 -0
  304. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_sender.py +0 -0
  305. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_template_cli.py +0 -0
  306. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_templates.py +0 -0
  307. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_timeutil.py +0 -0
  308. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_trends.py +0 -0
  309. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_trends_cli.py +0 -0
  310. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_use_cli.py +0 -0
  311. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped.py +0 -0
  312. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_cli.py +0 -0
  313. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_e2e.py +0 -0
  314. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_html.py +0 -0
  315. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_output.py +0 -0
  316. {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_share.py +0 -0
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [2.2.1] - 2026-04-01
6
+
7
+ ### Added
8
+ - **MCP server expanded** — 6→9 tools: `check_prompt_quality` (unified diagnostic), `build_prompt_from_parts` (prompt constructor), `explain_prompt_quality` (educational analysis). IDE integration now covers all prompt quality features.
9
+ - **File input** — all prompt commands (`check`, `score`, `explain`, `rewrite`, `compress`) accept `--file` to read from file and `-` for stdin. Enables pipeline integration and multi-line prompts.
10
+ - Tests: 1846 → 1864
11
+
5
12
  ## [2.2.0] - 2026-04-01
6
13
 
7
14
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reprompt-cli
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Discover, analyze, and optimize your prompts from AI coding sessions
5
5
  Project-URL: Homepage, https://github.com/reprompt-dev/reprompt
6
6
  Project-URL: Repository, https://github.com/reprompt-dev/reprompt
@@ -230,7 +230,7 @@ Captured prompts sync locally via Native Messaging -- nothing leaves your machin
230
230
  # .pre-commit-config.yaml
231
231
  repos:
232
232
  - repo: https://github.com/reprompt-dev/reprompt
233
- rev: v2.2.0
233
+ rev: v2.2.1
234
234
  hooks:
235
235
  - id: reprompt-lint
236
236
  ```
@@ -185,7 +185,7 @@ Captured prompts sync locally via Native Messaging -- nothing leaves your machin
185
185
  # .pre-commit-config.yaml
186
186
  repos:
187
187
  - repo: https://github.com/reprompt-dev/reprompt
188
- rev: v2.2.0
188
+ rev: v2.2.1
189
189
  hooks:
190
190
  - id: reprompt-lint
191
191
  ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "reprompt-cli"
3
- version = "2.2.0"
3
+ version = "2.2.1"
4
4
  description = "Discover, analyze, and optimize your prompts from AI coding sessions"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -15,6 +15,21 @@ if TYPE_CHECKING:
15
15
  from reprompt.storage.db import PromptDB
16
16
 
17
17
 
18
+ def _resolve_text(text: str, file: str) -> str:
19
+ """Resolve prompt text from argument or --file option."""
20
+ if file:
21
+ p = Path(file)
22
+ if not p.is_file():
23
+ typer.echo(f"Error: file not found: {file}", err=True)
24
+ raise typer.Exit(1)
25
+ return p.read_text(encoding="utf-8").strip()
26
+ if text == "-":
27
+ import sys
28
+
29
+ return sys.stdin.read().strip()
30
+ return text
31
+
32
+
18
33
  def _copy_to_clip(text: str, quiet: bool = False) -> None:
19
34
  """Copy text to clipboard with user feedback."""
20
35
  from reprompt.sharing.clipboard import copy_to_clipboard
@@ -948,9 +963,10 @@ def lint(
948
963
 
949
964
  @app.command(rich_help_panel="Analyze")
950
965
  def check(
951
- text: str = typer.Argument(..., help="Prompt text to check"),
966
+ text: str = typer.Argument(..., help="Prompt text to check (use '-' for stdin)"),
952
967
  model: str = typer.Option("", "--model", "-m", help="Target model (claude/gpt/gemini)"),
953
968
  max_tokens: int = typer.Option(0, "--max-tokens", help="Token budget (0 = disabled)"),
969
+ file: str = typer.Option("", "--file", "-f", help="Read prompt from file"),
954
970
  json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
955
971
  copy: bool = typer.Option(False, "--copy", help="Copy rewritten prompt to clipboard"),
956
972
  ) -> None:
@@ -967,6 +983,7 @@ def check(
967
983
 
968
984
  reprompt check "help me debug this crash" --json
969
985
  """
986
+ text = _resolve_text(text, file)
970
987
  from reprompt.core.check import check_prompt
971
988
 
972
989
  result = check_prompt(text, model=model, max_tokens=max_tokens)
@@ -1009,7 +1026,8 @@ def check(
1009
1026
 
1010
1027
  @app.command(rich_help_panel="Analyze")
1011
1028
  def explain(
1012
- text: str = typer.Argument(..., help="Prompt text to explain"),
1029
+ text: str = typer.Argument(..., help="Prompt text to explain (use '-' for stdin)"),
1030
+ file: str = typer.Option("", "--file", "-f", help="Read prompt from file"),
1013
1031
  json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
1014
1032
  ) -> None:
1015
1033
  """Explain what makes a prompt good or bad in plain English.
@@ -1021,8 +1039,9 @@ def explain(
1021
1039
 
1022
1040
  reprompt explain "fix the auth bug"
1023
1041
 
1024
- reprompt explain "Fix the JWT expiration in src/auth.ts line 42" --json
1042
+ reprompt explain --file prompt.txt --json
1025
1043
  """
1044
+ text = _resolve_text(text, file)
1026
1045
  from reprompt.core.explain import explain_prompt
1027
1046
 
1028
1047
  result = explain_prompt(text)
@@ -1053,7 +1072,8 @@ def explain(
1053
1072
 
1054
1073
  @app.command(rich_help_panel="Analyze")
1055
1074
  def score(
1056
- text: str = typer.Argument(..., help="Prompt text to score"),
1075
+ text: str = typer.Argument(..., help="Prompt text to score (use '-' for stdin)"),
1076
+ file: str = typer.Option("", "--file", "-f", help="Read prompt from file"),
1057
1077
  json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
1058
1078
  copy: bool = typer.Option(False, "--copy", help="Copy result to clipboard"),
1059
1079
  ) -> None:
@@ -1063,10 +1083,11 @@ def score(
1063
1083
 
1064
1084
  reprompt score "Fix the auth bug in login.ts where JWT expires"
1065
1085
 
1066
- reprompt score "Refactor auth module to use refresh tokens" --json
1086
+ reprompt score --file prompt.txt --json
1067
1087
 
1068
1088
  reprompt score "Fix bug" --copy
1069
1089
  """
1090
+ text = _resolve_text(text, file)
1070
1091
  from reprompt.core.cost import estimate_cost, format_cost, model_for_source
1071
1092
  from reprompt.core.extractors import extract_features
1072
1093
  from reprompt.core.scorer import score_prompt
@@ -1174,7 +1195,8 @@ def score(
1174
1195
 
1175
1196
  @app.command(rich_help_panel="Optimize")
1176
1197
  def compress(
1177
- text: str = typer.Argument(..., help="Prompt text to compress"),
1198
+ text: str = typer.Argument(..., help="Prompt text to compress (use '-' for stdin)"),
1199
+ file: str = typer.Option("", "--file", "-f", help="Read prompt from file"),
1178
1200
  json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
1179
1201
  copy: bool = typer.Option(False, "--copy", help="Copy compressed text to clipboard"),
1180
1202
  ) -> None:
@@ -1184,10 +1206,11 @@ def compress(
1184
1206
 
1185
1207
  reprompt compress "Can you please help me refactor this code?"
1186
1208
 
1187
- reprompt compress "I was wondering if you could fix the bug" --json
1209
+ reprompt compress --file prompt.txt --json
1188
1210
 
1189
1211
  reprompt compress "verbose prompt here" --copy
1190
1212
  """
1213
+ text = _resolve_text(text, file)
1191
1214
  from reprompt.core.compress import compress_text
1192
1215
 
1193
1216
  result = compress_text(text)
@@ -1208,7 +1231,8 @@ def compress(
1208
1231
 
1209
1232
  @app.command(rich_help_panel="Optimize")
1210
1233
  def rewrite(
1211
- text: str = typer.Argument(..., help="Prompt text to improve"),
1234
+ text: str = typer.Argument(..., help="Prompt text to improve (use '-' for stdin)"),
1235
+ file: str = typer.Option("", "--file", "-f", help="Read prompt from file"),
1212
1236
  json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
1213
1237
  diff: bool = typer.Option(False, "--diff", help="Show unified diff (red/green)"),
1214
1238
  copy: bool = typer.Option(False, "--copy", help="Copy rewritten text to clipboard"),
@@ -1223,10 +1247,11 @@ def rewrite(
1223
1247
 
1224
1248
  reprompt rewrite "I was wondering if you could fix the authentication bug"
1225
1249
 
1226
- reprompt rewrite "fix the login" --diff
1250
+ reprompt rewrite --file prompt.txt --diff
1227
1251
 
1228
1252
  reprompt rewrite "please help me refactor this code to be better" --copy
1229
1253
  """
1254
+ text = _resolve_text(text, file)
1230
1255
  from reprompt.core.rewrite import rewrite_prompt
1231
1256
 
1232
1257
  result = rewrite_prompt(text)
@@ -1,4 +1,4 @@
1
- """MCP server for reprompt — exposes prompt analytics as 6 focused tools.
1
+ """MCP server for reprompt — exposes prompt analytics as 9 focused tools.
2
2
 
3
3
  Usage:
4
4
  python -m reprompt.mcp # stdio transport (default)
@@ -297,6 +297,133 @@ def scan_sessions(source: str | None = None) -> str:
297
297
  return json.dumps({"error": str(exc)})
298
298
 
299
299
 
300
+ @mcp.tool
301
+ def check_prompt_quality(text: str, model: str | None = None) -> str:
302
+ """Full prompt diagnostic — score + lint + rewrite in one call.
303
+
304
+ Returns score breakdown, strengths, suggestions with point values,
305
+ lint issues, and an auto-rewritten version. The most comprehensive
306
+ single-call analysis available.
307
+
308
+ Args:
309
+ text: The prompt text to analyze
310
+ model: Target model for model-specific lint (claude/gpt/gemini). Optional.
311
+ """
312
+ try:
313
+ from reprompt.core.check import check_prompt as _check
314
+
315
+ result = _check(text, model=model or "")
316
+ return json.dumps(
317
+ {
318
+ "total": result.total,
319
+ "tier": result.tier,
320
+ "clarity": result.clarity,
321
+ "context": result.context,
322
+ "position": result.position,
323
+ "structure": result.structure,
324
+ "repetition": result.repetition,
325
+ "word_count": result.word_count,
326
+ "token_count": result.token_count,
327
+ "confirmations": result.confirmations[:3],
328
+ "suggestions": result.suggestions[:3],
329
+ "lint_issues": result.lint_issues,
330
+ "rewritten": result.rewritten,
331
+ "rewrite_delta": result.rewrite_delta,
332
+ "rewrite_changes": result.rewrite_changes,
333
+ },
334
+ indent=2,
335
+ )
336
+ except Exception as exc:
337
+ logger.debug("check_prompt_quality error: %s", exc)
338
+ return json.dumps({"error": str(exc)})
339
+
340
+
341
+ @mcp.tool
342
+ def build_prompt_from_parts(
343
+ task: str,
344
+ context: str = "",
345
+ files: str = "",
346
+ error: str = "",
347
+ constraints: str = "",
348
+ role: str = "",
349
+ model: str = "",
350
+ ) -> str:
351
+ """Build a well-structured prompt from components.
352
+
353
+ Assembles a prompt that maximizes quality score from individual parts.
354
+ Model-aware: uses XML tags for Claude, markdown for GPT.
355
+
356
+ Args:
357
+ task: What the AI should do (required)
358
+ context: Background information
359
+ files: Comma-separated file paths (e.g., "src/auth.ts,src/token.ts")
360
+ error: Error message or stack trace
361
+ constraints: Comma-separated constraints (e.g., "keep tests,no breaking changes")
362
+ role: AI role/persona (e.g., "senior backend engineer")
363
+ model: Target model (claude/gpt/gemini) for format optimization
364
+ """
365
+ try:
366
+ from reprompt.core.build import build_prompt as _build
367
+
368
+ file_list = [f.strip() for f in files.split(",") if f.strip()] if files else None
369
+ constraint_list = (
370
+ [c.strip() for c in constraints.split(",") if c.strip()] if constraints else None
371
+ )
372
+
373
+ result = _build(
374
+ task,
375
+ context=context,
376
+ files=file_list,
377
+ error=error,
378
+ constraints=constraint_list,
379
+ role=role,
380
+ model=model,
381
+ )
382
+ return json.dumps(
383
+ {
384
+ "prompt": result.prompt,
385
+ "score": result.score,
386
+ "tier": result.tier,
387
+ "components_used": result.components_used,
388
+ "suggestions": result.suggestions,
389
+ },
390
+ indent=2,
391
+ )
392
+ except Exception as exc:
393
+ logger.debug("build_prompt_from_parts error: %s", exc)
394
+ return json.dumps({"error": str(exc)})
395
+
396
+
397
+ @mcp.tool
398
+ def explain_prompt_quality(text: str) -> str:
399
+ """Explain what makes a prompt good or bad in plain English.
400
+
401
+ Returns educational feedback: what's working, what's missing,
402
+ and specific tips to improve. No LLM needed.
403
+
404
+ Args:
405
+ text: The prompt text to explain
406
+ """
407
+ try:
408
+ from reprompt.core.explain import explain_prompt as _explain
409
+
410
+ result = _explain(text)
411
+ return json.dumps(
412
+ {
413
+ "score": result.score,
414
+ "tier": result.tier,
415
+ "summary": result.summary,
416
+ "strengths": result.strengths,
417
+ "weaknesses": result.weaknesses,
418
+ "tips": result.tips,
419
+ },
420
+ indent=2,
421
+ )
422
+ except Exception as exc:
423
+ logger.debug("explain_prompt_quality error: %s", exc)
424
+ return json.dumps({"error": str(exc)})
425
+
426
+
300
427
  # ─── Resources ──────────────────────────────────────────────────────────────
301
428
 
302
429
 
@@ -0,0 +1,107 @@
1
+ """Tests for --file input support across prompt commands."""
2
+
3
+ import json
4
+
5
+ from typer.testing import CliRunner
6
+
7
+ from reprompt.cli import app
8
+
9
+ runner = CliRunner()
10
+
11
+
12
+ def _write_prompt(tmp_path, content="Fix the auth bug in src/auth.ts"):
13
+ f = tmp_path / "prompt.txt"
14
+ f.write_text(content)
15
+ return str(f)
16
+
17
+
18
+ class TestFileInputCheck:
19
+ def test_check_from_file(self, tmp_path):
20
+ path = _write_prompt(tmp_path)
21
+ result = runner.invoke(app, ["check", "ignored", "--file", path])
22
+ assert result.exit_code == 0
23
+ assert "Clarity" in result.output
24
+
25
+ def test_check_file_not_found(self, tmp_path):
26
+ result = runner.invoke(app, ["check", "x", "--file", "/nonexistent/file.txt"])
27
+ assert result.exit_code == 1
28
+
29
+ def test_check_file_json(self, tmp_path):
30
+ path = _write_prompt(tmp_path)
31
+ result = runner.invoke(app, ["check", "x", "--file", path, "--json"])
32
+ assert result.exit_code == 0
33
+ data = json.loads(result.output)
34
+ assert data["total"] > 0
35
+
36
+
37
+ class TestFileInputScore:
38
+ def test_score_from_file(self, tmp_path):
39
+ path = _write_prompt(tmp_path)
40
+ result = runner.invoke(app, ["score", "ignored", "--file", path])
41
+ assert result.exit_code == 0
42
+
43
+ def test_score_file_json(self, tmp_path):
44
+ path = _write_prompt(tmp_path)
45
+ result = runner.invoke(app, ["score", "x", "--file", path, "--json"])
46
+ assert result.exit_code == 0
47
+ data = json.loads(result.output)
48
+ assert "total" in data
49
+
50
+
51
+ class TestFileInputExplain:
52
+ def test_explain_from_file(self, tmp_path):
53
+ path = _write_prompt(tmp_path)
54
+ result = runner.invoke(app, ["explain", "x", "--file", path])
55
+ assert result.exit_code == 0
56
+ assert "Analysis" in result.output
57
+
58
+ def test_explain_file_json(self, tmp_path):
59
+ path = _write_prompt(tmp_path)
60
+ result = runner.invoke(app, ["explain", "x", "--file", path, "--json"])
61
+ assert result.exit_code == 0
62
+ data = json.loads(result.output)
63
+ assert "summary" in data
64
+
65
+
66
+ class TestFileInputRewrite:
67
+ def test_rewrite_from_file(self, tmp_path):
68
+ path = _write_prompt(
69
+ tmp_path, "I was wondering if you could maybe fix the authentication bug"
70
+ )
71
+ result = runner.invoke(app, ["rewrite", "x", "--file", path])
72
+ assert result.exit_code == 0
73
+
74
+ def test_rewrite_file_diff(self, tmp_path):
75
+ path = _write_prompt(
76
+ tmp_path, "I was wondering if you could maybe fix the authentication bug"
77
+ )
78
+ result = runner.invoke(app, ["rewrite", "x", "--file", path, "--diff"])
79
+ assert result.exit_code == 0
80
+
81
+
82
+ class TestFileInputCompress:
83
+ def test_compress_from_file(self, tmp_path):
84
+ path = _write_prompt(tmp_path, "Can you please help me refactor this code to be better?")
85
+ result = runner.invoke(app, ["compress", "x", "--file", path])
86
+ assert result.exit_code == 0
87
+
88
+ def test_compress_file_json(self, tmp_path):
89
+ path = _write_prompt(tmp_path, "Please help me with the thing")
90
+ result = runner.invoke(app, ["compress", "x", "--file", path, "--json"])
91
+ assert result.exit_code == 0
92
+
93
+
94
+ class TestMultilineFile:
95
+ def test_multiline_prompt(self, tmp_path):
96
+ content = (
97
+ "Fix the authentication middleware.\n\n"
98
+ "Context: JWT tokens expire after 1 hour.\n"
99
+ "Error: 401 on /api/users endpoint.\n\n"
100
+ "Don't modify existing tests."
101
+ )
102
+ path = _write_prompt(tmp_path, content)
103
+ result = runner.invoke(app, ["check", "x", "--file", path, "--json"])
104
+ assert result.exit_code == 0
105
+ data = json.loads(result.output)
106
+ assert data["total"] > 0
107
+ assert data["word_count"] > 10
@@ -170,11 +170,78 @@ def test_mcp_serve_cli(tmp_path, monkeypatch):
170
170
 
171
171
 
172
172
  def test_tool_count():
173
- """Verify the MCP server exposes exactly 6 tools."""
173
+ """Verify the MCP server exposes exactly 9 tools."""
174
174
  import asyncio
175
175
 
176
176
  from reprompt.mcp import mcp as _mcp
177
177
 
178
178
  tools = asyncio.run(_mcp.list_tools())
179
179
  names = [t.name for t in tools]
180
- assert len(tools) == 6, f"Expected 6 tools, got {len(tools)}: {names}"
180
+ assert len(tools) == 9, f"Expected 9 tools, got {len(tools)}: {names}"
181
+
182
+
183
+ # ─── New tools (check, build, explain) ────────────────────────────────────
184
+
185
+
186
+ def test_check_prompt_quality():
187
+ from reprompt.mcp import check_prompt_quality
188
+
189
+ result = json.loads(check_prompt_quality("fix the auth bug in login.ts"))
190
+ assert "total" in result
191
+ assert "tier" in result
192
+ assert "lint_issues" in result
193
+ assert "rewritten" in result
194
+ assert "suggestions" in result
195
+
196
+
197
+ def test_check_prompt_quality_with_model():
198
+ from reprompt.mcp import check_prompt_quality
199
+
200
+ result = json.loads(check_prompt_quality("fix the auth bug", model="claude"))
201
+ assert "total" in result
202
+
203
+
204
+ def test_build_prompt_from_parts():
205
+ from reprompt.mcp import build_prompt_from_parts
206
+
207
+ result = json.loads(
208
+ build_prompt_from_parts(
209
+ task="fix the auth bug",
210
+ files="src/auth.ts",
211
+ error="TypeError: null",
212
+ constraints="keep tests,no breaking changes",
213
+ )
214
+ )
215
+ assert "prompt" in result
216
+ assert "score" in result
217
+ assert "tier" in result
218
+ assert "src/auth.ts" in result["prompt"]
219
+ assert "components_used" in result
220
+
221
+
222
+ def test_build_prompt_from_parts_minimal():
223
+ from reprompt.mcp import build_prompt_from_parts
224
+
225
+ result = json.loads(build_prompt_from_parts(task="fix the bug"))
226
+ assert "prompt" in result
227
+ assert result["score"] > 0
228
+
229
+
230
+ def test_explain_prompt_quality():
231
+ from reprompt.mcp import explain_prompt_quality
232
+
233
+ result = json.loads(explain_prompt_quality("fix the auth bug in login.ts"))
234
+ assert "score" in result
235
+ assert "tier" in result
236
+ assert "summary" in result
237
+ assert "strengths" in result
238
+ assert "weaknesses" in result
239
+ assert "tips" in result
240
+
241
+
242
+ def test_explain_prompt_quality_short():
243
+ from reprompt.mcp import explain_prompt_quality
244
+
245
+ result = json.loads(explain_prompt_quality("fix it"))
246
+ assert result["score"] > 0
247
+ assert len(result["summary"]) > 0
@@ -2210,7 +2210,7 @@ wheels = [
2210
2210
 
2211
2211
  [[package]]
2212
2212
  name = "reprompt-cli"
2213
- version = "2.2.0"
2213
+ version = "2.2.1"
2214
2214
  source = { editable = "." }
2215
2215
  dependencies = [
2216
2216
  { name = "pydantic-settings" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes