reprompt-cli 1.3.0__tar.gz → 1.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reprompt_cli-1.4.1/.testmondata +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/CLAUDE.md +3 -2
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/PKG-INFO +1 -1
- reprompt_cli-1.4.1/docs/roadmap.md +97 -0
- reprompt_cli-1.4.1/docs/superpowers/specs/2026-03-23-v131-suggestions-source-design.md +179 -0
- reprompt_cli-1.4.1/docs/superpowers/specs/2026-03-24-v14-context-recovery-design.md +342 -0
- reprompt_cli-1.4.1/docs/superpowers/specs/2026-03-24-v141-polish-design.md +184 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/pyproject.toml +1 -1
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/__init__.py +1 -1
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/chatgpt.py +1 -3
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/claude_code.py +3 -5
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/cli.py +376 -182
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/conversation.py +1 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/digest.py +11 -10
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/distill.py +42 -21
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/insights.py +92 -1
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/style.py +62 -1
- reprompt_cli-1.4.1/src/reprompt/core/suggestions.py +22 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/trends.py +4 -2
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/compress_terminal.py +1 -0
- reprompt_cli-1.4.1/src/reprompt/output/export.py +270 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/terminal.py +139 -3
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/storage/db.py +66 -7
- reprompt_cli-1.4.1/tests/fixtures/export/default_export.md +29 -0
- reprompt_cli-1.4.1/tests/fixtures/export/full_export.md +36 -0
- reprompt_cli-1.4.1/tests/test_compare_best_worst.py +233 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_compress.py +1 -2
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_compress_cli.py +1 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_conversation.py +1 -3
- reprompt_cli-1.4.1/tests/test_deprecated_commands.py +60 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_distill.py +83 -37
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_distill_cli.py +12 -5
- reprompt_cli-1.4.1/tests/test_distill_weights.py +96 -0
- reprompt_cli-1.4.1/tests/test_export.py +332 -0
- reprompt_cli-1.4.1/tests/test_export_cli.py +122 -0
- reprompt_cli-1.4.1/tests/test_export_snapshot.py +182 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_import_cli.py +7 -0
- reprompt_cli-1.4.1/tests/test_insights_expanded.py +140 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_parse_conversation_base.py +8 -4
- reprompt_cli-1.4.1/tests/test_source_filter.py +176 -0
- reprompt_cli-1.4.1/tests/test_style_trends.py +256 -0
- reprompt_cli-1.4.1/tests/test_suggestions.py +55 -0
- reprompt_cli-1.4.1/tests/test_template_cli.py +180 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/uv.lock +1 -1
- reprompt_cli-1.3.0/.testmondata +0 -0
- reprompt_cli-1.3.0/.testmondata-shm +0 -0
- reprompt_cli-1.3.0/.testmondata-wal +0 -0
- reprompt_cli-1.3.0/docs/roadmap.md +0 -74
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.editorconfig +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/dependabot.yml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/workflows/ci.yml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.github/workflows/publish.yml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.gitignore +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/.pre-commit-config.yaml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/CHANGELOG.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/CODE_OF_CONDUCT.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/CONTRIBUTING.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/LICENSE +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/README.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/SECURITY.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/action.yml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/docs/launch-post.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/docs/superpowers/specs/2026-03-11-html-dashboard-design.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/docs/superpowers/specs/2026-03-11-merge-view-design.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/docs/superpowers/specs/2026-03-11-prompt-templates-design.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/docs/superpowers/specs/2026-03-22-prompt-compress-design.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/docs/superpowers/specs/2026-03-23-distill-design.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/module.yaml +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/scripts/generate_demo_data.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/scripts/launch/hn_monitor.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/scripts/launch/reddit_helper.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/aider.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/base.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/claude_chat.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/cline.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/cursor.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/filters.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/gemini.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/adapters/openclaw.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/bridge/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/bridge/handler.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/bridge/host.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/bridge/manifest.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/bridge/protocol.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/commands/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/commands/telemetry.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/commands/wrapped.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/config.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/analyzer.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/compress.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/dedup.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/effectiveness.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/extractors.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/extractors_zh.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/lang_detect.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/library.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/lint.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/merge_view.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/models.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/persona.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/pipeline.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/privacy.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/prompt_dna.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/recommend.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/scorer.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/segmenter.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/session_meta.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/templates.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/timeutil.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/core/wrapped.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/demo.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/embeddings/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/embeddings/base.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/embeddings/local_embed.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/embeddings/ollama.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/embeddings/openai_embed.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/embeddings/tfidf.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/mcp.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/mcp_main.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/chartjs.min.js +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/distill_terminal.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/html_report.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/json_out.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/markdown.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/wrapped_html.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/output/wrapped_terminal.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/py.typed +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/sharing/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/sharing/client.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/sharing/clipboard.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/storage/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/collector.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/consent.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/events.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/prompt.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/queue.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/src/reprompt/telemetry/sender.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/__init__.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/conftest.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/aider_chat_history.md +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/chatgpt_conversations.json +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/claude_chat_export.json +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/claude_session.jsonl +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/cline_task/api_conversation_history.json +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/gemini_session.json +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/fixtures/openclaw_session.jsonl +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_aider.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_chatgpt.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_claude.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_claude_chat.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_cline.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_gemini.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_adapter_openclaw.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_analyzer.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_bridge_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_bridge_handler.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_bridge_integration.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_bridge_manifest.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_bridge_protocol.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_cli_library_effectiveness.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_clipboard.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_compress_dna.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_compress_html.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_compress_insights.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_config.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_coverage_boost.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_cursor_adapter.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_db.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_db_digest.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_db_effectiveness.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_db_trends.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_dedup.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_demo.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_digest.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_digest_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_effectiveness.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_embeddings_local.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_embeddings_ollama.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_embeddings_openai.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_empty_state.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_extractors.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_extractors_routing.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_extractors_zh.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_extractors_zh_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_html_report.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_import_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_insights.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_insights_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_install_hook.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_lang_detect.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_library.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_lint.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_lint_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_markdown.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_mcp.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_merge_view.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_models.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_output.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_parse_conversation_chatgpt.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_parse_conversation_claude.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_persona.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_pipeline.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_privacy.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_privacy_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_privacy_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_privacy_output.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_prompt_dna.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_public_api.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_recommend.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_schema_version.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_score_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_scorer.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_segmenter.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_share_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_sharing_client.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_style.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_collector.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_consent.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_events.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_prompt.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_queue.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_telemetry_sender.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_templates.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_timeutil.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_trends.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_trends_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_use_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_wrapped.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_wrapped_cli.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_wrapped_e2e.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_wrapped_html.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_wrapped_output.py +0 -0
- {reprompt_cli-1.3.0 → reprompt_cli-1.4.1}/tests/test_wrapped_share.py +0 -0
|
Binary file
|
|
@@ -18,7 +18,7 @@ uv run python -m build # build wheel
|
|
|
18
18
|
|
|
19
19
|
```
|
|
20
20
|
src/reprompt/
|
|
21
|
-
├── cli.py # Typer CLI (scan, import, report, search, library, recommend, demo, status, purge, install-hook, install-extension, extension-status, score, compare, insights, digest, style, use, privacy, compress, distill) + plugin loading
|
|
21
|
+
├── cli.py # Typer CLI (scan, import, report, search, library, recommend, demo, status, purge, install-hook, install-extension, extension-status, score, compare, insights, digest, style, template [save|list|use], privacy, compress, distill) + plugin loading
|
|
22
22
|
├── config.py # pydantic-settings, env vars (REPROMPT_ prefix) + TOML config
|
|
23
23
|
├── demo.py # Built-in demo data generator (no network required)
|
|
24
24
|
├── core/
|
|
@@ -41,6 +41,7 @@ src/reprompt/
|
|
|
41
41
|
│ ├── wrapped.py # WrappedReport dataclass + build_wrapped(db) aggregation
|
|
42
42
|
│ ├── privacy.py # Privacy metadata registry + exposure summary per adapter
|
|
43
43
|
│ ├── compress.py # 4-layer prompt compression (char norm + phrase simplify + filler delete + structure cleanup)
|
|
44
|
+
│ ├── suggestions.py # Command journey suggestions ("→ Try:" hints for 5 core commands)
|
|
44
45
|
│ ├── conversation.py # ConversationTurn, Conversation, DistillResult dataclasses
|
|
45
46
|
│ └── distill.py # 6-signal importance scoring + filtering + summary generation
|
|
46
47
|
├── adapters/
|
|
@@ -123,7 +124,7 @@ reprompt-extension (private) ← Browser extension: Chrome/Firefox prompt capt
|
|
|
123
124
|
- Pattern upsert (not clear+re-insert) for stable IDs
|
|
124
125
|
- Prompts starting with `<` are filtered (system-injected XML)
|
|
125
126
|
- Config: env vars (REPROMPT_ prefix) > TOML (~/.config/reprompt/config.toml) > defaults
|
|
126
|
-
- Tests: pytest,
|
|
127
|
+
- Tests: pytest, 1295 tests, 95% coverage target
|
|
127
128
|
|
|
128
129
|
## Prompt Science Engine
|
|
129
130
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reprompt-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.1
|
|
4
4
|
Summary: Discover, analyze, and optimize your prompts from AI coding sessions
|
|
5
5
|
Project-URL: Homepage, https://github.com/reprompt-dev/reprompt
|
|
6
6
|
Project-URL: Repository, https://github.com/reprompt-dev/reprompt
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# reprompt Roadmap
|
|
2
|
+
|
|
3
|
+
> Last updated: 2026-03-25 · Current version: v1.4.1
|
|
4
|
+
|
|
5
|
+
## Vision
|
|
6
|
+
|
|
7
|
+
reprompt is the **prompt intelligence** tool for AI sessions — distill your conversations, compress your prompts, score them against research, and track your progress. Zero-config, privacy-first, CLI-first.
|
|
8
|
+
|
|
9
|
+
**Category definition:** reprompt analyzes *human inputs* (how you prompt), not *LLM outputs* (how models respond). Every other tool in the eval/observability space — Promptfoo, Braintrust, DeepEval, Langfuse — answers "did my AI system answer correctly?" reprompt answers "am I asking well?" This is an unoccupied category.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Current State (v1.4.0) — Production Stable
|
|
14
|
+
|
|
15
|
+
### Adapters (8)
|
|
16
|
+
Claude Code · OpenClaw · Cursor IDE · Aider · Gemini CLI · Cline · ChatGPT · Claude.ai
|
|
17
|
+
|
|
18
|
+
### Commands (23 visible, 5 deprecated)
|
|
19
|
+
`scan` · `import` · `report` · `library` · `trends` · `recommend` · `template [save|list|use]` · `lint` · `search` · `demo` · `status` · `purge` · `install-hook` · `install-extension` · `extension-status` · `score` · `compare` · `insights` · `digest` · `style` · `wrapped` · `telemetry` · `mcp-serve` · `compress` · `distill` · `privacy`
|
|
20
|
+
|
|
21
|
+
### Integrations
|
|
22
|
+
- MCP server (`reprompt mcp-serve`) for IDE integration
|
|
23
|
+
- GitHub Action (`action.yml`) for CI prompt quality checks
|
|
24
|
+
- HTML dashboard (`reprompt report --html`)
|
|
25
|
+
- Browser extension (Chrome/Firefox) via Native Messaging bridge
|
|
26
|
+
- JSON output on all commands for pipeline integration
|
|
27
|
+
|
|
28
|
+
### Key Features by Version
|
|
29
|
+
|
|
30
|
+
| Version | Feature | Description |
|
|
31
|
+
|---------|---------|-------------|
|
|
32
|
+
| v1.0.0 | Core platform | Scoring, dedup, report, trends, digest, style, effectiveness, templates, MCP, HTML dashboard |
|
|
33
|
+
| v1.1.0 | Privacy exposure | `reprompt privacy` — where your prompts went, training risk analysis |
|
|
34
|
+
| v1.2.0 | Prompt compression | `reprompt compress` — 4-layer rule-based compression (43 zh + 51 en rules) |
|
|
35
|
+
| v1.3.0 | Conversation distillation | `reprompt distill` — 6-signal importance scoring for conversation turns |
|
|
36
|
+
| v1.3.1 | UX polish | Actionable suggestions on 5 commands, `--source` filter on all data commands |
|
|
37
|
+
| v1.4.0 | Context recovery + consolidation | `distill --export` context document, signal transparency, command consolidation (27→23) |
|
|
38
|
+
| v1.4.1 | Compare + style polish | `compare --best-worst` auto-pick, `style --trends` period-over-period deltas |
|
|
39
|
+
|
|
40
|
+
### Quality
|
|
41
|
+
- 1316 tests, ≥90% coverage
|
|
42
|
+
- Strict mypy, ruff lint/format
|
|
43
|
+
- CI: coverage gate + pre-publish test step
|
|
44
|
+
- Stable public API (`score_prompt`, `compare_prompts`, `extract_features`)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## v1.4 — Context Recovery + Command Consolidation
|
|
49
|
+
|
|
50
|
+
| Priority | Item | Rationale |
|
|
51
|
+
|----------|------|-----------|
|
|
52
|
+
| P1 | `distill --export` context recovery | **DONE** — community signal: resume sessions after compaction/timeout |
|
|
53
|
+
| P2 | Command consolidation: `save`/`templates`/`use` → `template [save\|list\|use]` | **DONE** — 3 commands doing 1 thing = cognitive overload |
|
|
54
|
+
| P2 | Command consolidation: `effectiveness`/`merge-view` → `insights` sub-insights | **DONE** — concepts unclear to users |
|
|
55
|
+
| P3 | `style` shows change trends | **DONE** — `--trends` flag with period-over-period deltas |
|
|
56
|
+
| P4 | `distill --show-weights` / `--weights` signal transparency | Community request for weight visibility |
|
|
57
|
+
| P5 | `compare --best-worst` auto-pick | **DONE** — auto-selects from DB scores |
|
|
58
|
+
| P5 | `--copy` as standard option on remaining commands | Decided against — no clear paste destination for analysis commands |
|
|
59
|
+
|
|
60
|
+
**Status: 27 → 23 visible commands. P1+P2+P3+P5 shipped.**
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## v1.5+ — Future Work
|
|
65
|
+
|
|
66
|
+
| Feature | Description |
|
|
67
|
+
|---------|-------------|
|
|
68
|
+
| Distill false positive reduction | Position signal breaks on small-talk openers / "thanks bye" closers; long error dumps score high on length+uniqueness but aren't decision points; "ok try again" triggers error_recovery but is noise. Community feedback from r/LLMDevs. |
|
|
69
|
+
| Sensitive content detection | Privacy narrative; PII in prompts |
|
|
70
|
+
| Agent workflow analysis | Multi-step agent session patterns |
|
|
71
|
+
| `.reprompt.yml` configurable lint | Team/Pro direction |
|
|
72
|
+
| `reprompt suggest` (Ollama rewrite) | LLM-powered prompt improvement |
|
|
73
|
+
| Homebrew formula | `brew install reprompt` |
|
|
74
|
+
| More adapters | Perplexity, Mistral, Grok, Gemini Takeout |
|
|
75
|
+
| Windows Native Messaging | Extension support on Windows |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Architecture Principles
|
|
80
|
+
|
|
81
|
+
1. **Zero-config first** — Every feature works without LLM by default
|
|
82
|
+
2. **Privacy by design** — All data stays local; extension has zero server
|
|
83
|
+
3. **Adapter pattern** — New AI tools supported by adding ~50 lines
|
|
84
|
+
4. **Input not output** — We analyze human prompts (inputs); LLM eval tools analyze model responses (outputs)
|
|
85
|
+
5. **CLI first, GUI second** — Terminal is primary, HTML dashboard is secondary
|
|
86
|
+
6. **Composable** — Every command supports JSON output for piping
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## How to Contribute
|
|
91
|
+
|
|
92
|
+
- **New adapter** (~50 lines) — see `src/reprompt/adapters/base.py`
|
|
93
|
+
- **New lint rules** — see `src/reprompt/core/lint.py`
|
|
94
|
+
- **Better categorization** — improve keyword rules in `core/library.py`
|
|
95
|
+
- **Browser extension** — see `reprompt-extension` repo
|
|
96
|
+
|
|
97
|
+
See [CONTRIBUTING.md](../CONTRIBUTING.md) for details.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# v1.3.1 — Actionable Suggestions + `--source` Consistency
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Two improvements: (1) guide users to the next useful command after each analysis, (2) make `--source` filtering available on all data-querying commands.
|
|
6
|
+
|
|
7
|
+
## P2: Actionable Suggestions
|
|
8
|
+
|
|
9
|
+
### Problem
|
|
10
|
+
|
|
11
|
+
Commands show data but don't tell users what to do next. New users run `reprompt scan`, see results, and don't know to try `reprompt report` or `reprompt insights`. The "展示 → 行动" gap reduces retention.
|
|
12
|
+
|
|
13
|
+
### Design
|
|
14
|
+
|
|
15
|
+
A single dim "Next step" line appended to 5 core commands:
|
|
16
|
+
|
|
17
|
+
| Command | Suggestion |
|
|
18
|
+
|---------|-----------|
|
|
19
|
+
| `scan` | `reprompt report (see results) · reprompt insights (personal patterns)` |
|
|
20
|
+
| `report` | `reprompt insights (patterns) · reprompt distill --last (session review)` |
|
|
21
|
+
| `score` | `reprompt compress "..." (optimize) · reprompt insights (all patterns)` |
|
|
22
|
+
| `insights` | `reprompt compress "..." (verbose prompts) · reprompt distill --last (sessions)` |
|
|
23
|
+
| `distill` | `reprompt compress "..." (shorten turns) · reprompt report (full analytics)` |
|
|
24
|
+
|
|
25
|
+
### Implementation
|
|
26
|
+
|
|
27
|
+
**New file:** `src/reprompt/core/suggestions.py`
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
"""Command journey suggestions — guide users to the next useful action."""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
SUGGESTIONS: dict[str, str] = {
|
|
35
|
+
"scan": "reprompt report (see results) · reprompt insights (personal patterns)",
|
|
36
|
+
"report": "reprompt insights (patterns) · reprompt distill --last (session review)",
|
|
37
|
+
"score": 'reprompt compress "..." (optimize) · reprompt insights (all patterns)',
|
|
38
|
+
"insights": 'reprompt compress "..." (verbose prompts) · reprompt distill --last (sessions)',
|
|
39
|
+
"distill": 'reprompt compress "..." (shorten turns) · reprompt report (full analytics)',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_suggestion(command: str) -> str | None:
|
|
44
|
+
"""Return the suggestion line for a command, or None."""
|
|
45
|
+
return SUGGESTIONS.get(command)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**CLI integration pattern** (same for all 5 commands):
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
# At the end of the command function, before return:
|
|
52
|
+
from reprompt.core.suggestions import get_suggestion
|
|
53
|
+
hint = get_suggestion("command_name")
|
|
54
|
+
if hint and not json_output:
|
|
55
|
+
console.print(f"\n [dim]→ Try: {hint}[/dim]")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Display Rules
|
|
59
|
+
|
|
60
|
+
- Only in terminal mode — suppressed when `--json` or `--copy` is used
|
|
61
|
+
- `[dim]` Rich styling — visible but not distracting
|
|
62
|
+
- Not shown when the command produces no output (e.g. `scan` with 0 new sessions, `distill` with no sessions found)
|
|
63
|
+
- Single line — power users can ignore it instantly
|
|
64
|
+
|
|
65
|
+
### `scan` Conflict Resolution
|
|
66
|
+
|
|
67
|
+
`scan` already has a "Try next" block (cli.py:109-114) that shows when new prompts are imported and the DB is small. The new suggestion line must NOT duplicate this. Rule: **only show the dim suggestion when the existing "Try next" block does NOT fire** — i.e. when `result.new_stored == 0` or the DB already has substantial data.
|
|
68
|
+
|
|
69
|
+
### Why Only 5 Commands
|
|
70
|
+
|
|
71
|
+
These are the commands users hit in their first session and on return visits. Adding suggestions to all 27 commands would be noise. The 5 form a natural discovery loop:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
scan → report → insights → compress/distill → report (loop)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## P3: `--source` Filter Consistency
|
|
78
|
+
|
|
79
|
+
### Problem
|
|
80
|
+
|
|
81
|
+
`report`, `search`, `scan`, `lint`, `distill` support `--source` to filter by adapter. But `insights`, `trends`, `digest`, `style` don't — users with multiple tools (e.g. Claude Code + Cursor) can't analyze them separately.
|
|
82
|
+
|
|
83
|
+
### Current State
|
|
84
|
+
|
|
85
|
+
| Has `--source` | Missing (should have) | N/A (single-prompt commands) |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `scan`, `report`, `search`, `lint`, `distill` | `insights`, `trends`, `digest`, `style` | `score`, `compare`, `compress`, `privacy` |
|
|
88
|
+
|
|
89
|
+
### Design
|
|
90
|
+
|
|
91
|
+
Add `--source` / `-s` to the 4 missing commands. Each uses existing DB query functions that already support source filtering, except `get_all_features()`.
|
|
92
|
+
|
|
93
|
+
#### DB Change: `get_all_features(source=None)`
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
def get_all_features(self, source: str | None = None) -> list[dict[str, Any]]:
|
|
97
|
+
"""Return all stored feature vectors, optionally filtered by source."""
|
|
98
|
+
conn = self._conn()
|
|
99
|
+
try:
|
|
100
|
+
if source:
|
|
101
|
+
rows = conn.execute(
|
|
102
|
+
"""SELECT pf.features_json FROM prompt_features pf
|
|
103
|
+
JOIN prompts p ON pf.prompt_hash = p.hash
|
|
104
|
+
WHERE p.source = ?
|
|
105
|
+
ORDER BY pf.overall_score DESC""",
|
|
106
|
+
(source,),
|
|
107
|
+
).fetchall()
|
|
108
|
+
else:
|
|
109
|
+
rows = conn.execute(
|
|
110
|
+
"SELECT features_json FROM prompt_features ORDER BY overall_score DESC"
|
|
111
|
+
).fetchall()
|
|
112
|
+
return [json.loads(r["features_json"]) for r in rows]
|
|
113
|
+
finally:
|
|
114
|
+
conn.close()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Per-Command Changes
|
|
118
|
+
|
|
119
|
+
| Command | Data function | Change needed |
|
|
120
|
+
|---------|--------------|---------------|
|
|
121
|
+
| `insights` | `db.get_all_features()` | Add `source` CLI param, pass to `get_all_features(source=)` |
|
|
122
|
+
| `style` | `db.get_all_prompts()` | Add `source` CLI param, pass to `get_all_prompts(source=)` (NOTE: `style` uses `get_all_prompts`, not `get_all_features`) |
|
|
123
|
+
| `trends` | `db.get_all_prompts()` | `get_all_prompts()` already accepts `source` — add CLI param and pass through |
|
|
124
|
+
| `digest` | `build_digest()` → `compute_window_snapshot()` → `db.get_prompts_in_range()` | Full call chain needs `source` threaded through (see below) |
|
|
125
|
+
|
|
126
|
+
#### `digest` Call Chain Fix
|
|
127
|
+
|
|
128
|
+
`digest` has a 3-function call chain that all need `source` added:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
CLI digest(source=) → build_digest(db, period, source=) → compute_window_snapshot(db, window, period, source=) → db.get_prompts_in_range(start, end, source=)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Files to modify:**
|
|
135
|
+
- `src/reprompt/core/digest.py`: add `source: str | None = None` param to `build_digest()`, pass to `compute_window_snapshot()`
|
|
136
|
+
- `src/reprompt/core/trends.py`: add `source: str | None = None` param to `compute_window_snapshot()`, pass to `db.get_prompts_in_range()`
|
|
137
|
+
- `db.get_prompts_in_range()` already accepts `source` — no change needed
|
|
138
|
+
|
|
139
|
+
**Digest log edge case:** When `source` is set, skip `db.log_digest()` — a source-filtered digest run should not overwrite the unfiltered digest history.
|
|
140
|
+
|
|
141
|
+
#### CLI Parameter Pattern
|
|
142
|
+
|
|
143
|
+
Standardize on `None` default (matching `distill`), not empty string:
|
|
144
|
+
```python
|
|
145
|
+
source: str | None = typer.Option(
|
|
146
|
+
None, "--source", "-s", help="Filter by source (e.g. claude-code, cursor, aider)"
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Files Changed
|
|
151
|
+
|
|
152
|
+
| File | Action | What |
|
|
153
|
+
|------|--------|------|
|
|
154
|
+
| `src/reprompt/core/suggestions.py` | Create | Suggestion map + `get_suggestion()` |
|
|
155
|
+
| `src/reprompt/storage/db.py` | Modify | Add `source` param to `get_all_features()` |
|
|
156
|
+
| `src/reprompt/core/digest.py` | Modify | Add `source` param to `build_digest()` |
|
|
157
|
+
| `src/reprompt/core/trends.py` | Modify | Add `source` param to `compute_window_snapshot()` |
|
|
158
|
+
| `src/reprompt/cli.py` | Modify | Suggestions on 5 commands + `--source` on 4 commands |
|
|
159
|
+
| `tests/test_suggestions.py` | Create | Suggestion map tests |
|
|
160
|
+
| `tests/test_source_filter.py` | Create | `--source` CLI + behavioral tests (seeded DB with 2 sources) |
|
|
161
|
+
|
|
162
|
+
## DB Changes
|
|
163
|
+
|
|
164
|
+
**None.** No schema changes, no migrations. Only a query modification in `get_all_features()`.
|
|
165
|
+
|
|
166
|
+
## Testing Strategy
|
|
167
|
+
|
|
168
|
+
| Test file | Coverage |
|
|
169
|
+
|-----------|----------|
|
|
170
|
+
| `tests/test_suggestions.py` | All 5 commands return suggestions, unknown command returns None, suggestions contain valid command names |
|
|
171
|
+
| `tests/test_source_filter.py` | CLI `--source` flag on insights/trends/digest/style (`--help` shows flag), behavioral test with seeded DB (2 sources, verify filtered count != total count), `get_all_features(source=)` JOIN returns correct subset, digest source-filtered run skips log_digest |
|
|
172
|
+
|
|
173
|
+
## Success Criteria
|
|
174
|
+
|
|
175
|
+
1. `reprompt report` ends with a dim suggestion line pointing to `insights` and `distill`
|
|
176
|
+
2. `reprompt insights --source claude-code` shows patterns only from Claude Code sessions
|
|
177
|
+
3. `reprompt style --source cursor` shows style fingerprint from Cursor-only prompts
|
|
178
|
+
4. Suggestions suppressed in `--json` mode
|
|
179
|
+
5. Zero regressions in existing tests
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# v1.4 Design Spec: Context Recovery + Consolidation
|
|
2
|
+
|
|
3
|
+
> **Version:** v1.4.0
|
|
4
|
+
> **Date:** 2026-03-24
|
|
5
|
+
> **Status:** Draft
|
|
6
|
+
> **Community signal:** pvdyck (r/ClaudeAI), LLMDevs commenters, LeadingFarmer3923 (r/ClaudeAI)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Problem
|
|
11
|
+
|
|
12
|
+
AI coding sessions lose context through compaction, timeouts, and tool-switching. Users are forced to re-explain what they were doing, what decisions were made, and where they left off. This is a daily pain point for every Claude Code, Cursor, and Aider power user.
|
|
13
|
+
|
|
14
|
+
No tool produces a structured, portable, human-readable distillation of a coding session optimized for re-injection into a new session.
|
|
15
|
+
|
|
16
|
+
## Solution
|
|
17
|
+
|
|
18
|
+
Add `--export` flag to the existing `reprompt distill` command. Produces a markdown context document designed to be pasted into any AI tool as session resumption context.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Primary workflow
|
|
22
|
+
reprompt distill --last 1 --export | pbcopy
|
|
23
|
+
# → paste into new Claude Code / Cursor / ChatGPT session
|
|
24
|
+
|
|
25
|
+
# With clipboard shortcut
|
|
26
|
+
reprompt distill --last 1 --export --copy
|
|
27
|
+
|
|
28
|
+
# Full mode (includes assistant responses)
|
|
29
|
+
reprompt distill --last 1 --export --full
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Design Principles
|
|
33
|
+
|
|
34
|
+
1. **Generic markdown** — works in any AI tool, not coupled to one platform
|
|
35
|
+
2. **User turns only** by default — the goal is "what the human decided and did," not replaying the conversation
|
|
36
|
+
3. **~500 tokens default** — fits comfortably in any context window alongside other context
|
|
37
|
+
4. **Lost-in-the-Middle aware** — actionable sections at top and bottom, reference material in the middle (Stanford 2307.03172, MIT 2025 follow-up)
|
|
38
|
+
5. **Cache-friendly header** — stable identifiers first, volatile metadata second (arXiv 2601.06007)
|
|
39
|
+
6. **Zero-config** — no LLM required, rule-based extraction from existing distill engine
|
|
40
|
+
|
|
41
|
+
## Export Document Structure
|
|
42
|
+
|
|
43
|
+
```markdown
|
|
44
|
+
# Session Context: <project>
|
|
45
|
+
|
|
46
|
+
**Source:** <adapter> | **Date:** <YYYY-MM-DD> | **Duration:** <N>min
|
|
47
|
+
**Turns:** <total> → <kept> key turns | **~<N> tokens**
|
|
48
|
+
|
|
49
|
+
## Goal
|
|
50
|
+
|
|
51
|
+
<first user turn, compressed via compress_text()>
|
|
52
|
+
|
|
53
|
+
## Current State
|
|
54
|
+
|
|
55
|
+
<last high-importance user turn, compressed>
|
|
56
|
+
|
|
57
|
+
## Key Decisions
|
|
58
|
+
|
|
59
|
+
1. <turn with high semantic_shift — why a choice was made>
|
|
60
|
+
2. <turn with high semantic_shift — why a choice was made>
|
|
61
|
+
3. ...
|
|
62
|
+
|
|
63
|
+
## What Was Done
|
|
64
|
+
|
|
65
|
+
- <turn with high tool_trigger — what was implemented/changed>
|
|
66
|
+
- ...
|
|
67
|
+
|
|
68
|
+
## Files Changed
|
|
69
|
+
|
|
70
|
+
`file1.py`, `file2.py`, `file3.py`
|
|
71
|
+
|
|
72
|
+
## Resume
|
|
73
|
+
|
|
74
|
+
<last turn with forward-looking intent, if detected; omitted otherwise>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Section Design Details
|
|
78
|
+
|
|
79
|
+
#### Header
|
|
80
|
+
- Project name first (stable, cache-friendly), volatile metadata on second line.
|
|
81
|
+
- Token count is approximate: `len(output) // 4`. No external tokenizer dependency.
|
|
82
|
+
|
|
83
|
+
#### Goal
|
|
84
|
+
- Source: first user turn (`user_turns[0]`), processed through `compress_text()`.
|
|
85
|
+
- Truncated to 200 chars max.
|
|
86
|
+
- Always present (every conversation has a first turn).
|
|
87
|
+
|
|
88
|
+
#### Current State
|
|
89
|
+
- Source: last user turn with `importance >= threshold`, compressed.
|
|
90
|
+
- Represents where the session ended up, not where it started.
|
|
91
|
+
- If same as Goal (single-turn session), this section is omitted.
|
|
92
|
+
|
|
93
|
+
#### Key Decisions
|
|
94
|
+
- Source: user turns sorted by `semantic_shift` signal (descending), top 5.
|
|
95
|
+
- These are turns where the user changed direction or made a choice.
|
|
96
|
+
- Each entry compressed and truncated to 150 chars.
|
|
97
|
+
- Deduplicated against Goal and Current State (no repeats).
|
|
98
|
+
|
|
99
|
+
#### What Was Done
|
|
100
|
+
- Source: user turns sorted by `tool_trigger` signal (descending), top 5.
|
|
101
|
+
- These are turns that caused the most tool activity (implementation work).
|
|
102
|
+
- Each entry compressed and truncated to 150 chars.
|
|
103
|
+
- Deduplicated against Key Decisions (a turn appears in only one section).
|
|
104
|
+
|
|
105
|
+
#### Files Changed
|
|
106
|
+
- Source: existing `_extract_files_changed()` from distill engine.
|
|
107
|
+
- Displayed as inline code, comma-separated. Max 10 files shown (aligned with existing `generate_summary()` cap).
|
|
108
|
+
|
|
109
|
+
#### Resume
|
|
110
|
+
- Source: last 3 user turns, checked for forward-looking keywords.
|
|
111
|
+
- Keywords: `next`, `todo`, `now let's`, `then`, `after that`, `move on`, `接下来`, `然后`, `下一步`.
|
|
112
|
+
- If no forward-looking turn found, section is omitted entirely.
|
|
113
|
+
- Not fabricated — only extracted from actual user text.
|
|
114
|
+
|
|
115
|
+
### Turn Classification Logic
|
|
116
|
+
|
|
117
|
+
A user turn's primary section is determined by its highest-scoring signal:
|
|
118
|
+
|
|
119
|
+
| Highest signal | Section |
|
|
120
|
+
|---------------|---------|
|
|
121
|
+
| `semantic_shift` | Key Decisions |
|
|
122
|
+
| `tool_trigger` | What Was Done |
|
|
123
|
+
| Both equal | Key Decisions (decision > action) |
|
|
124
|
+
|
|
125
|
+
Turns used for Goal, Current State, or Resume are excluded from both lists to avoid repetition.
|
|
126
|
+
|
|
127
|
+
## `--full` Mode
|
|
128
|
+
|
|
129
|
+
When `--full` is passed, each user turn in Key Decisions and What Was Done includes the paired assistant response summary:
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
## Key Decisions
|
|
133
|
+
|
|
134
|
+
1. **User:** Used TF-IDF cosine distance for semantic_shift instead of embeddings
|
|
135
|
+
**Result:** Implemented in `_compute_semantic_signals()`, 4 helper functions added
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Assistant response is summarized as: first sentence of the response text, or "N tool calls, M files changed" if the response is primarily tool use. This roughly doubles token count (~1000-1500 tokens).
|
|
139
|
+
|
|
140
|
+
## Weight Transparency Flags
|
|
141
|
+
|
|
142
|
+
Two separate flags (Typer does not support a single option that acts as both bool flag and string option):
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Show current weights
|
|
146
|
+
reprompt distill --show-weights
|
|
147
|
+
# position=0.15, length=0.15, tool_trigger=0.20,
|
|
148
|
+
# error_recovery=0.15, semantic_shift=0.20, uniqueness=0.15
|
|
149
|
+
|
|
150
|
+
# Override weights (advanced)
|
|
151
|
+
reprompt distill --last 1 --export --weights "semantic_shift=0.4,tool_trigger=0.3"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**`--show-weights`** (bool flag): Prints current signal weights and exits. Ignores all other flags.
|
|
155
|
+
|
|
156
|
+
**`--weights TEXT`** (string option): Parses comma-separated `key=value` pairs, merges with defaults for unspecified keys. Validation:
|
|
157
|
+
- Unknown keys (typos like `tool_tigger`) → error with "unknown weight key" message listing valid keys
|
|
158
|
+
- Sum != 1.0 → warning printed to stderr, execution continues
|
|
159
|
+
- Override applies to this invocation only, does not persist
|
|
160
|
+
|
|
161
|
+
## Open/Pro Boundary
|
|
162
|
+
|
|
163
|
+
| Feature | Layer | Rationale |
|
|
164
|
+
|---------|-------|-----------|
|
|
165
|
+
| `--export` markdown output | **Open** | Rule-based, zero-config, individual tool |
|
|
166
|
+
| `--full` user+assistant pairs | **Open** | Same data, different format |
|
|
167
|
+
| `--weights` transparency | **Open** | Transparency builds trust |
|
|
168
|
+
| LLM-powered semantic summary | **Pro** | Requires Ollama, clear upgrade path |
|
|
169
|
+
| Cross-session memory ("what did I discuss about auth across 100 sessions?") | **Pro** | Needs persistent index + embeddings |
|
|
170
|
+
|
|
171
|
+
If Pro plugin is installed, `--export --summary` uses LLM to produce a condensed 3-sentence brief instead of rule-based extraction. Graceful degradation message if Pro is not installed.
|
|
172
|
+
|
|
173
|
+
## Architecture
|
|
174
|
+
|
|
175
|
+
### New Files
|
|
176
|
+
|
|
177
|
+
| File | Purpose | ~Lines |
|
|
178
|
+
|------|---------|--------|
|
|
179
|
+
| `output/export.py` | `generate_export(result, full=False) → str` | ~120 |
|
|
180
|
+
|
|
181
|
+
### Modified Files
|
|
182
|
+
|
|
183
|
+
| File | Change |
|
|
184
|
+
|------|--------|
|
|
185
|
+
| `cli.py` | Add `--export`, `--full`, `--show-weights`, `--weights` flags to `distill` command |
|
|
186
|
+
| `core/distill.py` | Expose per-signal scores on `ConversationTurn` for section classification; accept optional `weights` dict |
|
|
187
|
+
| `core/conversation.py` | Add `signal_scores: dict[str, float]` field to `ConversationTurn` |
|
|
188
|
+
| `core/suggestions.py` | Update distill suggestion to mention `--export` |
|
|
189
|
+
|
|
190
|
+
### Data Flow
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
Session files → Adapter.parse_conversation() → Conversation
|
|
194
|
+
→ distill_conversation(conv, threshold, weights?) → DistillResult
|
|
195
|
+
(turns now have per-signal scores in signal_scores dict)
|
|
196
|
+
→ generate_export(result, full=False) → str (markdown)
|
|
197
|
+
→ stdout / clipboard / file
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Key Implementation Details
|
|
201
|
+
|
|
202
|
+
1. **Per-signal scores on ConversationTurn:** Currently `importance` is a single float (weighted sum). To classify turns into "Key Decisions" vs "What Was Done," we need access to individual signal scores. Add `signal_scores: dict[str, float] = field(default_factory=dict)` to `ConversationTurn`. Populate during scoring inside `distill_conversation()`:
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
# Inside the user turn scoring loop (after computing all 6 scores):
|
|
206
|
+
user_turn.signal_scores = {
|
|
207
|
+
"position": pos_score,
|
|
208
|
+
"length": len_score,
|
|
209
|
+
"tool_trigger": tool_score,
|
|
210
|
+
"error_recovery": error_score,
|
|
211
|
+
"semantic_shift": shift_score,
|
|
212
|
+
"uniqueness": unique_score,
|
|
213
|
+
}
|
|
214
|
+
user_turn.importance = (
|
|
215
|
+
weights["position"] * pos_score
|
|
216
|
+
+ weights["length"] * len_score
|
|
217
|
+
+ ...
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
2. **`distill_conversation()` new signature:**
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
def distill_conversation(
|
|
225
|
+
conversation: Conversation,
|
|
226
|
+
threshold: float = 0.3,
|
|
227
|
+
weights: dict[str, float] | None = None,
|
|
228
|
+
) -> DistillResult:
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
When `weights` is None, use the existing `W_*` module constants as defaults. When provided, merge: `effective = {**DEFAULT_WEIGHTS, **weights}`. Unknown keys are already rejected at the CLI layer (see `--weights` validation).
|
|
232
|
+
|
|
233
|
+
3. **Forward-looking detection for Resume:** Simple keyword match on last 3 high-importance user turns. Bilingual (en + zh). No NLP dependency.
|
|
234
|
+
|
|
235
|
+
4. **Token estimation:** `len(output_text) // 4` — rough but sufficient. No external tokenizer.
|
|
236
|
+
|
|
237
|
+
5. **Deduplication across sections:** Goal turn, Current State turn, and Resume turn are tracked by `turn_index`. Excluded from Key Decisions and What Was Done candidate pools.
|
|
238
|
+
|
|
239
|
+
6. **`--full` mode assistant summary:** An assistant turn is "primarily tool use" when `tool_calls > 0 and len(text.strip()) < 200`. In that case, summarize as `"{N} tool calls, {M} files changed"`. Otherwise, use the first sentence of the response text (split on `. ` or `\n`, take first element, truncate to 150 chars).
|
|
240
|
+
|
|
241
|
+
7. **`--export` restricted to single session:** `--export` requires `--last 1` (or a specific session_id). If `--last N` with N > 1 is combined with `--export`, print error: `"--export works with a single session. Use --last 1 or specify a session ID."` and exit.
|
|
242
|
+
|
|
243
|
+
8. **`--export --json` envelope:** Outputs `{"export": "<markdown string>", "session_id": "...", "source": "...", "tokens": N}`. The markdown is a single string field, not the raw DistillResult.
|
|
244
|
+
|
|
245
|
+
9. **Empty filtered_turns fallback:** When `filtered_turns` is empty (threshold too high), `generate_export()` falls back to a minimal document using the first and last raw user turns from `conversation.turns`, with a note: `"(No turns above threshold {threshold}. Showing first and last turns.)"`.
|
|
246
|
+
|
|
247
|
+
10. **Suggestions update:** Replace the `distill` entry in `SUGGESTIONS` dict (`core/suggestions.py` line 10) with: `'reprompt distill --export --copy (context recovery) · reprompt compress "..." (shorten turns)'`. This replaces the current `report` hint (less relevant after distill) with the new `--export` hint, keeping `compress` as the second option.
|
|
248
|
+
|
|
249
|
+
11. **`--full` without `--export` warning:** If `--full` is passed without `--export`, print a warning to stderr: `"--full has no effect without --export"` and continue normally. Do not error.
|
|
250
|
+
|
|
251
|
+
## CLI Interface
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
reprompt distill [SESSION_ID] [OPTIONS]
|
|
255
|
+
|
|
256
|
+
Existing flags (unchanged):
|
|
257
|
+
--last N Distill N most recent sessions (default: 1)
|
|
258
|
+
--source TEXT Filter by adapter name
|
|
259
|
+
--summary Show compressed summary
|
|
260
|
+
--json Output as JSON
|
|
261
|
+
--copy Copy to clipboard
|
|
262
|
+
--threshold FLOAT Importance cutoff 0.0-1.0 (default: 0.3)
|
|
263
|
+
|
|
264
|
+
New flags (v1.4):
|
|
265
|
+
--export Output as markdown context document for session resumption
|
|
266
|
+
--full Include assistant responses in export (requires --export)
|
|
267
|
+
--show-weights Print current signal weights and exit
|
|
268
|
+
--weights TEXT Override signal weights, e.g. "semantic_shift=0.4,tool_trigger=0.3"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Flag interactions:
|
|
272
|
+
- `--export` and `--summary` are mutually exclusive (both produce text, different formats)
|
|
273
|
+
- `--export` requires single session: `--last 1` or a session_id. Error if `--last N` with N > 1.
|
|
274
|
+
- `--export --json` outputs `{"export": "<markdown>", "session_id": "...", "source": "...", "tokens": N}`
|
|
275
|
+
- `--export --copy` copies the markdown to clipboard
|
|
276
|
+
- `--full` without `--export` is ignored (only affects export format)
|
|
277
|
+
- `--show-weights` prints weights and exits (ignores all other flags)
|
|
278
|
+
- `--weights "k=v,..."` overrides weights for the current invocation; unknown keys → error
|
|
279
|
+
|
|
280
|
+
## v1.4 Full Scope (Context Recovery + Consolidation)
|
|
281
|
+
|
|
282
|
+
| Priority | Item | Type |
|
|
283
|
+
|----------|------|------|
|
|
284
|
+
| **P1** | `distill --export` context recovery | New feature |
|
|
285
|
+
| **P2** | Command consolidation: `save`/`templates`/`use` → `template [save\|list\|use]` | UX cleanup |
|
|
286
|
+
| **P2** | Command consolidation: `effectiveness`/`merge-view` → subcommands of `insights` | UX cleanup |
|
|
287
|
+
| **P3** | `style` change trends ("specificity +12% this week") | Enhancement |
|
|
288
|
+
| **P4** | `distill --weights` signal transparency | Enhancement |
|
|
289
|
+
| **P5** | `compare --best-worst` auto-pick | Enhancement |
|
|
290
|
+
| **P5** | `--copy` as standard option on remaining commands | Consistency |
|
|
291
|
+
|
|
292
|
+
**Target: 27 → ~21 commands after consolidation. 1 new flag (`--export`), not 1 new command.**
|
|
293
|
+
|
|
294
|
+
## Testing Strategy
|
|
295
|
+
|
|
296
|
+
| Layer | Tests | What |
|
|
297
|
+
|-------|-------|------|
|
|
298
|
+
| Unit | ~20 | `generate_export()` with various DistillResult shapes (empty, single turn, many turns, no forward-looking, etc.) |
|
|
299
|
+
| Unit | ~10 | Per-signal score classification (semantic_shift dominant → Key Decisions, tool_trigger dominant → What Was Done) |
|
|
300
|
+
| Unit | ~5 | Forward-looking keyword detection (en + zh) |
|
|
301
|
+
| Unit | ~5 | `--weights` parsing and validation |
|
|
302
|
+
| Unit | ~5 | Token estimation accuracy |
|
|
303
|
+
| Integration | ~5 | `distill --export` end-to-end through CLI |
|
|
304
|
+
| Integration | ~3 | `--export --full` vs default comparison |
|
|
305
|
+
| Integration | ~2 | `--export --copy` clipboard integration |
|
|
306
|
+
| Unit | ~3 | Empty filtered_turns fallback behavior |
|
|
307
|
+
| Snapshot | ~3 | Golden file tests for export format stability (fixtures in `tests/fixtures/export/`) |
|
|
308
|
+
|
|
309
|
+
**~61 new tests. Target: 1298+ total (currently 1237).**
|
|
310
|
+
|
|
311
|
+
### Snapshot Test Strategy
|
|
312
|
+
|
|
313
|
+
Golden file fixtures live in `tests/fixtures/export/`. Each fixture is a `.md` file containing the expected export output for a specific DistillResult shape. Tests compare `generate_export()` output against these files. When the export format intentionally changes, fixtures are regenerated with `pytest --update-snapshots` (custom marker).
|
|
314
|
+
|
|
315
|
+
## Competitive Position
|
|
316
|
+
|
|
317
|
+
| Tool | What it does | How reprompt differs |
|
|
318
|
+
|------|-------------|---------------------|
|
|
319
|
+
| continues (`npx continues`) | Cross-tool session handoff (14 tools) | reprompt adds *importance scoring* — not all turns are equal |
|
|
320
|
+
| claude-session-restore | Rust-based extraction of everything | reprompt extracts *what matters*, not everything |
|
|
321
|
+
| open-mem | LLM-compressed tool outputs | reprompt is rule-based, zero-config, tool-agnostic |
|
|
322
|
+
| Cline Memory Bank | Persistent project memory across tasks | reprompt is retrospective analysis, not live state |
|
|
323
|
+
| Cognetivy | Structured prompt creation templates | Complementary: Cognetivy = before, reprompt = after |
|
|
324
|
+
|
|
325
|
+
**Unique value:** reprompt is the only tool that produces an importance-scored, research-calibrated, portable context recovery document from any AI coding session without requiring an LLM.
|
|
326
|
+
|
|
327
|
+
## Success Criteria
|
|
328
|
+
|
|
329
|
+
1. `reprompt distill --last 1 --export` produces a markdown document under 600 tokens for a typical 50-turn session
|
|
330
|
+
2. The document, when pasted into a new AI session, gives the model enough context to continue the previous task without the user re-explaining
|
|
331
|
+
3. Export format is stable (golden file tests prevent accidental changes)
|
|
332
|
+
4. Works with all 8 adapters that support `parse_conversation()`
|
|
333
|
+
|
|
334
|
+
## References
|
|
335
|
+
|
|
336
|
+
- Stanford "Lost in the Middle" (arXiv 2307.03172) — U-shaped attention, critical info at top/bottom
|
|
337
|
+
- "Don't Break the Cache" (arXiv 2601.06007) — stable prefixes for prompt caching
|
|
338
|
+
- Anthropic Context Engineering Guide — compaction + structured notes pattern
|
|
339
|
+
- OpenAI GPT-4.1 Prompting Guide — section ordering best practices
|
|
340
|
+
- Cline new_task tool — structured handoff format (Completed/Current/Next)
|
|
341
|
+
- td (marcus/td) — minimalist handoff: done/remaining/decisions/uncertain
|
|
342
|
+
- CONTINUITY (duke-of-beans) — decisions as first-class objects
|