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.
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/PKG-INFO +1 -1
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/pyproject.toml +1 -1
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/__init__.py +1 -1
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/codex.py +3 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/application/pack_service.py +4 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/doctor.py +19 -12
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/init.py +11 -1
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/install.py +15 -9
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/learn.py +2 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/memory.py +31 -0
- agentpack_cli-0.3.29/src/agentpack/data/agentpack-learn.md +66 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/.codex-plugin/plugin.json +2 -1
- agentpack_cli-0.3.29/src/agentpack/data/codex_plugin/skills/agentpack-learn.md +67 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/codex.py +48 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/agents.py +31 -1
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/collector.py +6 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/extractor.py +2 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/models.py +2 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/renderers.py +5 -2
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/service.py +22 -1
- agentpack_cli-0.3.29/src/agentpack/session/references.py +288 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/.gitignore +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/LICENSE +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/README.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/antigravity.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/base.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/claude.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/cursor.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/detect.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/generic.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/adapters/windsurf.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/dependency_graph.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/go_imports.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/java_imports.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/js_ts_imports.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/monorepo.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/naming_signals.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/python_ast.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/python_imports.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/ranking.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/repo_map.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/role_inference.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/rust_imports.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/symbols.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/task_classifier.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/analysis/tests.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/application/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/cli.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/_shared.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/benchmark.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/ci_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/claude_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/compress_output.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/dashboard.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/dev_check.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/diagnose_selection.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/diff.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/eval_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/explain.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/guard.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/hook_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/ignore_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/mcp_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/migrate.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/monitor.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/next_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/pack.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/perf.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/quickstart.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/release_check.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/release_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/repair.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/retrieve.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/route.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/scan.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/skills.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/start_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/state_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/stats.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/status.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/summarize.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/task_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/threads.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/tune.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/upgrade.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/verify_wheel.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/watch.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/workflow_cmd.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/commands/wrap.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/bootstrap.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/cache.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/changed_paths.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/command_surface.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/config.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/context_pack.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/diff.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/e2e_benchmark.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/evals.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/execution_state.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/git.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/git_hooks.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/global_install.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/ignore.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/loop_protocol.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/merkle.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/models.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/modes.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/pack_registry.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/redactor.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/scanner.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/snapshot.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/task_freshness.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/thread_context.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/token_estimator.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/core/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/collectors.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/models.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/dashboard/renderers.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/agentpack.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-pack.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-refresh.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-review.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack-route.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/data/codex_plugin/skills/agentpack.md +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/antigravity.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/claude.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/cursor.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/installers/windsurf.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/git_hooks.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/global_install.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/platform.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/integrations/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/feedback.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/lesson_ranker.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/provider.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/quality.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/learning/skill_map.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/mcp_server.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/output_compression/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/output_compression/core.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/compact.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/markdown.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/renderers/receipts.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/discovery.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/models.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/parser.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/prompt_builder.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/scoring.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/router/skills_index.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/session/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/session/events.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/session/state.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/summaries/__init__.py +0 -0
- {agentpack_cli-0.3.28 → agentpack_cli-0.3.29}/src/agentpack/summaries/base.py +0 -0
- {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.
|
|
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.
|
|
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"
|
|
@@ -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
|
|
338
|
-
console.print("\n[bold]Slash
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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 (
|
|
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
|
|
51
|
-
console.print(f"[green]
|
|
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
|
-
|
|
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" /
|
|
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" /
|
|
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.
|
|
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
|
-
|
|
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=
|
|
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,
|