reprompt-cli 2.4.0__tar.gz → 2.5.0__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 (326) hide show
  1. reprompt_cli-2.5.0/.github/ISSUE_TEMPLATE/feedback.yml +32 -0
  2. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/PKG-INFO +35 -7
  3. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/README.md +34 -6
  4. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/pyproject.toml +1 -1
  5. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/__init__.py +1 -1
  6. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/cli.py +70 -65
  7. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/extractors.py +4 -6
  8. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/suggestions.py +28 -0
  9. reprompt_cli-2.5.0/tests/test_feedback.py +89 -0
  10. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/uv.lock +1 -1
  11. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.editorconfig +0 -0
  12. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  13. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  14. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  15. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  16. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  17. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/dependabot.yml +0 -0
  18. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/workflows/ci.yml +0 -0
  19. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.github/workflows/publish.yml +0 -0
  20. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.gitignore +0 -0
  21. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.pre-commit-config.yaml +0 -0
  22. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.pre-commit-hooks.yaml +0 -0
  23. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.testmondata-shm +0 -0
  24. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/.testmondata-wal +0 -0
  25. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/CHANGELOG.md +0 -0
  26. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/CODE_OF_CONDUCT.md +0 -0
  27. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/CONTRIBUTING.md +0 -0
  28. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/LICENSE +0 -0
  29. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/SECURITY.md +0 -0
  30. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/Screenshot 2026-03-24 at 09.45.03.png +0 -0
  31. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/action.yml +0 -0
  32. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/demo.gif +0 -0
  33. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-128.png +0 -0
  34. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-16.png +0 -0
  35. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-256.png +0 -0
  36. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-32.png +0 -0
  37. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-48.png +0 -0
  38. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-512.png +0 -0
  39. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon-96.png +0 -0
  40. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/brand-icon.svg +0 -0
  41. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-128.png +0 -0
  42. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-16.png +0 -0
  43. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-256.png +0 -0
  44. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-32.png +0 -0
  45. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-48.png +0 -0
  46. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-512.png +0 -0
  47. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon-96.png +0 -0
  48. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-favicon.svg +0 -0
  49. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-128.png +0 -0
  50. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-16.png +0 -0
  51. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-256.png +0 -0
  52. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-32.png +0 -0
  53. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-48.png +0 -0
  54. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-512.png +0 -0
  55. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon-96.png +0 -0
  56. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/cli-icon.svg +0 -0
  57. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-128.png +0 -0
  58. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-16.png +0 -0
  59. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-256.png +0 -0
  60. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-32.png +0 -0
  61. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-48.png +0 -0
  62. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-512.png +0 -0
  63. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon-96.png +0 -0
  64. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/favicon.svg +0 -0
  65. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/icons/generate.sh +0 -0
  66. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/screenshots/build.svg +0 -0
  67. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/screenshots/check-bad.svg +0 -0
  68. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/screenshots/check-good.svg +0 -0
  69. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/screenshots/rewrite.svg +0 -0
  70. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/superpowers/specs/2026-03-24-v14-command-consolidation-design.md +0 -0
  71. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/docs/superpowers/specs/2026-03-25-v1.5-dashboard-design.md +0 -0
  72. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/scripts/gen_screenshots.py +0 -0
  73. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/scripts/generate_demo_data.py +0 -0
  74. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/__init__.py +0 -0
  75. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/aider.py +0 -0
  76. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/base.py +0 -0
  77. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/chatgpt.py +0 -0
  78. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/claude_chat.py +0 -0
  79. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/claude_code.py +0 -0
  80. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/cline.py +0 -0
  81. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/codex.py +0 -0
  82. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/cursor.py +0 -0
  83. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/filters.py +0 -0
  84. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/gemini.py +0 -0
  85. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/adapters/openclaw.py +0 -0
  86. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/bridge/__init__.py +0 -0
  87. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/bridge/handler.py +0 -0
  88. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/bridge/host.py +0 -0
  89. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/bridge/manifest.py +0 -0
  90. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/bridge/protocol.py +0 -0
  91. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/commands/__init__.py +0 -0
  92. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/commands/telemetry.py +0 -0
  93. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/commands/wrapped.py +0 -0
  94. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/config.py +0 -0
  95. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/__init__.py +0 -0
  96. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/agent.py +0 -0
  97. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/analyzer.py +0 -0
  98. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/build.py +0 -0
  99. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/check.py +0 -0
  100. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/compress.py +0 -0
  101. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/conversation.py +0 -0
  102. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/cost.py +0 -0
  103. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/dashboard.py +0 -0
  104. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/dedup.py +0 -0
  105. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/digest.py +0 -0
  106. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/distill.py +0 -0
  107. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/effectiveness.py +0 -0
  108. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/explain.py +0 -0
  109. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/extractors_zh.py +0 -0
  110. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/insights.py +0 -0
  111. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/lang_detect.py +0 -0
  112. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/library.py +0 -0
  113. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/lint.py +0 -0
  114. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/merge_view.py +0 -0
  115. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/models.py +0 -0
  116. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/patterns.py +0 -0
  117. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/persona.py +0 -0
  118. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/pipeline.py +0 -0
  119. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/privacy.py +0 -0
  120. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/privacy_scan.py +0 -0
  121. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/prompt_dna.py +0 -0
  122. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/recommend.py +0 -0
  123. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/repetition.py +0 -0
  124. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/rewrite.py +0 -0
  125. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/scorer.py +0 -0
  126. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/segmenter.py +0 -0
  127. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/session_meta.py +0 -0
  128. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/session_quality.py +0 -0
  129. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/session_type.py +0 -0
  130. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/style.py +0 -0
  131. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/templates.py +0 -0
  132. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/timeutil.py +0 -0
  133. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/trends.py +0 -0
  134. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/core/wrapped.py +0 -0
  135. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/demo.py +0 -0
  136. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/embeddings/__init__.py +0 -0
  137. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/embeddings/base.py +0 -0
  138. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/embeddings/local_embed.py +0 -0
  139. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/embeddings/ollama.py +0 -0
  140. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/embeddings/openai_embed.py +0 -0
  141. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/embeddings/tfidf.py +0 -0
  142. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/mcp.py +0 -0
  143. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/mcp_main.py +0 -0
  144. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/__init__.py +0 -0
  145. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/agent_terminal.py +0 -0
  146. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/build_terminal.py +0 -0
  147. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/chartjs.min.js +0 -0
  148. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/check_terminal.py +0 -0
  149. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/compress_terminal.py +0 -0
  150. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/dashboard_terminal.py +0 -0
  151. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/distill_terminal.py +0 -0
  152. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/explain_terminal.py +0 -0
  153. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/export.py +0 -0
  154. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/html_report.py +0 -0
  155. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/json_out.py +0 -0
  156. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/markdown.py +0 -0
  157. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/patterns_terminal.py +0 -0
  158. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/projects_terminal.py +0 -0
  159. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/repetition_terminal.py +0 -0
  160. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/rewrite_terminal.py +0 -0
  161. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/sessions_terminal.py +0 -0
  162. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/terminal.py +0 -0
  163. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/wrapped_html.py +0 -0
  164. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/output/wrapped_terminal.py +0 -0
  165. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/py.typed +0 -0
  166. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/sharing/__init__.py +0 -0
  167. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/sharing/client.py +0 -0
  168. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/sharing/clipboard.py +0 -0
  169. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/storage/__init__.py +0 -0
  170. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/storage/db.py +0 -0
  171. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/__init__.py +0 -0
  172. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/collector.py +0 -0
  173. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/consent.py +0 -0
  174. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/events.py +0 -0
  175. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/prompt.py +0 -0
  176. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/queue.py +0 -0
  177. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/src/reprompt/telemetry/sender.py +0 -0
  178. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/__init__.py +0 -0
  179. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/conftest.py +0 -0
  180. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/aider_chat_history.md +0 -0
  181. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/chatgpt_conversations.json +0 -0
  182. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/claude_chat_export.json +0 -0
  183. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/claude_session.jsonl +0 -0
  184. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/cline_task/api_conversation_history.json +0 -0
  185. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/export/default_export.md +0 -0
  186. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/export/full_export.md +0 -0
  187. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/gemini_session.json +0 -0
  188. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/fixtures/openclaw_session.jsonl +0 -0
  189. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_aider.py +0 -0
  190. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_chatgpt.py +0 -0
  191. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_claude.py +0 -0
  192. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_claude_chat.py +0 -0
  193. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_cline.py +0 -0
  194. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_gemini.py +0 -0
  195. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_adapter_openclaw.py +0 -0
  196. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_agent.py +0 -0
  197. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_agent_cli.py +0 -0
  198. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_analyzer.py +0 -0
  199. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_bridge_cli.py +0 -0
  200. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_bridge_e2e.py +0 -0
  201. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_bridge_handler.py +0 -0
  202. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_bridge_integration.py +0 -0
  203. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_bridge_manifest.py +0 -0
  204. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_bridge_protocol.py +0 -0
  205. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_build.py +0 -0
  206. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_build_cli.py +0 -0
  207. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_build_output.py +0 -0
  208. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_check.py +0 -0
  209. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_check_cli.py +0 -0
  210. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_cli.py +0 -0
  211. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_cli_deprecations.py +0 -0
  212. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_cli_library_effectiveness.py +0 -0
  213. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_clipboard.py +0 -0
  214. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_codex_adapter.py +0 -0
  215. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_compare_best_worst.py +0 -0
  216. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_compress.py +0 -0
  217. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_compress_cli.py +0 -0
  218. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_compress_dna.py +0 -0
  219. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_compress_html.py +0 -0
  220. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_compress_insights.py +0 -0
  221. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_config.py +0 -0
  222. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_conversation.py +0 -0
  223. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_copy_flag.py +0 -0
  224. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_cost.py +0 -0
  225. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_coverage_boost.py +0 -0
  226. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_cursor_adapter.py +0 -0
  227. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_dashboard.py +0 -0
  228. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_db.py +0 -0
  229. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_db_digest.py +0 -0
  230. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_db_effectiveness.py +0 -0
  231. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_db_session_quality.py +0 -0
  232. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_db_trends.py +0 -0
  233. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_dedup.py +0 -0
  234. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_demo.py +0 -0
  235. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_deprecated_commands.py +0 -0
  236. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_digest.py +0 -0
  237. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_digest_cli.py +0 -0
  238. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_distill.py +0 -0
  239. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_distill_cli.py +0 -0
  240. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_distill_weights.py +0 -0
  241. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_e2e.py +0 -0
  242. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_effectiveness.py +0 -0
  243. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_embeddings_local.py +0 -0
  244. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_embeddings_ollama.py +0 -0
  245. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_embeddings_openai.py +0 -0
  246. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_empty_state.py +0 -0
  247. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_explain.py +0 -0
  248. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_explain_cli.py +0 -0
  249. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_export.py +0 -0
  250. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_export_cli.py +0 -0
  251. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_export_snapshot.py +0 -0
  252. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_extractors.py +0 -0
  253. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_extractors_routing.py +0 -0
  254. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_extractors_zh.py +0 -0
  255. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_extractors_zh_e2e.py +0 -0
  256. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_file_input.py +0 -0
  257. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_html_report.py +0 -0
  258. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_import_cli.py +0 -0
  259. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_import_e2e.py +0 -0
  260. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_init_cli.py +0 -0
  261. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_insights.py +0 -0
  262. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_insights_cli.py +0 -0
  263. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_insights_expanded.py +0 -0
  264. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_install_hook.py +0 -0
  265. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_lang_detect.py +0 -0
  266. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_library.py +0 -0
  267. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_lint.py +0 -0
  268. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_lint_cli.py +0 -0
  269. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_markdown.py +0 -0
  270. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_mcp.py +0 -0
  271. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_merge_view.py +0 -0
  272. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_models.py +0 -0
  273. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_output.py +0 -0
  274. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_parse_conversation_base.py +0 -0
  275. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_parse_conversation_chatgpt.py +0 -0
  276. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_parse_conversation_claude.py +0 -0
  277. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_patterns.py +0 -0
  278. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_persona.py +0 -0
  279. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_pipeline.py +0 -0
  280. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_privacy.py +0 -0
  281. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_privacy_cli.py +0 -0
  282. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_privacy_e2e.py +0 -0
  283. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_privacy_output.py +0 -0
  284. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_privacy_scan.py +0 -0
  285. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_projects.py +0 -0
  286. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_prompt_dna.py +0 -0
  287. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_public_api.py +0 -0
  288. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_recommend.py +0 -0
  289. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_repetition.py +0 -0
  290. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_repetition_cli.py +0 -0
  291. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_repetition_output.py +0 -0
  292. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_rewrite.py +0 -0
  293. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_schema_version.py +0 -0
  294. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_score_cli.py +0 -0
  295. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_scorer.py +0 -0
  296. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_segmenter.py +0 -0
  297. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_session_quality.py +0 -0
  298. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_session_type.py +0 -0
  299. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_sessions_cli.py +0 -0
  300. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_sessions_output.py +0 -0
  301. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_share_e2e.py +0 -0
  302. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_sharing_client.py +0 -0
  303. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_source_filter.py +0 -0
  304. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_style.py +0 -0
  305. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_style_trends.py +0 -0
  306. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_suggestions.py +0 -0
  307. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_cli.py +0 -0
  308. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_collector.py +0 -0
  309. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_consent.py +0 -0
  310. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_e2e.py +0 -0
  311. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_events.py +0 -0
  312. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_prompt.py +0 -0
  313. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_queue.py +0 -0
  314. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_telemetry_sender.py +0 -0
  315. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_template_cli.py +0 -0
  316. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_templates.py +0 -0
  317. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_timeutil.py +0 -0
  318. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_trends.py +0 -0
  319. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_trends_cli.py +0 -0
  320. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_use_cli.py +0 -0
  321. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_wrapped.py +0 -0
  322. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_wrapped_cli.py +0 -0
  323. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_wrapped_e2e.py +0 -0
  324. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_wrapped_html.py +0 -0
  325. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_wrapped_output.py +0 -0
  326. {reprompt_cli-2.4.0 → reprompt_cli-2.5.0}/tests/test_wrapped_share.py +0 -0
