agentpack-cli 0.3.26__tar.gz → 0.3.28__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 (163) hide show
  1. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/PKG-INFO +2 -1
  2. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/README.md +1 -0
  3. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/pyproject.toml +1 -1
  4. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/__init__.py +1 -1
  5. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/doctor.py +1 -1
  6. agentpack_cli-0.3.28/src/agentpack/commands/upgrade.py +93 -0
  7. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/command_surface.py +10 -1
  8. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/codex_plugin/.codex-plugin/plugin.json +1 -1
  9. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/installers/antigravity.py +4 -2
  10. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/installers/claude.py +4 -2
  11. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/installers/codex.py +4 -2
  12. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/installers/cursor.py +3 -2
  13. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/installers/windsurf.py +3 -2
  14. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/models.py +3 -0
  15. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/prompt_builder.py +15 -0
  16. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/scoring.py +24 -3
  17. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/service.py +115 -0
  18. agentpack_cli-0.3.26/src/agentpack/commands/upgrade.py +0 -38
  19. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/.gitignore +0 -0
  20. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/LICENSE +0 -0
  21. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/__init__.py +0 -0
  22. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/antigravity.py +0 -0
  23. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/base.py +0 -0
  24. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/claude.py +0 -0
  25. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/codex.py +0 -0
  26. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/cursor.py +0 -0
  27. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/detect.py +0 -0
  28. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/generic.py +0 -0
  29. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/adapters/windsurf.py +0 -0
  30. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/__init__.py +0 -0
  31. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/dependency_graph.py +0 -0
  32. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/go_imports.py +0 -0
  33. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/java_imports.py +0 -0
  34. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/js_ts_imports.py +0 -0
  35. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/monorepo.py +0 -0
  36. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/naming_signals.py +0 -0
  37. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/python_ast.py +0 -0
  38. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/python_imports.py +0 -0
  39. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/ranking.py +0 -0
  40. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/repo_map.py +0 -0
  41. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/role_inference.py +0 -0
  42. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/rust_imports.py +0 -0
  43. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/symbols.py +0 -0
  44. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/task_classifier.py +0 -0
  45. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/analysis/tests.py +0 -0
  46. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/application/__init__.py +0 -0
  47. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/application/pack_service.py +0 -0
  48. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/cli.py +0 -0
  49. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/__init__.py +0 -0
  50. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/_shared.py +0 -0
  51. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/benchmark.py +0 -0
  52. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/ci_cmd.py +0 -0
  53. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/claude_cmd.py +0 -0
  54. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/compress_output.py +0 -0
  55. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/dashboard.py +0 -0
  56. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/dev_check.py +0 -0
  57. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/diagnose_selection.py +0 -0
  58. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/diff.py +0 -0
  59. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/eval_cmd.py +0 -0
  60. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/explain.py +0 -0
  61. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/guard.py +0 -0
  62. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/hook_cmd.py +0 -0
  63. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/ignore_cmd.py +0 -0
  64. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/init.py +0 -0
  65. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/install.py +0 -0
  66. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/learn.py +0 -0
  67. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/mcp_cmd.py +0 -0
  68. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/memory.py +0 -0
  69. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/migrate.py +0 -0
  70. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/monitor.py +0 -0
  71. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/next_cmd.py +0 -0
  72. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/pack.py +0 -0
  73. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/perf.py +0 -0
  74. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/quickstart.py +0 -0
  75. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/release_check.py +0 -0
  76. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/release_cmd.py +0 -0
  77. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/repair.py +0 -0
  78. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/retrieve.py +0 -0
  79. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/route.py +0 -0
  80. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/scan.py +0 -0
  81. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/skills.py +0 -0
  82. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/start_cmd.py +0 -0
  83. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/state_cmd.py +0 -0
  84. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/stats.py +0 -0
  85. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/status.py +0 -0
  86. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/summarize.py +0 -0
  87. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/task_cmd.py +0 -0
  88. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/threads.py +0 -0
  89. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/tune.py +0 -0
  90. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/verify_wheel.py +0 -0
  91. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/watch.py +0 -0
  92. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/workflow_cmd.py +0 -0
  93. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/commands/wrap.py +0 -0
  94. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/__init__.py +0 -0
  95. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/bootstrap.py +0 -0
  96. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/cache.py +0 -0
  97. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/changed_paths.py +0 -0
  98. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/config.py +0 -0
  99. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/context_pack.py +0 -0
  100. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/diff.py +0 -0
  101. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/e2e_benchmark.py +0 -0
  102. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/evals.py +0 -0
  103. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/execution_state.py +0 -0
  104. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/git.py +0 -0
  105. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/git_hooks.py +0 -0
  106. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/global_install.py +0 -0
  107. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/ignore.py +0 -0
  108. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/loop_protocol.py +0 -0
  109. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/merkle.py +0 -0
  110. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/models.py +0 -0
  111. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/modes.py +0 -0
  112. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/pack_registry.py +0 -0
  113. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/redactor.py +0 -0
  114. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/scanner.py +0 -0
  115. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/snapshot.py +0 -0
  116. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/task_freshness.py +0 -0
  117. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/thread_context.py +0 -0
  118. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/token_estimator.py +0 -0
  119. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/core/vscode_tasks.py +0 -0
  120. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/dashboard/__init__.py +0 -0
  121. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/dashboard/collectors.py +0 -0
  122. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/dashboard/models.py +0 -0
  123. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/dashboard/renderers.py +0 -0
  124. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/agentpack.md +0 -0
  125. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/codex_plugin/skills/agentpack-pack.md +0 -0
  126. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/codex_plugin/skills/agentpack-refresh.md +0 -0
  127. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/codex_plugin/skills/agentpack-review.md +0 -0
  128. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/codex_plugin/skills/agentpack-route.md +0 -0
  129. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/data/codex_plugin/skills/agentpack.md +0 -0
  130. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/installers/__init__.py +0 -0
  131. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/integrations/__init__.py +0 -0
  132. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/integrations/agents.py +0 -0
  133. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/integrations/git_hooks.py +0 -0
  134. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/integrations/global_install.py +0 -0
  135. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/integrations/platform.py +0 -0
  136. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/integrations/vscode_tasks.py +0 -0
  137. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/__init__.py +0 -0
  138. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/collector.py +0 -0
  139. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/extractor.py +0 -0
  140. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/feedback.py +0 -0
  141. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/lesson_ranker.py +0 -0
  142. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/models.py +0 -0
  143. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/provider.py +0 -0
  144. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/quality.py +0 -0
  145. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/renderers.py +0 -0
  146. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/learning/skill_map.py +0 -0
  147. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/mcp_server.py +0 -0
  148. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/output_compression/__init__.py +0 -0
  149. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/output_compression/core.py +0 -0
  150. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/renderers/__init__.py +0 -0
  151. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/renderers/compact.py +0 -0
  152. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/renderers/markdown.py +0 -0
  153. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/renderers/receipts.py +0 -0
  154. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/__init__.py +0 -0
  155. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/discovery.py +0 -0
  156. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/parser.py +0 -0
  157. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/router/skills_index.py +0 -0
  158. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/session/__init__.py +0 -0
  159. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/session/events.py +0 -0
  160. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/session/state.py +0 -0
  161. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/summaries/__init__.py +0 -0
  162. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/src/agentpack/summaries/base.py +0 -0
  163. {agentpack_cli-0.3.26 → agentpack_cli-0.3.28}/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.26
