agentpack-cli 0.3.21__tar.gz → 0.3.23__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.
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/PKG-INFO +44 -36
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/README.md +35 -33
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/pyproject.toml +11 -3
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/__init__.py +1 -1
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/ranking.py +258 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/role_inference.py +19 -1
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/application/pack_service.py +4 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/benchmark.py +962 -2
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/ci_cmd.py +10 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/workflow_cmd.py +215 -8
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/config.py +5 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/context_pack.py +872 -8
- agentpack_cli-0.3.23/src/agentpack/core/loop_protocol.py +873 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/collectors.py +23 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/models.py +11 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/renderers.py +8 -2
- agentpack_cli-0.3.21/src/agentpack/core/loop_protocol.py +0 -349
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/.gitignore +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/LICENSE +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/antigravity.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/base.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/claude.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/codex.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/cursor.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/detect.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/generic.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/windsurf.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/dependency_graph.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/go_imports.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/java_imports.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/js_ts_imports.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/monorepo.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/naming_signals.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/python_ast.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/python_imports.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/repo_map.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/rust_imports.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/symbols.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/task_classifier.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/tests.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/application/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/cli.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/_shared.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/claude_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/compress_output.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/dashboard.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/dev_check.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/diagnose_selection.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/diff.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/doctor.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/eval_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/explain.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/guard.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/hook_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/ignore_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/init.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/install.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/learn.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/mcp_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/memory.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/migrate.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/monitor.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/next_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/pack.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/perf.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/quickstart.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/release_check.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/release_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/repair.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/retrieve.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/route.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/scan.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/skills.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/start_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/state_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/stats.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/status.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/summarize.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/task_cmd.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/threads.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/tune.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/verify_wheel.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/watch.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/wrap.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/bootstrap.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/cache.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/changed_paths.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/diff.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/evals.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/execution_state.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/git.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/git_hooks.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/global_install.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/ignore.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/merkle.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/models.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/modes.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/pack_registry.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/redactor.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/scanner.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/snapshot.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/task_freshness.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/thread_context.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/token_estimator.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/data/agentpack.md +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/antigravity.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/claude.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/codex.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/cursor.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/windsurf.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/agents.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/git_hooks.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/global_install.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/platform.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/collector.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/extractor.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/feedback.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/lesson_ranker.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/models.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/provider.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/quality.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/renderers.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/skill_map.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/mcp_server.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/output_compression/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/output_compression/core.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/compact.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/markdown.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/receipts.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/discovery.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/models.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/parser.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/prompt_builder.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/scoring.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/service.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/skills_index.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/session/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/session/events.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/session/state.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/summaries/__init__.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/summaries/base.py +0 -0
- {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/summaries/offline.py +0 -0
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentpack-cli
|
|
3
|
-
Version: 0.3.
|
|
4
|
-
Summary: Local
|
|
3
|
+
Version: 0.3.23
|
|
4
|
+
Summary: Local context engine for AI coding agents that ranks relevant repo files and builds compact task-focused context packs for Claude Code, Codex, Cursor, Windsurf, MCP, and CI workflows.
|
|
5
|
+
Project-URL: Homepage, https://github.com/vishal2612200/agentpack
|
|
6
|
+
Project-URL: Documentation, https://vishal2612200.github.io/agentpack/
|
|
7
|
+
Project-URL: Repository, https://github.com/vishal2612200/agentpack
|
|
8
|
+
Project-URL: Issues, https://github.com/vishal2612200/agentpack/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/vishal2612200/agentpack/blob/main/CHANGELOG.md
|
|
5
10
|
License: MIT
|
|
6
11
|
License-File: LICENSE
|
|
7
|
-
Keywords: ai,ai-agent,ai-coding-agents,antigravity,ci,claude-code,codex,coding-agent,context,context-engine,context-packing,context-router,cursor,developer-tools,llm,mcp,mcp-context-engine,packing,prompt-context,reduce-token-usage,repo-analysis,repo-context,windsurf
|
|
12
|
+
Keywords: ai,ai-agent,ai-coding-agents,antigravity,ci,claude-code,codex,coding-agent,context,context-engine,context-packing,context-router,cursor,developer-tools,llm,local-first,mcp,mcp-context-engine,packing,prompt-context,reduce-token-usage,repo-analysis,repo-context,repo-map,task-focused-context,windsurf
|
|
8
13
|
Classifier: Development Status :: 3 - Alpha
|
|
9
14
|
Classifier: Intended Audience :: Developers
|
|
10
15
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -12,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
12
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
21
|
Classifier: Topic :: Software Development :: Build Tools
|
|
16
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
23
|
Requires-Python: >=3.10
|
|
@@ -49,9 +55,13 @@ Description-Content-Type: text/markdown
|
|
|
49
55
|
[](https://opensource.org/licenses/MIT)
|
|
50
56
|
[](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
|
|
51
57
|
|
|
52
|
-
**Local context
|
|
58
|
+
**Local context engine for AI coding agents.**
|
|
53
59
|
|
|
54
|
-
AgentPack
|
|
60
|
+
AgentPack ranks relevant repository files and builds compact task-focused context packs for Claude Code, Codex, Cursor, Windsurf, Antigravity, MCP tools, CI jobs, and markdown-based LLM workflows.
|
|
61
|
+
|
|
62
|
+
It runs local/offline repo analysis, compresses selected files into a token budget, and keeps context fresh through CLI commands, MCP tools, hooks, and agent integrations. Use it when an AI coding agent needs a ranked starting map instead of burning tool calls rediscovering your repo.
|
|
63
|
+
|
|
64
|
+
AgentPack is a context preparation tool, not a coding agent.
|
|
55
65
|
|
|
56
66
|
One workflow matters:
|
|
57
67
|
|
|
@@ -67,19 +77,20 @@ pipx run --spec agentpack-cli agentpack route --task "fix auth token expiry"
|
|
|
67
77
|
|
|
68
78
|

|
|
69
79
|
|
|
70
|
-
> **Status: alpha (v0.3.
|
|
80
|
+
> **Status: alpha (v0.3.23).** Works, tested, and used in real sessions. Python and JavaScript/TypeScript are the best-supported languages. Current benchmarks are useful regression checks, not broad proof that AgentPack improves coding-agent success. API may change before 1.0.
|
|
71
81
|
>
|
|
72
82
|
> **Platform note:** macOS, Linux, and Windows are supported. Windows support targets PowerShell plus Git for Windows. `cmd.exe` and bare Git setups are not a supported path yet.
|
|
73
83
|
>
|
|
74
84
|
> **Name note:** PyPI package is `agentpack-cli`, npm package is `@vishal2612200/agentpack`, and the command is `agentpack`. This project is unrelated to AgentPack dataset papers or other repos with the same name.
|
|
75
85
|
|
|
76
|
-
## What's New in 0.3.
|
|
86
|
+
## What's New in 0.3.23
|
|
77
87
|
|
|
78
|
-
`0.3.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
88
|
+
`0.3.23` is a guarded-loop hardening release. It keeps AgentPack's core promise
|
|
89
|
+
focused on local context and workflow evidence while making `agentpack work --run`
|
|
90
|
+
an optional proof harness around existing agents. The loop now has known runner
|
|
91
|
+
adapters, smoke checks, phase/diff/risk/acceptance artifacts, rollback patches,
|
|
92
|
+
metrics, and stricter finish gates. The prior expanded public-suite baseline
|
|
93
|
+
remains **66.0% recall / 51.1% token precision** across 108 scored public cases.
|
|
83
94
|
|
|
84
95
|
## Core Workflow
|
|
85
96
|
|
|
@@ -128,23 +139,21 @@ ranked but cut by budget, or absent from scan.
|
|
|
128
139
|
|
|
129
140
|
## Benchmark Proof
|
|
130
141
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
each commit.
|
|
134
|
-
commits across Python, TypeScript, Go, Java, and monorepo repos for broader
|
|
135
|
-
release runs.
|
|
142
|
+
Current local release-candidate table: expanded public-suite historical commits
|
|
143
|
+
across Python, TypeScript, Go, Java, and monorepo repos, scored against files
|
|
144
|
+
actually changed by each commit.
|
|
136
145
|
|
|
137
146
|
| Metric | Result |
|
|
138
147
|
|---|---:|
|
|
139
|
-
|
|
|
140
|
-
| Avg
|
|
141
|
-
|
|
|
142
|
-
| Pack
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
| Scored cases | 108 |
|
|
149
|
+
| Avg recall | 66.0% |
|
|
150
|
+
| Avg token precision | 51.1% |
|
|
151
|
+
| Pack p50 | 315 tokens |
|
|
152
|
+
| Pack p95 | 1,150 tokens |
|
|
153
|
+
|
|
154
|
+
Full local table: [`benchmarks/results/2026-06-13-public.md`](benchmarks/results/2026-06-13-public.md). This is scoped benchmark evidence, not a universal quality claim.
|
|
155
|
+
The latest published v0.3.20 table remains available at
|
|
156
|
+
[`benchmarks/results/2026-06-11-public.md`](benchmarks/results/2026-06-11-public.md).
|
|
148
157
|
Reproduce the expanded public suite:
|
|
149
158
|
|
|
150
159
|
```bash
|
|
@@ -153,20 +162,19 @@ agentpack benchmark --public-suite --reproduce v0.3.20
|
|
|
153
162
|
|
|
154
163
|
Benchmark methodology lives under [`benchmarks/results/v0.3.20/`](benchmarks/results/v0.3.20/methodology.md).
|
|
155
164
|
|
|
156
|
-
###
|
|
165
|
+
### Release Benchmark Gate
|
|
157
166
|
|
|
158
|
-
The
|
|
159
|
-
|
|
160
|
-
while keeping token precision at **50%+**. The target should be measured on the
|
|
167
|
+
The current local release-candidate result clears the target: **66.0% recall**
|
|
168
|
+
and **51.1% token precision**. The target should continue to be measured on the
|
|
161
169
|
same 100+ public historical-commit suite, with per-language slices published so
|
|
162
|
-
|
|
170
|
+
aggregate gains are not hiding TypeScript, Go, Java, or monorepo regressions.
|
|
163
171
|
|
|
164
172
|
Decision gate for the next public table:
|
|
165
173
|
|
|
166
174
|
- full-suite recall is at least 65.0%
|
|
167
|
-
- full-suite token precision is at least
|
|
175
|
+
- full-suite token precision is at least 51.0%
|
|
168
176
|
- no major language or task slice loses more than 2 recall points
|
|
169
|
-
- Vite/TypeScript, Gin/Go, and NestJS monorepo misses are reported separately
|
|
177
|
+
- Vite/TypeScript, Gin/Go, Click/Python, and NestJS monorepo misses are reported separately
|
|
170
178
|
- any AgentPack-vs-no-AgentPack A/B claim includes task success, tool calls,
|
|
171
179
|
token cost, and time-to-first-correct-file
|
|
172
180
|
|
|
@@ -182,7 +190,7 @@ and [`docs/data-flow.md`](docs/data-flow.md).
|
|
|
182
190
|
Start with the [docs index](docs/index.md), or jump to guides for
|
|
183
191
|
[Claude Code](docs/claude-code-context-engine.md), [MCP](docs/mcp-context-engine.md),
|
|
184
192
|
[Cursor](docs/cursor-context-packing.md), [token usage](docs/reduce-claude-code-token-usage.md),
|
|
185
|
-
and [how AgentPack works](docs/how-agentpack-works.md).
|
|
193
|
+
[AI coding agent context](docs/ai-coding-agent-context.md), and [how AgentPack works](docs/how-agentpack-works.md).
|
|
186
194
|
|
|
187
195
|
## Install
|
|
188
196
|
|
|
@@ -191,7 +199,7 @@ pipx install agentpack-cli
|
|
|
191
199
|
agentpack --version
|
|
192
200
|
```
|
|
193
201
|
|
|
194
|
-
Requires Python 3.10
|
|
202
|
+
Requires Python 3.10+ and is tested on Python 3.10-3.14. The PyPI package is `agentpack-cli`; the command is `agentpack`. Use `pipx` for normal installs because many macOS/Linux Python distributions block global `pip install` with PEP 668's `externally-managed-environment` error. If you prefer `pip`, install inside a virtual environment.
|
|
195
203
|
|
|
196
204
|
Install `pipx` first if needed:
|
|
197
205
|
|
|
@@ -238,7 +246,7 @@ agentpack status
|
|
|
238
246
|
agentpack finish --since main
|
|
239
247
|
```
|
|
240
248
|
|
|
241
|
-
Use `agentpack quickstart --task "..." --write` when you want AgentPack to print the next commands and write the task file for you. Use `agentpack start "..." --pack-only` when you want only a fresh pack and not the guard path.
|
|
249
|
+
Use `agentpack quickstart --task "..." --write` when you want AgentPack to print the next commands and write the task file for you. Use `agentpack start "..." --pack-only` when you want only a fresh pack and not the guard path. Optional guardrail: `agentpack work --run` is a proof harness around existing agents, not AgentPack's default workflow or an autonomous coding agent.
|
|
242
250
|
|
|
243
251
|
### Learn from AI-assisted work
|
|
244
252
|
|
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
9
|
[](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
|
|
10
10
|
|
|
11
|
-
**Local context
|
|
11
|
+
**Local context engine for AI coding agents.**
|
|
12
12
|
|
|
13
|
-
AgentPack
|
|
13
|
+
AgentPack ranks relevant repository files and builds compact task-focused context packs for Claude Code, Codex, Cursor, Windsurf, Antigravity, MCP tools, CI jobs, and markdown-based LLM workflows.
|
|
14
|
+
|
|
15
|
+
It runs local/offline repo analysis, compresses selected files into a token budget, and keeps context fresh through CLI commands, MCP tools, hooks, and agent integrations. Use it when an AI coding agent needs a ranked starting map instead of burning tool calls rediscovering your repo.
|
|
16
|
+
|
|
17
|
+
AgentPack is a context preparation tool, not a coding agent.
|
|
14
18
|
|
|
15
19
|
One workflow matters:
|
|
16
20
|
|
|
@@ -26,19 +30,20 @@ pipx run --spec agentpack-cli agentpack route --task "fix auth token expiry"
|
|
|
26
30
|
|
|
27
31
|

|
|
28
32
|
|
|
29
|
-
> **Status: alpha (v0.3.
|
|
33
|
+
> **Status: alpha (v0.3.23).** Works, tested, and used in real sessions. Python and JavaScript/TypeScript are the best-supported languages. Current benchmarks are useful regression checks, not broad proof that AgentPack improves coding-agent success. API may change before 1.0.
|
|
30
34
|
>
|
|
31
35
|
> **Platform note:** macOS, Linux, and Windows are supported. Windows support targets PowerShell plus Git for Windows. `cmd.exe` and bare Git setups are not a supported path yet.
|
|
32
36
|
>
|
|
33
37
|
> **Name note:** PyPI package is `agentpack-cli`, npm package is `@vishal2612200/agentpack`, and the command is `agentpack`. This project is unrelated to AgentPack dataset papers or other repos with the same name.
|
|
34
38
|
|
|
35
|
-
## What's New in 0.3.
|
|
39
|
+
## What's New in 0.3.23
|
|
36
40
|
|
|
37
|
-
`0.3.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
`0.3.23` is a guarded-loop hardening release. It keeps AgentPack's core promise
|
|
42
|
+
focused on local context and workflow evidence while making `agentpack work --run`
|
|
43
|
+
an optional proof harness around existing agents. The loop now has known runner
|
|
44
|
+
adapters, smoke checks, phase/diff/risk/acceptance artifacts, rollback patches,
|
|
45
|
+
metrics, and stricter finish gates. The prior expanded public-suite baseline
|
|
46
|
+
remains **66.0% recall / 51.1% token precision** across 108 scored public cases.
|
|
42
47
|
|
|
43
48
|
## Core Workflow
|
|
44
49
|
|
|
@@ -87,23 +92,21 @@ ranked but cut by budget, or absent from scan.
|
|
|
87
92
|
|
|
88
93
|
## Benchmark Proof
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
each commit.
|
|
93
|
-
commits across Python, TypeScript, Go, Java, and monorepo repos for broader
|
|
94
|
-
release runs.
|
|
95
|
+
Current local release-candidate table: expanded public-suite historical commits
|
|
96
|
+
across Python, TypeScript, Go, Java, and monorepo repos, scored against files
|
|
97
|
+
actually changed by each commit.
|
|
95
98
|
|
|
96
99
|
| Metric | Result |
|
|
97
100
|
|---|---:|
|
|
98
|
-
|
|
|
99
|
-
| Avg
|
|
100
|
-
|
|
|
101
|
-
| Pack
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
| Scored cases | 108 |
|
|
102
|
+
| Avg recall | 66.0% |
|
|
103
|
+
| Avg token precision | 51.1% |
|
|
104
|
+
| Pack p50 | 315 tokens |
|
|
105
|
+
| Pack p95 | 1,150 tokens |
|
|
106
|
+
|
|
107
|
+
Full local table: [`benchmarks/results/2026-06-13-public.md`](benchmarks/results/2026-06-13-public.md). This is scoped benchmark evidence, not a universal quality claim.
|
|
108
|
+
The latest published v0.3.20 table remains available at
|
|
109
|
+
[`benchmarks/results/2026-06-11-public.md`](benchmarks/results/2026-06-11-public.md).
|
|
107
110
|
Reproduce the expanded public suite:
|
|
108
111
|
|
|
109
112
|
```bash
|
|
@@ -112,20 +115,19 @@ agentpack benchmark --public-suite --reproduce v0.3.20
|
|
|
112
115
|
|
|
113
116
|
Benchmark methodology lives under [`benchmarks/results/v0.3.20/`](benchmarks/results/v0.3.20/methodology.md).
|
|
114
117
|
|
|
115
|
-
###
|
|
118
|
+
### Release Benchmark Gate
|
|
116
119
|
|
|
117
|
-
The
|
|
118
|
-
|
|
119
|
-
while keeping token precision at **50%+**. The target should be measured on the
|
|
120
|
+
The current local release-candidate result clears the target: **66.0% recall**
|
|
121
|
+
and **51.1% token precision**. The target should continue to be measured on the
|
|
120
122
|
same 100+ public historical-commit suite, with per-language slices published so
|
|
121
|
-
|
|
123
|
+
aggregate gains are not hiding TypeScript, Go, Java, or monorepo regressions.
|
|
122
124
|
|
|
123
125
|
Decision gate for the next public table:
|
|
124
126
|
|
|
125
127
|
- full-suite recall is at least 65.0%
|
|
126
|
-
- full-suite token precision is at least
|
|
128
|
+
- full-suite token precision is at least 51.0%
|
|
127
129
|
- no major language or task slice loses more than 2 recall points
|
|
128
|
-
- Vite/TypeScript, Gin/Go, and NestJS monorepo misses are reported separately
|
|
130
|
+
- Vite/TypeScript, Gin/Go, Click/Python, and NestJS monorepo misses are reported separately
|
|
129
131
|
- any AgentPack-vs-no-AgentPack A/B claim includes task success, tool calls,
|
|
130
132
|
token cost, and time-to-first-correct-file
|
|
131
133
|
|
|
@@ -141,7 +143,7 @@ and [`docs/data-flow.md`](docs/data-flow.md).
|
|
|
141
143
|
Start with the [docs index](docs/index.md), or jump to guides for
|
|
142
144
|
[Claude Code](docs/claude-code-context-engine.md), [MCP](docs/mcp-context-engine.md),
|
|
143
145
|
[Cursor](docs/cursor-context-packing.md), [token usage](docs/reduce-claude-code-token-usage.md),
|
|
144
|
-
and [how AgentPack works](docs/how-agentpack-works.md).
|
|
146
|
+
[AI coding agent context](docs/ai-coding-agent-context.md), and [how AgentPack works](docs/how-agentpack-works.md).
|
|
145
147
|
|
|
146
148
|
## Install
|
|
147
149
|
|
|
@@ -150,7 +152,7 @@ pipx install agentpack-cli
|
|
|
150
152
|
agentpack --version
|
|
151
153
|
```
|
|
152
154
|
|
|
153
|
-
Requires Python 3.10
|
|
155
|
+
Requires Python 3.10+ and is tested on Python 3.10-3.14. The PyPI package is `agentpack-cli`; the command is `agentpack`. Use `pipx` for normal installs because many macOS/Linux Python distributions block global `pip install` with PEP 668's `externally-managed-environment` error. If you prefer `pip`, install inside a virtual environment.
|
|
154
156
|
|
|
155
157
|
Install `pipx` first if needed:
|
|
156
158
|
|
|
@@ -197,7 +199,7 @@ agentpack status
|
|
|
197
199
|
agentpack finish --since main
|
|
198
200
|
```
|
|
199
201
|
|
|
200
|
-
Use `agentpack quickstart --task "..." --write` when you want AgentPack to print the next commands and write the task file for you. Use `agentpack start "..." --pack-only` when you want only a fresh pack and not the guard path.
|
|
202
|
+
Use `agentpack quickstart --task "..." --write` when you want AgentPack to print the next commands and write the task file for you. Use `agentpack start "..." --pack-only` when you want only a fresh pack and not the guard path. Optional guardrail: `agentpack work --run` is a proof harness around existing agents, not AgentPack's default workflow or an autonomous coding agent.
|
|
201
203
|
|
|
202
204
|
### Learn from AI-assisted work
|
|
203
205
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentpack-cli"
|
|
3
|
-
version = "0.3.
|
|
4
|
-
description = "Local
|
|
3
|
+
version = "0.3.23"
|
|
4
|
+
description = "Local context engine for AI coding agents that ranks relevant repo files and builds compact task-focused context packs for Claude Code, Codex, Cursor, Windsurf, MCP, and CI workflows."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
license = {text = "MIT"}
|
|
8
|
-
keywords = ["ai-coding-agents", "coding-agent", "ai-agent", "claude-code", "developer-tools", "repo-analysis", "repo-context", "context-engine", "mcp-context-engine", "context-router", "context-packing", "prompt-context", "reduce-token-usage", "mcp", "ci", "codex", "cursor", "windsurf", "antigravity", "ai", "llm", "context", "packing"]
|
|
8
|
+
keywords = ["ai-coding-agents", "coding-agent", "ai-agent", "claude-code", "developer-tools", "repo-analysis", "repo-context", "context-engine", "mcp-context-engine", "context-router", "context-packing", "prompt-context", "task-focused-context", "reduce-token-usage", "local-first", "repo-map", "mcp", "ci", "codex", "cursor", "windsurf", "antigravity", "ai", "llm", "context", "packing"]
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Development Status :: 3 - Alpha",
|
|
11
11
|
"Intended Audience :: Developers",
|
|
@@ -14,6 +14,7 @@ classifiers = [
|
|
|
14
14
|
"Programming Language :: Python :: 3.11",
|
|
15
15
|
"Programming Language :: Python :: 3.12",
|
|
16
16
|
"Programming Language :: Python :: 3.13",
|
|
17
|
+
"Programming Language :: Python :: 3.14",
|
|
17
18
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
18
19
|
"Topic :: Software Development :: Build Tools",
|
|
19
20
|
]
|
|
@@ -28,6 +29,13 @@ dependencies = [
|
|
|
28
29
|
"tomli>=2.0.0; python_version < '3.11'"
|
|
29
30
|
]
|
|
30
31
|
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/vishal2612200/agentpack"
|
|
34
|
+
Documentation = "https://vishal2612200.github.io/agentpack/"
|
|
35
|
+
Repository = "https://github.com/vishal2612200/agentpack"
|
|
36
|
+
Issues = "https://github.com/vishal2612200/agentpack/issues"
|
|
37
|
+
Changelog = "https://github.com/vishal2612200/agentpack/blob/main/CHANGELOG.md"
|
|
38
|
+
|
|
31
39
|
[project.scripts]
|
|
32
40
|
agentpack = "agentpack.cli:app"
|
|
33
41
|
|
|
@@ -1160,6 +1160,149 @@ def _domain_tokens(path: str) -> set[str]:
|
|
|
1160
1160
|
return {tok for tok in _path_tokens(path) if len(tok) >= 3 and tok not in _PATH_NOISE_TOKENS}
|
|
1161
1161
|
|
|
1162
1162
|
|
|
1163
|
+
def _api_route_terms(path: str) -> tuple[str, ...]:
|
|
1164
|
+
parts = [part.lower() for part in Path(path).parts]
|
|
1165
|
+
if "api" not in parts:
|
|
1166
|
+
return ()
|
|
1167
|
+
api_index = parts.index("api")
|
|
1168
|
+
suffix = parts[api_index + 1:]
|
|
1169
|
+
if not suffix:
|
|
1170
|
+
return ()
|
|
1171
|
+
route_file_names = {
|
|
1172
|
+
"route.ts", "route.tsx", "route.js", "route.jsx",
|
|
1173
|
+
"routes.py", "urls.py", "views.py", "controller.ts", "controller.js",
|
|
1174
|
+
}
|
|
1175
|
+
if suffix[-1] in route_file_names or Path(suffix[-1]).stem.lower() in {"route", "routes", "urls", "views", "controller"}:
|
|
1176
|
+
suffix = suffix[:-1]
|
|
1177
|
+
terms: list[str] = []
|
|
1178
|
+
for part in suffix:
|
|
1179
|
+
clean = part.strip("[](){}")
|
|
1180
|
+
if not clean or clean.startswith("_"):
|
|
1181
|
+
continue
|
|
1182
|
+
terms.extend(token for token in _ordered_tokens(clean) if token and token not in _PATH_NOISE_TOKENS)
|
|
1183
|
+
return tuple(dict.fromkeys(terms))
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
def _is_api_route_path(path: str) -> bool:
|
|
1187
|
+
return bool(_api_route_terms(path))
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
def _api_route_label(path: str) -> str:
|
|
1191
|
+
terms = _api_route_terms(path)
|
|
1192
|
+
return "/api/" + "/".join(terms) if terms else path
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
def _normalize_api_path(value: str) -> str | None:
|
|
1196
|
+
match = re.search(r"/api/[A-Za-z0-9_./${}\[\]-]+", value)
|
|
1197
|
+
if not match:
|
|
1198
|
+
return None
|
|
1199
|
+
path = match.group(0).split("?", 1)[0].split("#", 1)[0].split("${", 1)[0]
|
|
1200
|
+
path = re.sub(r"/\[[^\]]+\]", "", path)
|
|
1201
|
+
path = path.rstrip("/,;)")
|
|
1202
|
+
return path.rstrip("/") or "/api"
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
def _api_paths_from_summary(summary_data: object | None) -> set[str]:
|
|
1206
|
+
paths: set[str] = set()
|
|
1207
|
+
if summary_data is None:
|
|
1208
|
+
return paths
|
|
1209
|
+
for summary_field in ("calls", "entrypoints", "public_api"):
|
|
1210
|
+
for value in _summary_values(summary_data, summary_field):
|
|
1211
|
+
normalized = _normalize_api_path(value)
|
|
1212
|
+
if normalized:
|
|
1213
|
+
paths.add(normalized)
|
|
1214
|
+
return paths
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
def _api_path_terms(api_path: str) -> set[str]:
|
|
1218
|
+
return {
|
|
1219
|
+
token
|
|
1220
|
+
for token in _ordered_tokens(api_path.removeprefix("/api/"))
|
|
1221
|
+
if token and token not in _PATH_NOISE_TOKENS
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
def _api_route_path(path: str, summary_data: object | None = None) -> str | None:
|
|
1226
|
+
for value in _summary_values(summary_data, "entrypoints"):
|
|
1227
|
+
normalized = _normalize_api_path(value)
|
|
1228
|
+
if normalized:
|
|
1229
|
+
return normalized
|
|
1230
|
+
terms = _api_route_terms(path)
|
|
1231
|
+
if terms:
|
|
1232
|
+
return "/api/" + "/".join(terms)
|
|
1233
|
+
return None
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
def _looks_like_frontend_consumer(path: str, summary_data: object | None) -> bool:
|
|
1237
|
+
suffix = Path(path).suffix.lower()
|
|
1238
|
+
if suffix in {".tsx", ".jsx"}:
|
|
1239
|
+
return True
|
|
1240
|
+
path_terms = _path_tokens(path)
|
|
1241
|
+
if path_terms & {"component", "components", "page", "pages", "client", "dashboard"}:
|
|
1242
|
+
return True
|
|
1243
|
+
return any(
|
|
1244
|
+
value.startswith(("React page:", "React layout:", "React component:"))
|
|
1245
|
+
for value in _summary_values(summary_data, "entrypoints")
|
|
1246
|
+
)
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
def _has_strong_structural_reason(reasons: list[str]) -> bool:
|
|
1250
|
+
return any(
|
|
1251
|
+
reason.startswith((
|
|
1252
|
+
"API endpoint pair",
|
|
1253
|
+
"API route owner match",
|
|
1254
|
+
"direct content evidence",
|
|
1255
|
+
"direct dependency",
|
|
1256
|
+
"historically co-changed",
|
|
1257
|
+
"keyword phrase match:",
|
|
1258
|
+
"literal definition match:",
|
|
1259
|
+
"matched call:",
|
|
1260
|
+
"matched define:",
|
|
1261
|
+
"matched entrypoint:",
|
|
1262
|
+
"multi-token",
|
|
1263
|
+
"quoted literal match:",
|
|
1264
|
+
"recall neighbor",
|
|
1265
|
+
"reverse dependency",
|
|
1266
|
+
"test for",
|
|
1267
|
+
"workspace match",
|
|
1268
|
+
))
|
|
1269
|
+
or reason in {
|
|
1270
|
+
"build/dependency metadata",
|
|
1271
|
+
"config file",
|
|
1272
|
+
"has related tests",
|
|
1273
|
+
"knowledge/architecture doc",
|
|
1274
|
+
"release/version metadata",
|
|
1275
|
+
}
|
|
1276
|
+
for reason in reasons
|
|
1277
|
+
)
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
def _keyword_only_false_positive(path: str, reasons: list[str], content_hits: int) -> bool:
|
|
1281
|
+
if _is_test_file(path):
|
|
1282
|
+
return False
|
|
1283
|
+
if _has_strong_structural_reason(reasons):
|
|
1284
|
+
return False
|
|
1285
|
+
keyword_reasons = [
|
|
1286
|
+
reason for reason in reasons
|
|
1287
|
+
if reason == "filename keyword match"
|
|
1288
|
+
or reason == "symbol keyword match"
|
|
1289
|
+
or reason.startswith((
|
|
1290
|
+
"content keyword match",
|
|
1291
|
+
"matched domain:",
|
|
1292
|
+
"matched naming keyword:",
|
|
1293
|
+
"matched ranking keyword:",
|
|
1294
|
+
"matched role keyword:",
|
|
1295
|
+
))
|
|
1296
|
+
]
|
|
1297
|
+
if len(keyword_reasons) < 2:
|
|
1298
|
+
return False
|
|
1299
|
+
if _is_api_route_path(path):
|
|
1300
|
+
return False
|
|
1301
|
+
if content_hits >= 4 and "symbol keyword match" in reasons:
|
|
1302
|
+
return False
|
|
1303
|
+
return True
|
|
1304
|
+
|
|
1305
|
+
|
|
1163
1306
|
def score_files(
|
|
1164
1307
|
files: list[FileInfo],
|
|
1165
1308
|
changed_paths: set[str],
|
|
@@ -1296,6 +1439,12 @@ def score_files(
|
|
|
1296
1439
|
score += min(-6.0, w.weak_filename_match_penalty / 2)
|
|
1297
1440
|
reasons.append(f"generic public API penalty: {generic_public_names[0]}")
|
|
1298
1441
|
|
|
1442
|
+
api_route_terms = set(_api_route_terms(fi.path))
|
|
1443
|
+
api_route_matches = api_route_terms & (set(_keyword_token_weights(keywords, path=fi.path)) - _PATH_NOISE_TOKENS)
|
|
1444
|
+
if api_route_matches:
|
|
1445
|
+
score += 170.0 + (35.0 * min(2, len(api_route_matches) - 1))
|
|
1446
|
+
reasons.append(f"API route owner match: {_api_route_label(fi.path)}")
|
|
1447
|
+
|
|
1299
1448
|
content_hits = 0
|
|
1300
1449
|
searchable_text = ""
|
|
1301
1450
|
if fi.content is not None:
|
|
@@ -1368,6 +1517,8 @@ def score_files(
|
|
|
1368
1517
|
if matched_task_signal and _has_role(fi.path, _IMPLEMENTATION_ROLE_TOKENS):
|
|
1369
1518
|
score += w.implementation_role
|
|
1370
1519
|
reasons.append("implementation role match")
|
|
1520
|
+
elif fi.path in changed_paths:
|
|
1521
|
+
reasons.append("modified workspace context only")
|
|
1371
1522
|
|
|
1372
1523
|
if explicit_test_task:
|
|
1373
1524
|
if _is_test_file(fi.path):
|
|
@@ -1397,6 +1548,8 @@ def score_files(
|
|
|
1397
1548
|
if tests and any(t in all_paths for t in tests):
|
|
1398
1549
|
score += w.related_test
|
|
1399
1550
|
reasons.append("has related tests")
|
|
1551
|
+
elif _is_api_route_path(fi.path):
|
|
1552
|
+
reasons.append("no direct tests found for endpoint")
|
|
1400
1553
|
|
|
1401
1554
|
if _is_test_file(fi.path):
|
|
1402
1555
|
for src_path in changed_paths:
|
|
@@ -1460,6 +1613,10 @@ def score_files(
|
|
|
1460
1613
|
score += w.large_unrelated_penalty
|
|
1461
1614
|
reasons.append("large unrelated file")
|
|
1462
1615
|
|
|
1616
|
+
if _keyword_only_false_positive(fi.path, reasons, content_hits):
|
|
1617
|
+
score = max(0.0, score * 0.72)
|
|
1618
|
+
reasons.append("likely false positive: keyword-only match")
|
|
1619
|
+
|
|
1463
1620
|
results.append((fi, score, reasons))
|
|
1464
1621
|
|
|
1465
1622
|
return results
|
|
@@ -1507,6 +1664,107 @@ def boost_cross_layer_related(
|
|
|
1507
1664
|
return result
|
|
1508
1665
|
|
|
1509
1666
|
|
|
1667
|
+
def boost_api_endpoint_pairs(
|
|
1668
|
+
scored: list[tuple[FileInfo, float, list[str]]],
|
|
1669
|
+
keywords: set[str] | dict[str, float] | KeywordPlan,
|
|
1670
|
+
weights: ScoringWeights | None = None,
|
|
1671
|
+
) -> list[tuple[FileInfo, float, list[str]]]:
|
|
1672
|
+
"""Boost sibling API endpoints once one endpoint in the family is a strong task match."""
|
|
1673
|
+
w = weights or _DEFAULT_WEIGHTS
|
|
1674
|
+
keyword_tokens = set(_keyword_token_weights(keywords)) - _PATH_NOISE_TOKENS
|
|
1675
|
+
api_rows: list[tuple[FileInfo, float, list[str], tuple[str, ...]]] = []
|
|
1676
|
+
for fi, score, reasons in scored:
|
|
1677
|
+
terms = _api_route_terms(fi.path)
|
|
1678
|
+
if terms and not fi.ignored and not fi.binary:
|
|
1679
|
+
api_rows.append((fi, score, reasons, terms))
|
|
1680
|
+
if len(api_rows) < 2:
|
|
1681
|
+
return scored
|
|
1682
|
+
|
|
1683
|
+
seeds: dict[str, tuple[str, float]] = {}
|
|
1684
|
+
for fi, score, reasons, terms in api_rows:
|
|
1685
|
+
if not terms:
|
|
1686
|
+
continue
|
|
1687
|
+
family = terms[0]
|
|
1688
|
+
direct_owner = any(reason.startswith("API route owner match:") for reason in reasons)
|
|
1689
|
+
endpoint_matches_task = bool(set(terms) & keyword_tokens)
|
|
1690
|
+
if score < 90 and not direct_owner:
|
|
1691
|
+
continue
|
|
1692
|
+
if not (direct_owner or endpoint_matches_task):
|
|
1693
|
+
continue
|
|
1694
|
+
current = seeds.get(family)
|
|
1695
|
+
if current is None or score > current[1]:
|
|
1696
|
+
seeds[family] = (fi.path, score)
|
|
1697
|
+
if not seeds:
|
|
1698
|
+
return scored
|
|
1699
|
+
|
|
1700
|
+
result: list[tuple[FileInfo, float, list[str]]] = []
|
|
1701
|
+
for fi, score, reasons in scored:
|
|
1702
|
+
terms = _api_route_terms(fi.path)
|
|
1703
|
+
if terms:
|
|
1704
|
+
family = terms[0]
|
|
1705
|
+
seed = seeds.get(family)
|
|
1706
|
+
if seed and seed[0] != fi.path and not any(reason.startswith("API endpoint pair") for reason in reasons):
|
|
1707
|
+
seed_path, _seed_score = seed
|
|
1708
|
+
amount = min(85.0, w.cross_layer_related + 15.0)
|
|
1709
|
+
if set(terms) & keyword_tokens:
|
|
1710
|
+
amount += 25.0
|
|
1711
|
+
score += amount
|
|
1712
|
+
reasons = reasons + [f"API endpoint pair with {_api_route_label(seed_path)}"]
|
|
1713
|
+
result.append((fi, score, reasons))
|
|
1714
|
+
return result
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
def boost_frontend_api_consumers(
|
|
1718
|
+
scored: list[tuple[FileInfo, float, list[str]]],
|
|
1719
|
+
summaries: dict[str, Any] | None,
|
|
1720
|
+
keywords: set[str] | dict[str, float] | KeywordPlan,
|
|
1721
|
+
weights: ScoringWeights | None = None,
|
|
1722
|
+
) -> list[tuple[FileInfo, float, list[str]]]:
|
|
1723
|
+
"""Boost API route files consumed by scored frontend/client files."""
|
|
1724
|
+
if not summaries:
|
|
1725
|
+
return scored
|
|
1726
|
+
w = weights or _DEFAULT_WEIGHTS
|
|
1727
|
+
keyword_tokens = set(_keyword_token_weights(keywords)) - _PATH_NOISE_TOKENS
|
|
1728
|
+
endpoint_by_api_path: dict[str, str] = {}
|
|
1729
|
+
for fi, _score, _reasons in scored:
|
|
1730
|
+
api_path = _api_route_path(fi.path, summaries.get(fi.path))
|
|
1731
|
+
if api_path:
|
|
1732
|
+
endpoint_by_api_path[api_path] = fi.path
|
|
1733
|
+
if not endpoint_by_api_path:
|
|
1734
|
+
return scored
|
|
1735
|
+
|
|
1736
|
+
boosts: dict[str, tuple[float, str, str]] = {}
|
|
1737
|
+
for consumer, consumer_score, _consumer_reasons in scored:
|
|
1738
|
+
summary_data = summaries.get(consumer.path)
|
|
1739
|
+
consumed_paths = _api_paths_from_summary(summary_data)
|
|
1740
|
+
if not consumed_paths or consumer_score <= 0:
|
|
1741
|
+
continue
|
|
1742
|
+
if not _looks_like_frontend_consumer(consumer.path, summary_data):
|
|
1743
|
+
continue
|
|
1744
|
+
for api_path in consumed_paths:
|
|
1745
|
+
endpoint_path = endpoint_by_api_path.get(api_path)
|
|
1746
|
+
if not endpoint_path or endpoint_path == consumer.path:
|
|
1747
|
+
continue
|
|
1748
|
+
amount = min(150.0, 90.0 + (w.cross_layer_related * 0.6))
|
|
1749
|
+
if _api_path_terms(api_path) & keyword_tokens:
|
|
1750
|
+
amount += 45.0
|
|
1751
|
+
current = boosts.get(endpoint_path)
|
|
1752
|
+
if current is None or amount > current[0]:
|
|
1753
|
+
boosts[endpoint_path] = (amount, api_path, consumer.path)
|
|
1754
|
+
|
|
1755
|
+
if not boosts:
|
|
1756
|
+
return scored
|
|
1757
|
+
result: list[tuple[FileInfo, float, list[str]]] = []
|
|
1758
|
+
for fi, score, reasons in scored:
|
|
1759
|
+
boost = boosts.get(fi.path)
|
|
1760
|
+
if boost:
|
|
1761
|
+
amount, api_path, consumer_path = boost
|
|
1762
|
+
score += amount
|
|
1763
|
+
reasons = reasons + [f"API producer for frontend call {api_path} from {consumer_path}"]
|
|
1764
|
+
result.append((fi, score, reasons))
|
|
1765
|
+
return result
|
|
1766
|
+
|
|
1767
|
+
|
|
1510
1768
|
def boost_paired_tests(
|
|
1511
1769
|
scored: list[tuple[FileInfo, float, list[str]]],
|
|
1512
1770
|
weights: ScoringWeights | None = None,
|