@@ -0,0 +1,32 @@
1
+ name: Feedback
2
+ description: Share your experience, ideas, or anything on your mind
3
+ labels: ["feedback"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ We'd love to hear from you — what's working, what's not, or any ideas you have.
9
+ - type: textarea
10
+ id: feedback
11
+ attributes:
12
+ label: Your feedback
13
+ description: Tell us anything — what you like, what could be better, or what you wish existed.
14
+ placeholder: "I tried reprompt rewrite and..."
15
+ validations:
16
+ required: true
17
+ - type: input
18
+ id: commands
19
+ attributes:
20
+ label: Which commands do you use most?
21
+ placeholder: "rewrite, check, patterns"
22
+ - type: input
23
+ id: tools
24
+ attributes:
25
+ label: Which AI tools do you use?
26
+ placeholder: "Claude Code, Cursor, ChatGPT"
27
+ - type: input
28
+ id: version
29
+ attributes:
30
+ label: reprompt version
31
+ description: "Run: reprompt --version"
32
+ placeholder: "2.4.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reprompt-cli
3
- Version: 2.4.0
3
+ Version: 2.5.0
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
@@ -114,6 +114,7 @@ $ reprompt check "Fix the auth bug in src/login.ts where JWT expires"
114
114
  | `reprompt agent` | Agent workflow analysis -- error loops, tool patterns, session efficiency |
115
115
  | `reprompt sessions` | Session quality scores with frustration signal detection |
116
116
  | `reprompt repetition` | Cross-session repetition detection -- spot recurring prompts |
117
+ | `reprompt patterns` | **Personal prompt weaknesses** -- recurring gaps by task type |
117
118
  | `reprompt projects` | Per-project quality breakdown -- sessions, scores, frustration signals |
118
119
 
119
120
  ### Optimize
@@ -210,7 +211,7 @@ reprompt install-hook # adds post-session hook to Claude Code
210
211
 
211
212
  ### Browser extension
212
213
 
213
- Capture prompts from ChatGPT, Claude.ai, and Gemini directly in your browser. Live score badge shows prompt quality as you type.
214
+ Capture prompts from ChatGPT, Claude.ai, and Gemini directly in your browser. Live score badge shows prompt quality as you type — click "Rewrite & Apply" to improve your prompt and replace the text directly in the input box.
214
215
 
215
216
  1. **Install the extension** from [Chrome Web Store](https://chromewebstore.google.com/detail/reprompt/ojdccpagaanchmkninlbgbgemdcjckhn) or [Firefox Add-ons](https://addons.mozilla.org/addon/reprompt-cli/)
216
217
  2. **Connect to the CLI:** `reprompt install-extension`
@@ -224,13 +225,40 @@ Captured prompts sync locally via Native Messaging -- nothing leaves your machin
224
225
 
225
226
  ```yaml
226
227
  # .github/workflows/prompt-lint.yml
227
- - uses: reprompt-dev/reprompt@main
228
- with:
229
- score-threshold: 50 # fail if avg prompt score < 50
230
- strict: true # fail on warnings too
231
- comment-on-pr: true # post quality report as PR comment
228
+ name: Prompt Quality
229
+ on: pull_request
230
+
231
+ jobs:
232
+ lint:
233
+ runs-on: ubuntu-latest
234
+ permissions:
235
+ pull-requests: write # needed for PR comments
236
+ steps:
237
+ - uses: actions/checkout@v4
238
+ - uses: reprompt-dev/reprompt@main
239
+ with:
240
+ score-threshold: 50 # fail if avg prompt score < 50
241
+ strict: true # fail on warnings too
242
+ comment-on-pr: true # post quality report as PR comment
232
243
  ```
233
244
 
245
+ When `comment-on-pr: true`, every PR gets a quality report:
246
+
247
+ ```
248
+ ## reprompt lint 🟢 Passed
249
+
250
+ | Metric | Value |
251
+ |-----------------|----------------|
252
+ | Prompts checked | 12 |
253
+ | Errors | 0 |
254
+ | Warnings | 2 |
255
+ | Avg Score | 62/100 ✅ (threshold: 50) |
256
+
257
+ 📋 2 violation(s) [click to expand]
258
+ ```
259
+
260
+ The comment updates on each push — no duplicates. Uses `GITHUB_TOKEN` (no extra secrets needed).
261
+
234
262
  #### pre-commit
235
263
 
236
264
  ```yaml
@@ -69,6 +69,7 @@ $ reprompt check "Fix the auth bug in src/login.ts where JWT expires"
69
69
  | `reprompt agent` | Agent workflow analysis -- error loops, tool patterns, session efficiency |
70
70
  | `reprompt sessions` | Session quality scores with frustration signal detection |
71
71
  | `reprompt repetition` | Cross-session repetition detection -- spot recurring prompts |
72
+ | `reprompt patterns` | **Personal prompt weaknesses** -- recurring gaps by task type |
72
73
  | `reprompt projects` | Per-project quality breakdown -- sessions, scores, frustration signals |
73
74
 
74
75
  ### Optimize
@@ -165,7 +166,7 @@ reprompt install-hook # adds post-session hook to Claude Code
165
166
 
166
167
  ### Browser extension
167
168
 
168
- Capture prompts from ChatGPT, Claude.ai, and Gemini directly in your browser. Live score badge shows prompt quality as you type.
169
+ Capture prompts from ChatGPT, Claude.ai, and Gemini directly in your browser. Live score badge shows prompt quality as you type — click "Rewrite & Apply" to improve your prompt and replace the text directly in the input box.
169
170
 
170
171
  1. **Install the extension** from [Chrome Web Store](https://chromewebstore.google.com/detail/reprompt/ojdccpagaanchmkninlbgbgemdcjckhn) or [Firefox Add-ons](https://addons.mozilla.org/addon/reprompt-cli/)
171
172
  2. **Connect to the CLI:** `reprompt install-extension`
@@ -179,13 +180,40 @@ Captured prompts sync locally via Native Messaging -- nothing leaves your machin
179
180
 
180
181
  ```yaml
181
182
  # .github/workflows/prompt-lint.yml
182
- - uses: reprompt-dev/reprompt@main
183
- with:
184
- score-threshold: 50 # fail if avg prompt score < 50
185
- strict: true # fail on warnings too
186
- comment-on-pr: true # post quality report as PR comment
183
+ name: Prompt Quality
184
+ on: pull_request
185
+
186
+ jobs:
187
+ lint:
188
+ runs-on: ubuntu-latest
189
+ permissions:
190
+ pull-requests: write # needed for PR comments
191
+ steps:
192
+ - uses: actions/checkout@v4
193
+ - uses: reprompt-dev/reprompt@main
194
+ with:
195
+ score-threshold: 50 # fail if avg prompt score < 50
196
+ strict: true # fail on warnings too
197
+ comment-on-pr: true # post quality report as PR comment
187
198
  ```
188
199
 
200
+ When `comment-on-pr: true`, every PR gets a quality report:
201
+
202
+ ```
203
+ ## reprompt lint 🟢 Passed
204
+
205
+ | Metric | Value |
206
+ |-----------------|----------------|
207
+ | Prompts checked | 12 |
208
+ | Errors | 0 |
209
+ | Warnings | 2 |
210
+ | Avg Score | 62/100 ✅ (threshold: 50) |
211
+
212
+ 📋 2 violation(s) [click to expand]
213
+ ```
214
+
215
+ The comment updates on each push — no duplicates. Uses `GITHUB_TOKEN` (no extra secrets needed).
216
+
189
217
  #### pre-commit
190
218
 
191
219
  ```yaml
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "reprompt-cli"
3
- version = "2.4.0"
3
+ version = "2.5.0"
4
4
  description = "Discover, analyze, and optimize your prompts from AI coding sessions"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -1,6 +1,6 @@
1
1
  """reprompt — Discover, analyze, and evolve your best prompts from AI coding sessions."""
2
2
 
3
- __version__ = "2.0.2"
3
+ __version__ = "2.5.0"
4
4
 
5
5
  __all__ = [
6
6
  "__version__",
@@ -55,6 +55,22 @@ app = typer.Typer(
55
55
  )
56
56
  console = Console()
57
57
 
58
+
59
+ def _show_hint(db: object, command: str, *, json_output: bool = False) -> None:
60
+ """Show journey hint or one-time feedback hint after a command."""
61
+ if json_output:
62
+ return
63
+ from reprompt.core.suggestions import get_suggestion, maybe_feedback_hint
64
+
65
+ fb = maybe_feedback_hint(db, command)
66
+ if fb:
67
+ console.print(f" [dim]\u2192 {fb}[/dim]\n")
68
+ return
69
+ hint = get_suggestion(command)
70
+ if hint:
71
+ console.print(f" [dim]\u2192 Try: {hint}[/dim]\n")
72
+
73
+
58
74
  # --- Template sub-app ---
59
75
  template_app = typer.Typer(help="Manage prompt templates.", invoke_without_command=True)
60
76
 
@@ -320,11 +336,8 @@ def scan(
320
336
  console.print(" reprompt template list — see your prompt patterns")
321
337
  console.print(" reprompt insights — personal analysis")
322
338
  else:
323
- from reprompt.core.suggestions import get_suggestion
324
-
325
- hint = get_suggestion("scan")
326
- if hint and result.unique_after_dedup > 0:
327
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
339
+ if result.unique_after_dedup > 0:
340
+ _show_hint(db, "scan")
328
341
 
329
342
 
330
343
  def _hook_registered() -> bool:
@@ -524,13 +537,11 @@ def report(
524
537
 
525
538
  print(format_json_report(data))
526
539
  else:
527
- from reprompt.core.suggestions import get_suggestion
528
540
  from reprompt.output.terminal import render_report
541
+ from reprompt.storage.db import PromptDB
529
542
 
530
543
  print(render_report(data), end="")
531
- hint = get_suggestion("report")
532
- if hint:
533
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
544
+ _show_hint(PromptDB(settings.db_path), "report")
534
545
 
535
546
 
536
547
  @app.command(deprecated=True, hidden=True)
@@ -1017,11 +1028,11 @@ def check(
1017
1028
  if copy:
1018
1029
  _copy_to_clip(result.rewritten, quiet=json_output)
1019
1030
 
1020
- from reprompt.core.suggestions import get_suggestion
1031
+ if not json_output:
1032
+ from reprompt.config import Settings as _S
1033
+ from reprompt.storage.db import PromptDB as _DB
1021
1034
 
1022
- hint = get_suggestion("check")
1023
- if hint and not json_output:
1024
- console.print(f" [dim]→ Try: {hint}[/dim]\n")
1035
+ _show_hint(_DB(_S().db_path), "check", json_output=json_output)
1025
1036
 
1026
1037
 
1027
1038
  @app.command(rich_help_panel="Analyze")
@@ -1063,11 +1074,11 @@ def explain(
1063
1074
 
1064
1075
  typer.echo(render_explain(result))
1065
1076
 
1066
- from reprompt.core.suggestions import get_suggestion
1077
+ if not json_output:
1078
+ from reprompt.config import Settings as _S
1079
+ from reprompt.storage.db import PromptDB as _DB
1067
1080
 
1068
- hint = get_suggestion("explain")
1069
- if hint and not json_output:
1070
- console.print(f" [dim]→ Try: {hint}[/dim]\n")
1081
+ _show_hint(_DB(_S().db_path), "explain", json_output=json_output)
1071
1082
 
1072
1083
 
1073
1084
  @app.command(rich_help_panel="Analyze")
@@ -1171,11 +1182,10 @@ def score(
1171
1182
  ],
1172
1183
  }
1173
1184
  typer.echo(render_score(data))
1174
- from reprompt.core.suggestions import get_suggestion
1185
+ from reprompt.config import Settings as _S
1186
+ from reprompt.storage.db import PromptDB as _DB
1175
1187
 
1176
- hint = get_suggestion("score")
1177
- if hint:
1178
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
1188
+ _show_hint(_DB(_S().db_path), "score")
1179
1189
 
1180
1190
  if copy:
1181
1191
  import json as json_mod
@@ -1281,11 +1291,11 @@ def rewrite(
1281
1291
  if copy:
1282
1292
  _copy_to_clip(result.rewritten, quiet=json_output)
1283
1293
 
1284
- from reprompt.core.suggestions import get_suggestion
1294
+ if not json_output:
1295
+ from reprompt.config import Settings as _S
1296
+ from reprompt.storage.db import PromptDB as _DB
1285
1297
 
1286
- hint = get_suggestion("rewrite")
1287
- if hint and not json_output:
1288
- console.print(f" [dim]→ Try: {hint}[/dim]\n")
1298
+ _show_hint(_DB(_S().db_path), "rewrite", json_output=json_output)
1289
1299
 
1290
1300
 
1291
1301
  @app.command(rich_help_panel="Optimize")
@@ -1348,11 +1358,11 @@ def build(
1348
1358
  if copy:
1349
1359
  _copy_to_clip(result.prompt, quiet=json_output)
1350
1360
 
1351
- from reprompt.core.suggestions import get_suggestion
1361
+ if not json_output:
1362
+ from reprompt.config import Settings as _S
1363
+ from reprompt.storage.db import PromptDB as _DB
1352
1364
 
1353
- hint = get_suggestion("build")
1354
- if hint and not json_output:
1355
- console.print(f" [dim]→ Try: {hint}[/dim]\n")
1365
+ _show_hint(_DB(_S().db_path), "build", json_output=json_output)
1356
1366
 
1357
1367
 
1358
1368
  @app.command(rich_help_panel="Optimize")
@@ -1505,11 +1515,7 @@ def distill(
1505
1515
  else:
1506
1516
  parts.append(render_distill(result))
1507
1517
  typer.echo("\n---\n".join(parts) if len(parts) > 1 else parts[0])
1508
- from reprompt.core.suggestions import get_suggestion
1509
-
1510
- hint = get_suggestion("distill")
1511
- if hint:
1512
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
1518
+ _show_hint(db, "distill")
1513
1519
 
1514
1520
  if copy:
1515
1521
  if summary:
@@ -1794,7 +1800,6 @@ def insights(
1794
1800
  result["cross_session_repetition"] = rep_data
1795
1801
  typer.echo(json_mod.dumps(result, indent=2))
1796
1802
  else:
1797
- from reprompt.core.suggestions import get_suggestion
1798
1803
  from reprompt.output.terminal import (
1799
1804
  render_effectiveness_section,
1800
1805
  render_insights,
@@ -1824,9 +1829,7 @@ def insights(
1824
1829
  console.print(f' "{t["canonical_text"]}" \u2014 {t["session_count"]} sessions')
1825
1830
  console.print(" [dim]\u2192 Try: reprompt repetition (full analysis)[/dim]")
1826
1831
 
1827
- hint = get_suggestion("insights")
1828
- if hint:
1829
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
1832
+ _show_hint(db, "insights")
1830
1833
 
1831
1834
  if copy:
1832
1835
  import json as json_mod
@@ -1982,13 +1985,10 @@ def digest(
1982
1985
  if format == "json":
1983
1986
  print(json_mod.dumps(data, indent=2, default=str))
1984
1987
  else:
1985
- from reprompt.core.suggestions import get_suggestion
1986
1988
  from reprompt.output.terminal import render_digest
1987
1989
 
1988
1990
  print(render_digest(data), end="")
1989
- hint = get_suggestion("digest")
1990
- if hint:
1991
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
1991
+ _show_hint(db, "digest")
1992
1992
 
1993
1993
  if trends_flag:
1994
1994
  from reprompt.core.trends import compute_trends
@@ -2291,6 +2291,29 @@ debug-needs-reference = true
2291
2291
  console.print(" Edit rules, then run [bold]reprompt lint[/bold] to verify.")
2292
2292
 
2293
2293
 
2294
+ @app.command(rich_help_panel="Setup")
2295
+ def feedback() -> None:
2296
+ """Open the feedback form — share your experience, ideas, or suggestions.
2297
+
2298
+ Opens a GitHub issue template in your browser. No account required to view,
2299
+ but you'll need a GitHub account to submit.
2300
+
2301
+ Examples:
2302
+
2303
+ reprompt feedback
2304
+ """
2305
+ import webbrowser
2306
+
2307
+ from reprompt.core.suggestions import FEEDBACK_URL
2308
+
2309
+ console.print(
2310
+ "\n [bold]We'd love to hear from you![/bold]\n Opening feedback form in your browser...\n"
2311
+ )
2312
+ opened = webbrowser.open(FEEDBACK_URL)
2313
+ if not opened:
2314
+ console.print(f" [dim]Could not open browser. Visit:[/dim]\n {FEEDBACK_URL}\n")
2315
+
2316
+
2294
2317
  @app.command(rich_help_panel="Analyze")
2295
2318
  def projects(
2296
2319
  source: str = typer.Option(
@@ -2335,11 +2358,7 @@ def projects(
2335
2358
  else:
2336
2359
  _copy_to_clip(output)
2337
2360
 
2338
- from reprompt.core.suggestions import get_suggestion
2339
-
2340
- hint = get_suggestion("projects")
2341
- if hint and not json_output:
2342
- console.print(f" [dim]→ Try: {hint}[/dim]\n")
2361
+ _show_hint(db, "projects", json_output=json_output)
2343
2362
 
2344
2363
 
2345
2364
  @app.command(rich_help_panel="Analyze")
@@ -2385,12 +2404,7 @@ def sessions(
2385
2404
  typer.echo(json_mod.dumps(data, indent=2, default=str))
2386
2405
  else:
2387
2406
  typer.echo(render_sessions_table(data), nl=False)
2388
-
2389
- from reprompt.core.suggestions import get_suggestion
2390
-
2391
- hint = get_suggestion("sessions")
2392
- if hint:
2393
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
2407
+ _show_hint(db, "sessions")
2394
2408
 
2395
2409
  if copy:
2396
2410
  if detail:
@@ -2426,6 +2440,7 @@ def patterns(
2426
2440
  typer.echo(json_mod.dumps(asdict(report), indent=2, default=str))
2427
2441
  else:
2428
2442
  typer.echo(render_patterns(report), nl=False)
2443
+ _show_hint(db, "patterns", json_output=json_output)
2429
2444
 
2430
2445
  if copy:
2431
2446
  copy_text = json_mod.dumps(asdict(report), indent=2, default=str)
@@ -2458,12 +2473,7 @@ def repetition(
2458
2473
  typer.echo(json_mod.dumps(asdict(report), indent=2, default=str))
2459
2474
  else:
2460
2475
  typer.echo(render_repetition_report(report), nl=False)
2461
-
2462
- from reprompt.core.suggestions import get_suggestion
2463
-
2464
- hint = get_suggestion("repetition")
2465
- if hint:
2466
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
2476
+ _show_hint(db, "repetition")
2467
2477
 
2468
2478
  if copy:
2469
2479
  copy_text = json_mod.dumps(asdict(report), indent=2, default=str)
@@ -2528,12 +2538,7 @@ def agent(
2528
2538
  from reprompt.output.agent_terminal import render_agent_report
2529
2539
 
2530
2540
  typer.echo(render_agent_report(agg), nl=False)
2531
-
2532
- from reprompt.core.suggestions import get_suggestion
2533
-
2534
- hint = get_suggestion("agent")
2535
- if hint:
2536
- console.print(f"\n [dim]\u2192 Try: {hint}[/dim]")
2541
+ _show_hint(db, "agent")
2537
2542
 
2538
2543
  if copy:
2539
2544
  import json as json_mod
@@ -362,13 +362,11 @@ def _find_instruction_position(segments: list[PromptSegment]) -> float:
362
362
  # No instruction found -- default to start (assume the whole thing is instruction)
363
363
  return 0.0
364
364
 
365
- # Single-segment prompt: the instruction starts at the beginning
366
- if len(segments) == 1 and instruction_segments[0] is segments[0]:
367
- return 0.0
368
-
369
- # Multi-segment: use the midpoint of the first instruction segment
365
+ # Use the start position of the first instruction segment.
366
+ # Not the midpoint the instruction *starts* at start_pos,
367
+ # and that's what matters for the Lost in the Middle effect.
370
368
  seg = instruction_segments[0]
371
- return (seg.start_pos + seg.end_pos) / 2
369
+ return seg.start_pos
372
370
 
373
371
 
374
372
  def _classify_distribution(segments: list[PromptSegment]) -> str:
@@ -2,6 +2,11 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import sys
6
+
7
+ FEEDBACK_URL = "https://github.com/reprompt-dev/reprompt/issues/new?template=feedback.yml"
8
+ FEEDBACK_COMMANDS_THRESHOLD = 5 # show feedback hint after 5 distinct commands used
9
+
5
10
  SUGGESTIONS: dict[str, str] = {
6
11
  "scan": "reprompt report (see results) · reprompt insights (personal patterns)",
7
12
  "report": "reprompt insights (patterns) · reprompt distill --last (session review)",
@@ -35,3 +40,26 @@ SUGGESTIONS: dict[str, str] = {
35
40
  def get_suggestion(command: str) -> str | None:
36
41
  """Return the suggestion line for a command, or None."""
37
42
  return SUGGESTIONS.get(command)
43
+
44
+
45
+ def maybe_feedback_hint(db: object, command: str) -> str | None:
46
+ """Return a one-time feedback hint if the user has used enough commands.
47
+
48
+ Returns the hint string (replacing the journey hint) exactly once,
49
+ then never again. Returns None in non-TTY / CI / JSON contexts.
50
+ """
51
+ if not sys.stdout.isatty():
52
+ return None
53
+ if hasattr(db, "get_setting") and db.get_setting("feedback_hint_shown"): # type: ignore[union-attr]
54
+ return None
55
+ # Track distinct commands used
56
+ used_raw = db.get_setting("commands_used") if hasattr(db, "get_setting") else None # type: ignore[union-attr]
57
+ used: set[str] = set(used_raw.split(",")) if used_raw else set()
58
+ used.add(command)
59
+ if hasattr(db, "set_setting"):
60
+ db.set_setting("commands_used", ",".join(sorted(used))) # type: ignore[union-attr]
61
+ if len(used) >= FEEDBACK_COMMANDS_THRESHOLD:
62
+ if hasattr(db, "set_setting"):
63
+ db.set_setting("feedback_hint_shown", "1") # type: ignore[union-attr]
64
+ return "Feedback or ideas? reprompt feedback"
65
+ return None
@@ -0,0 +1,89 @@
1
+ """Tests for feedback hint and command tracking."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from unittest.mock import MagicMock, patch
6
+
7
+ from reprompt.core.suggestions import (
8
+ FEEDBACK_COMMANDS_THRESHOLD,
9
+ FEEDBACK_URL,
10
+ maybe_feedback_hint,
11
+ )
12
+
13
+
14
+ class TestFeedbackHint:
15
+ def _make_db(self, settings: dict[str, str] | None = None) -> MagicMock:
16
+ """Create a mock DB with get_setting/set_setting."""
17
+ store: dict[str, str] = dict(settings) if settings else {}
18
+ db = MagicMock()
19
+ db.get_setting = MagicMock(side_effect=lambda k: store.get(k))
20
+
21
+ def _set(k: str, v: str) -> None:
22
+ store[k] = v
23
+
24
+ db.set_setting = MagicMock(side_effect=_set)
25
+ db._store = store # expose for assertions
26
+ return db
27
+
28
+ def test_returns_none_when_not_tty(self):
29
+ db = self._make_db()
30
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
31
+ mock_sys.stdout.isatty.return_value = False
32
+ assert maybe_feedback_hint(db, "score") is None
33
+
34
+ def test_returns_none_when_already_shown(self):
35
+ db = self._make_db({"feedback_hint_shown": "1"})
36
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
37
+ mock_sys.stdout.isatty.return_value = True
38
+ assert maybe_feedback_hint(db, "score") is None
39
+
40
+ def test_tracks_commands_used(self):
41
+ db = self._make_db()
42
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
43
+ mock_sys.stdout.isatty.return_value = True
44
+ maybe_feedback_hint(db, "score")
45
+ assert "score" in db._store.get("commands_used", "")
46
+
47
+ def test_returns_none_below_threshold(self):
48
+ db = self._make_db()
49
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
50
+ mock_sys.stdout.isatty.return_value = True
51
+ # Only 1 command used
52
+ result = maybe_feedback_hint(db, "score")
53
+ assert result is None
54
+
55
+ def test_returns_hint_at_threshold(self):
56
+ # Pre-populate with threshold - 1 commands
57
+ cmds = ["score", "rewrite", "check", "patterns"]
58
+ assert len(cmds) == FEEDBACK_COMMANDS_THRESHOLD - 1
59
+ db = self._make_db({"commands_used": ",".join(cmds)})
60
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
61
+ mock_sys.stdout.isatty.return_value = True
62
+ result = maybe_feedback_hint(db, "insights") # 5th unique command
63
+ assert result is not None
64
+ assert "feedback" in result
65
+
66
+ def test_marks_shown_after_trigger(self):
67
+ cmds = ["score", "rewrite", "check", "patterns"]
68
+ db = self._make_db({"commands_used": ",".join(cmds)})
69
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
70
+ mock_sys.stdout.isatty.return_value = True
71
+ maybe_feedback_hint(db, "insights")
72
+ assert db._store.get("feedback_hint_shown") == "1"
73
+
74
+ def test_duplicate_commands_dont_count(self):
75
+ db = self._make_db()
76
+ with patch("reprompt.core.suggestions.sys") as mock_sys:
77
+ mock_sys.stdout.isatty.return_value = True
78
+ result = None
79
+ for _ in range(10):
80
+ result = maybe_feedback_hint(db, "score")
81
+ # Only 1 unique command, should not trigger
82
+ assert result is None
83
+
84
+ def test_feedback_url_is_valid(self):
85
+ assert "github.com" in FEEDBACK_URL
86
+ assert "feedback" in FEEDBACK_URL
87
+
88
+ def test_threshold_is_reasonable(self):
89
+ assert 3 <= FEEDBACK_COMMANDS_THRESHOLD <= 10
@@ -2210,7 +2210,7 @@ wheels = [
2210
2210
 
2211
2211
  [[package]]
2212
2212
  name = "reprompt-cli"
2213
- version = "2.4.0"
2213
+ version = "2.5.0"
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
File without changes