agentpack-cli 0.3.28__tar.gz → 0.3.29__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 (165) hide show
  1. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/PKG-INFO +1 -1
  2. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/pyproject.toml +1 -1
  3. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/__init__.py +1 -1
  4. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/codex.py +3 -0
  5. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/application/pack_service.py +4 -0
  6. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/doctor.py +19 -12
  7. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/init.py +11 -1
  8. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/install.py +15 -9
  9. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/learn.py +2 -0
  10. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/memory.py +31 -0
  11. agentpack_cli-0.3.29/src/agentpack/data/agentpack-learn.md +66 -0
  12. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/.codex-plugin/plugin.json +2 -1
  13. agentpack_cli-0.3.29/src/agentpack/data/codex_plugin/skills/agentpack-learn.md +67 -0
  14. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/codex.py +48 -0
  15. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/agents.py +31 -1
  16. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/collector.py +6 -0
  17. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/extractor.py +2 -0
  18. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/models.py +2 -0
  19. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/renderers.py +5 -2
  20. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/service.py +22 -1
  21. agentpack_cli-0.3.29/src/agentpack/session/references.py +288 -0
  22. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/.gitignore +0 -0
  23. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/LICENSE +0 -0
  24. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/README.md +0 -0
  25. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/__init__.py +0 -0
  26. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/antigravity.py +0 -0
  27. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/base.py +0 -0
  28. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/claude.py +0 -0
  29. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/cursor.py +0 -0
  30. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/detect.py +0 -0
  31. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/generic.py +0 -0
  32. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/windsurf.py +0 -0
  33. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/__init__.py +0 -0
  34. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/dependency_graph.py +0 -0
  35. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/go_imports.py +0 -0
  36. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/java_imports.py +0 -0
  37. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/js_ts_imports.py +0 -0
  38. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/monorepo.py +0 -0
  39. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/naming_signals.py +0 -0
  40. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/python_ast.py +0 -0
  41. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/python_imports.py +0 -0
  42. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/ranking.py +0 -0
  43. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/repo_map.py +0 -0
  44. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/role_inference.py +0 -0
  45. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/rust_imports.py +0 -0
  46. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/symbols.py +0 -0
  47. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/task_classifier.py +0 -0
  48. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/tests.py +0 -0
  49. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/application/__init__.py +0 -0
  50. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/cli.py +0 -0
  51. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/__init__.py +0 -0
  52. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/_shared.py +0 -0
  53. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/benchmark.py +0 -0
  54. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/ci_cmd.py +0 -0
  55. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/claude_cmd.py +0 -0
  56. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/compress_output.py +0 -0
  57. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/dashboard.py +0 -0
  58. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/dev_check.py +0 -0
  59. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/diagnose_selection.py +0 -0
  60. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/diff.py +0 -0
  61. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/eval_cmd.py +0 -0
  62. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/explain.py +0 -0
  63. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/guard.py +0 -0
  64. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/hook_cmd.py +0 -0
  65. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/ignore_cmd.py +0 -0
  66. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/mcp_cmd.py +0 -0
  67. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/migrate.py +0 -0
  68. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/monitor.py +0 -0
  69. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/next_cmd.py +0 -0
  70. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/pack.py +0 -0
  71. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/perf.py +0 -0
  72. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/quickstart.py +0 -0
  73. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/release_check.py +0 -0
  74. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/release_cmd.py +0 -0
  75. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/repair.py +0 -0
  76. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/retrieve.py +0 -0
  77. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/route.py +0 -0
  78. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/scan.py +0 -0
  79. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/skills.py +0 -0
  80. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/start_cmd.py +0 -0
  81. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/state_cmd.py +0 -0
  82. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/stats.py +0 -0
  83. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/status.py +0 -0
  84. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/summarize.py +0 -0
  85. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/task_cmd.py +0 -0
  86. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/threads.py +0 -0
  87. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/tune.py +0 -0
  88. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/upgrade.py +0 -0
  89. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/verify_wheel.py +0 -0
  90. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/watch.py +0 -0
  91. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/workflow_cmd.py +0 -0
  92. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/wrap.py +0 -0
  93. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/__init__.py +0 -0
  94. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/bootstrap.py +0 -0
  95. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/cache.py +0 -0
  96. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/changed_paths.py +0 -0
  97. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/command_surface.py +0 -0
  98. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/config.py +0 -0
  99. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/context_pack.py +0 -0
  100. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/diff.py +0 -0
  101. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/e2e_benchmark.py +0 -0
  102. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/evals.py +0 -0
  103. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/execution_state.py +0 -0
  104. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/git.py +0 -0
  105. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/git_hooks.py +0 -0
  106. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/global_install.py +0 -0
  107. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/ignore.py +0 -0
  108. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/loop_protocol.py +0 -0
  109. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/merkle.py +0 -0
  110. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/models.py +0 -0
  111. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/modes.py +0 -0
  112. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/pack_registry.py +0 -0
  113. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/redactor.py +0 -0
  114. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/scanner.py +0 -0
  115. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/snapshot.py +0 -0
  116. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/task_freshness.py +0 -0
  117. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/thread_context.py +0 -0
  118. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/token_estimator.py +0 -0
  119. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/vscode_tasks.py +0 -0
  120. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/__init__.py +0 -0
  121. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/collectors.py +0 -0
  122. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/models.py +0 -0
  123. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/renderers.py +0 -0
  124. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/agentpack.md +0 -0
  125. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-pack.md +0 -0
  126. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-refresh.md +0 -0
  127. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-review.md +0 -0
  128. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-route.md +0 -0
  129. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack.md +0 -0
  130. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/__init__.py +0 -0
  131. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/antigravity.py +0 -0
  132. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/claude.py +0 -0
  133. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/cursor.py +0 -0
  134. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/windsurf.py +0 -0
  135. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/__init__.py +0 -0
  136. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/git_hooks.py +0 -0
  137. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/global_install.py +0 -0
  138. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/platform.py +0 -0
  139. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/vscode_tasks.py +0 -0
  140. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/__init__.py +0 -0
  141. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/feedback.py +0 -0
  142. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/lesson_ranker.py +0 -0
  143. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/provider.py +0 -0
  144. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/quality.py +0 -0
  145. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/skill_map.py +0 -0
  146. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/mcp_server.py +0 -0
  147. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/output_compression/__init__.py +0 -0
  148. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/output_compression/core.py +0 -0
  149. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/__init__.py +0 -0
  150. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/compact.py +0 -0
  151. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/markdown.py +0 -0
  152. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/receipts.py +0 -0
  153. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/__init__.py +0 -0
  154. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/discovery.py +0 -0
  155. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/models.py +0 -0
  156. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/parser.py +0 -0
  157. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/prompt_builder.py +0 -0
  158. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/scoring.py +0 -0
  159. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/skills_index.py +0 -0
  160. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/session/__init__.py +0 -0
  161. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/session/events.py +0 -0
  162. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/session/state.py +0 -0
  163. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/summaries/__init__.py +0 -0
  164. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/summaries/base.py +0 -0
  165. {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/summaries/offline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentpack-cli
3
- Version: 0.3.28
3
+ Version: 0.3.29
4
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
5
  Project-URL: Homepage, https://github.com/vishal2612200/agentpack
6
6
  Project-URL: Documentation, https://vishal2612200.github.io/agentpack/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentpack-cli"
3
- version = "0.3.28"
3
+ version = "0.3.29"
4
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"
@@ -1,3 +1,3 @@
1
1
  """AgentPack — task-aware context packing for AI coding agents."""
2
2
 
3
- __version__ = "0.3.28"
3
+ __version__ = "0.3.29"
@@ -25,5 +25,8 @@ class CodexAdapter(BaseAdapter):
25
25
  def patch_codex_hooks(self, root: Path) -> str:
26
26
  return CodexInstaller().patch_codex_hooks(root)
27
27
 
28
+ def patch_codex_mcp_config(self, *, codex_home: Path | None = None) -> str:
29
+ return CodexInstaller().patch_codex_mcp_config(codex_home=codex_home)
30
+
28
31
  def install_auto_repack(self, root: Path) -> dict[str, str]:
29
32
  return CodexInstaller().install_auto_repack(root)
@@ -67,6 +67,7 @@ from agentpack.analysis.tests import find_related_tests
67
67
  from agentpack.analysis import dependency_graph as dep_graph_mod
68
68
  from agentpack.summaries.base import build_all_summaries
69
69
  from agentpack.session.events import record_event
70
+ from agentpack.session.references import collect_repo_issue_references
70
71
 
71
72
 
72
73
  @dataclass
@@ -829,11 +830,14 @@ class PackService:
829
830
  output_path=cfg.runtime.pack_registry_output,
830
831
  max_records=cfg.runtime.max_registry_records,
831
832
  )
