reprompt-cli 1.9.1__tar.gz → 2.0.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.
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/PKG-INFO +51 -16
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/README.md +50 -15
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/pyproject.toml +1 -1
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/__init__.py +1 -1
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/cli.py +111 -0
- reprompt_cli-2.0.0/src/reprompt/core/rewrite.py +221 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/suggestions.py +2 -0
- reprompt_cli-2.0.0/src/reprompt/output/rewrite_terminal.py +69 -0
- reprompt_cli-2.0.0/tests/test_init_cli.py +80 -0
- reprompt_cli-2.0.0/tests/test_rewrite.py +157 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_suggestions.py +4 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/uv.lock +1 -1
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.editorconfig +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/dependabot.yml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/workflows/ci.yml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.github/workflows/publish.yml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.gitignore +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.pre-commit-config.yaml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.pre-commit-hooks.yaml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.testmondata-shm +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/.testmondata-wal +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/CHANGELOG.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/CODE_OF_CONDUCT.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/CONTRIBUTING.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/LICENSE +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/SECURITY.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/Screenshot 2026-03-24 at 09.45.03.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/action.yml +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/demo.gif +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-128.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-16.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-256.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-32.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-48.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-512.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon-96.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/brand-icon.svg +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-128.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-16.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-256.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-32.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-48.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-512.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon-96.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-favicon.svg +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-128.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-16.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-256.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-32.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-48.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-512.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon-96.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/cli-icon.svg +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-128.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-16.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-256.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-32.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-48.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-512.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon-96.png +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/favicon.svg +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/icons/generate.sh +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/superpowers/specs/2026-03-24-v14-command-consolidation-design.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/docs/superpowers/specs/2026-03-25-v1.5-dashboard-design.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/scripts/generate_demo_data.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/aider.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/base.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/chatgpt.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/claude_chat.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/claude_code.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/cline.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/codex.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/cursor.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/filters.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/gemini.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/adapters/openclaw.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/bridge/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/bridge/handler.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/bridge/host.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/bridge/manifest.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/bridge/protocol.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/commands/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/commands/telemetry.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/commands/wrapped.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/config.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/agent.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/analyzer.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/compress.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/conversation.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/cost.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/dashboard.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/dedup.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/digest.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/distill.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/effectiveness.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/extractors.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/extractors_zh.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/insights.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/lang_detect.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/library.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/lint.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/merge_view.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/models.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/persona.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/pipeline.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/privacy.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/privacy_scan.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/prompt_dna.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/recommend.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/repetition.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/scorer.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/segmenter.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/session_meta.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/session_quality.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/session_type.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/style.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/templates.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/timeutil.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/trends.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/core/wrapped.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/demo.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/embeddings/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/embeddings/base.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/embeddings/local_embed.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/embeddings/ollama.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/embeddings/openai_embed.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/embeddings/tfidf.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/mcp.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/mcp_main.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/agent_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/chartjs.min.js +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/compress_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/dashboard_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/distill_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/export.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/html_report.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/json_out.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/markdown.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/repetition_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/sessions_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/wrapped_html.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/output/wrapped_terminal.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/py.typed +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/sharing/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/sharing/client.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/sharing/clipboard.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/storage/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/storage/db.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/collector.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/consent.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/events.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/prompt.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/queue.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/src/reprompt/telemetry/sender.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/__init__.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/conftest.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/aider_chat_history.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/chatgpt_conversations.json +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/claude_chat_export.json +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/claude_session.jsonl +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/cline_task/api_conversation_history.json +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/export/default_export.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/export/full_export.md +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/gemini_session.json +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/fixtures/openclaw_session.jsonl +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_aider.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_chatgpt.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_claude.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_claude_chat.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_cline.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_gemini.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_adapter_openclaw.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_agent.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_agent_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_analyzer.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_bridge_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_bridge_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_bridge_handler.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_bridge_integration.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_bridge_manifest.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_bridge_protocol.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_cli_deprecations.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_cli_library_effectiveness.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_clipboard.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_codex_adapter.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_compare_best_worst.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_compress.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_compress_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_compress_dna.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_compress_html.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_compress_insights.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_config.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_conversation.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_copy_flag.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_cost.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_coverage_boost.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_cursor_adapter.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_dashboard.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_db.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_db_digest.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_db_effectiveness.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_db_session_quality.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_db_trends.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_dedup.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_demo.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_deprecated_commands.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_digest.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_digest_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_distill.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_distill_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_distill_weights.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_effectiveness.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_embeddings_local.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_embeddings_ollama.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_embeddings_openai.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_empty_state.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_export.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_export_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_export_snapshot.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_extractors.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_extractors_routing.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_extractors_zh.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_extractors_zh_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_html_report.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_import_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_import_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_insights.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_insights_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_insights_expanded.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_install_hook.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_lang_detect.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_library.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_lint.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_lint_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_markdown.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_mcp.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_merge_view.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_models.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_output.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_parse_conversation_base.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_parse_conversation_chatgpt.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_parse_conversation_claude.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_persona.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_pipeline.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_privacy.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_privacy_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_privacy_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_privacy_output.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_privacy_scan.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_prompt_dna.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_public_api.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_recommend.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_repetition.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_repetition_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_repetition_output.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_schema_version.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_score_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_scorer.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_segmenter.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_session_quality.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_session_type.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_sessions_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_sessions_output.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_share_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_sharing_client.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_source_filter.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_style.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_style_trends.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_collector.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_consent.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_events.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_prompt.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_queue.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_telemetry_sender.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_template_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_templates.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_timeutil.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_trends.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_trends_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_use_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_wrapped.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_wrapped_cli.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_wrapped_e2e.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_wrapped_html.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_wrapped_output.py +0 -0
- {reprompt_cli-1.9.1 → reprompt_cli-2.0.0}/tests/test_wrapped_share.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reprompt-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.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
|
|
@@ -45,7 +45,7 @@ Description-Content-Type: text/markdown
|
|
|
45
45
|
|
|
46
46
|
# `re:prompt`
|
|
47
47
|
|
|
48
|
-
**
|
|
48
|
+
**Score, rewrite, and optimize your AI prompts** -- the only CLI that improves your prompts automatically. No LLM needed.
|
|
49
49
|
|
|
50
50
|
[](https://pypi.org/project/reprompt-cli/)
|
|
51
51
|
[](https://pypi.org/project/reprompt-cli/)
|
|
@@ -61,26 +61,39 @@ Description-Content-Type: text/markdown
|
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
$ pip install reprompt-cli
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
|
|
65
|
+
# Rewrite a weak prompt into a better one (no LLM, rule-based)
|
|
66
|
+
$ reprompt rewrite "I was wondering if you could maybe help me fix the auth bug"
|
|
67
|
+
34 → 52 (+18)
|
|
68
|
+
|
|
69
|
+
╭─ Rewritten ────────────────────────────────────────────────╮
|
|
70
|
+
│ Help me fix the auth bug. │
|
|
69
71
|
╰────────────────────────────────────────────────────────────╯
|
|
70
72
|
|
|
73
|
+
Changes
|
|
74
|
+
✓ Removed filler (24% shorter)
|
|
75
|
+
✓ Removed hedging language
|
|
76
|
+
|
|
77
|
+
You should also
|
|
78
|
+
→ Add actual code snippets or error messages for context
|
|
79
|
+
→ Reference specific files or functions by name
|
|
80
|
+
→ Add constraints (e.g., "Do not modify existing tests")
|
|
81
|
+
|
|
82
|
+
# Score any prompt instantly (research-backed, 30+ features)
|
|
71
83
|
$ reprompt score "Fix the auth bug in src/login.ts where JWT expires"
|
|
72
84
|
Score: 40/100 (Fair)
|
|
73
|
-
Structure: 0/25 | Context: 8/25 | Position: 20/20 | Repetition: 0/15 | Clarity: 12/15
|
|
74
85
|
Tip: Include the error message -- debug prompts with errors are 3.7x more effective
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
Key moments: initial spec → auth module → test failures → JWT fix → passing
|
|
79
|
-
Context: "Building auth system with JWT refresh tokens for Express API"
|
|
80
|
-
|
|
81
|
-
$ reprompt compress "I was wondering if you could please help me refactor this code. Basically what I need is to split this function into smaller helpers and add error handling."
|
|
87
|
+
# Compress prompts to save tokens
|
|
88
|
+
$ reprompt compress "I was wondering if you could please help me refactor this code. Basically what I need is to split this function into smaller helpers."
|
|
82
89
|
Before: 28 tokens → After: 14 tokens (50% saved)
|
|
83
|
-
|
|
90
|
+
|
|
91
|
+
# Your personal dashboard
|
|
92
|
+
$ reprompt
|
|
93
|
+
╭─ Prompt Dashboard ─────────────────────────────────────────╮
|
|
94
|
+
│ Prompts: 1,063 (295 unique) Sessions: 890 │
|
|
95
|
+
│ Avg Score: 68/100 Top: debug (31%), impl (24%)│
|
|
96
|
+
╰────────────────────────────────────────────────────────────╯
|
|
84
97
|
```
|
|
85
98
|
|
|
86
99
|
## What it does
|
|
@@ -96,15 +109,19 @@ $ reprompt compress "I was wondering if you could please help me refactor this c
|
|
|
96
109
|
| `reprompt insights` | Personal patterns vs research-optimal benchmarks |
|
|
97
110
|
| `reprompt style` | Prompting fingerprint with `--trends` for evolution tracking |
|
|
98
111
|
| `reprompt agent` | Agent workflow analysis -- error loops, tool patterns, session efficiency |
|
|
112
|
+
| `reprompt sessions` | Session quality scores with frustration signal detection |
|
|
113
|
+
| `reprompt repetition` | Cross-session repetition detection -- spot recurring prompts |
|
|
99
114
|
|
|
100
115
|
### Optimize
|
|
101
116
|
|
|
102
117
|
| Command | Description |
|
|
103
118
|
|---------|-------------|
|
|
119
|
+
| `reprompt rewrite "prompt"` | **Rewrite prompts to score higher** -- filler removal, restructuring, hedging cleanup |
|
|
104
120
|
| `reprompt compress "prompt"` | 4-layer prompt compression (40-60% token savings typical) |
|
|
105
121
|
| `reprompt distill` | Extract important turns from conversations with 6-signal scoring |
|
|
106
122
|
| `reprompt distill --export` | Recover context when a session runs out -- paste into new session |
|
|
107
|
-
| `reprompt lint` |
|
|
123
|
+
| `reprompt lint` | Configurable prompt quality linter with CI/GitHub Action support |
|
|
124
|
+
| `reprompt init` | Generate `.reprompt.toml` config for your project |
|
|
108
125
|
|
|
109
126
|
### Manage
|
|
110
127
|
|
|
@@ -223,6 +240,24 @@ reprompt lint --strict # exit 1 on warnings
|
|
|
223
240
|
reprompt lint --json # machine-readable output
|
|
224
241
|
```
|
|
225
242
|
|
|
243
|
+
#### Project configuration
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
reprompt init # generates .reprompt.toml with all rules documented
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```toml
|
|
250
|
+
# .reprompt.toml (or [tool.reprompt.lint] in pyproject.toml)
|
|
251
|
+
[lint]
|
|
252
|
+
score-threshold = 50 # fail if avg score < 50
|
|
253
|
+
|
|
254
|
+
[lint.rules]
|
|
255
|
+
min-length = 20 # error if prompt < 20 chars (0 = off)
|
|
256
|
+
short-prompt = 40 # warning if < 40 chars (0 = off)
|
|
257
|
+
vague-prompt = true # error on "fix it" etc (false = off)
|
|
258
|
+
debug-needs-reference = true
|
|
259
|
+
```
|
|
260
|
+
|
|
226
261
|
## Privacy
|
|
227
262
|
|
|
228
263
|
- All analysis runs locally. No prompts leave your machine.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `re:prompt`
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Score, rewrite, and optimize your AI prompts** -- the only CLI that improves your prompts automatically. No LLM needed.
|
|
4
4
|
|
|
5
5
|
[](https://pypi.org/project/reprompt-cli/)
|
|
6
6
|
[](https://pypi.org/project/reprompt-cli/)
|
|
@@ -16,26 +16,39 @@
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
$ pip install reprompt-cli
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
|
|
20
|
+
# Rewrite a weak prompt into a better one (no LLM, rule-based)
|
|
21
|
+
$ reprompt rewrite "I was wondering if you could maybe help me fix the auth bug"
|
|
22
|
+
34 → 52 (+18)
|
|
23
|
+
|
|
24
|
+
╭─ Rewritten ────────────────────────────────────────────────╮
|
|
25
|
+
│ Help me fix the auth bug. │
|
|
24
26
|
╰────────────────────────────────────────────────────────────╯
|
|
25
27
|
|
|
28
|
+
Changes
|
|
29
|
+
✓ Removed filler (24% shorter)
|
|
30
|
+
✓ Removed hedging language
|
|
31
|
+
|
|
32
|
+
You should also
|
|
33
|
+
→ Add actual code snippets or error messages for context
|
|
34
|
+
→ Reference specific files or functions by name
|
|
35
|
+
→ Add constraints (e.g., "Do not modify existing tests")
|
|
36
|
+
|
|
37
|
+
# Score any prompt instantly (research-backed, 30+ features)
|
|
26
38
|
$ reprompt score "Fix the auth bug in src/login.ts where JWT expires"
|
|
27
39
|
Score: 40/100 (Fair)
|
|
28
|
-
Structure: 0/25 | Context: 8/25 | Position: 20/20 | Repetition: 0/15 | Clarity: 12/15
|
|
29
40
|
Tip: Include the error message -- debug prompts with errors are 3.7x more effective
|
|
30
41
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Key moments: initial spec → auth module → test failures → JWT fix → passing
|
|
34
|
-
Context: "Building auth system with JWT refresh tokens for Express API"
|
|
35
|
-
|
|
36
|
-
$ reprompt compress "I was wondering if you could please help me refactor this code. Basically what I need is to split this function into smaller helpers and add error handling."
|
|
42
|
+
# Compress prompts to save tokens
|
|
43
|
+
$ reprompt compress "I was wondering if you could please help me refactor this code. Basically what I need is to split this function into smaller helpers."
|
|
37
44
|
Before: 28 tokens → After: 14 tokens (50% saved)
|
|
38
|
-
|
|
45
|
+
|
|
46
|
+
# Your personal dashboard
|
|
47
|
+
$ reprompt
|
|
48
|
+
╭─ Prompt Dashboard ─────────────────────────────────────────╮
|
|
49
|
+
│ Prompts: 1,063 (295 unique) Sessions: 890 │
|
|
50
|
+
│ Avg Score: 68/100 Top: debug (31%), impl (24%)│
|
|
51
|
+
╰────────────────────────────────────────────────────────────╯
|
|
39
52
|
```
|
|
40
53
|
|
|
41
54
|
## What it does
|
|
@@ -51,15 +64,19 @@ $ reprompt compress "I was wondering if you could please help me refactor this c
|
|
|
51
64
|
| `reprompt insights` | Personal patterns vs research-optimal benchmarks |
|
|
52
65
|
| `reprompt style` | Prompting fingerprint with `--trends` for evolution tracking |
|
|
53
66
|
| `reprompt agent` | Agent workflow analysis -- error loops, tool patterns, session efficiency |
|
|
67
|
+
| `reprompt sessions` | Session quality scores with frustration signal detection |
|
|
68
|
+
| `reprompt repetition` | Cross-session repetition detection -- spot recurring prompts |
|
|
54
69
|
|
|
55
70
|
### Optimize
|
|
56
71
|
|
|
57
72
|
| Command | Description |
|
|
58
73
|
|---------|-------------|
|
|
74
|
+
| `reprompt rewrite "prompt"` | **Rewrite prompts to score higher** -- filler removal, restructuring, hedging cleanup |
|
|
59
75
|
| `reprompt compress "prompt"` | 4-layer prompt compression (40-60% token savings typical) |
|
|
60
76
|
| `reprompt distill` | Extract important turns from conversations with 6-signal scoring |
|
|
61
77
|
| `reprompt distill --export` | Recover context when a session runs out -- paste into new session |
|
|
62
|
-
| `reprompt lint` |
|
|
78
|
+
| `reprompt lint` | Configurable prompt quality linter with CI/GitHub Action support |
|
|
79
|
+
| `reprompt init` | Generate `.reprompt.toml` config for your project |
|
|
63
80
|
|
|
64
81
|
### Manage
|
|
65
82
|
|
|
@@ -178,6 +195,24 @@ reprompt lint --strict # exit 1 on warnings
|
|
|
178
195
|
reprompt lint --json # machine-readable output
|
|
179
196
|
```
|
|
180
197
|
|
|
198
|
+
#### Project configuration
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
reprompt init # generates .reprompt.toml with all rules documented
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```toml
|
|
205
|
+
# .reprompt.toml (or [tool.reprompt.lint] in pyproject.toml)
|
|
206
|
+
[lint]
|
|
207
|
+
score-threshold = 50 # fail if avg score < 50
|
|
208
|
+
|
|
209
|
+
[lint.rules]
|
|
210
|
+
min-length = 20 # error if prompt < 20 chars (0 = off)
|
|
211
|
+
short-prompt = 40 # warning if < 40 chars (0 = off)
|
|
212
|
+
vague-prompt = true # error on "fix it" etc (false = off)
|
|
213
|
+
debug-needs-reference = true
|
|
214
|
+
```
|
|
215
|
+
|
|
181
216
|
## Privacy
|
|
182
217
|
|
|
183
218
|
- All analysis runs locally. No prompts leave your machine.
|
|
@@ -1065,6 +1065,58 @@ def compress(
|
|
|
1065
1065
|
_copy_to_clip(result.compressed, quiet=json_output)
|
|
1066
1066
|
|
|
1067
1067
|
|
|
1068
|
+
@app.command(rich_help_panel="Optimize")
|
|
1069
|
+
def rewrite(
|
|
1070
|
+
text: str = typer.Argument(..., help="Prompt text to improve"),
|
|
1071
|
+
json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
1072
|
+
copy: bool = typer.Option(False, "--copy", help="Copy rewritten text to clipboard"),
|
|
1073
|
+
) -> None:
|
|
1074
|
+
"""Rewrite a prompt to improve its score. Rule-based, no LLM needed.
|
|
1075
|
+
|
|
1076
|
+
Applies 4 layers: filler removal, instruction front-loading,
|
|
1077
|
+
key requirement echo, and hedging cleanup. Also suggests manual
|
|
1078
|
+
improvements you can make.
|
|
1079
|
+
|
|
1080
|
+
Examples:
|
|
1081
|
+
|
|
1082
|
+
reprompt rewrite "I was wondering if you could fix the authentication bug"
|
|
1083
|
+
|
|
1084
|
+
reprompt rewrite "please help me refactor this code to be better" --copy
|
|
1085
|
+
|
|
1086
|
+
reprompt rewrite "fix the login" --json
|
|
1087
|
+
"""
|
|
1088
|
+
from reprompt.core.rewrite import rewrite_prompt
|
|
1089
|
+
|
|
1090
|
+
result = rewrite_prompt(text)
|
|
1091
|
+
|
|
1092
|
+
if json_output:
|
|
1093
|
+
import json as json_mod
|
|
1094
|
+
|
|
1095
|
+
data = {
|
|
1096
|
+
"original": result.original,
|
|
1097
|
+
"rewritten": result.rewritten,
|
|
1098
|
+
"score_before": result.score_before,
|
|
1099
|
+
"score_after": result.score_after,
|
|
1100
|
+
"score_delta": result.score_delta,
|
|
1101
|
+
"changes": result.changes,
|
|
1102
|
+
"manual_suggestions": result.manual_suggestions,
|
|
1103
|
+
}
|
|
1104
|
+
typer.echo(json_mod.dumps(data, indent=2, ensure_ascii=False))
|
|
1105
|
+
else:
|
|
1106
|
+
from reprompt.output.rewrite_terminal import render_rewrite
|
|
1107
|
+
|
|
1108
|
+
typer.echo(render_rewrite(result))
|
|
1109
|
+
|
|
1110
|
+
if copy:
|
|
1111
|
+
_copy_to_clip(result.rewritten, quiet=json_output)
|
|
1112
|
+
|
|
1113
|
+
from reprompt.core.suggestions import get_suggestion
|
|
1114
|
+
|
|
1115
|
+
hint = get_suggestion("rewrite")
|
|
1116
|
+
if hint and not json_output:
|
|
1117
|
+
console.print(f" [dim]→ Try: {hint}[/dim]\n")
|
|
1118
|
+
|
|
1119
|
+
|
|
1068
1120
|
@app.command(rich_help_panel="Optimize")
|
|
1069
1121
|
def distill(
|
|
1070
1122
|
session_id: str = typer.Argument(None, help="Session ID to distill"),
|
|
@@ -1935,6 +1987,65 @@ def extension_status() -> None:
|
|
|
1935
1987
|
console.print(" Last sync: never")
|
|
1936
1988
|
|
|
1937
1989
|
|
|
1990
|
+
@app.command(rich_help_panel="Setup")
|
|
1991
|
+
def init(
|
|
1992
|
+
force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing config"),
|
|
1993
|
+
) -> None:
|
|
1994
|
+
"""Generate a .reprompt.toml config file in the current directory.
|
|
1995
|
+
|
|
1996
|
+
Creates a starter config with all lint rules documented and commented.
|
|
1997
|
+
Use this to customize reprompt for your project or CI pipeline.
|
|
1998
|
+
|
|
1999
|
+
Examples:
|
|
2000
|
+
|
|
2001
|
+
reprompt init # create .reprompt.toml
|
|
2002
|
+
|
|
2003
|
+
reprompt init --force # overwrite existing config
|
|
2004
|
+
"""
|
|
2005
|
+
config_path = Path.cwd() / ".reprompt.toml"
|
|
2006
|
+
|
|
2007
|
+
if config_path.exists() and not force:
|
|
2008
|
+
console.print(
|
|
2009
|
+
f"[yellow]{config_path.name} already exists.[/yellow]"
|
|
2010
|
+
" Use [bold]--force[/bold] to overwrite."
|
|
2011
|
+
)
|
|
2012
|
+
raise typer.Exit(1)
|
|
2013
|
+
|
|
2014
|
+
config_content = """\
|
|
2015
|
+
# reprompt configuration
|
|
2016
|
+
# Docs: https://github.com/reprompt-dev/reprompt
|
|
2017
|
+
#
|
|
2018
|
+
# This file configures `reprompt lint` rules and CI thresholds.
|
|
2019
|
+
# Place in your project root — reprompt walks up from CWD to find it.
|
|
2020
|
+
# Alternatively, add [tool.reprompt.lint] to pyproject.toml.
|
|
2021
|
+
|
|
2022
|
+
[lint]
|
|
2023
|
+
# Fail `reprompt lint` if average prompt score < threshold (0 = disabled)
|
|
2024
|
+
# Useful for CI: reprompt lint --score-threshold reads this value
|
|
2025
|
+
# score-threshold = 50
|
|
2026
|
+
|
|
2027
|
+
[lint.rules]
|
|
2028
|
+
# min-length: error if prompt < N chars (0 = disabled)
|
|
2029
|
+
min-length = 20
|
|
2030
|
+
|
|
2031
|
+
# short-prompt: warning if prompt < N chars (0 = disabled)
|
|
2032
|
+
short-prompt = 40
|
|
2033
|
+
|
|
2034
|
+
# vague-prompt: error on vague prompts like "fix it" (false = disabled)
|
|
2035
|
+
vague-prompt = true
|
|
2036
|
+
|
|
2037
|
+
# debug-needs-reference: warning if debug prompt lacks file reference (false = disabled)
|
|
2038
|
+
debug-needs-reference = true
|
|
2039
|
+
|
|
2040
|
+
# file-extensions: extensions recognized as file references
|
|
2041
|
+
# file-extensions = [".py", ".ts", ".js", ".go", ".rs", ".java", ".rb", ".cpp", ".c"]
|
|
2042
|
+
"""
|
|
2043
|
+
|
|
2044
|
+
config_path.write_text(config_content)
|
|
2045
|
+
console.print(f"[green]Created[/green] {config_path.name}")
|
|
2046
|
+
console.print(" Edit rules, then run [bold]reprompt lint[/bold] to verify.")
|
|
2047
|
+
|
|
2048
|
+
|
|
1938
2049
|
@app.command(rich_help_panel="Analyze")
|
|
1939
2050
|
def sessions(
|
|
1940
2051
|
last: int = typer.Option(10, "--last", help="Show N most recent sessions"),
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""Rule-based prompt rewrite engine.
|
|
2
|
+
|
|
3
|
+
Transforms low-scoring prompts into better versions using research-backed
|
|
4
|
+
rules. No LLM required — pure regex + structural transforms.
|
|
5
|
+
|
|
6
|
+
Layers:
|
|
7
|
+
1. Compress — remove filler (reuse compress engine)
|
|
8
|
+
2. Restructure — front-load instructions (move imperative to start)
|
|
9
|
+
3. Reinforce — echo key requirement at end for long prompts
|
|
10
|
+
4. Annotate — suggest what the user should add manually
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import re
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class RewriteResult:
|
|
21
|
+
"""Result of rewriting a prompt."""
|
|
22
|
+
|
|
23
|
+
original: str
|
|
24
|
+
rewritten: str
|
|
25
|
+
changes: list[str] = field(default_factory=list)
|
|
26
|
+
manual_suggestions: list[str] = field(default_factory=list)
|
|
27
|
+
score_before: float = 0.0
|
|
28
|
+
score_after: float = 0.0
|
|
29
|
+
score_delta: float = 0.0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def rewrite_prompt(text: str) -> RewriteResult:
|
|
33
|
+
"""Rewrite a prompt to improve its score. Returns before/after with changes."""
|
|
34
|
+
from reprompt.core.compress import compress_text
|
|
35
|
+
from reprompt.core.extractors import extract_features
|
|
36
|
+
from reprompt.core.scorer import score_prompt
|
|
37
|
+
from reprompt.core.segmenter import segment_prompt
|
|
38
|
+
|
|
39
|
+
# Score original
|
|
40
|
+
dna = extract_features(text, source="rewrite", session_id="")
|
|
41
|
+
score_before = score_prompt(dna)
|
|
42
|
+
|
|
43
|
+
result = text
|
|
44
|
+
changes: list[str] = []
|
|
45
|
+
|
|
46
|
+
# Layer 1: Compress (filler removal)
|
|
47
|
+
compressed = compress_text(result)
|
|
48
|
+
if compressed.savings_pct > 5:
|
|
49
|
+
result = compressed.compressed
|
|
50
|
+
changes.append(f"Removed filler ({compressed.savings_pct:.0f}% shorter)")
|
|
51
|
+
|
|
52
|
+
# Layer 2: Front-load instruction (if buried in middle)
|
|
53
|
+
if dna.key_instruction_position > 0.3:
|
|
54
|
+
segments = segment_prompt(result)
|
|
55
|
+
new_result = _front_load_instruction(result, segments)
|
|
56
|
+
if new_result != result:
|
|
57
|
+
result = new_result
|
|
58
|
+
changes.append("Moved main instruction to front")
|
|
59
|
+
|
|
60
|
+
# Layer 3: Echo key requirement (for long prompts with low repetition)
|
|
61
|
+
current_word_count = len(result.split())
|
|
62
|
+
if dna.keyword_repetition_freq < 0.15 and current_word_count > 40:
|
|
63
|
+
echoed = _echo_key_requirement(result)
|
|
64
|
+
if echoed != result:
|
|
65
|
+
result = echoed
|
|
66
|
+
changes.append("Echoed key requirement at end")
|
|
67
|
+
|
|
68
|
+
# Layer 4: Clarity — replace hedge phrases
|
|
69
|
+
cleaned = _remove_hedging(result)
|
|
70
|
+
if cleaned != result:
|
|
71
|
+
result = cleaned
|
|
72
|
+
changes.append("Removed hedging language")
|
|
73
|
+
|
|
74
|
+
# Score rewritten
|
|
75
|
+
dna_after = extract_features(result, source="rewrite", session_id="")
|
|
76
|
+
score_after = score_prompt(dna_after)
|
|
77
|
+
|
|
78
|
+
# Generate manual suggestions for things we can't auto-fix
|
|
79
|
+
manual = _generate_manual_suggestions(dna)
|
|
80
|
+
|
|
81
|
+
return RewriteResult(
|
|
82
|
+
original=text,
|
|
83
|
+
rewritten=result,
|
|
84
|
+
changes=changes,
|
|
85
|
+
manual_suggestions=manual,
|
|
86
|
+
score_before=score_before.total,
|
|
87
|
+
score_after=score_after.total,
|
|
88
|
+
score_delta=round(score_after.total - score_before.total, 1),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _front_load_instruction(text: str, segments: list) -> str:
|
|
93
|
+
"""Move the first instruction segment to the front of the prompt."""
|
|
94
|
+
instruction_seg = None
|
|
95
|
+
instruction_idx = -1
|
|
96
|
+
|
|
97
|
+
for i, seg in enumerate(segments):
|
|
98
|
+
if seg.segment_type == "instruction" and seg.start_pos > 0.2:
|
|
99
|
+
instruction_seg = seg
|
|
100
|
+
instruction_idx = i
|
|
101
|
+
break
|
|
102
|
+
|
|
103
|
+
if instruction_seg is None:
|
|
104
|
+
return text
|
|
105
|
+
|
|
106
|
+
# Extract the instruction text and rebuild
|
|
107
|
+
inst_text = instruction_seg.text.strip()
|
|
108
|
+
# Remove the instruction from its original position
|
|
109
|
+
remaining_parts = []
|
|
110
|
+
for i, seg in enumerate(segments):
|
|
111
|
+
if i == instruction_idx:
|
|
112
|
+
continue
|
|
113
|
+
remaining_parts.append(seg.text.strip())
|
|
114
|
+
|
|
115
|
+
remaining = "\n\n".join(p for p in remaining_parts if p)
|
|
116
|
+
|
|
117
|
+
# Ensure instruction ends with period for clean sentence
|
|
118
|
+
if inst_text and inst_text[-1] not in ".!?":
|
|
119
|
+
inst_text = inst_text + "."
|
|
120
|
+
|
|
121
|
+
return f"{inst_text}\n\n{remaining}".strip()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _echo_key_requirement(text: str) -> str:
|
|
125
|
+
"""Add a reinforcement of the key requirement at the end."""
|
|
126
|
+
# Extract the most important action phrase from the first sentence
|
|
127
|
+
lines = text.strip().split("\n")
|
|
128
|
+
first_line = ""
|
|
129
|
+
for line in lines:
|
|
130
|
+
stripped = line.strip()
|
|
131
|
+
if stripped and not stripped.startswith("#") and not stripped.startswith("```"):
|
|
132
|
+
first_line = stripped
|
|
133
|
+
break
|
|
134
|
+
|
|
135
|
+
if not first_line or len(first_line) < 10:
|
|
136
|
+
return text
|
|
137
|
+
|
|
138
|
+
# Extract the core verb+object phrase
|
|
139
|
+
key_phrase = _extract_key_phrase(first_line)
|
|
140
|
+
if not key_phrase or len(key_phrase) < 8:
|
|
141
|
+
return text
|
|
142
|
+
|
|
143
|
+
# Don't echo if text already ends with similar content
|
|
144
|
+
last_100 = text[-100:].lower()
|
|
145
|
+
if key_phrase.lower() in last_100:
|
|
146
|
+
return text
|
|
147
|
+
|
|
148
|
+
return f"{text.rstrip()}\n\nImportant: {key_phrase}."
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _extract_key_phrase(sentence: str) -> str:
|
|
152
|
+
"""Extract the core verb+object from a sentence."""
|
|
153
|
+
# Remove leading filler
|
|
154
|
+
cleaned = re.sub(
|
|
155
|
+
r"^(?:please\s+|can you\s+|could you\s+|i need you to\s+|i want you to\s+|"
|
|
156
|
+
r"i would like you to\s+|help me\s+)",
|
|
157
|
+
"",
|
|
158
|
+
sentence.strip(),
|
|
159
|
+
flags=re.IGNORECASE,
|
|
160
|
+
)
|
|
161
|
+
# Take the main clause (before first comma or period)
|
|
162
|
+
main = re.split(r"[,.]", cleaned)[0].strip()
|
|
163
|
+
# Cap length
|
|
164
|
+
if len(main) > 80:
|
|
165
|
+
words = main.split()
|
|
166
|
+
main = " ".join(words[:12])
|
|
167
|
+
return main
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
_HEDGE_PATTERNS = [
|
|
171
|
+
(re.compile(r"\bI was wondering if you could\b", re.IGNORECASE), ""),
|
|
172
|
+
(re.compile(r"\bI think maybe\b", re.IGNORECASE), ""),
|
|
173
|
+
(re.compile(r"\bif possible,?\s*", re.IGNORECASE), ""),
|
|
174
|
+
(re.compile(r"\bif you don'?t mind,?\s*", re.IGNORECASE), ""),
|
|
175
|
+
(re.compile(r"\bbasically,?\s*", re.IGNORECASE), ""),
|
|
176
|
+
(re.compile(r"\bkind of\b", re.IGNORECASE), ""),
|
|
177
|
+
(re.compile(r"\bsort of\b", re.IGNORECASE), ""),
|
|
178
|
+
(re.compile(r"\bjust\s+", re.IGNORECASE), ""),
|
|
179
|
+
(re.compile(r"\bmaybe\s+", re.IGNORECASE), ""),
|
|
180
|
+
(re.compile(r"\bperhaps\s+", re.IGNORECASE), ""),
|
|
181
|
+
(re.compile(r"\ba little bit\b", re.IGNORECASE), ""),
|
|
182
|
+
(re.compile(r"\bI guess\s+", re.IGNORECASE), ""),
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _remove_hedging(text: str) -> str:
|
|
187
|
+
"""Remove hedging language that weakens the prompt."""
|
|
188
|
+
result = text
|
|
189
|
+
for pattern, replacement in _HEDGE_PATTERNS:
|
|
190
|
+
result = pattern.sub(replacement, result)
|
|
191
|
+
# Clean up double spaces
|
|
192
|
+
result = re.sub(r" +", " ", result)
|
|
193
|
+
# Clean up leading spaces on lines
|
|
194
|
+
lines = result.split("\n")
|
|
195
|
+
result = "\n".join(line.lstrip() if line.strip() else line for line in lines)
|
|
196
|
+
return result
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _generate_manual_suggestions(dna: object) -> list[str]:
|
|
200
|
+
"""Generate suggestions for improvements that require human input."""
|
|
201
|
+
suggestions: list[str] = []
|
|
202
|
+
|
|
203
|
+
specificity = getattr(dna, "context_specificity", 1.0)
|
|
204
|
+
if specificity < 0.4:
|
|
205
|
+
suggestions.append("Add actual code snippets or error messages for context")
|
|
206
|
+
|
|
207
|
+
if not getattr(dna, "has_constraints", True):
|
|
208
|
+
suggestions.append('Add constraints (e.g., "Do not modify existing tests")')
|
|
209
|
+
|
|
210
|
+
if not getattr(dna, "has_output_format", True):
|
|
211
|
+
suggestions.append("Specify expected output format (e.g., JSON, code block)")
|
|
212
|
+
|
|
213
|
+
if not getattr(dna, "has_file_references", True):
|
|
214
|
+
task = getattr(dna, "task_type", "")
|
|
215
|
+
if task in ("debug", "implement", "refactor", "test"):
|
|
216
|
+
suggestions.append("Reference specific files or functions by name")
|
|
217
|
+
|
|
218
|
+
if not getattr(dna, "has_examples", True):
|
|
219
|
+
suggestions.append("Add an example of expected input/output")
|
|
220
|
+
|
|
221
|
+
return suggestions
|
|
@@ -22,6 +22,8 @@ SUGGESTIONS: dict[str, str] = {
|
|
|
22
22
|
'reprompt template save "..." (reuse patterns) · reprompt insights (all patterns)'
|
|
23
23
|
),
|
|
24
24
|
"template": "reprompt insights (see which patterns work best)",
|
|
25
|
+
"lint": "reprompt init (generate .reprompt.toml) · reprompt rewrite (improve prompts)",
|
|
26
|
+
"rewrite": "reprompt compress (reduce tokens) · reprompt score (verify improvement)",
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Rich terminal output for rewrite command."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from io import StringIO
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.panel import Panel
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from reprompt.core.rewrite import RewriteResult
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def render_rewrite(result: RewriteResult) -> str:
|
|
16
|
+
"""Render a rewrite result as a Rich-formatted string."""
|
|
17
|
+
buf = StringIO()
|
|
18
|
+
console = Console(file=buf, width=100, record=True)
|
|
19
|
+
|
|
20
|
+
# Score change header
|
|
21
|
+
delta = result.score_delta
|
|
22
|
+
if delta > 0:
|
|
23
|
+
delta_str = f"[green]+{delta:.0f}[/green]"
|
|
24
|
+
elif delta < 0:
|
|
25
|
+
delta_str = f"[red]{delta:.0f}[/red]"
|
|
26
|
+
else:
|
|
27
|
+
delta_str = "[dim]±0[/dim]"
|
|
28
|
+
|
|
29
|
+
before_color = _score_color(result.score_before)
|
|
30
|
+
after_color = _score_color(result.score_after)
|
|
31
|
+
|
|
32
|
+
console.print(
|
|
33
|
+
f"\n [{before_color}]{result.score_before:.0f}[/{before_color}]"
|
|
34
|
+
f" → [{after_color}]{result.score_after:.0f}[/{after_color}]"
|
|
35
|
+
f" ({delta_str})\n"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Rewritten prompt
|
|
39
|
+
if result.changes:
|
|
40
|
+
console.print(Panel(result.rewritten, title="Rewritten", border_style="green"))
|
|
41
|
+
else:
|
|
42
|
+
console.print("[dim]No automated improvements found.[/dim]")
|
|
43
|
+
|
|
44
|
+
# Changes applied
|
|
45
|
+
if result.changes:
|
|
46
|
+
console.print("\n [bold]Changes[/bold]")
|
|
47
|
+
for change in result.changes:
|
|
48
|
+
console.print(f" [green]✓[/green] {change}")
|
|
49
|
+
|
|
50
|
+
# Manual suggestions
|
|
51
|
+
if result.manual_suggestions:
|
|
52
|
+
console.print("\n [bold]You should also[/bold]")
|
|
53
|
+
for s in result.manual_suggestions:
|
|
54
|
+
console.print(f" [yellow]→[/yellow] {s}")
|
|
55
|
+
|
|
56
|
+
console.print()
|
|
57
|
+
return buf.getvalue()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _score_color(score: float) -> str:
|
|
61
|
+
if score >= 85:
|
|
62
|
+
return "bold magenta"
|
|
63
|
+
if score >= 70:
|
|
64
|
+
return "bold green"
|
|
65
|
+
if score >= 55:
|
|
66
|
+
return "bold yellow"
|
|
67
|
+
if score >= 40:
|
|
68
|
+
return "yellow"
|
|
69
|
+
return "bold red"
|