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.
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/CHANGELOG.md +7 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/PKG-INFO +2 -2
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/README.md +1 -1
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/pyproject.toml +1 -1
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/cli.py +34 -9
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/mcp.py +128 -1
- reprompt_cli-2.2.1/tests/test_file_input.py +107 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_mcp.py +69 -2
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/uv.lock +1 -1
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.editorconfig +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/dependabot.yml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/workflows/ci.yml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.github/workflows/publish.yml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.gitignore +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.pre-commit-config.yaml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.pre-commit-hooks.yaml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.testmondata-shm +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/.testmondata-wal +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/CODE_OF_CONDUCT.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/CONTRIBUTING.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/LICENSE +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/SECURITY.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/Screenshot 2026-03-24 at 09.45.03.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/action.yml +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/demo.gif +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-128.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-16.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-256.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-32.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-48.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-512.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon-96.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/brand-icon.svg +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-128.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-16.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-256.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-32.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-48.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-512.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon-96.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-favicon.svg +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-128.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-16.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-256.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-32.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-48.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-512.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon-96.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/cli-icon.svg +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-128.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-16.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-256.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-32.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-48.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-512.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon-96.png +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/favicon.svg +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/icons/generate.sh +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/superpowers/specs/2026-03-24-v14-command-consolidation-design.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/docs/superpowers/specs/2026-03-25-v1.5-dashboard-design.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/scripts/generate_demo_data.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/aider.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/base.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/chatgpt.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/claude_chat.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/claude_code.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/cline.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/codex.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/cursor.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/filters.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/gemini.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/adapters/openclaw.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/handler.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/host.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/manifest.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/bridge/protocol.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/commands/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/commands/telemetry.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/commands/wrapped.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/config.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/agent.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/analyzer.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/build.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/check.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/compress.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/conversation.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/cost.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/dashboard.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/dedup.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/digest.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/distill.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/effectiveness.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/explain.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/extractors.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/extractors_zh.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/insights.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/lang_detect.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/library.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/lint.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/merge_view.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/models.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/persona.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/pipeline.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/privacy.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/privacy_scan.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/prompt_dna.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/recommend.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/repetition.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/rewrite.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/scorer.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/segmenter.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/session_meta.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/session_quality.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/session_type.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/style.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/suggestions.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/templates.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/timeutil.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/trends.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/core/wrapped.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/demo.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/base.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/local_embed.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/ollama.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/openai_embed.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/embeddings/tfidf.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/mcp_main.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/agent_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/build_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/chartjs.min.js +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/check_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/compress_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/dashboard_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/distill_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/explain_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/export.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/html_report.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/json_out.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/markdown.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/projects_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/repetition_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/rewrite_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/sessions_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/wrapped_html.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/output/wrapped_terminal.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/py.typed +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/sharing/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/sharing/client.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/sharing/clipboard.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/storage/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/storage/db.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/collector.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/consent.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/events.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/prompt.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/queue.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/src/reprompt/telemetry/sender.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/__init__.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/conftest.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/aider_chat_history.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/chatgpt_conversations.json +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/claude_chat_export.json +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/claude_session.jsonl +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/cline_task/api_conversation_history.json +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/export/default_export.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/export/full_export.md +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/gemini_session.json +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/fixtures/openclaw_session.jsonl +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_aider.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_chatgpt.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_claude.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_claude_chat.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_cline.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_gemini.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_adapter_openclaw.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_agent.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_agent_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_analyzer.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_handler.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_integration.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_manifest.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_bridge_protocol.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_build.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_build_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_build_output.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_check.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_check_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cli_deprecations.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cli_library_effectiveness.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_clipboard.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_codex_adapter.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compare_best_worst.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_dna.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_html.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_compress_insights.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_config.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_conversation.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_copy_flag.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cost.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_coverage_boost.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_cursor_adapter.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_dashboard.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_digest.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_effectiveness.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_session_quality.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_db_trends.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_dedup.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_demo.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_deprecated_commands.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_digest.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_digest_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_distill.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_distill_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_distill_weights.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_effectiveness.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_embeddings_local.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_embeddings_ollama.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_embeddings_openai.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_empty_state.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_explain.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_explain_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_export.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_export_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_export_snapshot.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors_routing.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors_zh.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_extractors_zh_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_html_report.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_import_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_import_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_init_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_insights.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_insights_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_insights_expanded.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_install_hook.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_lang_detect.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_library.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_lint.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_lint_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_markdown.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_merge_view.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_models.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_output.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_parse_conversation_base.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_parse_conversation_chatgpt.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_parse_conversation_claude.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_persona.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_pipeline.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_output.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_privacy_scan.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_projects.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_prompt_dna.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_public_api.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_recommend.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_repetition.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_repetition_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_repetition_output.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_rewrite.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_schema_version.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_score_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_scorer.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_segmenter.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_session_quality.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_session_type.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_sessions_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_sessions_output.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_share_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_sharing_client.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_source_filter.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_style.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_style_trends.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_suggestions.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_collector.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_consent.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_events.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_prompt.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_queue.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_telemetry_sender.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_template_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_templates.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_timeutil.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_trends.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_trends_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_use_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_cli.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_e2e.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_html.py +0 -0
- {reprompt_cli-2.2.0 → reprompt_cli-2.2.1}/tests/test_wrapped_output.py +0 -0
- {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.
|
|
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.
|
|
233
|
+
rev: v2.2.1
|
|
234
234
|
hooks:
|
|
235
235
|
- id: reprompt-lint
|
|
236
236
|
```
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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) ==
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|