833
+ issue_reference_details = collect_repo_issue_references(root, request.task)
832
834
  record_event(
833
835
  root,
834
836
  "pack",
835
837
  {
836
838
  "task": request.task,
839
+ "issue_references": [item.ref for item in issue_reference_details],
840
+ "issue_reference_details": [item.to_dict() for item in issue_reference_details],
837
841
  "agent": request.agent,
838
842
  "mode": plan.mode,
839
843
  "packed_tokens": packed_tokens,
@@ -334,18 +334,25 @@ def register(app: typer.Typer) -> None:
334
334
  else:
335
335
  console.print(" [green]✓[/] npm publish token available in environment")
336
336
 
337
- # --- Slash command ---
338
- console.print("\n[bold]Slash command (/agentpack)[/]")
339
- local_cmd = root / ".claude" / "commands" / "agentpack.md"
340
- global_cmd = Path.home() / ".claude" / "commands" / "agentpack.md"
341
- if local_cmd.exists():
342
- console.print(f" [green]✓[/] Slash command installed (local): {local_cmd}")
343
- else:
344
- console.print(" [dim]-[/] Slash command not installed locally — run: agentpack install --agent claude")
345
- if global_cmd.exists():
346
- console.print(f" [green][/] Slash command installed (global): {global_cmd}")
347
- else:
348
- console.print(" [dim]-[/] Slash command not installed globally — run: agentpack install --agent claude --global")
337
+ # --- Slash commands ---
338
+ console.print("\n[bold]Slash commands (/agentpack, /agentpack-learn)[/]")
339
+ for filename in ("agentpack.md", "agentpack-learn.md"):
340
+ local_cmd = root / ".claude" / "commands" / filename
341
+ global_cmd = Path.home() / ".claude" / "commands" / filename
342
+ if local_cmd.exists():
343
+ console.print(f" [green]✓[/] Slash command installed (local): {local_cmd}")
344
+ else:
345
+ console.print(
346
+ f" [dim]-[/] Slash command not installed locally: {local_cmd}"
347
+ "run: agentpack install --agent claude"
348
+ )
349
+ if global_cmd.exists():
350
+ console.print(f" [green]✓[/] Slash command installed (global): {global_cmd}")
351
+ else:
352
+ console.print(
353
+ f" [dim]-[/] Slash command not installed globally: {global_cmd} — "
354
+ "run: agentpack install --agent claude --global"
355
+ )
349
356
 
350
357
  _print_summary(ok)
351
358
 
@@ -206,6 +206,10 @@ def _patch_agentignore(
206
206
 
207
207
  def _install_agent_integration(root, agent: str) -> dict[str, str]:
208
208
  """Install repo-local agent integration files after `agentpack init`."""
209
+ if agent == "claude":
210
+ from agentpack.commands.install import _install_slash_command
211
+
212
+ return install_agent_integration(root, agent, install_slash_command=_install_slash_command)
209
213
  return install_agent_integration(root, agent)
210
214
 
211
215
 
@@ -246,7 +250,13 @@ def _resolve_init_agent(root: Path, agent: str, *, force: bool = False) -> str:
246
250
 
247
251
  def _agent_integration_paths(agent: str) -> tuple[str, ...]:
248
252
  if agent == "claude":
249
- return ("CLAUDE.md", ".claude/settings.json", ".mcp.json")
253
+ return (
254
+ "CLAUDE.md",
255
+ ".claude/settings.json",
256
+ ".mcp.json",
257
+ ".claude/commands/agentpack.md",
258
+ ".claude/commands/agentpack-learn.md",
259
+ )
250
260
  if agent == "cursor":
251
261
  return (".cursorrules", ".cursor/rules/agentpack.mdc", ".vscode/tasks.json")
252
262
  if agent == "windsurf":
@@ -47,8 +47,8 @@ def _print_install_results(agent: str, results: dict[str, str]) -> None:
47
47
  console.print(f"[green].git/hooks/{key[4:]} {action}.[/]")
48
48
  elif key == "vscode:tasks":
49
49
  console.print(f"[green].vscode/tasks.json {action}.[/]")
50
- elif key == "/agentpack":
51
- console.print(f"[green]/agentpack slash command {action}.[/]")
50
+ elif key.startswith("/"):
51
+ console.print(f"[green]{key} slash command {action}.[/]")
52
52
  else:
53
53
  console.print(f"[green]{key} {action}.[/]")
54
54
 
@@ -66,7 +66,7 @@ def _print_dry_run_agent(agent: str) -> None:
66
66
  elif agent == "windsurf":
67
67
  console.print("\n[dim]Would patch: .windsurfrules, VS Code task, git hooks[/]")
68
68
  elif agent == "codex":
69
- console.print("\n[dim]Would patch: AGENTS.md, .codex/hooks.json, git hooks[/]")
69
+ console.print("\n[dim]Would patch: AGENTS.md, .codex/hooks.json, Codex MCP config, git hooks[/]")
70
70
  elif agent == "antigravity":
71
71
  console.print("\n[dim]Would patch: GEMINI.md, VS Code task, git hooks[/]")
72
72
  elif agent == "generic":
@@ -256,18 +256,24 @@ def register(app: typer.Typer) -> None:
256
256
  console.print(" Current repo hooks now delegate through AgentPack's safe GitAutoRepack path.")
257
257
 
258
258
 
259
- def _install_slash_command(root: Path, global_install: bool) -> str:
260
- import importlib.resources
261
-
259
+ def _install_slash_command(root: Path, global_install: bool) -> dict[str, str]:
262
260
  commands_dir = Path.home() / ".claude" / "commands" if global_install else root / ".claude" / "commands"
263
261
  commands_dir.mkdir(parents=True, exist_ok=True)
264
- dest = commands_dir / "agentpack.md"
262
+ return {
263
+ "/agentpack": _install_slash_command_file(commands_dir, "agentpack.md"),
264
+ "/agentpack-learn": _install_slash_command_file(commands_dir, "agentpack-learn.md"),
265
+ }
266
+
267
+
268
+ def _install_slash_command_file(commands_dir: Path, filename: str) -> str:
269
+ import importlib.resources
265
270
 
271
+ dest = commands_dir / filename
266
272
  try:
267
- pkg_files = importlib.resources.files("agentpack") / "data" / "agentpack.md"
273
+ pkg_files = importlib.resources.files("agentpack") / "data" / filename
268
274
  source_text = pkg_files.read_text(encoding="utf-8")
269
275
  except Exception:
270
- source_text = (Path(__file__).parent.parent / "data" / "agentpack.md").read_text(encoding="utf-8")
276
+ source_text = (Path(__file__).parent.parent / "data" / filename).read_text(encoding="utf-8")
271
277
 
272
278
  existed = dest.exists()
273
279
  if existed and dest.read_text(encoding="utf-8") == source_text:
@@ -248,6 +248,8 @@ def register(app: typer.Typer) -> None:
248
248
  "learn",
249
249
  {
250
250
  "task": report.task,
251
+ "issue_references": report.issue_references,
252
+ "issue_reference_details": report.issue_reference_details,
251
253
  "changed_files": len(report.source_files),
252
254
  "concepts": report.concepts,
253
255
  "selected_hits": len(report.selected_hits),
@@ -9,6 +9,7 @@ from rich import box
9
9
 
10
10
  from agentpack.commands._shared import _root, console
11
11
  from agentpack.core.config import load_config
12
+ from agentpack.session.references import merge_issue_reference_objects, merge_issue_references
12
13
  from agentpack.session.events import read_events
13
14
 
14
15
 
@@ -26,8 +27,29 @@ def register(app: typer.Typer) -> None:
26
27
  for concept in (event.get("concepts") or [])
27
28
  if isinstance(concept, str)
28
29
  )
30
+ issue_references = merge_issue_references(
31
+ ref
32
+ for event in events
33
+ for ref in (event.get("issue_references") or [])
34
+ if isinstance(ref, str)
35
+ )
36
+ top_issue_references = Counter(
37
+ ref
38
+ for event in events
39
+ for ref in (event.get("issue_references") or [])
40
+ if isinstance(ref, str)
41
+ ).most_common(20)
42
+ issue_reference_details = merge_issue_reference_objects(
43
+ item
44
+ for event in events
45
+ for item in (event.get("issue_reference_details") or [])
46
+ if isinstance(item, dict)
47
+ )
29
48
  payload = {
30
49
  "recent_tasks": tasks[-20:],
50
+ "recent_issue_references": issue_references[-20:],
51
+ "issue_reference_details": [item.to_dict() for item in issue_reference_details[-20:]],
52
+ "top_issue_references": top_issue_references,
31
53
  "top_concepts": concepts.most_common(20),
32
54
  "event_count": len(events),
33
55
  }
@@ -40,6 +62,15 @@ def register(app: typer.Typer) -> None:
40
62
  table.add_row("events", str(len(events)))
41
63
  for task in tasks[-10:]:
42
64
  table.add_row("task", task)
65
+ for ref in issue_references[-10:]:
66
+ table.add_row("issue", ref)
67
+ for item in issue_reference_details[-10:]:
68
+ label = item.ref
69
+ if item.title:
70
+ label += f" — {item.title}"
71
+ if item.state:
72
+ label += f" ({item.state})"
73
+ table.add_row("issue detail", label)
43
74
  for concept, count in concepts.most_common(10):
44
75
  table.add_row("concept", f"{concept} ({count})")
45
76
  console.print(table)
@@ -0,0 +1,66 @@
1
+ ---
2
+ description: Learn one thing from the current local AgentPack session context.
3
+ ---
4
+
5
+ # AgentPack Learn
6
+
7
+ Use current local agent session context to teach what the user asks to learn.
8
+
9
+ Keep this prompt prefix stable for caching. Do not move the user learning statement above the final line.
10
+
11
+ ## Freshness Check
12
+
13
+ Check whether current AgentPack context is present and current:
14
+
15
+ ```bash
16
+ agentpack status
17
+ ```
18
+
19
+ If `agentpack status` fails, says context is stale/missing, or `.agentpack/context.compact.md` is absent, refresh once:
20
+
21
+ ```bash
22
+ agentpack pack --task auto
23
+ ```
24
+
25
+ Do not loop on refresh. If refresh fails, continue from whatever local context exists and state that context may be stale.
26
+
27
+ ## Context Source
28
+
29
+ Use only local files first:
30
+
31
+ ```bash
32
+ test -f .agentpack/context.compact.md && sed -n '1,220p' .agentpack/context.compact.md
33
+ test -f .agentpack/task.md && sed -n '1,40p' .agentpack/task.md
34
+ test -f .agentpack/session.json && sed -n '1,120p' .agentpack/session.json
35
+ test -f .agentpack/learning.md && sed -n '1,220p' .agentpack/learning.md
36
+ test -f .agentpack/agent-lessons.md && sed -n '1,160p' .agentpack/agent-lessons.md
37
+ test -f .agentpack/skills-progress.json && sed -n '1,120p' .agentpack/skills-progress.json
38
+ test -f .agentpack/session-events.jsonl && tail -n 40 .agentpack/session-events.jsonl
39
+ ```
40
+
41
+ Use `.agentpack/context.md` only when compact context lacks needed detail.
42
+ Do not invent repo facts not present in local context or checked files.
43
+
44
+ ## Teaching Modes
45
+
46
+ Choose the smallest mode that matches the user's learning statement.
47
+
48
+ Learning Curve Destroyer: use when user wants to become functional fast. You only have 4 hours with them and will never see them again. No theory without practical use. No lists. Tell them what to learn first, what to ignore, and one exercise that puts them ahead of most people studying for months.
49
+
50
+ Real Error Simulator: use when user wants practice with a concept. Do not explain first. Drop them into a real situation from local context where they would use it and likely get it wrong. When they make a mistake, ask a question that exposes where thinking broke. Reveal answer only after at least two tries. Repeat until they get it right without hesitating.
51
+
52
+ Confusion Breaker: use when user says content or context is confusing. Before explaining, give one sentence that makes everything click. Explain only that sentence first using an everyday analogy with zero technical terms. Ask 3 questions only someone who truly gets it can answer. Do not move on until they pass all three.
53
+
54
+ Personal Learning Path: use when user gives a real goal, desired result, deadline, or current knowledge. Build a 7-day path. Each day has one 45-minute task, a clear correctness check, and what not to do that day. If path does not lead to goal, rebuild it.
55
+
56
+ Forced Feynman Method: use when user says they studied something or wants to explain back. Let them explain as if to a 10-year-old. Stop them when they use unknown words, skip reasoning, or oversimplify until wrong. End with exactly what mistakes reveal about weak understanding.
57
+
58
+ ## Output Rules
59
+
60
+ - Be practical and interactive.
61
+ - Ground examples in local agent session context when useful.
62
+ - Ask for missing goal/deadline/current-knowledge only if needed for the selected mode.
63
+ - Do not dump generic theory.
64
+ - Do not produce long lists unless the selected mode explicitly requires a 7-day path.
65
+
66
+ User learning statement: $ARGUMENTS
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentpack",
3
- "version": "0.3.28",
3
+ "version": "0.3.29",
4
4
  "description": "Thin Codex plugin for AgentPack ranked repo context.",
5
5
  "author": {
6
6
  "name": "AgentPack",
@@ -29,6 +29,7 @@
29
29
  "defaultPrompt": [
30
30
  "@agentpack-route fix auth token expiry",
31
31
  "@agentpack-pack fix auth token expiry",
32
+ "@agentpack-learn retry handling in this repo",
32
33
  "@agentpack-review"
33
34
  ],
34
35
  "brandColor": "#1F6FEB"
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: agentpack-learn
3
+ description: Learn one thing from current local AgentPack session context.
4
+ ---
5
+
6
+ # AgentPack Learn
7
+
8
+ Use when the user invokes `/agentpack-learn <statement>` or `@agentpack-learn <statement>`.
9
+
10
+ Use current local agent session context to teach what the user asks to learn.
11
+
12
+ Keep prompt prefix stable for caching. Treat the user's learning statement as the only variable and keep it at the end when constructing any reusable prompt.
13
+
14
+ ## Freshness Check
15
+
16
+ Check whether current AgentPack context is present and current:
17
+
18
+ ```bash
19
+ agentpack status
20
+ ```
21
+
22
+ If `agentpack status` fails, says context is stale/missing, or `.agentpack/context.compact.md` is absent, refresh once:
23
+
24
+ ```bash
25
+ agentpack pack --task auto
26
+ ```
27
+
28
+ Do not loop on refresh. If refresh fails, continue from whatever local context exists and state that context may be stale.
29
+
30
+ ## Context Source
31
+
32
+ Use only local files first:
33
+
34
+ ```bash
35
+ test -f .agentpack/context.compact.md && sed -n '1,220p' .agentpack/context.compact.md
36
+ test -f .agentpack/task.md && sed -n '1,40p' .agentpack/task.md
37
+ test -f .agentpack/session.json && sed -n '1,120p' .agentpack/session.json
38
+ test -f .agentpack/learning.md && sed -n '1,220p' .agentpack/learning.md
39
+ test -f .agentpack/agent-lessons.md && sed -n '1,160p' .agentpack/agent-lessons.md
40
+ test -f .agentpack/skills-progress.json && sed -n '1,120p' .agentpack/skills-progress.json
41
+ test -f .agentpack/session-events.jsonl && tail -n 40 .agentpack/session-events.jsonl
42
+ ```
43
+
44
+ Use `.agentpack/context.md` only when compact context lacks needed detail.
45
+ Do not invent repo facts not present in local context or checked files.
46
+
47
+ ## Teaching Modes
48
+
49
+ Choose the smallest mode that matches the user's learning statement.
50
+
51
+ Learning Curve Destroyer: use when user wants to become functional fast. You only have 4 hours with them and will never see them again. No theory without practical use. No lists. Tell them what to learn first, what to ignore, and one exercise that puts them ahead of most people studying for months.
52
+
53
+ Real Error Simulator: use when user wants practice with a concept. Do not explain first. Drop them into a real situation from local context where they would use it and likely get it wrong. When they make a mistake, ask a question that exposes where thinking broke. Reveal answer only after at least two tries. Repeat until they get it right without hesitating.
54
+
55
+ Confusion Breaker: use when user says content or context is confusing. Before explaining, give one sentence that makes everything click. Explain only that sentence first using an everyday analogy with zero technical terms. Ask 3 questions only someone who truly gets it can answer. Do not move on until they pass all three.
56
+
57
+ Personal Learning Path: use when user gives a real goal, desired result, deadline, or current knowledge. Build a 7-day path. Each day has one 45-minute task, a clear correctness check, and what not to do that day. If path does not lead to goal, rebuild it.
58
+
59
+ Forced Feynman Method: use when user says they studied something or wants to explain back. Let them explain as if to a 10-year-old. Stop them when they use unknown words, skip reasoning, or oversimplify until wrong. End with exactly what mistakes reveal about weak understanding.
60
+
61
+ ## Output Rules
62
+
63
+ - Be practical and interactive.
64
+ - Ground examples in local agent session context when useful.
65
+ - Ask for missing goal/deadline/current-knowledge only if needed for the selected mode.
66
+ - Do not dump generic theory.
67
+ - Do not produce long lists unless the selected mode explicitly requires a 7-day path.
@@ -57,6 +57,25 @@ _USER_PROMPT_SUBMIT_HOOK = {
57
57
  "statusMessage": "Checking agentpack index...",
58
58
  }
59
59
 
60
+ _CODEX_MCP_BLOCK = """\
61
+ # agentpack:mcp:start
62
+ [mcp_servers.agentpack]
63
+ command = "agentpack"
64
+ args = ["mcp"]
65
+ startup_timeout_sec = 30
66
+ tool_timeout_sec = 120
67
+ enabled = true
68
+ # agentpack:mcp:end
69
+ """
70
+
71
+ _CODEX_MCP_BLOCK_RE = re.compile(
72
+ r"# agentpack:mcp:start\n.*?# agentpack:mcp:end\n?",
73
+ re.DOTALL,
74
+ )
75
+ _CODEX_MCP_TABLE_RE = re.compile(
76
+ r"(?ms)^\[mcp_servers\.agentpack\]\n.*?(?=^\[[^\n]+\]\n|\Z)",
77
+ )
78
+
60
79
 
61
80
  class CodexInstaller:
62
81
  """Configures Codex/OpenAI-specific repo files and auto-repack hooks."""
@@ -125,6 +144,18 @@ class CodexInstaller:
125
144
  results.update({f"git:{k}": v for k, v in hook_results.items()})
126
145
  return results
127
146
 
147
+ def patch_codex_mcp_config(self, *, codex_home: Path | None = None) -> str:
148
+ """Install AgentPack's MCP server in Codex's user config."""
149
+ config_path = _codex_config_path(codex_home)
150
+ config_path.parent.mkdir(parents=True, exist_ok=True)
151
+ existed = config_path.exists()
152
+ content = config_path.read_text(encoding="utf-8") if existed else ""
153
+ desired = _patch_codex_mcp_config_text(content)
154
+ if content == desired:
155
+ return "unchanged"
156
+ config_path.write_text(desired, encoding="utf-8")
157
+ return "updated" if existed else "created"
158
+
128
159
  def install_codex_plugin(self, *, codex_home: Path | None = None) -> dict[str, str]:
129
160
  """Install AgentPack's thin Codex plugin package into the local Codex cache."""
130
161
  source = _codex_plugin_source()
@@ -133,11 +164,28 @@ class CodexInstaller:
133
164
  return {str(target): action}
134
165
 
135
166
 
167
+ def _patch_codex_mcp_config_text(content: str) -> str:
168
+ normalized_block = _CODEX_MCP_BLOCK
169
+ if _CODEX_MCP_BLOCK_RE.search(content):
170
+ return _CODEX_MCP_BLOCK_RE.sub(normalized_block, content)
171
+ if _CODEX_MCP_TABLE_RE.search(content):
172
+ return _CODEX_MCP_TABLE_RE.sub(normalized_block, content)
173
+ prefix = content.rstrip()
174
+ if not prefix:
175
+ return normalized_block
176
+ return prefix + "\n\n" + normalized_block
177
+
178
+
136
179
  def _codex_plugin_target(codex_home: Path | None = None) -> Path:
137
180
  root = codex_home or Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser()
138
181
  return root / "plugins" / "cache" / "local" / "agentpack" / __version__
139
182
 
140
183
 
184
+ def _codex_config_path(codex_home: Path | None = None) -> Path:
185
+ root = codex_home or Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser()
186
+ return root / "config.toml"
187
+
188
+
141
189
  def _codex_plugin_source() -> Path:
142
190
  checkout_source = Path(__file__).resolve().parents[3] / "src" / "agentpack" / "data" / "codex_plugin"
143
191
  if checkout_source.exists():
@@ -62,7 +62,11 @@ def install_agent_integration(
62
62
  ),
63
63
  }
64
64
  if slash_command and install_slash_command is not None:
65
- results["/agentpack"] = install_slash_command(root, global_install)
65
+ slash_results = install_slash_command(root, global_install)
66
+ if isinstance(slash_results, dict):
67
+ results.update(slash_results)
68
+ else:
69
+ results["/agentpack"] = slash_results
66
70
  return results
67
71
 
68
72
  if agent == "cursor":
@@ -88,6 +92,7 @@ def install_agent_integration(
88
92
  results = {
89
93
  "AGENTS.md": installer.patch_agents_md(root),
90
94
  "~/.codex/plugins/cache/local/agentpack": next(iter(plugin_result.values())),
95
+ "~/.codex/config.toml:mcp_servers.agentpack": installer.patch_codex_mcp_config(),
91
96
  }
92
97
  if not global_install:
93
98
  results.update(installer.install_auto_repack(root))
@@ -126,6 +131,7 @@ def check_agent_integration(root: Path, agent: str) -> list[AgentCheck]:
126
131
  return [
127
132
  _current_rule_file(root, agent, "AGENTS.md", "agentpack repair --agent codex"),
128
133
  _codex_hooks(root),
134
+ _codex_mcp_config(),
129
135
  *_check_git_hooks(root, agent),
130
136
  ]
131
137
  if agent == "antigravity":
@@ -313,3 +319,27 @@ def _codex_hooks(root: Path) -> AgentCheck:
313
319
  "Codex app lifecycle hooks present" if ok else "missing SessionStart/UserPromptSubmit hooks",
314
320
  None if ok else "agentpack repair --agent codex",
315
321
  )
322
+
323
+
324
+ def _codex_mcp_config() -> AgentCheck:
325
+ import os
326
+
327
+ path = Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser() / "config.toml"
328
+ if not path.exists():
329
+ return AgentCheck("codex", "~/.codex/config.toml", False, "missing Codex MCP config", "agentpack repair --agent codex")
330
+ try:
331
+ content = path.read_text(encoding="utf-8")
332
+ except OSError:
333
+ return AgentCheck("codex", "~/.codex/config.toml", False, "unreadable", "agentpack repair --agent codex")
334
+ ok = (
335
+ "[mcp_servers.agentpack]" in content
336
+ and 'command = "agentpack"' in content
337
+ and 'args = ["mcp"]' in content
338
+ )
339
+ return AgentCheck(
340
+ "codex",
341
+ "~/.codex/config.toml",
342
+ ok,
343
+ "Codex MCP server registered" if ok else "agentpack MCP server missing",
344
+ None if ok else "agentpack repair --agent codex",
345
+ )
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
 
6
6
  from agentpack.core import git
7
7
  from agentpack.core.context_pack import load_pack_metadata
8
+ from agentpack.session.references import collect_repo_issue_references
8
9
  from agentpack.session.state import TASK_FILE
9
10
 
10
11
 
@@ -18,6 +19,8 @@ class LearningInputs:
18
19
  redaction_warnings: list[str] = field(default_factory=list)
19
20
  selected_files: list[str] = field(default_factory=list)
20
21
  selected_modes: dict[str, str] = field(default_factory=dict)
22
+ issue_references: list[str] = field(default_factory=list)
23
+ issue_reference_details: list[dict] = field(default_factory=list)
21
24
 
22
25
 
23
26
  def collect_learning_inputs(
@@ -46,6 +49,7 @@ def collect_learning_inputs(
46
49
  diffs[path] = diff
47
50
  warnings.extend(redaction_warnings)
48
51
  selected_files, selected_modes = _latest_selected_files(root)
52
+ issue_reference_details = collect_repo_issue_references(root, task)
49
53
  return LearningInputs(
50
54
  task=task,
51
55
  since=since,
@@ -55,6 +59,8 @@ def collect_learning_inputs(
55
59
  redaction_warnings=warnings,
56
60
  selected_files=selected_files,
57
61
  selected_modes=selected_modes,
62
+ issue_references=[item.ref for item in issue_reference_details],
63
+ issue_reference_details=[item.to_dict() for item in issue_reference_details],
58
64
  )
59
65
 
60
66
 
@@ -65,6 +65,8 @@ def build_learning_report(
65
65
  task=inputs.task,
66
66
  scope="task",
67
67
  since=inputs.since,
68
+ issue_references=inputs.issue_references,
69
+ issue_reference_details=inputs.issue_reference_details,
68
70
  source_files=source_files,
69
71
  summary=summary,
70
72
  concepts=concepts,
@@ -94,6 +94,8 @@ class LearningReport(BaseModel):
94
94
  task: str
95
95
  scope: str
96
96
  since: str | None = None
97
+ issue_references: list[str] = Field(default_factory=list)
98
+ issue_reference_details: list[dict] = Field(default_factory=list)
97
99
  source_files: list[LearningSourceFile] = Field(default_factory=list)
98
100
  summary: list[str] = Field(default_factory=list)
99
101
  concepts: list[str] = Field(default_factory=list)
@@ -60,9 +60,10 @@ def render_provider_preview_markdown(report: LearningReport) -> str:
60
60
  "",
61
61
  f"Task: {report.task}",
62
62
  f"Scope: {report.scope}",
63
- "",
64
- "## Changed File Evidence",
65
63
  ]
64
+ if report.issue_references:
65
+ lines.append("Issue references: " + ", ".join(report.issue_references))
66
+ lines.extend(["", "## Changed File Evidence"])
66
67
  for source in report.source_files:
67
68
  concepts = ", ".join(source.concepts) if source.concepts else "none"
68
69
  lines.append(f"- `{source.path}` ({source.change_kind}) concepts: {concepts}")
@@ -316,6 +317,8 @@ def render_learning_markdown(report: LearningReport) -> str:
316
317
  ]
317
318
  if report.since:
318
319
  lines.append(f"**Since:** `{report.since}`")
320
+ if report.issue_references:
321
+ lines.append("**Issue references:** " + ", ".join(report.issue_references))
319
322
  lines.extend(["", "## Summary"])
320
323
  lines.extend(f"- {item}" for item in report.summary)
321
324
  lines.extend(["", "## Changed Files"])
@@ -11,6 +11,8 @@ from pathlib import Path
11
11
  from agentpack.core import git
12
12
  from agentpack.application.pack_service import PackPlanner, PackRequest
13
13
  from agentpack.core.config import load_config
14
+ from agentpack.session.events import read_events
15
+ from agentpack.session.references import extract_issue_references, merge_issue_references
14
16
  from agentpack.router.discovery import discover_inventory, inventory_for_route
15
17
  from agentpack.router.models import (
16
18
  AppliedRule,
@@ -52,6 +54,7 @@ class RouteService:
52
54
 
53
55
  def route_task(self, root: Path, task: str) -> RouteResult:
54
56
  task = _normalize_task(task)
57
+ routing_task = _task_with_recent_issue_context(root, task)
55
58
  mode_decision = classify_task_mode(task)
56
59
  task_mode = mode_decision.mode
57
60
  prompt_quality = assess_prompt_quality(task, task_mode)
@@ -59,7 +62,7 @@ class RouteService:
59
62
  plan = PackPlanner().plan(PackRequest(
60
63
  root=root,
61
64
  agent="generic",
62
- task=task,
65
+ task=routing_task,
63
66
  mode="balanced",
64
67
  budget=0,
65
68
  since=None,
@@ -94,6 +97,8 @@ class RouteService:
94
97
  commands = _suggest_commands(task, selected_paths)
95
98
  checklist = _evidence_checklist(task_mode)
96
99
  notes = _routing_notes(task_mode, pr_paths)
100
+ if routing_task != task:
101
+ notes.append("Used recent issue references from AgentPack memory as routing hints.")
97
102
 
98
103
  result = RouteResult(
99
104
  task=task,
@@ -164,6 +169,22 @@ def _normalize_task(task: str) -> str:
164
169
  return normalized
165
170
 
166
171
 
172
+ def _task_with_recent_issue_context(root: Path, task: str) -> str:
173
+ if extract_issue_references(task):
174
+ return task
175
+ cfg = load_config(root)
176
+ events = read_events(root, output_path=cfg.runtime.session_events_output, limit=50)
177
+ refs = merge_issue_references(
178
+ ref
179
+ for event in events
180
+ for ref in (event.get("issue_references") or [])
181
+ if isinstance(ref, str)
182
+ )
183
+ if not refs:
184
+ return task
185
+ return f"{task} issue references {' '.join(refs[-5:])}"
186
+
187
+
167
188
  def _selected_file_dict(item) -> dict:
168
189
  return {
169
190
  "path": item.path,