3
+ Version: 0.3.28
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/
@@ -60,6 +60,7 @@ Description-Content-Type: text/markdown
60
60
  </p>
61
61
 
62
62
  <p align="center">
63
+ <a href="https://deepwiki.com/vishal2612200/agentpack"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
63
64
  <a href="https://pypi.org/project/agentpack-cli/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/agentpack-cli.svg"></a>
64
65
  <a href="https://pepy.tech/projects/agentpack-cli"><img alt="PyPI downloads" src="https://static.pepy.tech/personalized-badge/agentpack-cli?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads"></a>
65
66
  <a href="https://www.npmjs.com/package/@vishal2612200/agentpack"><img alt="npm version" src="https://img.shields.io/npm/v/@vishal2612200/agentpack.svg"></a>
@@ -13,6 +13,7 @@
13
13
  </p>
14
14
 
15
15
  <p align="center">
16
+ <a href="https://deepwiki.com/vishal2612200/agentpack"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
16
17
  <a href="https://pypi.org/project/agentpack-cli/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/agentpack-cli.svg"></a>
17
18
  <a href="https://pepy.tech/projects/agentpack-cli"><img alt="PyPI downloads" src="https://static.pepy.tech/personalized-badge/agentpack-cli?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads"></a>
18
19
  <a href="https://www.npmjs.com/package/@vishal2612200/agentpack"><img alt="npm version" src="https://img.shields.io/npm/v/@vishal2612200/agentpack.svg"></a>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentpack-cli"
