agentpack-cli 0.3.1__tar.gz → 0.3.2__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 (93) hide show
  1. agentpack_cli-0.3.1/README.md → agentpack_cli-0.3.2/PKG-INFO +114 -9
  2. agentpack_cli-0.3.1/PKG-INFO → agentpack_cli-0.3.2/README.md +75 -48
  3. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/pyproject.toml +3 -3
  4. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/__init__.py +1 -1
  5. agentpack_cli-0.3.2/src/agentpack/analysis/naming_signals.py +140 -0
  6. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/ranking.py +17 -0
  7. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/models.py +2 -0
  8. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/data/agentpack.md +19 -10
  9. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/summaries/offline.py +11 -0
  10. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/.gitignore +0 -0
  11. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/LICENSE +0 -0
  12. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/__init__.py +0 -0
  13. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/antigravity.py +0 -0
  14. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/base.py +0 -0
  15. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/claude.py +0 -0
  16. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/codex.py +0 -0
  17. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/cursor.py +0 -0
  18. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/detect.py +0 -0
  19. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/generic.py +0 -0
  20. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/windsurf.py +0 -0
  21. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/__init__.py +0 -0
  22. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/dependency_graph.py +0 -0
  23. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/go_imports.py +0 -0
  24. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/java_imports.py +0 -0
  25. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/js_ts_imports.py +0 -0
  26. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/monorepo.py +0 -0
  27. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/python_imports.py +0 -0
  28. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/repo_map.py +0 -0
  29. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/role_inference.py +0 -0
  30. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/rust_imports.py +0 -0
  31. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/symbols.py +0 -0
  32. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/task_classifier.py +0 -0
  33. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/tests.py +0 -0
  34. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/application/__init__.py +0 -0
  35. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/application/pack_service.py +0 -0
  36. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/cli.py +0 -0
  37. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/__init__.py +0 -0
  38. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/_shared.py +0 -0
  39. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/benchmark.py +0 -0
  40. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/claude_cmd.py +0 -0
  41. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/diff.py +0 -0
  42. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/doctor.py +0 -0
  43. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/explain.py +0 -0
  44. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/hook_cmd.py +0 -0
  45. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/init.py +0 -0
  46. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/install.py +0 -0
  47. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/mcp_cmd.py +0 -0
  48. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/monitor.py +0 -0
  49. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/pack.py +0 -0
  50. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/quickstart.py +0 -0
  51. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/repair.py +0 -0
  52. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/scan.py +0 -0
  53. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/stats.py +0 -0
  54. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/status.py +0 -0
  55. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/summarize.py +0 -0
  56. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/tune.py +0 -0
  57. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/watch.py +0 -0
  58. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/__init__.py +0 -0
  59. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/bootstrap.py +0 -0
  60. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/cache.py +0 -0
  61. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/config.py +0 -0
  62. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/context_pack.py +0 -0
  63. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/diff.py +0 -0
  64. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/git.py +0 -0
  65. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/git_hooks.py +0 -0
  66. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/global_install.py +0 -0
  67. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/ignore.py +0 -0
  68. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/merkle.py +0 -0
  69. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/redactor.py +0 -0
  70. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/scanner.py +0 -0
  71. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/snapshot.py +0 -0
  72. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/token_estimator.py +0 -0
  73. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/vscode_tasks.py +0 -0
  74. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/__init__.py +0 -0
  75. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/antigravity.py +0 -0
  76. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/claude.py +0 -0
  77. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/codex.py +0 -0
  78. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/cursor.py +0 -0
  79. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/windsurf.py +0 -0
  80. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/__init__.py +0 -0
  81. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/agents.py +0 -0
  82. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/git_hooks.py +0 -0
  83. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/global_install.py +0 -0
  84. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/vscode_tasks.py +0 -0
  85. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/mcp_server.py +0 -0
  86. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/__init__.py +0 -0
  87. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/compact.py +0 -0
  88. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/markdown.py +0 -0
  89. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/receipts.py +0 -0
  90. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/session/__init__.py +0 -0
  91. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/session/state.py +0 -0
  92. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/summaries/__init__.py +0 -0
  93. {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/summaries/base.py +0 -0
@@ -1,19 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentpack-cli
3
+ Version: 0.3.2
4
+ Summary: Local context engine for AI coding agents that ranks relevant files and builds task-focused context packs.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: ai,ai-coding-agents,antigravity,ci,claude,claude-code,codex,context,context-engine,context-packing,cursor,developer-tools,llm,mcp,packing,prompt-context,repo-analysis,windsurf
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Software Development :: Build Tools
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: pathspec>=0.12.1
19
+ Requires-Dist: pydantic>=2.0.0
20
+ Requires-Dist: rich>=13.0.0
21
+ Requires-Dist: tiktoken>=0.7.0
22
+ Requires-Dist: tomli-w>=1.0.0
23
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
24
+ Requires-Dist: typer>=0.12.0
25
+ Provides-Extra: all
26
+ Requires-Dist: mcp>=1.0.0; extra == 'all'
27
+ Requires-Dist: watchdog>=4.0.0; extra == 'all'
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy; extra == 'dev'
30
+ Requires-Dist: pytest; extra == 'dev'
31
+ Requires-Dist: pytest-cov; extra == 'dev'
32
+ Requires-Dist: ruff; extra == 'dev'
33
+ Requires-Dist: tomli>=2.0.0; (python_version < '3.11') and extra == 'dev'
34
+ Provides-Extra: mcp
35
+ Requires-Dist: mcp>=1.0.0; extra == 'mcp'
36
+ Provides-Extra: watch
37
+ Requires-Dist: watchdog>=4.0.0; extra == 'watch'
38
+ Description-Content-Type: text/markdown
39
+
1
40
  # AgentPack
2
41
 
3
42
  [![PyPI version](https://img.shields.io/pypi/v/agentpack-cli.svg)](https://pypi.org/project/agentpack-cli/)
43
+ [![npm version](https://img.shields.io/npm/v/@vishal2612200/agentpack.svg)](https://www.npmjs.com/package/@vishal2612200/agentpack)
44
+ [![npm downloads](https://img.shields.io/npm/dm/@vishal2612200/agentpack.svg)](https://www.npmjs.com/package/@vishal2612200/agentpack)
4
45
  [![Python versions](https://img.shields.io/pypi/pyversions/agentpack-cli.svg)](https://pypi.org/project/agentpack-cli/)
5
46
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
47
  [![CI](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml/badge.svg)](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
7
48
 
8
- > **Status: alpha (v0.3.1).** Works, tested, used in real sessions. Python and JavaScript/TypeScript are the best-supported languages. Public benchmark proof exists for the current suite, but broader repo coverage is still growing. API may change before 1.0.
49
+ > **Status: alpha (v0.3.2).** Works, tested, used in real sessions. Python and JavaScript/TypeScript are the best-supported languages. Public benchmark proof exists for the current suite, but broader repo coverage is still growing. API may change before 1.0.
9
50
  >
10
51
  > **Platform note:** macOS and Linux are fully supported. Windows support is not yet implemented (git hooks use POSIX shell; the Claude Code session hooks use `python3`/`rm -f`). Contributions welcome.
11
52
 
12
53
  **Local context engine for AI coding agents.**
13
54
 
14
- AgentPack builds task-focused context packs for Claude Code, Cursor, Windsurf, Codex, Antigravity, CI jobs, and any LLM workflow that can read markdown. It scans your repo locally, ranks files for the task, compresses the result into a token budget, and keeps the pack fresh through CLI commands, MCP tools, hooks, and agent integrations.
55
+ AgentPack gives Claude Code, Codex, Cursor, Windsurf, Antigravity, CI jobs, and other agent workflows a better starting point. It analyzes your repo locally, finds the relevant files for a task, and packages them into compact task-focused context packs for CLI and MCP tool workflows.
15
56
 
16
- AgentPack is useful when a repo is too large to paste, but a blank agent session wastes time rediscovering the same code structure. It is a context preparation tool, not a coding agent.
57
+ Use AgentPack when a repo is too large to paste and you want faster, more consistent context preparation before an agent starts working. It works offline, keeps the product boundary explicit, and is a context preparation tool, not a coding agent.
17
58
 
18
59
  ## Contents
19
60
 
@@ -21,6 +62,7 @@ AgentPack is useful when a repo is too large to paste, but a blank agent session
21
62
  - [Install](#install)
22
63
  - [Quickstart](#quickstart)
23
64
  - [Quality Bar](#quality-bar)
65
+ - [Download Stats](#download-stats)
24
66
  - [Debugging Selection](#debugging-selection)
25
67
  - [Supported Integrations](#supported-integrations)
26
68
  - [Commands](#commands)
@@ -31,8 +73,9 @@ AgentPack is useful when a repo is too large to paste, but a blank agent session
31
73
 
32
74
  ## Features
33
75
 
34
- - **Task-focused packing**: ranks files from git changes, task terms, symbols, imports, related tests, configs, churn, and repo history.
76
+ - **Task-focused packing**: ranks files from git changes, task terms, symbols, imports, related tests, configs, churn, repo history, and deterministic offline summaries.
35
77
  - **Budget-aware compression**: emits `full`, `diff`, `symbols`, `skeleton`, or `summary` views instead of all-or-nothing file dumps.
78
+ - **Local code intelligence**: extracts roles, domains, entrypoints, definitions, dependencies, env reads, side effects, and external systems using static analysis.
36
79
  - **Semantic repo map**: adds a compact module-level map before file context so agents orient faster.
37
80
  - **Freshness and deltas**: records task source, git state, snapshot hashes, selected-file deltas, and stale-context warnings.
38
81
  - **Agent integrations**: installs Claude Code, Cursor, Windsurf, Codex, Antigravity, VS Code tasks, git hooks, and MCP configuration.
@@ -66,6 +109,27 @@ sudo pacman -S python-pipx
66
109
  pipx ensurepath
67
110
  ```
68
111
 
112
+ If `pipx` is not installed yet:
113
+
114
+ ```bash
115
+ # macOS
116
+ brew install pipx
117
+
118
+ # Ubuntu/Debian
119
+ sudo apt install pipx
120
+
121
+ # Fedora
122
+ sudo dnf install pipx
123
+
124
+ # Arch
125
+ sudo pacman -S python-pipx
126
+
127
+ # Then ensure pipx apps are on PATH
128
+ pipx ensurepath
129
+ ```
130
+
131
+ `pipx` is the recommended default because it keeps the CLI isolated and avoids many macOS/Linux global `pip install` issues, including PEP 668 `externally-managed-environment` errors. If you prefer `pip`, install inside a virtual environment.
132
+
69
133
  JavaScript-heavy teams can install the npm wrapper:
70
134
 
71
135
  ```bash
@@ -73,7 +137,7 @@ npm install -g @vishal2612200/agentpack
73
137
  agentpack --version
74
138
  ```
75
139
 
76
- The npm package is a Node launcher around the Python implementation. It requires Node.js 18+ and Python 3.10+, then installs the matching core `agentpack-cli` package into a per-version virtual environment on first run. The Python package remains the source of truth; npm is the convenience install path for JavaScript-heavy teams. Use the PyPI extras below when you need optional `watch` or `mcp` dependencies.
140
+ The npm package is a Node launcher around the Python implementation. It requires Node.js 18+ and Python 3.10+, then installs the matching core `agentpack-cli` package into a per-version virtual environment on first run. The Python package remains the source of truth; npm is the convenience install path for JavaScript-heavy teams. See the [npm README](https://github.com/vishal2612200/agentpack/blob/main/npm/README.md) for wrapper cache controls and troubleshooting. Use the PyPI extras below when you need optional `watch` or `mcp` dependencies.
77
141
 
78
142
  ## Quickstart
79
143
 
@@ -144,6 +208,24 @@ ItsDangerous, and MarkupSafe by checking out each commit's parent and scoring
144
208
  against files actually changed by the commit. Synthetic fixtures are useful
145
209
  regression tests, but should not be presented as market proof.
146
210
 
211
+ ## Download Stats
212
+
213
+ npm exposes official package download counts through its public registry API and the npm downloads badge above:
214
+
215
+ ```bash
216
+ curl https://api.npmjs.org/downloads/point/last-month/%40vishal2612200%2Fagentpack
217
+ curl https://api.npmjs.org/downloads/point/last-week/%40vishal2612200%2Fagentpack
218
+ ```
219
+
220
+ PyPI does not show official project download counts on package pages. For rough trend data on the Python core package, use third-party mirrors:
221
+
222
+ ```bash
223
+ curl https://pypistats.org/api/packages/agentpack-cli/recent
224
+ ```
225
+
226
+ - PyPI Stats: <https://pypistats.org/packages/agentpack-cli>
227
+ - pepy.tech: <https://pepy.tech/project/agentpack-cli>
228
+
147
229
  ## Debugging Selection
148
230
 
149
231
  When AgentPack misses a file, the next command should explain the miss:
@@ -748,8 +830,12 @@ Uses `watchdog` if installed, falls back to polling. Context is refreshed whenev
748
830
  Install watchdog for better performance:
749
831
  ```bash
750
832
  pipx inject agentpack-cli watchdog
833
+ PIPX_AGENTPACK="$(pipx environment --value PIPX_BIN_DIR)/agentpack"
834
+ "$PIPX_AGENTPACK" watch
751
835
  ```
752
836
 
837
+ Use the explicit `pipx` binary path above if you also have the npm wrapper on `PATH`; otherwise `agentpack watch` may still resolve to the Node launcher.
838
+
753
839
  ---
754
840
 
755
841
  ### `agentpack claude`
@@ -770,9 +856,12 @@ Run AgentPack as an MCP server — exposes context packing as tools that Claude
770
856
 
771
857
  ```bash
772
858
  pipx inject agentpack-cli "agentpack-cli[mcp]"
773
- agentpack mcp
859
+ PIPX_AGENTPACK="$(pipx environment --value PIPX_BIN_DIR)/agentpack"
860
+ "$PIPX_AGENTPACK" mcp
774
861
  ```
775
862
 
863
+ Use the explicit `pipx` binary path above if you also have the npm wrapper on `PATH`; otherwise `agentpack mcp` may still resolve to the Node launcher instead of the extras-enabled Python CLI.
864
+
776
865
  Register in Claude Code settings (`~/.claude/settings.json`):
777
866
 
778
867
  ```json
@@ -1191,7 +1280,8 @@ Works like `.gitignore`. Default rules exclude:
1191
1280
  │ │
1192
1281
  │ Summary cache ── role, imports, │
1193
1282
  │ (offline) symbols, side effects, │
1194
- │ public API, errors
1283
+ │ public API, naming
1284
+ │ signals, errors │
1195
1285
  │ │
1196
1286
  │ Import graph ── Python AST │
1197
1287
  │ (6 languages) ─ JS/TS regex │
@@ -1204,6 +1294,9 @@ Works like `.gitignore`. Default rules exclude:
1204
1294
  │ ast.get_source_segment) classes, │
1205
1295
  │ ── arrow fns w/ =>) │
1206
1296
  │ │
1297
+ │ Naming signals ── public files/symbols │
1298
+ │ ── env/config/test ids │
1299
+ │ ── generic-name hints │
1207
1300
  │ Test detection ── name heuristics │
1208
1301
  │ Task keywords ── stopwords + variants│
1209
1302
  │ ── concept synonyms │
@@ -1229,6 +1322,7 @@ Works like `.gitignore`. Default rules exclude:
1229
1322
  │ +70 symbol +60 content match │
1230
1323
  │ +50 dep +40 rev-dep │
1231
1324
  │ +35 test +25 config +20 recent │
1325
+ │ +20 naming -6 generic public API │
1232
1326
  │ -50 large unrelated │
1233
1327
  │ History noise penalty from metrics │
1234
1328
  └────────────────────┬────────────────────┘
@@ -1316,14 +1410,15 @@ src/agentpack/
1316
1410
  rust_imports.py # use, mod, extern crate
1317
1411
  java_imports.py # Java import + Kotlin import
1318
1412
  symbols.py # AST symbols + body via ast.get_source_segment
1413
+ naming_signals.py # public-name classification for summaries + ranking boosts
1319
1414
  tests.py # source → test file mapping heuristics
1320
- ranking.py # keyword extraction, concept synonyms, scoring
1415
+ ranking.py # keyword extraction, concept synonyms, scoring, naming receipts
1321
1416
  monorepo.py # workspace detection + workspace ownership helpers
1322
1417
  repo_map.py # compact semantic repo map reserved inside token budget
1323
1418
  task_classifier.py # coarse task class for freshness/rendering/scoring context
1324
1419
 
1325
1420
  summaries/
1326
- offline.py # zero-API: AST/regex → imports, symbols, role, side effects, API, errors
1421
+ offline.py # zero-API: AST/regex → imports, symbols, role, side effects, API, naming signals, errors
1327
1422
  base.py # cache-or-build orchestration (parallel, ThreadPool+ProcessPool)
1328
1423
 
1329
1424
  adapters/ # context rendering only — no installation logic
@@ -1453,6 +1548,16 @@ pipx inject agentpack-cli "agentpack-cli[all]" # watch + mcp
1453
1548
 
1454
1549
  ## Development
1455
1550
 
1551
+ ## Public Naming And Ranking
1552
+
1553
+ AgentPack works better when public surfaces carry domain context. Prefer domain-revealing names for files, exported functions/classes, CLI commands, tests, and config/env identifiers.
1554
+
1555
+ - `verify_otp` is better than `handle`
1556
+ - `StripeWebhookHandler` is better than `Processor`
1557
+ - `session_token_expiry_test` is better than `test_flow`
1558
+
1559
+ This is guidance, not a lint rule. Local variable names are out of scope for AgentPack ranking.
1560
+
1456
1561
  Clone and run locally:
1457
1562
 
1458
1563
  ```bash
@@ -1,58 +1,21 @@
1
- Metadata-Version: 2.4
2
- Name: agentpack-cli
3
- Version: 0.3.1
4
- Summary: Task-aware context packing for AI coding agents — Claude, Cursor, Windsurf, Codex, and Antigravity
5
- License: MIT
6
- License-File: LICENSE
7
- Keywords: ai,claude,codex,coding-agent,context,cursor,llm,packing,windsurf
8
- Classifier: Development Status :: 3 - Alpha
9
- Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
- Classifier: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
15
- Classifier: Topic :: Software Development :: Build Tools
16
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
- Requires-Python: >=3.10
18
- Requires-Dist: pathspec>=0.12.1
19
- Requires-Dist: pydantic>=2.0.0
20
- Requires-Dist: rich>=13.0.0
21
- Requires-Dist: tiktoken>=0.7.0
22
- Requires-Dist: tomli-w>=1.0.0
23
- Requires-Dist: tomli>=2.0.0; python_version < '3.11'
24
- Requires-Dist: typer>=0.12.0
25
- Provides-Extra: all
26
- Requires-Dist: mcp>=1.0.0; extra == 'all'
27
- Requires-Dist: watchdog>=4.0.0; extra == 'all'
28
- Provides-Extra: dev
29
- Requires-Dist: mypy; extra == 'dev'
30
- Requires-Dist: pytest; extra == 'dev'
31
- Requires-Dist: pytest-cov; extra == 'dev'
32
- Requires-Dist: ruff; extra == 'dev'
33
- Requires-Dist: tomli>=2.0.0; (python_version < '3.11') and extra == 'dev'
34
- Provides-Extra: mcp
35
- Requires-Dist: mcp>=1.0.0; extra == 'mcp'
36
- Provides-Extra: watch
37
- Requires-Dist: watchdog>=4.0.0; extra == 'watch'
38
- Description-Content-Type: text/markdown
39
-
40
1
  # AgentPack
41
2
 
42
3
  [![PyPI version](https://img.shields.io/pypi/v/agentpack-cli.svg)](https://pypi.org/project/agentpack-cli/)
4
+ [![npm version](https://img.shields.io/npm/v/@vishal2612200/agentpack.svg)](https://www.npmjs.com/package/@vishal2612200/agentpack)
5
+ [![npm downloads](https://img.shields.io/npm/dm/@vishal2612200/agentpack.svg)](https://www.npmjs.com/package/@vishal2612200/agentpack)
43
6
  [![Python versions](https://img.shields.io/pypi/pyversions/agentpack-cli.svg)](https://pypi.org/project/agentpack-cli/)
44
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
45
8
  [![CI](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml/badge.svg)](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
46
9
 
47
- > **Status: alpha (v0.3.1).** Works, tested, used in real sessions. Python and JavaScript/TypeScript are the best-supported languages. Public benchmark proof exists for the current suite, but broader repo coverage is still growing. API may change before 1.0.
10
+ > **Status: alpha (v0.3.2).** Works, tested, used in real sessions. Python and JavaScript/TypeScript are the best-supported languages. Public benchmark proof exists for the current suite, but broader repo coverage is still growing. API may change before 1.0.
48
11
  >
49
12
  > **Platform note:** macOS and Linux are fully supported. Windows support is not yet implemented (git hooks use POSIX shell; the Claude Code session hooks use `python3`/`rm -f`). Contributions welcome.
50
13
 
51
14
  **Local context engine for AI coding agents.**
52
15
 
53
- AgentPack builds task-focused context packs for Claude Code, Cursor, Windsurf, Codex, Antigravity, CI jobs, and any LLM workflow that can read markdown. It scans your repo locally, ranks files for the task, compresses the result into a token budget, and keeps the pack fresh through CLI commands, MCP tools, hooks, and agent integrations.
16
+ AgentPack gives Claude Code, Codex, Cursor, Windsurf, Antigravity, CI jobs, and other agent workflows a better starting point. It analyzes your repo locally, finds the relevant files for a task, and packages them into compact task-focused context packs for CLI and MCP tool workflows.
54
17
 
55
- AgentPack is useful when a repo is too large to paste, but a blank agent session wastes time rediscovering the same code structure. It is a context preparation tool, not a coding agent.
18
+ Use AgentPack when a repo is too large to paste and you want faster, more consistent context preparation before an agent starts working. It works offline, keeps the product boundary explicit, and is a context preparation tool, not a coding agent.
56
19
 
57
20
  ## Contents
58
21
 
@@ -60,6 +23,7 @@ AgentPack is useful when a repo is too large to paste, but a blank agent session
60
23
  - [Install](#install)
61
24
  - [Quickstart](#quickstart)
62
25
  - [Quality Bar](#quality-bar)
26
+ - [Download Stats](#download-stats)
63
27
  - [Debugging Selection](#debugging-selection)
64
28
  - [Supported Integrations](#supported-integrations)
65
29
  - [Commands](#commands)
@@ -70,8 +34,9 @@ AgentPack is useful when a repo is too large to paste, but a blank agent session
70
34
 
71
35
  ## Features
72
36
 
73
- - **Task-focused packing**: ranks files from git changes, task terms, symbols, imports, related tests, configs, churn, and repo history.
37
+ - **Task-focused packing**: ranks files from git changes, task terms, symbols, imports, related tests, configs, churn, repo history, and deterministic offline summaries.
74
38
  - **Budget-aware compression**: emits `full`, `diff`, `symbols`, `skeleton`, or `summary` views instead of all-or-nothing file dumps.
39
+ - **Local code intelligence**: extracts roles, domains, entrypoints, definitions, dependencies, env reads, side effects, and external systems using static analysis.
75
40
  - **Semantic repo map**: adds a compact module-level map before file context so agents orient faster.
76
41
  - **Freshness and deltas**: records task source, git state, snapshot hashes, selected-file deltas, and stale-context warnings.
77
42
  - **Agent integrations**: installs Claude Code, Cursor, Windsurf, Codex, Antigravity, VS Code tasks, git hooks, and MCP configuration.
@@ -105,6 +70,27 @@ sudo pacman -S python-pipx
105
70
  pipx ensurepath
106
71
  ```
107
72
 
73
+ If `pipx` is not installed yet:
74
+
75
+ ```bash
76
+ # macOS
77
+ brew install pipx
78
+
79
+ # Ubuntu/Debian
80
+ sudo apt install pipx
81
+
82
+ # Fedora
83
+ sudo dnf install pipx
84
+
85
+ # Arch
86
+ sudo pacman -S python-pipx
87
+
88
+ # Then ensure pipx apps are on PATH
89
+ pipx ensurepath
90
+ ```
91
+
92
+ `pipx` is the recommended default because it keeps the CLI isolated and avoids many macOS/Linux global `pip install` issues, including PEP 668 `externally-managed-environment` errors. If you prefer `pip`, install inside a virtual environment.
93
+
108
94
  JavaScript-heavy teams can install the npm wrapper:
109
95
 
110
96
  ```bash
@@ -112,7 +98,7 @@ npm install -g @vishal2612200/agentpack
112
98
  agentpack --version
113
99
  ```
114
100
 
115
- The npm package is a Node launcher around the Python implementation. It requires Node.js 18+ and Python 3.10+, then installs the matching core `agentpack-cli` package into a per-version virtual environment on first run. The Python package remains the source of truth; npm is the convenience install path for JavaScript-heavy teams. Use the PyPI extras below when you need optional `watch` or `mcp` dependencies.
101
+ The npm package is a Node launcher around the Python implementation. It requires Node.js 18+ and Python 3.10+, then installs the matching core `agentpack-cli` package into a per-version virtual environment on first run. The Python package remains the source of truth; npm is the convenience install path for JavaScript-heavy teams. See the [npm README](https://github.com/vishal2612200/agentpack/blob/main/npm/README.md) for wrapper cache controls and troubleshooting. Use the PyPI extras below when you need optional `watch` or `mcp` dependencies.
116
102
 
117
103
  ## Quickstart
118
104
 
@@ -183,6 +169,24 @@ ItsDangerous, and MarkupSafe by checking out each commit's parent and scoring
183
169
  against files actually changed by the commit. Synthetic fixtures are useful
184
170
  regression tests, but should not be presented as market proof.
185
171
 
172
+ ## Download Stats
173
+
174
+ npm exposes official package download counts through its public registry API and the npm downloads badge above:
175
+
176
+ ```bash
177
+ curl https://api.npmjs.org/downloads/point/last-month/%40vishal2612200%2Fagentpack
178
+ curl https://api.npmjs.org/downloads/point/last-week/%40vishal2612200%2Fagentpack
179
+ ```
180
+
181
+ PyPI does not show official project download counts on package pages. For rough trend data on the Python core package, use third-party mirrors:
182
+
183
+ ```bash
184
+ curl https://pypistats.org/api/packages/agentpack-cli/recent
185
+ ```
186
+
187
+ - PyPI Stats: <https://pypistats.org/packages/agentpack-cli>
188
+ - pepy.tech: <https://pepy.tech/project/agentpack-cli>
189
+
186
190
  ## Debugging Selection
187
191
 
188
192
  When AgentPack misses a file, the next command should explain the miss:
@@ -787,8 +791,12 @@ Uses `watchdog` if installed, falls back to polling. Context is refreshed whenev
787
791
  Install watchdog for better performance:
788
792
  ```bash
789
793
  pipx inject agentpack-cli watchdog
794
+ PIPX_AGENTPACK="$(pipx environment --value PIPX_BIN_DIR)/agentpack"
795
+ "$PIPX_AGENTPACK" watch
790
796
  ```
791
797
 
798
+ Use the explicit `pipx` binary path above if you also have the npm wrapper on `PATH`; otherwise `agentpack watch` may still resolve to the Node launcher.
799
+
792
800
  ---
793
801
 
794
802
  ### `agentpack claude`
@@ -809,9 +817,12 @@ Run AgentPack as an MCP server — exposes context packing as tools that Claude
809
817
 
810
818
  ```bash
811
819
  pipx inject agentpack-cli "agentpack-cli[mcp]"
812
- agentpack mcp
820
+ PIPX_AGENTPACK="$(pipx environment --value PIPX_BIN_DIR)/agentpack"
821
+ "$PIPX_AGENTPACK" mcp
813
822
  ```
814
823
 
824
+ Use the explicit `pipx` binary path above if you also have the npm wrapper on `PATH`; otherwise `agentpack mcp` may still resolve to the Node launcher instead of the extras-enabled Python CLI.
825
+
815
826
  Register in Claude Code settings (`~/.claude/settings.json`):
816
827
 
817
828
  ```json
@@ -1230,7 +1241,8 @@ Works like `.gitignore`. Default rules exclude:
1230
1241
  │ │
1231
1242
  │ Summary cache ── role, imports, │
1232
1243
  │ (offline) symbols, side effects, │
1233
- │ public API, errors
1244
+ │ public API, naming
1245
+ │ signals, errors │
1234
1246
  │ │
1235
1247
  │ Import graph ── Python AST │
1236
1248
  │ (6 languages) ─ JS/TS regex │
@@ -1243,6 +1255,9 @@ Works like `.gitignore`. Default rules exclude:
1243
1255
  │ ast.get_source_segment) classes, │
1244
1256
  │ ── arrow fns w/ =>) │
1245
1257
  │ │
1258
+ │ Naming signals ── public files/symbols │
1259
+ │ ── env/config/test ids │
1260
+ │ ── generic-name hints │
1246
1261
  │ Test detection ── name heuristics │
1247
1262
  │ Task keywords ── stopwords + variants│
1248
1263
  │ ── concept synonyms │
@@ -1268,6 +1283,7 @@ Works like `.gitignore`. Default rules exclude:
1268
1283
  │ +70 symbol +60 content match │
1269
1284
  │ +50 dep +40 rev-dep │
1270
1285
  │ +35 test +25 config +20 recent │
1286
+ │ +20 naming -6 generic public API │
1271
1287
  │ -50 large unrelated │
1272
1288
  │ History noise penalty from metrics │
1273
1289
  └────────────────────┬────────────────────┘
@@ -1355,14 +1371,15 @@ src/agentpack/
1355
1371
  rust_imports.py # use, mod, extern crate
1356
1372
  java_imports.py # Java import + Kotlin import
1357
1373
  symbols.py # AST symbols + body via ast.get_source_segment
1374
+ naming_signals.py # public-name classification for summaries + ranking boosts
1358
1375
  tests.py # source → test file mapping heuristics
1359
- ranking.py # keyword extraction, concept synonyms, scoring
1376
+ ranking.py # keyword extraction, concept synonyms, scoring, naming receipts
1360
1377
  monorepo.py # workspace detection + workspace ownership helpers
1361
1378
  repo_map.py # compact semantic repo map reserved inside token budget
1362
1379
  task_classifier.py # coarse task class for freshness/rendering/scoring context
1363
1380
 
1364
1381
  summaries/
1365
- offline.py # zero-API: AST/regex → imports, symbols, role, side effects, API, errors
1382
+ offline.py # zero-API: AST/regex → imports, symbols, role, side effects, API, naming signals, errors
1366
1383
  base.py # cache-or-build orchestration (parallel, ThreadPool+ProcessPool)
1367
1384
 
1368
1385
  adapters/ # context rendering only — no installation logic
@@ -1492,6 +1509,16 @@ pipx inject agentpack-cli "agentpack-cli[all]" # watch + mcp
1492
1509
 
1493
1510
  ## Development
1494
1511
 
1512
+ ## Public Naming And Ranking
1513
+
1514
+ AgentPack works better when public surfaces carry domain context. Prefer domain-revealing names for files, exported functions/classes, CLI commands, tests, and config/env identifiers.
1515
+
1516
+ - `verify_otp` is better than `handle`
1517
+ - `StripeWebhookHandler` is better than `Processor`
1518
+ - `session_token_expiry_test` is better than `test_flow`
1519
+
1520
+ This is guidance, not a lint rule. Local variable names are out of scope for AgentPack ranking.
1521
+
1495
1522
  Clone and run locally:
1496
1523
 
1497
1524
  ```bash
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "agentpack-cli"
3
- version = "0.3.1"
4
- description = "Task-aware context packing for AI coding agents Claude, Cursor, Windsurf, Codex, and Antigravity"
3
+ version = "0.3.2"
4
+ description = "Local context engine for AI coding agents that ranks relevant files and builds task-focused context packs."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  license = {text = "MIT"}
8
- keywords = ["context", "llm", "packing", "claude", "cursor", "windsurf", "codex", "ai", "coding-agent"]
8
+ keywords = ["ai-coding-agents", "developer-tools", "repo-analysis", "context-engine", "context-packing", "prompt-context", "mcp", "ci", "claude-code", "codex", "cursor", "windsurf", "antigravity", "ai", "llm", "context", "packing", "claude"]
9
9
  classifiers = [
10
10
  "Development Status :: 3 - Alpha",
11
11
  "Intended Audience :: Developers",
@@ -1,3 +1,3 @@
1
1
  """AgentPack — task-aware context packing for AI coding agents."""
2
2
 
3
- __version__ = "0.3.1"
3
+ __version__ = "0.3.2"
@@ -0,0 +1,140 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+
7
+ from agentpack.analysis.symbols import extract_symbols
8
+
9
+
10
+ _GENERIC_PUBLIC_STEMS = {
11
+ "base",
12
+ "common",
13
+ "data",
14
+ "handle",
15
+ "helper",
16
+ "manager",
17
+ "misc",
18
+ "process",
19
+ "processor",
20
+ "run",
21
+ "service",
22
+ "thing",
23
+ "tool",
24
+ "util",
25
+ "utils",
26
+ }
27
+
28
+ _GENERIC_FILE_STEMS = {"base", "common", "helpers", "misc", "shared", "util", "utils"}
29
+ _IGNORE_TOKENS = {"api", "app", "class", "component", "controller", "file", "function", "handler", "http", "method", "module", "page", "route", "service", "test"}
30
+ _DOMAIN_HINTS = {
31
+ "auth", "billing", "cache", "chart", "checkout", "compatibility", "config",
32
+ "context", "cursor", "env", "invoice", "jwt", "kundali", "mcp", "notification",
33
+ "otp", "pack", "payment", "ranking", "redis", "repo", "search", "session",
34
+ "stats", "stripe", "summaries", "summary", "token", "watch", "webhook",
35
+ }
36
+ _ACTION_HINTS = {
37
+ "add", "apply", "build", "check", "collect", "create", "delete", "dispatch",
38
+ "enrich", "explain", "extract", "fetch", "find", "generate", "get", "infer",
39
+ "install", "issue", "load", "manage", "pack", "parse", "rank", "read",
40
+ "refresh", "render", "resolve", "save", "scan", "score", "select", "send",
41
+ "start", "stop", "summarize", "sync", "track", "update", "validate", "verify",
42
+ "watch", "write",
43
+ }
44
+
45
+
46
+ @dataclass
47
+ class PublicNameSignal:
48
+ name: str
49
+ label: str
50
+ keywords: list[str]
51
+ reasons: list[str]
52
+
53
+
54
+ def name_tokens(name: str) -> list[str]:
55
+ spaced = re.sub(r"([a-z0-9])([A-Z])", r"\1 \2", name)
56
+ raw = re.split(r"[^a-zA-Z0-9]+", spaced.lower())
57
+ return [tok for tok in raw if tok]
58
+
59
+
60
+ def classify_public_name(name: str) -> PublicNameSignal:
61
+ tokens = name_tokens(name)
62
+ meaningful = [tok for tok in tokens if len(tok) >= 3 and tok not in _IGNORE_TOKENS]
63
+ generic = [tok for tok in meaningful if tok in _GENERIC_PUBLIC_STEMS]
64
+ domain = [tok for tok in meaningful if tok in _DOMAIN_HINTS]
65
+ action = [tok for tok in meaningful if tok in _ACTION_HINTS]
66
+
67
+ if len(meaningful) == 1 and meaningful[0] in _GENERIC_PUBLIC_STEMS:
68
+ return PublicNameSignal(name=name, label="generic", keywords=meaningful, reasons=["unqualified generic public stem"])
69
+ if domain and (action or len(meaningful) >= 2):
70
+ return PublicNameSignal(name=name, label="domain_revealing", keywords=_dedupe([*domain, *action, *meaningful]), reasons=["domain-qualified public name"])
71
+ if len(meaningful) >= 2 and not generic:
72
+ return PublicNameSignal(name=name, label="domain_revealing", keywords=meaningful, reasons=["multi-part public name"])
73
+ if generic and len(meaningful) == len(generic):
74
+ return PublicNameSignal(name=name, label="generic", keywords=meaningful, reasons=["mostly generic public stems"])
75
+ return PublicNameSignal(name=name, label="neutral", keywords=meaningful, reasons=[])
76
+
77
+
78
+ def filename_signal(path: str) -> PublicNameSignal:
79
+ stem = Path(path).stem
80
+ signal = classify_public_name(stem)
81
+ if signal.label == "neutral" and stem.lower() in _GENERIC_FILE_STEMS:
82
+ return PublicNameSignal(name=stem, label="generic", keywords=[stem.lower()], reasons=["generic filename stem"])
83
+ return signal
84
+
85
+
86
+ def collect_public_name_candidates(path: Path, language: str | None) -> list[str]:
87
+ if language in {"javascript", "typescript"}:
88
+ return _collect_js_export_names(path)
89
+
90
+ candidates: list[str] = []
91
+ for sym in extract_symbols(path, language):
92
+ tail = sym.name.split(".")[-1]
93
+ if tail.startswith("_"):
94
+ continue
95
+ candidates.append(sym.name)
96
+ return _dedupe(candidates)
97
+
98
+
99
+ def summarize_naming_signals(path: str, public_names: list[str], extra_names: list[str] | None = None) -> tuple[list[str], list[str]]:
100
+ signals: list[str] = []
101
+ keywords: list[str] = []
102
+ for signal in [filename_signal(path), *[classify_public_name(name.split(".")[-1]) for name in public_names]]:
103
+ if signal.label == "domain_revealing":
104
+ signals.append(f"strong public name: {signal.name}")
105
+ elif signal.label == "generic":
106
+ signals.append(f"generic public name: {signal.name}")
107
+ keywords.extend(signal.keywords)
108
+ for name in extra_names or []:
109
+ extra_signal = classify_public_name(name)
110
+ if extra_signal.label == "domain_revealing":
111
+ signals.append(f"strong public name: {name}")
112
+ keywords.extend(extra_signal.keywords)
113
+ return _dedupe(signals)[:12], _dedupe(keywords)[:12]
114
+
115
+
116
+ def _collect_js_export_names(path: Path) -> list[str]:
117
+ try:
118
+ text = path.read_text(errors="replace")
119
+ except OSError:
120
+ return []
121
+
122
+ names: list[str] = []
123
+ patterns = [
124
+ re.compile(r"export\s+(?:default\s+)?(?:async\s+)?function\s+(\w+)\s*\("),
125
+ re.compile(r"export\s+(?:default\s+)?class\s+(\w+)"),
126
+ re.compile(r"export\s+(?:const|let|var)\s+(\w+)\s*="),
127
+ ]
128
+ for pattern in patterns:
129
+ names.extend(pattern.findall(text))
130
+ return _dedupe(names)
131
+
132
+
133
+ def _dedupe(items: list[str]) -> list[str]:
134
+ seen: set[str] = set()
135
+ result: list[str] = []
136
+ for item in items:
137
+ if item and item not in seen:
138
+ seen.add(item)
139
+ result.append(item)
140
+ return result
@@ -578,6 +578,23 @@ def score_files(
578
578
  score += _summary_boost_weight(field, value, amount) * match_weight
579
579
  reasons.append(f"{label}: {_short_reason_value(value)}")
580
580
 
581
+ naming_keywords = _summary_values(summary_data, "naming_keywords")
582
+ naming_signals = _summary_values(summary_data, "naming_signals")
583
+ naming_match = _best_summary_match(naming_keywords, keywords)
584
+ if naming_match:
585
+ value, match_weight = naming_match
586
+ score += min(20.0, match_weight * 18.0)
587
+ reasons.append(f"matched naming keyword: {_short_reason_value(value)}")
588
+
589
+ generic_public_names = [
590
+ value.split(": ", 1)[1]
591
+ for value in naming_signals
592
+ if value.startswith("generic public name: ")
593
+ ]
594
+ if generic_public_names and filename_weight == 0 and symbol_weight == 0:
595
+ score += min(-6.0, w.weak_filename_match_penalty / 2)
596
+ reasons.append(f"generic public API penalty: {generic_public_names[0]}")
597
+
581
598
  content_hits = 0
582
599
  if fi.content is not None:
583
600
  hits, hit_weight = _content_matches_keywords(fi.content, keywords)
@@ -64,6 +64,8 @@ class FileSummary(BaseModel):
64
64
  ranking_keywords: list[str] = Field(default_factory=list)
65
65
  related_hints: list[str] = Field(default_factory=list)
66
66
  public_api: list[str] = Field(default_factory=list)
67
+ naming_signals: list[str] = Field(default_factory=list)
68
+ naming_keywords: list[str] = Field(default_factory=list)
67
69
  error_paths: list[str] = Field(default_factory=list)
68
70
  test_hints: list[str] = Field(default_factory=list)
69
71
 
@@ -82,25 +82,34 @@ Then read `.agentpack/context.claude.md` in full.
82
82
  ### Step 1: Check agentpack is installed
83
83
 
84
84
  ```bash
85
- agentpack --help 2>/dev/null || pipx install agentpack-cli
85
+ if command -v pipx >/dev/null 2>&1; then
86
+ export AGENTPACK_BIN="$(pipx environment --value PIPX_BIN_DIR)/agentpack"
87
+ test -x "$AGENTPACK_BIN" || pipx install agentpack-cli
88
+ elif command -v agentpack >/dev/null 2>&1; then
89
+ export AGENTPACK_BIN="$(command -v agentpack)"
90
+ else
91
+ python3 -m venv .venv
92
+ "$PWD/.venv/bin/pip" install agentpack-cli
93
+ export AGENTPACK_BIN="$PWD/.venv/bin/agentpack"
94
+ fi
86
95
  ```
87
96
 
88
97
  ### Step 2: Initialize if not already done
89
98
 
90
99
  ```bash
91
- test -f .agentpack/config.toml || agentpack init --yes
100
+ test -f .agentpack/config.toml || "$AGENTPACK_BIN" init --yes
92
101
  ```
93
102
 
94
103
  ### Step 3: Determine workflow
95
104
 
96
105
  **Session active** (`.agentpack/session.json` exists, `"active": true`):
97
106
  - Update `.agentpack/task.md` if task changed
98
- - Run `agentpack pack --task auto` unless watch already refreshed it
107
+ - Run `"$AGENTPACK_BIN" pack --task auto` unless watch already refreshed it
99
108
  - Read `.agentpack/context.md`
100
109
  - Proceed immediately
101
110
 
102
111
  **No session**:
103
- - Run `agentpack session start` or `agentpack pack --task auto`
112
+ - Run `"$AGENTPACK_BIN" session start` or `"$AGENTPACK_BIN" pack --task auto`
104
113
  - Read the context file
105
114
  - Proceed
106
115
 
@@ -116,9 +125,9 @@ Do not say "context pack ready" and stop. Do not tell the user to run more comma
116
125
 
117
126
  ## Stale pack handling
118
127
 
119
- If `agentpack status` exits non-zero or context seems unrelated to the task:
120
- - Run `agentpack session refresh` (if session active)
121
- - Or run `agentpack pack --task auto` (manual mode)
128
+ If `"$AGENTPACK_BIN" status` exits non-zero or context seems unrelated to the task:
129
+ - Run `"$AGENTPACK_BIN" session refresh` (if session active)
130
+ - Or run `"$AGENTPACK_BIN" pack --task auto` (manual mode)
122
131
  - Re-read the context, then proceed
123
132
 
124
133
  Do not ask the user — just refresh and proceed.
@@ -126,9 +135,9 @@ Do not ask the user — just refresh and proceed.
126
135
  ## Debugging selection
127
136
 
128
137
  ```bash
129
- agentpack explain --task auto # show ranked file list
130
- agentpack explain --file src/auth/session.py # per-file score breakdown
131
- agentpack explain --omitted # see what was excluded and why
138
+ "$AGENTPACK_BIN" explain --task auto # show ranked file list
139
+ "$AGENTPACK_BIN" explain --file src/auth/session.py # per-file score breakdown
140
+ "$AGENTPACK_BIN" explain --omitted # see what was excluded and why
132
141
  ```
133
142
 
134
143
  ## Subcommand routing
@@ -10,6 +10,7 @@ from agentpack.analysis.role_inference import (
10
10
  extract_side_effects,
11
11
  infer_role_domain,
12
12
  )
13
+ from agentpack.analysis.naming_signals import collect_public_name_candidates, summarize_naming_signals
13
14
  from agentpack.analysis.symbols import extract_python_symbols, extract_js_symbols
14
15
  from agentpack.analysis.python_imports import extract_imports as py_imports
15
16
  from agentpack.analysis.js_ts_imports import extract_imports as js_imports
@@ -42,6 +43,8 @@ def _python_summary(path: str, abs_path: Path, file_hash: str) -> FileSummary:
42
43
  role = role_info.role or _infer_responsibility(path, intel.defines)
43
44
  failure_hints = extract_failure_hints(text)
44
45
  public_api = _dedupe([*_infer_public_api(path, intel.defines, text), *intel.entrypoints])[:12]
46
+ public_names = collect_public_name_candidates(abs_path, "python")
47
+ naming_signals, naming_keywords = summarize_naming_signals(path, public_names, effects.reads_env)
45
48
  test_hints = _infer_test_hints(path, role, intel.defines)
46
49
  summary_text = _render_summary(
47
50
  language="Python",
@@ -81,6 +84,8 @@ def _python_summary(path: str, abs_path: Path, file_hash: str) -> FileSummary:
81
84
  ranking_keywords=role_info.ranking_keywords,
82
85
  related_hints=role_info.reasons,
83
86
  public_api=public_api,
87
+ naming_signals=naming_signals,
88
+ naming_keywords=naming_keywords,
84
89
  error_paths=failure_hints,
85
90
  test_hints=test_hints,
86
91
  )
@@ -105,6 +110,8 @@ def _js_summary(path: str, abs_path: Path, language: str, file_hash: str) -> Fil
105
110
  role = role_info.role or _infer_responsibility(path, intel.defines)
106
111
  failure_hints = extract_failure_hints(text)
107
112
  public_api = _dedupe([*_infer_public_api(path, intel.defines, text), *intel.entrypoints])[:12]
113
+ public_names = collect_public_name_candidates(abs_path, language)
114
+ naming_signals, naming_keywords = summarize_naming_signals(path, public_names, effects.reads_env)
108
115
  test_hints = _infer_test_hints(path, role, intel.defines)
109
116
  summary_text = _render_summary(
110
117
  language=language.capitalize(),
@@ -144,6 +151,8 @@ def _js_summary(path: str, abs_path: Path, language: str, file_hash: str) -> Fil
144
151
  ranking_keywords=role_info.ranking_keywords,
145
152
  related_hints=role_info.reasons,
146
153
  public_api=public_api,
154
+ naming_signals=naming_signals,
155
+ naming_keywords=naming_keywords,
147
156
  error_paths=failure_hints,
148
157
  test_hints=test_hints,
149
158
  )
@@ -206,6 +215,8 @@ def _generic_summary(path: str, abs_path: Path, language: str | None, file_hash:
206
215
  ranking_keywords=role_info.ranking_keywords,
207
216
  related_hints=role_info.reasons,
208
217
  public_api=[],
218
+ naming_signals=[],
219
+ naming_keywords=[],
209
220
  error_paths=failure_hints,
210
221
  test_hints=_infer_test_hints(path, role, []),
211
222
  )
File without changes
File without changes