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.
Files changed (154) hide show
  1. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/PKG-INFO +44 -36
  2. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/README.md +35 -33
  3. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/pyproject.toml +11 -3
  4. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/__init__.py +1 -1
  5. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/ranking.py +258 -0
  6. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/role_inference.py +19 -1
  7. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/application/pack_service.py +4 -0
  8. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/benchmark.py +962 -2
  9. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/ci_cmd.py +10 -0
  10. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/workflow_cmd.py +215 -8
  11. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/config.py +5 -0
  12. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/context_pack.py +872 -8
  13. agentpack_cli-0.3.23/src/agentpack/core/loop_protocol.py +873 -0
  14. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/collectors.py +23 -0
  15. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/models.py +11 -0
  16. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/renderers.py +8 -2
  17. agentpack_cli-0.3.21/src/agentpack/core/loop_protocol.py +0 -349
  18. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/.gitignore +0 -0
  19. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/LICENSE +0 -0
  20. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/__init__.py +0 -0
  21. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/antigravity.py +0 -0
  22. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/base.py +0 -0
  23. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/claude.py +0 -0
  24. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/codex.py +0 -0
  25. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/cursor.py +0 -0
  26. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/detect.py +0 -0
  27. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/generic.py +0 -0
  28. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/adapters/windsurf.py +0 -0
  29. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/__init__.py +0 -0
  30. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/dependency_graph.py +0 -0
  31. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/go_imports.py +0 -0
  32. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/java_imports.py +0 -0
  33. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/js_ts_imports.py +0 -0
  34. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/monorepo.py +0 -0
  35. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/naming_signals.py +0 -0
  36. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/python_ast.py +0 -0
  37. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/python_imports.py +0 -0
  38. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/repo_map.py +0 -0
  39. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/rust_imports.py +0 -0
  40. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/symbols.py +0 -0
  41. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/task_classifier.py +0 -0
  42. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/analysis/tests.py +0 -0
  43. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/application/__init__.py +0 -0
  44. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/cli.py +0 -0
  45. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/__init__.py +0 -0
  46. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/_shared.py +0 -0
  47. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/claude_cmd.py +0 -0
  48. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/compress_output.py +0 -0
  49. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/dashboard.py +0 -0
  50. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/dev_check.py +0 -0
  51. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/diagnose_selection.py +0 -0
  52. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/diff.py +0 -0
  53. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/doctor.py +0 -0
  54. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/eval_cmd.py +0 -0
  55. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/explain.py +0 -0
  56. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/guard.py +0 -0
  57. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/hook_cmd.py +0 -0
  58. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/ignore_cmd.py +0 -0
  59. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/init.py +0 -0
  60. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/install.py +0 -0
  61. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/learn.py +0 -0
  62. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/mcp_cmd.py +0 -0
  63. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/memory.py +0 -0
  64. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/migrate.py +0 -0
  65. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/monitor.py +0 -0
  66. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/next_cmd.py +0 -0
  67. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/pack.py +0 -0
  68. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/perf.py +0 -0
  69. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/quickstart.py +0 -0
  70. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/release_check.py +0 -0
  71. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/release_cmd.py +0 -0
  72. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/repair.py +0 -0
  73. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/retrieve.py +0 -0
  74. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/route.py +0 -0
  75. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/scan.py +0 -0
  76. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/skills.py +0 -0
  77. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/start_cmd.py +0 -0
  78. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/state_cmd.py +0 -0
  79. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/stats.py +0 -0
  80. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/status.py +0 -0
  81. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/summarize.py +0 -0
  82. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/task_cmd.py +0 -0
  83. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/threads.py +0 -0
  84. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/tune.py +0 -0
  85. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/verify_wheel.py +0 -0
  86. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/watch.py +0 -0
  87. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/commands/wrap.py +0 -0
  88. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/__init__.py +0 -0
  89. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/bootstrap.py +0 -0
  90. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/cache.py +0 -0
  91. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/changed_paths.py +0 -0
  92. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/diff.py +0 -0
  93. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/evals.py +0 -0
  94. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/execution_state.py +0 -0
  95. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/git.py +0 -0
  96. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/git_hooks.py +0 -0
  97. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/global_install.py +0 -0
  98. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/ignore.py +0 -0
  99. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/merkle.py +0 -0
  100. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/models.py +0 -0
  101. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/modes.py +0 -0
  102. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/pack_registry.py +0 -0
  103. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/redactor.py +0 -0
  104. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/scanner.py +0 -0
  105. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/snapshot.py +0 -0
  106. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/task_freshness.py +0 -0
  107. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/thread_context.py +0 -0
  108. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/token_estimator.py +0 -0
  109. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/core/vscode_tasks.py +0 -0
  110. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/dashboard/__init__.py +0 -0
  111. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/data/agentpack.md +0 -0
  112. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/__init__.py +0 -0
  113. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/antigravity.py +0 -0
  114. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/claude.py +0 -0
  115. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/codex.py +0 -0
  116. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/cursor.py +0 -0
  117. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/installers/windsurf.py +0 -0
  118. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/__init__.py +0 -0
  119. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/agents.py +0 -0
  120. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/git_hooks.py +0 -0
  121. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/global_install.py +0 -0
  122. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/platform.py +0 -0
  123. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/integrations/vscode_tasks.py +0 -0
  124. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/__init__.py +0 -0
  125. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/collector.py +0 -0
  126. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/extractor.py +0 -0
  127. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/feedback.py +0 -0
  128. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/lesson_ranker.py +0 -0
  129. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/models.py +0 -0
  130. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/provider.py +0 -0
  131. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/quality.py +0 -0
  132. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/renderers.py +0 -0
  133. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/learning/skill_map.py +0 -0
  134. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/mcp_server.py +0 -0
  135. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/output_compression/__init__.py +0 -0
  136. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/output_compression/core.py +0 -0
  137. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/__init__.py +0 -0
  138. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/compact.py +0 -0
  139. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/markdown.py +0 -0
  140. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/renderers/receipts.py +0 -0
  141. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/__init__.py +0 -0
  142. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/discovery.py +0 -0
  143. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/models.py +0 -0
  144. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/parser.py +0 -0
  145. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/prompt_builder.py +0 -0
  146. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/scoring.py +0 -0
  147. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/service.py +0 -0
  148. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/router/skills_index.py +0 -0
  149. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/session/__init__.py +0 -0
  150. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/session/events.py +0 -0
  151. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/session/state.py +0 -0
  152. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/summaries/__init__.py +0 -0
  153. {agentpack_cli-0.3.21 → agentpack_cli-0.3.23}/src/agentpack/summaries/base.py +0 -0
  154. {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.21
4
- Summary: Local MCP context router for Claude Code, Codex, Cursor, and AI coding agents.
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
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
50
56
  [![CI](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml/badge.svg)](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
51
57
 
52
- **Local context router for AI coding agents.**
58
+ **Local context engine for AI coding agents.**
53
59
 
54
- AgentPack gives Claude Code, Codex, Cursor, and other coding agents a ranked starting map before they burn tool calls rediscovering your repo.
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
  ![AgentPack route demo](docs/assets/agentpack-route-demo.svg)
69
79
 
70
- > **Status: alpha (v0.3.21).** 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.
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.21
86
+ ## What's New in 0.3.23
77
87
 
78
- `0.3.21` is a benchmark trust release. It keeps the current honest expanded
79
- public-suite baseline at **57.0% recall / 50.6% token precision**, removes the
80
- legacy minimal-mode surface in favor of `balanced`, improves benchmark
81
- diagnostics and public-suite methodology, and documents the next release target:
82
- **65%+ recall while holding 50%+ token precision**.
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
- Latest published v0.3.20 release table: 8 pinned public commits from Pallets
132
- Click, ItsDangerous, and MarkupSafe, scored against files actually changed by
133
- each commit. The public manifest now also supports 100+ sampled historical
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
- | Avg recall | 79.2% |
140
- | Avg token precision | 51.2% |
141
- | Pack p50 | 1,450 tokens |
142
- | Pack p95 | 3,805 tokens |
143
-
144
- Full v0.3.20 table: [`benchmarks/results/2026-06-11-public.md`](benchmarks/results/2026-06-11-public.md). This is scoped benchmark evidence, not a universal quality claim.
145
- The expanded 109-case public suite is the current optimization baseline:
146
- **57.0% recall / 50.6% token precision**. It is broader and harder than the
147
- 8-case published table, and recall remains the active improvement target.
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
- ### Next Release Benchmark Target
165
+ ### Release Benchmark Gate
157
166
 
158
- The next benchmark release target is to raise the expanded public suite from the
159
- current **57.0% recall / 50.6% token precision** baseline to **65%+ recall**
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
- precision gains are not hiding TypeScript, Go, Java, or monorepo regressions.
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 50.0%
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+. 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.
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
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
9
  [![CI](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml/badge.svg)](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
10
10
 
11
- **Local context router for AI coding agents.**
11
+ **Local context engine for AI coding agents.**
12
12
 
13
- AgentPack gives Claude Code, Codex, Cursor, and other coding agents a ranked starting map before they burn tool calls rediscovering your repo.
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
  ![AgentPack route demo](docs/assets/agentpack-route-demo.svg)
28
32
 
29
- > **Status: alpha (v0.3.21).** 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.
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.21
39
+ ## What's New in 0.3.23
36
40
 
37
- `0.3.21` is a benchmark trust release. It keeps the current honest expanded
38
- public-suite baseline at **57.0% recall / 50.6% token precision**, removes the
39
- legacy minimal-mode surface in favor of `balanced`, improves benchmark
40
- diagnostics and public-suite methodology, and documents the next release target:
41
- **65%+ recall while holding 50%+ token precision**.
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
- Latest published v0.3.20 release table: 8 pinned public commits from Pallets
91
- Click, ItsDangerous, and MarkupSafe, scored against files actually changed by
92
- each commit. The public manifest now also supports 100+ sampled historical
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
- | Avg recall | 79.2% |
99
- | Avg token precision | 51.2% |
100
- | Pack p50 | 1,450 tokens |
101
- | Pack p95 | 3,805 tokens |
102
-
103
- Full v0.3.20 table: [`benchmarks/results/2026-06-11-public.md`](benchmarks/results/2026-06-11-public.md). This is scoped benchmark evidence, not a universal quality claim.
104
- The expanded 109-case public suite is the current optimization baseline:
105
- **57.0% recall / 50.6% token precision**. It is broader and harder than the
106
- 8-case published table, and recall remains the active improvement target.
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
- ### Next Release Benchmark Target
118
+ ### Release Benchmark Gate
116
119
 
117
- The next benchmark release target is to raise the expanded public suite from the
118
- current **57.0% recall / 50.6% token precision** baseline to **65%+ recall**
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
- precision gains are not hiding TypeScript, Go, Java, or monorepo regressions.
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 50.0%
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+. 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.
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.21"
4
- description = "Local MCP context router for Claude Code, Codex, Cursor, and AI coding agents."
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
 
@@ -1,3 +1,3 @@
1
1
  """AgentPack — task-aware context packing for AI coding agents."""
2
2
 
3
- __version__ = "0.3.21"
3
+ __version__ = "0.3.23"
@@ -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,