3
- version = "0.3.26"
3
+ version = "0.3.28"
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.26"
3
+ __version__ = "0.3.28"
@@ -321,7 +321,7 @@ def register(app: typer.Typer) -> None:
321
321
  if findings:
322
322
  for finding in findings:
323
323
  console.print(f" [yellow]![/] {finding}")
324
- ok = False
324
+ console.print(" [dim]warning only; keep these out of commits/releases.[/]")
325
325
  else:
326
326
  console.print(" [green]✓[/] no generated release-noise files staged or untracked")
327
327
 
@@ -0,0 +1,93 @@
1
+ from __future__ import annotations
2
+
3
+ import subprocess
4
+
5
+ import typer
6
+
7
+ from agentpack.commands._shared import console, _root
8
+ from agentpack.commands.install import (
9
+ _install_slash_command,
10
+ _print_global_template_results,
11
+ _print_install_results,
12
+ )
13
+ from agentpack.integrations import global_install as global_hooks
14
+ from agentpack.integrations.agents import SUPPORTED_AGENTS, expand_agents, install_agent_integration
15
+
16
+
17
+ def register(app: typer.Typer) -> None:
18
+ @app.command()
19
+ def upgrade(
20
+ agent: str = typer.Option(
21
+ "auto",
22
+ "--agent",
23
+ help=f"Agent integration to refresh after package upgrade ({' | '.join(SUPPORTED_AGENTS)}).",
24
+ ),
25
+ repair_existing_global_hooks: bool = typer.Option(
26
+ True,
27
+ "--repair-existing-global-hooks/--no-repair-existing-global-hooks",
28
+ help="Refresh already-installed global git/shell hooks after upgrading AgentPack.",
29
+ ),
30
+ ) -> None:
31
+ """Refresh existing AgentPack repo/global integration surfaces after a package upgrade."""
32
+ root = _root()
33
+ if agent not in SUPPORTED_AGENTS:
34
+ console.print(f"[yellow]Unknown agent: {agent}. Supported: {', '.join(SUPPORTED_AGENTS)}[/]")
35
+ raise typer.Exit(1)
36
+
37
+ agents = expand_agents(agent, root)
38
+ if agent == "auto":
39
+ console.print(f"[dim]Auto-detected agent: {agents[0]}[/]")
40
+
41
+ for selected in agents:
42
+ console.print(f"\n[bold]{selected}[/]")
43
+ results = install_agent_integration(
44
+ root,
45
+ selected,
46
+ install_slash_command=_install_slash_command,
47
+ )
48
+ _print_install_results(selected, results)
49
+
50
+ if repair_existing_global_hooks:
51
+ _repair_existing_global_hooks()
52
+
53
+ console.print("\n[bold green]Upgrade integration refresh complete.[/]")
54
+ console.print(f" Verify with: [bold]agentpack doctor --agent {agent}[/]")
55
+
56
+
57
+ def _repair_existing_global_hooks() -> None:
58
+ repaired = False
59
+ if _global_git_templates_are_installed():
60
+ repaired = True
61
+ console.print("\n[bold]Refreshing existing global git template hooks...[/]")
62
+ hook_results = global_hooks.install_git_template_hooks()
63
+ _print_global_template_results(hook_results)
64
+ git_cfg_action = global_hooks.configure_git_template_dir(dry_run=False)
65
+ console.print(f"[green]git config --global init.templateDir {git_cfg_action}.[/]")
66
+
67
+ rc_file = global_hooks._detect_rc_file()
68
+ if rc_file is not None and rc_file.exists() and global_hooks._SHELL_MARKER_START in rc_file.read_text(encoding="utf-8"):
69
+ repaired = True
70
+ console.print("\n[bold]Refreshing existing shell cd hook...[/]")
71
+ action, path = global_hooks.install_shell_hook(rc_file)
72
+ if path is not None:
73
+ console.print(f"[green]{path} {action}.[/]")
74
+
75
+ if not repaired:
76
+ console.print("\n[dim]No existing global AgentPack hooks found to refresh.[/]")
77
+
78
+
79
+ def _global_git_templates_are_installed() -> bool:
80
+ hooks_dir = global_hooks._GIT_TEMPLATE_DIR / "hooks"
81
+ for name in global_hooks._HOOK_SCRIPTS:
82
+ hook_path = hooks_dir / name
83
+ if hook_path.exists() and global_hooks._AGENTPACK_MARKER in hook_path.read_text(encoding="utf-8"):
84
+ return True
85
+ try:
86
+ result = subprocess.run(
87
+ ["git", "config", "--global", "init.templateDir"],
88
+ capture_output=True,
89
+ text=True,
90
+ )
91
+ except Exception:
92
+ return False
93
+ return result.stdout.strip() == str(global_hooks._GIT_TEMPLATE_DIR)
@@ -73,6 +73,15 @@ def fallback_agent_guidance() -> str:
73
73
  )
