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.
- agentpack_cli-0.3.1/README.md → agentpack_cli-0.3.2/PKG-INFO +114 -9
- agentpack_cli-0.3.1/PKG-INFO → agentpack_cli-0.3.2/README.md +75 -48
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/pyproject.toml +3 -3
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/__init__.py +1 -1
- agentpack_cli-0.3.2/src/agentpack/analysis/naming_signals.py +140 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/ranking.py +17 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/models.py +2 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/data/agentpack.md +19 -10
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/summaries/offline.py +11 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/.gitignore +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/LICENSE +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/antigravity.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/base.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/claude.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/codex.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/cursor.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/detect.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/generic.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/adapters/windsurf.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/dependency_graph.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/go_imports.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/java_imports.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/js_ts_imports.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/monorepo.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/python_imports.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/repo_map.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/role_inference.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/rust_imports.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/symbols.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/task_classifier.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/analysis/tests.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/application/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/application/pack_service.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/cli.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/_shared.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/benchmark.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/claude_cmd.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/diff.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/doctor.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/explain.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/hook_cmd.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/init.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/install.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/mcp_cmd.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/monitor.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/pack.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/quickstart.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/repair.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/scan.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/stats.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/status.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/summarize.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/tune.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/commands/watch.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/bootstrap.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/cache.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/config.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/context_pack.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/diff.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/git.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/git_hooks.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/global_install.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/ignore.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/merkle.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/redactor.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/scanner.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/snapshot.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/token_estimator.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/core/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/antigravity.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/claude.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/codex.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/cursor.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/installers/windsurf.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/agents.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/git_hooks.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/global_install.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/integrations/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/mcp_server.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/compact.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/markdown.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/renderers/receipts.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/session/__init__.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/session/state.py +0 -0
- {agentpack_cli-0.3.1 → agentpack_cli-0.3.2}/src/agentpack/summaries/__init__.py +0 -0
- {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
|
[](https://pypi.org/project/agentpack-cli/)
|
|
43
|
+
[](https://www.npmjs.com/package/@vishal2612200/agentpack)
|
|
44
|
+
[](https://www.npmjs.com/package/@vishal2612200/agentpack)
|
|
4
45
|
[](https://pypi.org/project/agentpack-cli/)
|
|
5
46
|
[](https://opensource.org/licenses/MIT)
|
|
6
47
|
[](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
|
|
7
48
|
|
|
8
|
-
> **Status: alpha (v0.3.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
[](https://pypi.org/project/agentpack-cli/)
|
|
4
|
+
[](https://www.npmjs.com/package/@vishal2612200/agentpack)
|
|
5
|
+
[](https://www.npmjs.com/package/@vishal2612200/agentpack)
|
|
43
6
|
[](https://pypi.org/project/agentpack-cli/)
|
|
44
7
|
[](https://opensource.org/licenses/MIT)
|
|
45
8
|
[](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
|
|
46
9
|
|
|
47
|
-
> **Status: alpha (v0.3.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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.
|
|
4
|
-
description = "
|
|
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 = ["
|
|
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",
|
|
@@ -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
|
-
|
|
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 ||
|
|
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 `
|
|
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 `
|
|
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 `
|
|
120
|
-
- Run `
|
|
121
|
-
- Or run `
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|