reprompt-cli 2.0.2__tar.gz → 2.2.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-2.0.2 → reprompt_cli-2.2.0}/CHANGELOG.md +23 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/PKG-INFO +4 -2
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/README.md +3 -1
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/pyproject.toml +1 -1
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/cli.py +204 -2
- reprompt_cli-2.2.0/src/reprompt/core/build.py +246 -0
- reprompt_cli-2.2.0/src/reprompt/core/check.py +115 -0
- reprompt_cli-2.2.0/src/reprompt/core/explain.py +208 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/lint.py +170 -4
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/scorer.py +21 -10
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/suggestions.py +3 -0
- reprompt_cli-2.2.0/src/reprompt/output/build_terminal.py +52 -0
- reprompt_cli-2.2.0/src/reprompt/output/check_terminal.py +105 -0
- reprompt_cli-2.2.0/src/reprompt/output/explain_terminal.py +58 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/rewrite_terminal.py +47 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/terminal.py +1 -3
- reprompt_cli-2.2.0/tests/test_build.py +270 -0
- reprompt_cli-2.2.0/tests/test_build_cli.py +126 -0
- reprompt_cli-2.2.0/tests/test_build_output.py +59 -0
- reprompt_cli-2.2.0/tests/test_check.py +101 -0
- reprompt_cli-2.2.0/tests/test_check_cli.py +80 -0
- reprompt_cli-2.2.0/tests/test_explain.py +100 -0
- reprompt_cli-2.2.0/tests/test_explain_cli.py +56 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_lint.py +176 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/uv.lock +1 -1
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.editorconfig +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/dependabot.yml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/workflows/ci.yml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.github/workflows/publish.yml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.gitignore +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.pre-commit-config.yaml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.pre-commit-hooks.yaml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.testmondata-shm +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/.testmondata-wal +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/CODE_OF_CONDUCT.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/CONTRIBUTING.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/LICENSE +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/SECURITY.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/Screenshot 2026-03-24 at 09.45.03.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/action.yml +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/demo.gif +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-128.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-16.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-256.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-32.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-48.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-512.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon-96.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/brand-icon.svg +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-128.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-16.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-256.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-32.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-48.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-512.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon-96.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-favicon.svg +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-128.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-16.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-256.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-32.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-48.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-512.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon-96.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/cli-icon.svg +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-128.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-16.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-256.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-32.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-48.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-512.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon-96.png +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/favicon.svg +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/icons/generate.sh +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/superpowers/specs/2026-03-24-v14-command-consolidation-design.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/docs/superpowers/specs/2026-03-25-v1.5-dashboard-design.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/scripts/generate_demo_data.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/aider.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/base.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/chatgpt.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/claude_chat.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/claude_code.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/cline.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/codex.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/cursor.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/filters.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/gemini.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/adapters/openclaw.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/bridge/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/bridge/handler.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/bridge/host.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/bridge/manifest.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/bridge/protocol.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/commands/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/commands/telemetry.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/commands/wrapped.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/config.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/agent.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/analyzer.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/compress.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/conversation.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/cost.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/dashboard.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/dedup.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/digest.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/distill.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/effectiveness.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/extractors.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/extractors_zh.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/insights.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/lang_detect.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/library.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/merge_view.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/models.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/persona.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/pipeline.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/privacy.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/privacy_scan.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/prompt_dna.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/recommend.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/repetition.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/rewrite.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/segmenter.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/session_meta.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/session_quality.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/session_type.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/style.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/templates.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/timeutil.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/trends.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/core/wrapped.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/demo.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/embeddings/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/embeddings/base.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/embeddings/local_embed.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/embeddings/ollama.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/embeddings/openai_embed.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/embeddings/tfidf.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/mcp.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/mcp_main.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/agent_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/chartjs.min.js +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/compress_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/dashboard_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/distill_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/export.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/html_report.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/json_out.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/markdown.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/projects_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/repetition_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/sessions_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/wrapped_html.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/output/wrapped_terminal.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/py.typed +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/sharing/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/sharing/client.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/sharing/clipboard.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/storage/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/storage/db.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/collector.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/consent.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/events.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/prompt.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/queue.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/src/reprompt/telemetry/sender.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/__init__.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/conftest.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/aider_chat_history.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/chatgpt_conversations.json +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/claude_chat_export.json +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/claude_session.jsonl +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/cline_task/api_conversation_history.json +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/export/default_export.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/export/full_export.md +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/gemini_session.json +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/fixtures/openclaw_session.jsonl +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_aider.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_chatgpt.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_claude.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_claude_chat.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_cline.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_gemini.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_adapter_openclaw.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_agent.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_agent_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_analyzer.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_bridge_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_bridge_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_bridge_handler.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_bridge_integration.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_bridge_manifest.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_bridge_protocol.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_cli_deprecations.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_cli_library_effectiveness.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_clipboard.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_codex_adapter.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_compare_best_worst.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_compress.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_compress_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_compress_dna.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_compress_html.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_compress_insights.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_config.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_conversation.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_copy_flag.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_cost.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_coverage_boost.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_cursor_adapter.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_dashboard.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_db.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_db_digest.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_db_effectiveness.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_db_session_quality.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_db_trends.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_dedup.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_demo.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_deprecated_commands.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_digest.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_digest_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_distill.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_distill_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_distill_weights.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_effectiveness.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_embeddings_local.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_embeddings_ollama.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_embeddings_openai.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_empty_state.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_export.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_export_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_export_snapshot.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_extractors.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_extractors_routing.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_extractors_zh.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_extractors_zh_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_html_report.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_import_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_import_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_init_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_insights.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_insights_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_insights_expanded.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_install_hook.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_lang_detect.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_library.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_lint_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_markdown.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_mcp.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_merge_view.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_models.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_output.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_parse_conversation_base.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_parse_conversation_chatgpt.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_parse_conversation_claude.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_persona.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_pipeline.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_privacy.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_privacy_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_privacy_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_privacy_output.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_privacy_scan.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_projects.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_prompt_dna.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_public_api.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_recommend.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_repetition.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_repetition_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_repetition_output.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_rewrite.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_schema_version.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_score_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_scorer.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_segmenter.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_session_quality.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_session_type.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_sessions_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_sessions_output.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_share_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_sharing_client.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_source_filter.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_style.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_style_trends.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_suggestions.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_collector.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_consent.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_events.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_prompt.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_queue.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_telemetry_sender.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_template_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_templates.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_timeutil.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_trends.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_trends_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_use_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_wrapped.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_wrapped_cli.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_wrapped_e2e.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_wrapped_html.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_wrapped_output.py +0 -0
- {reprompt_cli-2.0.2 → reprompt_cli-2.2.0}/tests/test_wrapped_share.py +0 -0
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.2.0] - 2026-04-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Prompt builder** — `reprompt build "task" --file src/auth.ts --error "TypeError" --constraint "keep tests"` assembles well-scored prompts from components. Model-aware formatting: XML tags for Claude, markdown headers for GPT. Shows score, tier, and suggestions for missing components.
|
|
9
|
+
- **Unified diagnostic** — `reprompt check "prompt"` runs score + lint + rewrite in one command. Shows dimensional breakdown, strengths, suggestions with point values, lint issues, and auto-rewrite preview.
|
|
10
|
+
- **Prompt explainer** — `reprompt explain "prompt"` explains what makes a prompt good or bad in plain English. Educational feedback with research-backed insights per dimension.
|
|
11
|
+
- Tests: 1741 → 1846
|
|
12
|
+
|
|
13
|
+
## [2.1.0] - 2026-04-01
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Model-specific lint rules** — `reprompt lint --model claude/gpt/gemini` checks prompts against model-specific best practices. 8 rules: XML tag preference (Claude), markdown structure (GPT), JSON instruction requirements (GPT), CoT anti-pattern for o-series (GPT), prompt length limits (Gemini), broad negative detection (Gemini). Based on official model documentation.
|
|
17
|
+
- **Diff preview for rewrite** — `reprompt rewrite --diff` shows a git-style unified diff between original and rewritten prompt. Color-coded: red removals, green additions, cyan range markers.
|
|
18
|
+
- **Token budget lint** — `reprompt lint --max-tokens 4096` warns when prompts exceed a token budget. Configurable via `.reprompt.toml` (`max-tokens`) or CLI flag. Uses locale-aware token estimation from cost module.
|
|
19
|
+
- Tests: 1716 → 1741
|
|
20
|
+
|
|
21
|
+
## [2.0.2] - 2026-04-01
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **Scoring rebalance** — Structure weight reduced 25→15, Clarity increased 15→25. Plain-text prompts now score 55-65 instead of 35-45. Real-world conversational prompts are no longer penalized for lacking markdown structure.
|
|
25
|
+
- **Tier labels** — Scores display as EXPERT (85+), STRONG (70+), GOOD (50+), BASIC (30+), DRAFT (<30) instead of raw numbers. Applied across CLI, extension badge, popup, and HTML dashboard.
|
|
26
|
+
- **Positive UX feedback** — Score output now includes "Strengths" section showing what the prompt does well. Suggestions show expected point gain (`+N pts`). Badge color thresholds adjusted: 85/60/40/25.
|
|
27
|
+
|
|
5
28
|
## [2.0.1] - 2026-03-31
|
|
6
29
|
|
|
7
30
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reprompt-cli
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.2.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
|
|
@@ -104,6 +104,7 @@ $ reprompt
|
|
|
104
104
|
|---------|-------------|
|
|
105
105
|
| `reprompt` | Instant dashboard -- prompts, sessions, avg score, top categories |
|
|
106
106
|
| `reprompt scan` | Auto-discover prompts from 9 AI tools |
|
|
107
|
+
| `reprompt check "prompt"` | **Full diagnostic** -- score + lint + rewrite preview in one command |
|
|
107
108
|
| `reprompt score "prompt"` | Research-backed 0-100 scoring with 30+ features |
|
|
108
109
|
| `reprompt compare "a" "b"` | Side-by-side prompt analysis (or `--best-worst` for auto-selection) |
|
|
109
110
|
| `reprompt insights` | Personal patterns vs research-optimal benchmarks |
|
|
@@ -117,6 +118,7 @@ $ reprompt
|
|
|
117
118
|
|
|
118
119
|
| Command | Description |
|
|
119
120
|
|---------|-------------|
|
|
121
|
+
| `reprompt build "task"` | **Build prompts from components** -- task, context, files, errors, constraints. Model-aware (Claude/GPT/Gemini) |
|
|
120
122
|
| `reprompt rewrite "prompt"` | **Rewrite prompts to score higher** -- filler removal, restructuring, hedging cleanup |
|
|
121
123
|
| `reprompt compress "prompt"` | 4-layer prompt compression (40-60% token savings typical) |
|
|
122
124
|
| `reprompt distill` | Extract important turns from conversations with 6-signal scoring |
|
|
@@ -228,7 +230,7 @@ Captured prompts sync locally via Native Messaging -- nothing leaves your machin
|
|
|
228
230
|
# .pre-commit-config.yaml
|
|
229
231
|
repos:
|
|
230
232
|
- repo: https://github.com/reprompt-dev/reprompt
|
|
231
|
-
rev: v2.0
|
|
233
|
+
rev: v2.2.0
|
|
232
234
|
hooks:
|
|
233
235
|
- id: reprompt-lint
|
|
234
236
|
```
|
|
@@ -59,6 +59,7 @@ $ reprompt
|
|
|
59
59
|
|---------|-------------|
|
|
60
60
|
| `reprompt` | Instant dashboard -- prompts, sessions, avg score, top categories |
|
|
61
61
|
| `reprompt scan` | Auto-discover prompts from 9 AI tools |
|
|
62
|
+
| `reprompt check "prompt"` | **Full diagnostic** -- score + lint + rewrite preview in one command |
|
|
62
63
|
| `reprompt score "prompt"` | Research-backed 0-100 scoring with 30+ features |
|
|
63
64
|
| `reprompt compare "a" "b"` | Side-by-side prompt analysis (or `--best-worst` for auto-selection) |
|
|
64
65
|
| `reprompt insights` | Personal patterns vs research-optimal benchmarks |
|
|
@@ -72,6 +73,7 @@ $ reprompt
|
|
|
72
73
|
|
|
73
74
|
| Command | Description |
|
|
74
75
|
|---------|-------------|
|
|
76
|
+
| `reprompt build "task"` | **Build prompts from components** -- task, context, files, errors, constraints. Model-aware (Claude/GPT/Gemini) |
|
|
75
77
|
| `reprompt rewrite "prompt"` | **Rewrite prompts to score higher** -- filler removal, restructuring, hedging cleanup |
|
|
76
78
|
| `reprompt compress "prompt"` | 4-layer prompt compression (40-60% token savings typical) |
|
|
77
79
|
| `reprompt distill` | Extract important turns from conversations with 6-signal scoring |
|
|
@@ -183,7 +185,7 @@ Captured prompts sync locally via Native Messaging -- nothing leaves your machin
|
|
|
183
185
|
# .pre-commit-config.yaml
|
|
184
186
|
repos:
|
|
185
187
|
- repo: https://github.com/reprompt-dev/reprompt
|
|
186
|
-
rev: v2.0
|
|
188
|
+
rev: v2.2.0
|
|
187
189
|
hooks:
|
|
188
190
|
- id: reprompt-lint
|
|
189
191
|
```
|
|
@@ -797,6 +797,12 @@ def lint(
|
|
|
797
797
|
score_threshold: int = typer.Option(
|
|
798
798
|
0, "--score-threshold", help="Fail if avg prompt score < threshold (CI mode)"
|
|
799
799
|
),
|
|
800
|
+
model: str = typer.Option(
|
|
801
|
+
None, "--model", "-m", help="Target model for model-specific rules (claude/gpt/gemini)"
|
|
802
|
+
),
|
|
803
|
+
max_tokens: int = typer.Option(
|
|
804
|
+
0, "--max-tokens", help="Warn when prompts exceed token budget (0 = disabled)"
|
|
805
|
+
),
|
|
800
806
|
copy: bool = typer.Option(False, "--copy", help="Copy result to clipboard"),
|
|
801
807
|
) -> None:
|
|
802
808
|
"""Check prompt quality against lint rules.
|
|
@@ -806,6 +812,12 @@ def lint(
|
|
|
806
812
|
- short-prompt: prompts under 40 chars (warning)
|
|
807
813
|
- vague-prompt: overly vague prompts like "fix it"
|
|
808
814
|
- debug-needs-reference: debug prompts without file/function references
|
|
815
|
+
- max-tokens: prompt exceeds token budget
|
|
816
|
+
|
|
817
|
+
Model-specific rules (--model):
|
|
818
|
+
- claude: suggests XML tags for structure
|
|
819
|
+
- gpt: warns on XML tags (may echo verbatim), prefers markdown
|
|
820
|
+
- gemini: warns on very long prompts
|
|
809
821
|
|
|
810
822
|
CI mode: use --score-threshold to fail if average score is below a threshold.
|
|
811
823
|
|
|
@@ -813,6 +825,8 @@ def lint(
|
|
|
813
825
|
|
|
814
826
|
reprompt lint # lint stored prompts
|
|
815
827
|
|
|
828
|
+
reprompt lint --model claude # with Claude-specific hints
|
|
829
|
+
|
|
816
830
|
reprompt lint --score-threshold 50 # fail if avg score < 50 (CI mode)
|
|
817
831
|
|
|
818
832
|
reprompt lint --strict --json # strict mode with JSON output
|
|
@@ -832,6 +846,10 @@ def lint(
|
|
|
832
846
|
|
|
833
847
|
# CLI flags override config file
|
|
834
848
|
effective_threshold = score_threshold if score_threshold > 0 else lint_config.score_threshold
|
|
849
|
+
if model:
|
|
850
|
+
lint_config.model = model.lower()
|
|
851
|
+
if max_tokens > 0:
|
|
852
|
+
lint_config.max_tokens = max_tokens
|
|
835
853
|
|
|
836
854
|
# Collect prompts from DB (already scanned)
|
|
837
855
|
rows = db.get_all_prompts()
|
|
@@ -928,6 +946,111 @@ def lint(
|
|
|
928
946
|
raise typer.Exit(1)
|
|
929
947
|
|
|
930
948
|
|
|
949
|
+
@app.command(rich_help_panel="Analyze")
|
|
950
|
+
def check(
|
|
951
|
+
text: str = typer.Argument(..., help="Prompt text to check"),
|
|
952
|
+
model: str = typer.Option("", "--model", "-m", help="Target model (claude/gpt/gemini)"),
|
|
953
|
+
max_tokens: int = typer.Option(0, "--max-tokens", help="Token budget (0 = disabled)"),
|
|
954
|
+
json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
955
|
+
copy: bool = typer.Option(False, "--copy", help="Copy rewritten prompt to clipboard"),
|
|
956
|
+
) -> None:
|
|
957
|
+
"""Full prompt diagnostic — score + lint + rewrite in one command.
|
|
958
|
+
|
|
959
|
+
Runs all quality checks and shows a unified report with score breakdown,
|
|
960
|
+
strengths, suggestions, lint issues, and auto-rewrite preview.
|
|
961
|
+
|
|
962
|
+
Examples:
|
|
963
|
+
|
|
964
|
+
reprompt check "fix the auth bug in login.ts"
|
|
965
|
+
|
|
966
|
+
reprompt check "refactor the middleware" --model claude
|
|
967
|
+
|
|
968
|
+
reprompt check "help me debug this crash" --json
|
|
969
|
+
"""
|
|
970
|
+
from reprompt.core.check import check_prompt
|
|
971
|
+
|
|
972
|
+
result = check_prompt(text, model=model, max_tokens=max_tokens)
|
|
973
|
+
|
|
974
|
+
if json_output:
|
|
975
|
+
import json as json_mod
|
|
976
|
+
|
|
977
|
+
data = {
|
|
978
|
+
"total": result.total,
|
|
979
|
+
"tier": result.tier,
|
|
980
|
+
"clarity": result.clarity,
|
|
981
|
+
"context": result.context,
|
|
982
|
+
"position": result.position,
|
|
983
|
+
"structure": result.structure,
|
|
984
|
+
"repetition": result.repetition,
|
|
985
|
+
"word_count": result.word_count,
|
|
986
|
+
"token_count": result.token_count,
|
|
987
|
+
"confirmations": result.confirmations,
|
|
988
|
+
"suggestions": result.suggestions,
|
|
989
|
+
"lint_issues": result.lint_issues,
|
|
990
|
+
"rewritten": result.rewritten,
|
|
991
|
+
"rewrite_delta": result.rewrite_delta,
|
|
992
|
+
"rewrite_changes": result.rewrite_changes,
|
|
993
|
+
}
|
|
994
|
+
typer.echo(json_mod.dumps(data, indent=2, ensure_ascii=False))
|
|
995
|
+
else:
|
|
996
|
+
from reprompt.output.check_terminal import render_check
|
|
997
|
+
|
|
998
|
+
typer.echo(render_check(result))
|
|
999
|
+
|
|
1000
|
+
if copy:
|
|
1001
|
+
_copy_to_clip(result.rewritten, quiet=json_output)
|
|
1002
|
+
|
|
1003
|
+
from reprompt.core.suggestions import get_suggestion
|
|
1004
|
+
|
|
1005
|
+
hint = get_suggestion("check")
|
|
1006
|
+
if hint and not json_output:
|
|
1007
|
+
console.print(f" [dim]→ Try: {hint}[/dim]\n")
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
@app.command(rich_help_panel="Analyze")
|
|
1011
|
+
def explain(
|
|
1012
|
+
text: str = typer.Argument(..., help="Prompt text to explain"),
|
|
1013
|
+
json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
1014
|
+
) -> None:
|
|
1015
|
+
"""Explain what makes a prompt good or bad in plain English.
|
|
1016
|
+
|
|
1017
|
+
Analyzes the prompt and provides educational feedback: what's working,
|
|
1018
|
+
what's missing, and specific tips to improve. No LLM needed.
|
|
1019
|
+
|
|
1020
|
+
Examples:
|
|
1021
|
+
|
|
1022
|
+
reprompt explain "fix the auth bug"
|
|
1023
|
+
|
|
1024
|
+
reprompt explain "Fix the JWT expiration in src/auth.ts line 42" --json
|
|
1025
|
+
"""
|
|
1026
|
+
from reprompt.core.explain import explain_prompt
|
|
1027
|
+
|
|
1028
|
+
result = explain_prompt(text)
|
|
1029
|
+
|
|
1030
|
+
if json_output:
|
|
1031
|
+
import json as json_mod
|
|
1032
|
+
|
|
1033
|
+
data = {
|
|
1034
|
+
"score": result.score,
|
|
1035
|
+
"tier": result.tier,
|
|
1036
|
+
"summary": result.summary,
|
|
1037
|
+
"strengths": result.strengths,
|
|
1038
|
+
"weaknesses": result.weaknesses,
|
|
1039
|
+
"tips": result.tips,
|
|
1040
|
+
}
|
|
1041
|
+
typer.echo(json_mod.dumps(data, indent=2, ensure_ascii=False))
|
|
1042
|
+
else:
|
|
1043
|
+
from reprompt.output.explain_terminal import render_explain
|
|
1044
|
+
|
|
1045
|
+
typer.echo(render_explain(result))
|
|
1046
|
+
|
|
1047
|
+
from reprompt.core.suggestions import get_suggestion
|
|
1048
|
+
|
|
1049
|
+
hint = get_suggestion("explain")
|
|
1050
|
+
if hint and not json_output:
|
|
1051
|
+
console.print(f" [dim]→ Try: {hint}[/dim]\n")
|
|
1052
|
+
|
|
1053
|
+
|
|
931
1054
|
@app.command(rich_help_panel="Analyze")
|
|
932
1055
|
def score(
|
|
933
1056
|
text: str = typer.Argument(..., help="Prompt text to score"),
|
|
@@ -1087,6 +1210,7 @@ def compress(
|
|
|
1087
1210
|
def rewrite(
|
|
1088
1211
|
text: str = typer.Argument(..., help="Prompt text to improve"),
|
|
1089
1212
|
json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
1213
|
+
diff: bool = typer.Option(False, "--diff", help="Show unified diff (red/green)"),
|
|
1090
1214
|
copy: bool = typer.Option(False, "--copy", help="Copy rewritten text to clipboard"),
|
|
1091
1215
|
) -> None:
|
|
1092
1216
|
"""Rewrite a prompt to improve its score. Rule-based, no LLM needed.
|
|
@@ -1099,9 +1223,9 @@ def rewrite(
|
|
|
1099
1223
|
|
|
1100
1224
|
reprompt rewrite "I was wondering if you could fix the authentication bug"
|
|
1101
1225
|
|
|
1102
|
-
reprompt rewrite "
|
|
1226
|
+
reprompt rewrite "fix the login" --diff
|
|
1103
1227
|
|
|
1104
|
-
reprompt rewrite "
|
|
1228
|
+
reprompt rewrite "please help me refactor this code to be better" --copy
|
|
1105
1229
|
"""
|
|
1106
1230
|
from reprompt.core.rewrite import rewrite_prompt
|
|
1107
1231
|
|
|
@@ -1120,6 +1244,10 @@ def rewrite(
|
|
|
1120
1244
|
"manual_suggestions": result.manual_suggestions,
|
|
1121
1245
|
}
|
|
1122
1246
|
typer.echo(json_mod.dumps(data, indent=2, ensure_ascii=False))
|
|
1247
|
+
elif diff:
|
|
1248
|
+
from reprompt.output.rewrite_terminal import render_rewrite_diff
|
|
1249
|
+
|
|
1250
|
+
typer.echo(render_rewrite_diff(result))
|
|
1123
1251
|
else:
|
|
1124
1252
|
from reprompt.output.rewrite_terminal import render_rewrite
|
|
1125
1253
|
|
|
@@ -1135,6 +1263,73 @@ def rewrite(
|
|
|
1135
1263
|
console.print(f" [dim]→ Try: {hint}[/dim]\n")
|
|
1136
1264
|
|
|
1137
1265
|
|
|
1266
|
+
@app.command(rich_help_panel="Optimize")
|
|
1267
|
+
def build(
|
|
1268
|
+
task: str = typer.Argument(..., help="What the AI should do"),
|
|
1269
|
+
context: str = typer.Option("", "--context", "-c", help="Background information"),
|
|
1270
|
+
file: list[str] = typer.Option([], "--file", "-f", help="File references (repeatable)"),
|
|
1271
|
+
error: str = typer.Option("", "--error", "-e", help="Error message or stack trace"),
|
|
1272
|
+
constraint: list[str] = typer.Option([], "--constraint", help="Constraints (repeatable)"),
|
|
1273
|
+
example: str = typer.Option("", "--example", help="Example input/output"),
|
|
1274
|
+
output_format: str = typer.Option("", "--output-format", help="Expected response format"),
|
|
1275
|
+
role: str = typer.Option("", "--role", "-r", help="AI role/persona"),
|
|
1276
|
+
model: str = typer.Option("", "--model", "-m", help="Target model (claude/gpt/gemini)"),
|
|
1277
|
+
json_output: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
1278
|
+
copy: bool = typer.Option(False, "--copy", help="Copy built prompt to clipboard"),
|
|
1279
|
+
) -> None:
|
|
1280
|
+
"""Build a well-structured prompt from components.
|
|
1281
|
+
|
|
1282
|
+
Assembles a prompt that maximizes quality score by combining
|
|
1283
|
+
your task with context, files, errors, and constraints.
|
|
1284
|
+
|
|
1285
|
+
Examples:
|
|
1286
|
+
|
|
1287
|
+
reprompt build "fix the auth bug"
|
|
1288
|
+
|
|
1289
|
+
reprompt build "fix the crash" --file src/auth.ts --error "TypeError: ..."
|
|
1290
|
+
|
|
1291
|
+
reprompt build "refactor" -f src/app.py --constraint "keep tests" --model claude
|
|
1292
|
+
"""
|
|
1293
|
+
from reprompt.core.build import build_prompt
|
|
1294
|
+
|
|
1295
|
+
result = build_prompt(
|
|
1296
|
+
task,
|
|
1297
|
+
context=context,
|
|
1298
|
+
files=file if file else None,
|
|
1299
|
+
error=error,
|
|
1300
|
+
constraints=constraint if constraint else None,
|
|
1301
|
+
examples=example,
|
|
1302
|
+
output_format=output_format,
|
|
1303
|
+
role=role,
|
|
1304
|
+
model=model,
|
|
1305
|
+
)
|
|
1306
|
+
|
|
1307
|
+
if json_output:
|
|
1308
|
+
import json as json_mod
|
|
1309
|
+
|
|
1310
|
+
data = {
|
|
1311
|
+
"prompt": result.prompt,
|
|
1312
|
+
"score": result.score,
|
|
1313
|
+
"tier": result.tier,
|
|
1314
|
+
"components_used": result.components_used,
|
|
1315
|
+
"suggestions": result.suggestions,
|
|
1316
|
+
}
|
|
1317
|
+
typer.echo(json_mod.dumps(data, indent=2, ensure_ascii=False))
|
|
1318
|
+
else:
|
|
1319
|
+
from reprompt.output.build_terminal import render_build
|
|
1320
|
+
|
|
1321
|
+
typer.echo(render_build(result))
|
|
1322
|
+
|
|
1323
|
+
if copy:
|
|
1324
|
+
_copy_to_clip(result.prompt, quiet=json_output)
|
|
1325
|
+
|
|
1326
|
+
from reprompt.core.suggestions import get_suggestion
|
|
1327
|
+
|
|
1328
|
+
hint = get_suggestion("build")
|
|
1329
|
+
if hint and not json_output:
|
|
1330
|
+
console.print(f" [dim]→ Try: {hint}[/dim]\n")
|
|
1331
|
+
|
|
1332
|
+
|
|
1138
1333
|
@app.command(rich_help_panel="Optimize")
|
|
1139
1334
|
def distill(
|
|
1140
1335
|
session_id: str = typer.Argument(None, help="Session ID to distill"),
|
|
@@ -2042,6 +2237,13 @@ def init(
|
|
|
2042
2237
|
# Useful for CI: reprompt lint --score-threshold reads this value
|
|
2043
2238
|
# score-threshold = 50
|
|
2044
2239
|
|
|
2240
|
+
# Target model for model-specific rules (claude, gpt, gemini)
|
|
2241
|
+
# Enables rules like "prefer XML tags" (Claude) or "avoid XML tags" (GPT)
|
|
2242
|
+
# model = "claude"
|
|
2243
|
+
|
|
2244
|
+
# Token budget — warn when prompts exceed this limit (0 = disabled)
|
|
2245
|
+
# max-tokens = 4096
|
|
2246
|
+
|
|
2045
2247
|
[lint.rules]
|
|
2046
2248
|
# min-length: error if prompt < N chars (0 = disabled)
|
|
2047
2249
|
min-length = 20
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"""Prompt builder — assemble a well-structured prompt from components.
|
|
2
|
+
|
|
3
|
+
Takes a task description and optional context, files, errors, constraints,
|
|
4
|
+
and examples, then assembles a prompt that maximizes the scoring dimensions.
|
|
5
|
+
Scoring-aware: structures the output to hit clarity, context, and position.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class BuildResult:
|
|
15
|
+
"""Result of building a prompt from components."""
|
|
16
|
+
|
|
17
|
+
prompt: str
|
|
18
|
+
score: float = 0.0
|
|
19
|
+
tier: str = ""
|
|
20
|
+
components_used: list[str] = field(default_factory=list)
|
|
21
|
+
suggestions: list[str] = field(default_factory=list)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def build_prompt(
|
|
25
|
+
task: str,
|
|
26
|
+
*,
|
|
27
|
+
context: str = "",
|
|
28
|
+
files: list[str] | None = None,
|
|
29
|
+
error: str = "",
|
|
30
|
+
constraints: list[str] | None = None,
|
|
31
|
+
examples: str = "",
|
|
32
|
+
output_format: str = "",
|
|
33
|
+
role: str = "",
|
|
34
|
+
model: str = "",
|
|
35
|
+
) -> BuildResult:
|
|
36
|
+
"""Build a well-structured prompt from components.
|
|
37
|
+
|
|
38
|
+
Returns the assembled prompt with its score and suggestions
|
|
39
|
+
for components the user could still add.
|
|
40
|
+
"""
|
|
41
|
+
parts: list[str] = []
|
|
42
|
+
components: list[str] = []
|
|
43
|
+
|
|
44
|
+
# Role (if provided) — goes first
|
|
45
|
+
if role:
|
|
46
|
+
parts.append(f"You are {role}.")
|
|
47
|
+
components.append("role")
|
|
48
|
+
|
|
49
|
+
# Task — always present, imperative form, at the front (position bias)
|
|
50
|
+
task_text = _ensure_imperative(task.strip())
|
|
51
|
+
if task_text and task_text[-1] not in ".!?":
|
|
52
|
+
task_text += "."
|
|
53
|
+
parts.append(task_text)
|
|
54
|
+
components.append("task")
|
|
55
|
+
|
|
56
|
+
# File references — high context value
|
|
57
|
+
if files:
|
|
58
|
+
if len(files) == 1:
|
|
59
|
+
parts.append(f"File: {files[0]}")
|
|
60
|
+
else:
|
|
61
|
+
file_list = ", ".join(files)
|
|
62
|
+
parts.append(f"Files: {file_list}")
|
|
63
|
+
components.append("files")
|
|
64
|
+
|
|
65
|
+
# Error context — critical for debug prompts
|
|
66
|
+
if error:
|
|
67
|
+
parts.append(f"Error: {error}")
|
|
68
|
+
components.append("error")
|
|
69
|
+
|
|
70
|
+
# Context — background information
|
|
71
|
+
if context:
|
|
72
|
+
parts.append(f"Context: {context}")
|
|
73
|
+
components.append("context")
|
|
74
|
+
|
|
75
|
+
# Examples
|
|
76
|
+
if examples:
|
|
77
|
+
parts.append(f"Example:\n{examples}")
|
|
78
|
+
components.append("examples")
|
|
79
|
+
|
|
80
|
+
# Constraints
|
|
81
|
+
if constraints:
|
|
82
|
+
if len(constraints) == 1:
|
|
83
|
+
parts.append(f"Constraint: {constraints[0]}")
|
|
84
|
+
else:
|
|
85
|
+
constraint_lines = "\n".join(f"- {c}" for c in constraints)
|
|
86
|
+
parts.append(f"Constraints:\n{constraint_lines}")
|
|
87
|
+
components.append("constraints")
|
|
88
|
+
|
|
89
|
+
# Output format
|
|
90
|
+
if output_format:
|
|
91
|
+
parts.append(f"Output format: {output_format}")
|
|
92
|
+
components.append("output_format")
|
|
93
|
+
|
|
94
|
+
# Model-specific formatting
|
|
95
|
+
prompt = _format_for_model(parts, model)
|
|
96
|
+
|
|
97
|
+
# Score the assembled prompt
|
|
98
|
+
from reprompt.core.extractors import extract_features
|
|
99
|
+
from reprompt.core.scorer import score_prompt
|
|
100
|
+
|
|
101
|
+
dna = extract_features(prompt, source="build", session_id="")
|
|
102
|
+
score_result = score_prompt(dna)
|
|
103
|
+
|
|
104
|
+
# Determine tier
|
|
105
|
+
tier = _get_tier(score_result.total)
|
|
106
|
+
|
|
107
|
+
# Generate suggestions for missing components
|
|
108
|
+
suggestions = _missing_suggestions(components)
|
|
109
|
+
|
|
110
|
+
return BuildResult(
|
|
111
|
+
prompt=prompt,
|
|
112
|
+
score=score_result.total,
|
|
113
|
+
tier=tier,
|
|
114
|
+
components_used=components,
|
|
115
|
+
suggestions=suggestions,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _ensure_imperative(task: str) -> str:
|
|
120
|
+
"""Strip filler prefixes to get an imperative task statement."""
|
|
121
|
+
import re
|
|
122
|
+
|
|
123
|
+
# Remove common polite/filler prefixes
|
|
124
|
+
cleaned = re.sub(
|
|
125
|
+
r"^(?:please\s+|can you\s+|could you\s+|i need you to\s+|"
|
|
126
|
+
r"i want you to\s+|i would like you to\s+|help me\s+|"
|
|
127
|
+
r"i was wondering if you could\s+)",
|
|
128
|
+
"",
|
|
129
|
+
task,
|
|
130
|
+
flags=re.IGNORECASE,
|
|
131
|
+
)
|
|
132
|
+
# Capitalize first letter
|
|
133
|
+
if cleaned:
|
|
134
|
+
cleaned = cleaned[0].upper() + cleaned[1:]
|
|
135
|
+
return cleaned
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _format_for_model(parts: list[str], model: str) -> str:
|
|
139
|
+
"""Format prompt parts with model-appropriate structure."""
|
|
140
|
+
if model == "claude":
|
|
141
|
+
return _format_xml(parts)
|
|
142
|
+
elif model == "gpt":
|
|
143
|
+
return _format_markdown(parts)
|
|
144
|
+
else:
|
|
145
|
+
# Default: clean plain text with double newlines
|
|
146
|
+
return "\n\n".join(parts)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _format_xml(parts: list[str]) -> str:
|
|
150
|
+
"""Format with XML tags (preferred by Claude)."""
|
|
151
|
+
if len(parts) <= 2:
|
|
152
|
+
# Short prompts don't need XML
|
|
153
|
+
return "\n\n".join(parts)
|
|
154
|
+
|
|
155
|
+
sections: list[str] = []
|
|
156
|
+
for part in parts:
|
|
157
|
+
lower = part.lower()
|
|
158
|
+
if lower.startswith("you are "):
|
|
159
|
+
sections.append(part)
|
|
160
|
+
elif lower.startswith("context:"):
|
|
161
|
+
content = part[len("Context:") :].strip()
|
|
162
|
+
sections.append(f"<context>\n{content}\n</context>")
|
|
163
|
+
elif lower.startswith("error:"):
|
|
164
|
+
content = part[len("Error:") :].strip()
|
|
165
|
+
sections.append(f"<context>\n{content}\n</context>")
|
|
166
|
+
elif lower.startswith("constraint"):
|
|
167
|
+
content = part.split(":", 1)[1].strip() if ":" in part else part
|
|
168
|
+
sections.append(f"<constraints>\n{content}\n</constraints>")
|
|
169
|
+
elif lower.startswith("example"):
|
|
170
|
+
content = part.split(":", 1)[1].strip() if ":" in part else part
|
|
171
|
+
content = part.split("\n", 1)[1].strip() if "\n" in part else content
|
|
172
|
+
sections.append(f"<examples>\n{content}\n</examples>")
|
|
173
|
+
elif lower.startswith("output format:"):
|
|
174
|
+
content = part[len("Output format:") :].strip()
|
|
175
|
+
sections.append(f"<output>\n{content}\n</output>")
|
|
176
|
+
else:
|
|
177
|
+
sections.append(part)
|
|
178
|
+
|
|
179
|
+
return "\n\n".join(sections)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _format_markdown(parts: list[str]) -> str:
|
|
183
|
+
"""Format with markdown headers (preferred by GPT)."""
|
|
184
|
+
if len(parts) <= 2:
|
|
185
|
+
return "\n\n".join(parts)
|
|
186
|
+
|
|
187
|
+
sections: list[str] = []
|
|
188
|
+
for part in parts:
|
|
189
|
+
lower = part.lower()
|
|
190
|
+
if lower.startswith("you are "):
|
|
191
|
+
sections.append(part)
|
|
192
|
+
elif lower.startswith("context:"):
|
|
193
|
+
content = part[len("Context:") :].strip()
|
|
194
|
+
sections.append(f"## Context\n{content}")
|
|
195
|
+
elif lower.startswith("error:"):
|
|
196
|
+
content = part[len("Error:") :].strip()
|
|
197
|
+
sections.append(f"## Error\n{content}")
|
|
198
|
+
elif lower.startswith("constraint"):
|
|
199
|
+
content = part.split(":", 1)[1].strip() if ":" in part else part
|
|
200
|
+
sections.append(f"## Constraints\n{content}")
|
|
201
|
+
elif lower.startswith("example"):
|
|
202
|
+
content = part.split(":", 1)[1].strip() if ":" in part else part
|
|
203
|
+
content = part.split("\n", 1)[1].strip() if "\n" in part else content
|
|
204
|
+
sections.append(f"## Examples\n{content}")
|
|
205
|
+
elif lower.startswith("output format:"):
|
|
206
|
+
content = part[len("Output format:") :].strip()
|
|
207
|
+
sections.append(f"## Output Format\n{content}")
|
|
208
|
+
else:
|
|
209
|
+
sections.append(part)
|
|
210
|
+
|
|
211
|
+
return "\n\n".join(sections)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _get_tier(score: float) -> str:
|
|
215
|
+
"""Map score to tier label."""
|
|
216
|
+
if score >= 85:
|
|
217
|
+
return "EXPERT"
|
|
218
|
+
if score >= 70:
|
|
219
|
+
return "STRONG"
|
|
220
|
+
if score >= 50:
|
|
221
|
+
return "GOOD"
|
|
222
|
+
if score >= 30:
|
|
223
|
+
return "BASIC"
|
|
224
|
+
return "DRAFT"
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def _missing_suggestions(components: list[str]) -> list[str]:
|
|
228
|
+
"""Suggest components the user could add to improve the prompt."""
|
|
229
|
+
suggestions: list[str] = []
|
|
230
|
+
|
|
231
|
+
if "files" not in components:
|
|
232
|
+
suggestions.append("Add --file to reference specific files (+6 pts)")
|
|
233
|
+
if "error" not in components:
|
|
234
|
+
suggestions.append("Add --error with the actual error message (+6 pts)")
|
|
235
|
+
if "constraints" not in components:
|
|
236
|
+
suggestions.append("Add --constraint to set boundaries (+5 pts)")
|
|
237
|
+
if "context" not in components:
|
|
238
|
+
suggestions.append("Add --context for background information (+4 pts)")
|
|
239
|
+
if "examples" not in components:
|
|
240
|
+
suggestions.append("Add --example with expected input/output (+3 pts)")
|
|
241
|
+
if "role" not in components:
|
|
242
|
+
suggestions.append("Add --role to set the AI's perspective (+3 pts)")
|
|
243
|
+
if "output_format" not in components:
|
|
244
|
+
suggestions.append("Add --output-format to specify response structure (+2 pts)")
|
|
245
|
+
|
|
246
|
+
return suggestions
|