74
74
 
75
75
 
76
+ def prompt_quality_guidance() -> str:
77
+ return (
78
+ "Prompt hygiene: for agent-mode coding work, prefer `Task`, `Files`, "
79
+ "`Acceptance criteria`, `Constraints`, `Validation`, and `Output` sections. "
80
+ "For short/simple questions, use Ask/Chat mode instead of agent mode. "
81
+ "Keep routine responses concise unless the user asks for detail."
82
+ )
83
+
84
+
76
85
  def installed_cli_status() -> dict[str, object]:
77
86
  binary = shutil.which("agentpack")
78
87
  status: dict[str, object] = {
@@ -113,7 +122,7 @@ def _commands_from_help(text: str) -> list[str]:
113
122
  commands: set[str] = set()
114
123
  known = set(available_cli_commands())
115
124
  for line in text.splitlines():
116
- stripped = line.strip()
125
+ stripped = line.strip().strip("│").strip()
117
126
  if not stripped:
118
127
  continue
119
128
  first = stripped.split()[0].strip("`")
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentpack",
3
- "version": "0.3.26",
3
+ "version": "0.3.28",
4
4
  "description": "Thin Codex plugin for AgentPack ranked repo context.",
5
5
  "author": {
6
6
  "name": "AgentPack",
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import re
4
4
  from pathlib import Path
5
5
 
6
- from agentpack.core.command_surface import fallback_agent_guidance, refresh_commands
6
+ from agentpack.core.command_surface import fallback_agent_guidance, prompt_quality_guidance, refresh_commands
7
7
  from agentpack.integrations.git_hooks import install_git_hooks
8
8
  from agentpack.integrations.vscode_tasks import install_vscode_tasks
9
9
 
@@ -31,7 +31,9 @@ At the start of every coding task:
31
31
 
32
32
  When the user switches to a different coding task, update `.agentpack/task.md`, then call MCP again or rerun the refresh command before editing.
33
33
 
34
- {fallback_agent_guidance()}{thread_line}
34
+ {fallback_agent_guidance()}
35
+
36
+ {prompt_quality_guidance()}{thread_line}
35
37
  <!-- agentpack:block:end -->"""
36
38
 
37
39
  _BLOCK_RE = re.compile(
@@ -4,7 +4,7 @@ import json
4
4
  import re
5
5
  from pathlib import Path
6
6
 
7
- from agentpack.core.command_surface import fallback_agent_guidance, refresh_commands
7
+ from agentpack.core.command_surface import fallback_agent_guidance, prompt_quality_guidance, refresh_commands
8
8
 
9
9
 
10
10
  def _agentpack_block() -> str:
@@ -59,7 +59,9 @@ agentpack pack --agent claude --task auto
59
59
 
60
60
  Then read `.agentpack/context.claude.md`.
61
61
 
62
- {fallback_agent_guidance()}{thread_line}
62
+ {fallback_agent_guidance()}
63
+
64
+ {prompt_quality_guidance()}{thread_line}
63
65
  <!-- agentpack:end -->"""
64
66
 
65
67
 
@@ -8,7 +8,7 @@ from importlib import resources
8
8
  from pathlib import Path
9
9
 
10
10
  from agentpack import __version__
11
- from agentpack.core.command_surface import fallback_agent_guidance, refresh_commands
11
+ from agentpack.core.command_surface import fallback_agent_guidance, prompt_quality_guidance, refresh_commands
12
12
  from agentpack.integrations.git_hooks import install_git_hooks
13
13
 
14
14
  def _agentpack_block() -> str:
@@ -35,7 +35,9 @@ At the start of every coding task:
35
35
 
36
36
  When the user switches to a different coding task, update `.agentpack/task.md`, then call MCP again or rerun the refresh command before editing.
37
37
 
38
- {fallback_agent_guidance()}{thread_line}
38
+ {fallback_agent_guidance()}
39
+
40
+ {prompt_quality_guidance()}{thread_line}
39
41
  <!-- agentpack:end -->"""
40
42
 
41
43
  _BLOCK_RE = re.compile(
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import re
4
4
  from pathlib import Path
5
5
 
6
- from agentpack.core.command_surface import fallback_agent_guidance, refresh_commands
6
+ from agentpack.core.command_surface import fallback_agent_guidance, prompt_quality_guidance, refresh_commands
7
7
  from agentpack.integrations.git_hooks import install_git_hooks
8
8
  from agentpack.integrations.vscode_tasks import install_vscode_tasks
9
9
 
@@ -27,7 +27,8 @@ At the start of every coding task:
27
27
  6. Use files listed in context as starting points, but verify with actual code before editing.
28
28
  When the user switches to a different coding task, update `.agentpack/task.md`, then call MCP again or rerun the refresh command before editing.
29
29
  If context is missing: {commands.context_missing}.
30
- {fallback_agent_guidance()}{thread_line}
30
+ {fallback_agent_guidance()}
31
+ {prompt_quality_guidance()}{thread_line}
31
32
  <!-- agentpack:rule:end -->"""
32
33
 
33
34
  _RULE_RE = re.compile(
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import re
4
4
  from pathlib import Path
5
5
 
6
- from agentpack.core.command_surface import fallback_agent_guidance, refresh_commands
6
+ from agentpack.core.command_surface import fallback_agent_guidance, prompt_quality_guidance, refresh_commands
7
7
  from agentpack.integrations.git_hooks import install_git_hooks
8
8
  from agentpack.integrations.vscode_tasks import install_vscode_tasks
9
9
 
@@ -26,7 +26,8 @@ At the start of every coding task:
26
26
  5. Use files listed in context as starting points, but verify with actual code before editing.
27
27
  When the user switches to a different coding task, update `.agentpack/task.md`, then call MCP again or rerun the refresh command before editing.
28
28
  If context is missing: {commands.context_missing}.
29
- {fallback_agent_guidance()}{thread_line}
29
+ {fallback_agent_guidance()}
30
+ {prompt_quality_guidance()}{thread_line}
30
31
  <!-- agentpack:rule:end -->"""
31
32
 
32
33
  _RULE_RE = re.compile(
@@ -64,6 +64,7 @@ class SkillInventory(BaseModel):
64
64
 
65
65
  class RouteResult(BaseModel):
66
66
  task: str
67
+ recommended_interaction_mode: str = "agent"
67
68
  task_mode: str = "broad_feature"
68
69
  task_mode_confidence: float = 0.0
69
70
  task_mode_signals: list[str] = Field(default_factory=list)
@@ -74,6 +75,8 @@ class RouteResult(BaseModel):
74
75
  suggested_commands: list[CommandSuggestion] = Field(default_factory=list)
75
76
  evidence_checklist: list[str] = Field(default_factory=list)
76
77
  routing_notes: list[str] = Field(default_factory=list)
78
+ prompt_quality_warnings: list[str] = Field(default_factory=list)
79
+ recommended_prompt_template: list[str] = Field(default_factory=list)
77
80
  safety_warnings: list[str] = Field(default_factory=list)
78
81
  agent_prompt: str = ""
79
82
 
@@ -8,6 +8,7 @@ def build_agent_prompt(result: RouteResult) -> str:
8
8
  "Use Agentpack route result before editing.",
9
9
  "",
10
10
  f"Task: {result.task}",
11
+ f"Recommended interaction mode: {result.recommended_interaction_mode}",
11
12
  f"Task mode: {result.task_mode} (confidence {result.task_mode_confidence:.2f})",
12
13
  "",
13
14
  "Read these files first:",
@@ -42,6 +43,13 @@ def build_agent_prompt(result: RouteResult) -> str:
42
43
  lines += ["", "Safety warnings:"]
43
44
  lines.extend(f"- {warning}" for warning in result.safety_warnings)
44
45
 
46
+ if result.prompt_quality_warnings:
47
+ lines += ["", "Prompt quality warnings:"]
48
+ lines.extend(f"- {warning}" for warning in result.prompt_quality_warnings)
49
+ if result.recommended_prompt_template:
50
+ lines += ["", "Better prompt template:"]
51
+ lines.extend(f"- {item}" for item in result.recommended_prompt_template)
52
+
45
53
  if result.routing_notes:
46
54
  lines += ["", "Routing notes:"]
47
55
  lines.extend(f"- {note}" for note in result.routing_notes)
@@ -115,6 +123,7 @@ def render_plain(result: RouteResult) -> str:
115
123
  lines.append("- No external side-effect skills selected.")
116
124
 
117
125
  lines += ["", "Routing:"]
126
+ lines.append(f"- recommended_interaction_mode: {result.recommended_interaction_mode}")
118
127
  lines.append(f"- task_mode: {result.task_mode} (confidence {result.task_mode_confidence:.2f})")
119
128
  if result.task_mode_signals:
120
129
  lines.append(f"- signals: {', '.join(result.task_mode_signals[:4])}")
@@ -123,6 +132,12 @@ def render_plain(result: RouteResult) -> str:
123
132
  if result.evidence_checklist:
124
133
  lines.append("- evidence checklist:")
125
134
  lines.extend(f" - {item}" for item in result.evidence_checklist)
135
+ if result.prompt_quality_warnings:
136
+ lines.append("- prompt quality warnings:")
137
+ lines.extend(f" - {warning}" for warning in result.prompt_quality_warnings)
138
+ if result.recommended_prompt_template:
139
+ lines.append("- prompt template:")
140
+ lines.extend(f" - {item}" for item in result.recommended_prompt_template)
126
141
 
127
142
  lines += ["", "Agent prompt:", result.agent_prompt]
128
143
  return "\n".join(lines)
@@ -17,8 +17,8 @@ _GENERAL_CODING_SKILL_TERMS = {
17
17
  "surgical", "verification", "verifiable", "writing",
18
18
  }
19
19
  _STOPWORDS = {
20
- "and", "are", "but", "for", "from", "into", "the", "this", "that", "then",
21
- "with", "your", "fix", "add", "make", "debug",
20
+ "and", "are", "but", "can", "for", "from", "into", "the", "this", "that", "then",
21
+ "with", "you", "your", "fix", "add", "make", "debug",
22
22
  }
23
23
  _TASK_TYPE_TERMS = {
24
24
  "bugfix": {"bug", "broken", "error", "exception", "fail", "failing", "fix", "issue", "regression"},
@@ -92,7 +92,9 @@ def score_skills(
92
92
  item = max(pool, key=lambda candidate: (_diverse_score(candidate, selected), candidate.score))
93
93
  pool.remove(item)
94
94
  if item.skill.side_effect_level == "external" and not allow_external:
95
- if len(warnings) < 10:
95
+ if not _should_warn_blocked_external(item):
96
+ continue
97
+ if len(warnings) < 5:
96
98
  warnings.append(
97
99
  f"External side-effect skill not auto-selected: {item.skill.name} ({item.skill.path})"
98
100
  )
@@ -107,6 +109,25 @@ def score_skills(
107
109
  return selected, warnings, scored
108
110
 
109
111
 
112
+ def _should_warn_blocked_external(item: SelectedSkill) -> bool:
113
+ if item.confidence >= item.skill.confidence_threshold:
114
+ return True
115
+ return _has_strong_external_warning_reason(item.reasons)
116
+
117
+
118
+ def _has_strong_external_warning_reason(reasons: list[str]) -> bool:
119
+ for reason in reasons:
120
+ if reason == "test task match":
121
+ return True
122
+ if reason.startswith(("task type match:", "framework match:", "language match:", "path hint match:", "tool match:", "historical success boost:")):
123
+ return True
124
+ if reason.startswith("task keyword match:"):
125
+ matches = [part.strip() for part in reason.split(":", 1)[1].split(",") if part.strip()]
126
+ if len(matches) >= 2:
127
+ return True
128
+ return False
129
+
130
+
110
131
  def _score_skill(
111
132
  skill: SkillArtifact,
112
133
  *,
@@ -35,6 +35,13 @@ class TaskModeDecision:
35
35
  signals: list[str]
36
36
 
37
37
 
38
+ @dataclass(frozen=True)
39
+ class PromptQualityDecision:
40
+ recommended_interaction_mode: str
41
+ warnings: list[str]
42
+ template: list[str]
43
+
44
+
38
45
  class RouteService:
39
46
  def inventory(self, root: Path, *, use_index: bool = True) -> SkillInventory:
40
47
  cfg = load_config(root)
@@ -47,6 +54,7 @@ class RouteService:
47
54
  task = _normalize_task(task)
48
55
  mode_decision = classify_task_mode(task)
49
56
  task_mode = mode_decision.mode
57
+ prompt_quality = assess_prompt_quality(task, task_mode)
50
58
  cfg = load_config(root)
51
59
  plan = PackPlanner().plan(PackRequest(
52
60
  root=root,
@@ -89,6 +97,7 @@ class RouteService:
89
97
 
90
98
  result = RouteResult(
91
99
  task=task,
100
+ recommended_interaction_mode=prompt_quality.recommended_interaction_mode,
92
101
  task_mode=task_mode,
93
102
  task_mode_confidence=mode_decision.confidence,
94
103
  task_mode_signals=mode_decision.signals,
@@ -99,6 +108,8 @@ class RouteService:
99
108
  suggested_commands=commands,
100
109
  evidence_checklist=checklist,
101
110
  routing_notes=notes,
111
+ prompt_quality_warnings=prompt_quality.warnings,
112
+ recommended_prompt_template=prompt_quality.template,
102
113
  safety_warnings=safety_warnings,
103
114
  )
104
115
  result.agent_prompt = build_agent_prompt(result)
@@ -183,6 +194,110 @@ def classify_task_mode(task: str) -> TaskModeDecision:
183
194
  return TaskModeDecision("broad_feature", 0.35, ["fallback"])
184
195
 
185
196
 
197
+ def assess_prompt_quality(task: str, task_mode: str) -> PromptQualityDecision:
198
+ lower = task.lower()
199
+ warnings: list[str] = []
200
+ words = _task_words(task)
201
+ has_file_context = _has_file_context(task)
202
+ has_output_constraint = _has_output_constraint(lower)
203
+ has_spec_signal = _has_spec_signal(lower)
204
+ simple_question = _is_simple_question(task, words)
205
+
206
+ if not has_file_context and task_mode not in {"pr_review", "runtime_debugging", "integration_readiness"}:
207
+ warnings.append("No file context detected. Add `#file` references or name the target files before using agent mode.")
208
+ if _looks_vague_or_repeated(lower, words):
209
+ warnings.append("Prompt is very short or retry-shaped. Rephrase with concrete files, observed behavior, and acceptance criteria instead of repeating.")
210
+ if len(words) <= 35 and not has_output_constraint:
211
+ warnings.append("Short prompt has no output constraint. Ask for concise bullets, no commentary, or a max length to avoid verbose output.")
212
+ if not has_spec_signal and task_mode in {"broad_feature", "runtime_debugging", "integration_readiness", "release_docs"}:
213
+ warnings.append("No spec or acceptance criteria detected. Add requirements, constraints, and validation before coding.")
214
+ if simple_question:
215
+ warnings.append("Simple question shape detected. Prefer Ask/Chat mode unless files, commands, or edits are required.")
216
+ if _has_frustration_signal(task):
217
+ warnings.append("Frustration signal detected. Pause retries and switch to a smaller diagnostic prompt.")
218
+ if _has_session_drift_signal(lower):
219
+ warnings.append("Multiple task types detected. Start a fresh focused session when switching between review, debug, release, docs, and feature work.")
220
+
221
+ mode = "ask" if simple_question and not has_file_context else "agent"
222
+ return PromptQualityDecision(
223
+ recommended_interaction_mode=mode,
224
+ warnings=warnings,
225
+ template=_prompt_template() if warnings else [],
226
+ )
227
+
228
+
229
+ def _task_words(task: str) -> list[str]:
230
+ return re.findall(r"[A-Za-z0-9_#./:-]+", task)
231
+
232
+
233
+ def _has_file_context(task: str) -> bool:
234
+ if "#file" in task.lower():
235
+ return True
236
+ return bool(re.search(r"(?:^|\s)[\w./-]+\.(?:py|ts|tsx|js|jsx|go|rs|java|rb|md|json|toml|ya?ml|css|scss)(?=\s|$|[:,])", task))
237
+
238
+
239
+ def _has_output_constraint(lower: str) -> bool:
240
+ return any(term in lower for term in ("concise", "one-line", "one line", "no commentary", "brief", "max ", "bullets", "json only", "short"))
241
+
242
+
243
+ def _has_spec_signal(lower: str) -> bool:
244
+ return any(term in lower for term in ("acceptance", "criteria", "requirements", "constraints", "validation", "must", "ensure", "spec", "plan:"))
245
+
246
+
247
+ def _is_simple_question(task: str, words: list[str]) -> bool:
248
+ lower = task.lower().strip()
249
+ if len(words) > 14:
250
+ return False
251
+ if any(term in lower for term in ("fix", "edit", "change", "implement", "add ", "remove", "update", "release", "run ")):
252
+ return False
253
+ return lower.endswith("?") or lower.startswith(("what ", "why ", "how ", "can ", "should ", "is ", "does ", "do "))
254
+
255
+
256
+ def _looks_vague_or_repeated(lower: str, words: list[str]) -> bool:
257
+ if len(words) <= 5:
258
+ return True
259
+ return lower.strip() in {
260
+ "fix this",
261
+ "try again",
262
+ "do it again",
263
+ "not working",
264
+ "can you fix this",
265
+ "can you fix these gaps",
266
+ }
267
+
268
+
269
+ def _has_frustration_signal(task: str) -> bool:
270
+ letters = [char for char in task if char.isalpha()]
271
+ uppercase_ratio = sum(1 for char in letters if char.isupper()) / len(letters) if letters else 0
272
+ return "!!!" in task or "???" in task or (len(letters) >= 10 and uppercase_ratio >= 0.65)
273
+
274
+
275
+ def _has_session_drift_signal(lower: str) -> bool:
276
+ task_types = sum(
277
+ 1
278
+ for terms in (
279
+ ("review", "pr "),
280
+ ("debug", "log", "runtime"),
281
+ ("release", "publish", "changelog"),
282
+ ("docs", "readme"),
283
+ ("feature", "implement", "build"),
284
+ )
285
+ if any(term in lower for term in terms)
286
+ )
287
+ return task_types >= 3
288
+
289
+
290
+ def _prompt_template() -> list[str]:
291
+ return [
292
+ "Task: <what to change or answer>",
293
+ "Files: #file:<path> #file:<path> (or name the target files)",
294
+ "Acceptance criteria: <bullets>",
295
+ "Constraints: <scope, style, risk limits>",
296
+ "Validation: <tests/checks to run>",
297
+ "Output: concise bullets; no extra commentary",
298
+ ]
299
+
300
+
186
301
  def _has_any(lower: str, terms: tuple[str, ...], signals: list[str], label: str) -> bool:
187
302
  matched = [term.strip() for term in terms if term in lower]
188
303
  if matched:
@@ -1,38 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import typer
4
-
5
- from agentpack.commands._shared import console, _root
6
- from agentpack.commands.install import _install_slash_command, _print_install_results
7
- from agentpack.integrations.agents import SUPPORTED_AGENTS, expand_agents, install_agent_integration
8
-
9
-
10
- def register(app: typer.Typer) -> None:
11
- @app.command()
12
- def upgrade(
13
- agent: str = typer.Option(
14
- "auto",
15
- "--agent",
16
- help=f"Agent integration to refresh after package upgrade ({' | '.join(SUPPORTED_AGENTS)}).",
17
- ),
18
- ) -> None:
19
- """Refresh the detected AgentPack IDE/agent integration after upgrading the package."""
20
- root = _root()
21
- if agent not in SUPPORTED_AGENTS:
22
- console.print(f"[yellow]Unknown agent: {agent}. Supported: {', '.join(SUPPORTED_AGENTS)}[/]")
23
- raise typer.Exit(1)
24
-
25
- agents = expand_agents(agent, root)
26
- if agent == "auto":
27
- console.print(f"[dim]Auto-detected agent: {agents[0]}[/]")
28
-
29
- for selected in agents:
30
- console.print(f"\n[bold]{selected}[/]")
31
- results = install_agent_integration(
32
- root,
33
- selected,
34
- install_slash_command=_install_slash_command,
35
- )
36
- _print_install_results(selected, results)
37
-
38
- console.print("\n[bold green]Upgrade integration refresh complete.[/]")
File without changes