agentpack-cli 0.3.5__tar.gz → 0.3.8__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.5/README.md → agentpack_cli-0.3.8/PKG-INFO +84 -2
- agentpack_cli-0.3.5/PKG-INFO → agentpack_cli-0.3.8/README.md +45 -41
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/pyproject.toml +2 -2
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/__init__.py +1 -1
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/ranking.py +6 -4
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/application/pack_service.py +84 -11
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/cli.py +2 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/doctor.py +18 -0
- agentpack_cli-0.3.8/src/agentpack/commands/ignore_cmd.py +51 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/init.py +31 -8
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/pack.py +3 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/stats.py +3 -2
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/context_pack.py +27 -0
- agentpack_cli-0.3.8/src/agentpack/core/ignore.py +448 -0
- agentpack_cli-0.3.5/src/agentpack/core/ignore.py +0 -90
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/.gitignore +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/LICENSE +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/antigravity.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/base.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/claude.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/codex.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/cursor.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/detect.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/generic.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/adapters/windsurf.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/dependency_graph.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/go_imports.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/java_imports.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/js_ts_imports.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/monorepo.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/naming_signals.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/python_imports.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/repo_map.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/role_inference.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/rust_imports.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/symbols.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/task_classifier.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/analysis/tests.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/application/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/_shared.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/benchmark.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/claude_cmd.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/diff.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/explain.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/guard.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/hook_cmd.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/install.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/mcp_cmd.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/migrate.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/monitor.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/quickstart.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/repair.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/scan.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/status.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/summarize.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/tune.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/commands/watch.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/bootstrap.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/cache.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/config.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/diff.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/git.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/git_hooks.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/global_install.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/merkle.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/models.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/redactor.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/scanner.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/snapshot.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/task_freshness.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/token_estimator.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/core/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/data/agentpack.md +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/installers/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/installers/antigravity.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/installers/claude.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/installers/codex.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/installers/cursor.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/installers/windsurf.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/integrations/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/integrations/agents.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/integrations/git_hooks.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/integrations/global_install.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/integrations/platform.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/integrations/vscode_tasks.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/mcp_server.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/renderers/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/renderers/compact.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/renderers/markdown.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/renderers/receipts.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/session/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/session/state.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/summaries/__init__.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/summaries/base.py +0 -0
- {agentpack_cli-0.3.5 → agentpack_cli-0.3.8}/src/agentpack/summaries/offline.py +0 -0
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentpack-cli
|
|
3
|
+
Version: 0.3.8
|
|
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,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/)
|
|
@@ -7,7 +46,7 @@
|
|
|
7
46
|
[](https://opensource.org/licenses/MIT)
|
|
8
47
|
[](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
|
|
9
48
|
|
|
10
|
-
> **Status: alpha (v0.3.
|
|
49
|
+
> **Status: alpha (v0.3.8).** 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.
|
|
11
50
|
>
|
|
12
51
|
> **Platform note:** macOS, Linux, and Windows are supported. Windows support targets PowerShell plus Git for Windows. `cmd.exe` and bare Git setups are not a supported path yet.
|
|
13
52
|
|
|
@@ -109,7 +148,19 @@ printf '%s\n' "fix auth token expiry" > .agentpack/task.md
|
|
|
109
148
|
agentpack pack
|
|
110
149
|
```
|
|
111
150
|
|
|
112
|
-
This creates `.agentpack/` state, installs the requested agent integration, generates a ranked context pack, and writes the adapter output for that agent.
|
|
151
|
+
This creates `.agentpack/` state, installs the requested agent integration, seeds `.agentignore` with safe defaults, imports obvious generated/noisy rules from git ignore sources, generates a ranked context pack, and writes the adapter output for that agent.
|
|
152
|
+
|
|
153
|
+
Task text matters. Good task text names the concrete feature, route, service, or file you are about to change. Bad task text uses repo-meta words like `improve context`, `pack quality`, `stats`, or `ignore`, which can pull README or tool internals by keyword.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# good
|
|
157
|
+
printf '%s\n' "fix billing webhook retry handling in app/api/billing/route.ts" > .agentpack/task.md
|
|
158
|
+
|
|
159
|
+
# too broad
|
|
160
|
+
printf '%s\n' "improve context pack quality from stats" > .agentpack/task.md
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
For active local work, keep context fresh with:
|
|
113
164
|
|
|
114
165
|
```bash
|
|
115
166
|
agentpack watch
|
|
@@ -202,6 +253,23 @@ agentpack explain --task "fix billing webhook" --budget-plan
|
|
|
202
253
|
|
|
203
254
|
This is the core reliability loop: pack, measure recall, inspect misses, then tune task wording, `.agentignore`, or scoring weights.
|
|
204
255
|
|
|
256
|
+
If top includes look noisy:
|
|
257
|
+
|
|
258
|
+
1. Rewrite `.agentpack/task.md` with concrete domain nouns, entrypoints, or filenames.
|
|
259
|
+
2. Re-pack and re-check `agentpack stats`.
|
|
260
|
+
3. If generated output still dominates, add that path to `.agentignore` or run `agentpack ignore sync`.
|
|
261
|
+
4. Use `agentpack explain --file <path>` on repeat offenders before changing scoring.
|
|
262
|
+
|
|
263
|
+
`.agentignore` is for AgentPack ranking noise, not general git hygiene. `agentpack init` seeds it with safe defaults and imports obvious generated/noisy entries from the root `.gitignore`, nested `.gitignore` files, `.git/info/exclude`, and your global git ignore when they look safe to carry over. You should still add repo-specific outputs such as deploy artifacts, exports, or generated SDK folders when they are not useful context.
|
|
264
|
+
|
|
265
|
+
When ignore sources change later, re-sync with:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
agentpack ignore sync
|
|
269
|
+
agentpack ignore sync --dry-run
|
|
270
|
+
agentpack ignore sync --check
|
|
271
|
+
```
|
|
272
|
+
|
|
205
273
|
## MCP-First Workflow
|
|
206
274
|
|
|
207
275
|
For MCP-capable agents, the preferred workflow is pull-based:
|
|
@@ -817,6 +885,20 @@ agentpack quickstart --task "fix auth token expiry" --write
|
|
|
817
885
|
|
|
818
886
|
---
|
|
819
887
|
|
|
888
|
+
### `agentpack ignore sync`
|
|
889
|
+
|
|
890
|
+
Refresh imported generated/noisy rules inside `.agentignore` without touching your manual entries.
|
|
891
|
+
|
|
892
|
+
```bash
|
|
893
|
+
agentpack ignore sync
|
|
894
|
+
agentpack ignore sync --dry-run
|
|
895
|
+
agentpack ignore sync --check
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
Use this after editing `.gitignore`, nested workspace ignores, or `.git/info/exclude`. `doctor` also warns when the imported `.agentignore` block is stale.
|
|
899
|
+
|
|
900
|
+
---
|
|
901
|
+
|
|
820
902
|
### `agentpack watch`
|
|
821
903
|
|
|
822
904
|
Watch for file and task changes, refresh context automatically.
|
|
@@ -1,42 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: agentpack-cli
|
|
3
|
-
Version: 0.3.5
|
|
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
|
-
|
|
40
1
|
# AgentPack
|
|
41
2
|
|
|
42
3
|
[](https://pypi.org/project/agentpack-cli/)
|
|
@@ -46,7 +7,7 @@ Description-Content-Type: text/markdown
|
|
|
46
7
|
[](https://opensource.org/licenses/MIT)
|
|
47
8
|
[](https://github.com/vishal2612200/agentpack/actions/workflows/ci.yml)
|
|
48
9
|
|
|
49
|
-
> **Status: alpha (v0.3.
|
|
10
|
+
> **Status: alpha (v0.3.8).** 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.
|
|
50
11
|
>
|
|
51
12
|
> **Platform note:** macOS, Linux, and Windows are supported. Windows support targets PowerShell plus Git for Windows. `cmd.exe` and bare Git setups are not a supported path yet.
|
|
52
13
|
|
|
@@ -148,7 +109,19 @@ printf '%s\n' "fix auth token expiry" > .agentpack/task.md
|
|
|
148
109
|
agentpack pack
|
|
149
110
|
```
|
|
150
111
|
|
|
151
|
-
This creates `.agentpack/` state, installs the requested agent integration, generates a ranked context pack, and writes the adapter output for that agent.
|
|
112
|
+
This creates `.agentpack/` state, installs the requested agent integration, seeds `.agentignore` with safe defaults, imports obvious generated/noisy rules from git ignore sources, generates a ranked context pack, and writes the adapter output for that agent.
|
|
113
|
+
|
|
114
|
+
Task text matters. Good task text names the concrete feature, route, service, or file you are about to change. Bad task text uses repo-meta words like `improve context`, `pack quality`, `stats`, or `ignore`, which can pull README or tool internals by keyword.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# good
|
|
118
|
+
printf '%s\n' "fix billing webhook retry handling in app/api/billing/route.ts" > .agentpack/task.md
|
|
119
|
+
|
|
120
|
+
# too broad
|
|
121
|
+
printf '%s\n' "improve context pack quality from stats" > .agentpack/task.md
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
For active local work, keep context fresh with:
|
|
152
125
|
|
|
153
126
|
```bash
|
|
154
127
|
agentpack watch
|
|
@@ -241,6 +214,23 @@ agentpack explain --task "fix billing webhook" --budget-plan
|
|
|
241
214
|
|
|
242
215
|
This is the core reliability loop: pack, measure recall, inspect misses, then tune task wording, `.agentignore`, or scoring weights.
|
|
243
216
|
|
|
217
|
+
If top includes look noisy:
|
|
218
|
+
|
|
219
|
+
1. Rewrite `.agentpack/task.md` with concrete domain nouns, entrypoints, or filenames.
|
|
220
|
+
2. Re-pack and re-check `agentpack stats`.
|
|
221
|
+
3. If generated output still dominates, add that path to `.agentignore` or run `agentpack ignore sync`.
|
|
222
|
+
4. Use `agentpack explain --file <path>` on repeat offenders before changing scoring.
|
|
223
|
+
|
|
224
|
+
`.agentignore` is for AgentPack ranking noise, not general git hygiene. `agentpack init` seeds it with safe defaults and imports obvious generated/noisy entries from the root `.gitignore`, nested `.gitignore` files, `.git/info/exclude`, and your global git ignore when they look safe to carry over. You should still add repo-specific outputs such as deploy artifacts, exports, or generated SDK folders when they are not useful context.
|
|
225
|
+
|
|
226
|
+
When ignore sources change later, re-sync with:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
agentpack ignore sync
|
|
230
|
+
agentpack ignore sync --dry-run
|
|
231
|
+
agentpack ignore sync --check
|
|
232
|
+
```
|
|
233
|
+
|
|
244
234
|
## MCP-First Workflow
|
|
245
235
|
|
|
246
236
|
For MCP-capable agents, the preferred workflow is pull-based:
|
|
@@ -856,6 +846,20 @@ agentpack quickstart --task "fix auth token expiry" --write
|
|
|
856
846
|
|
|
857
847
|
---
|
|
858
848
|
|
|
849
|
+
### `agentpack ignore sync`
|
|
850
|
+
|
|
851
|
+
Refresh imported generated/noisy rules inside `.agentignore` without touching your manual entries.
|
|
852
|
+
|
|
853
|
+
```bash
|
|
854
|
+
agentpack ignore sync
|
|
855
|
+
agentpack ignore sync --dry-run
|
|
856
|
+
agentpack ignore sync --check
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
Use this after editing `.gitignore`, nested workspace ignores, or `.git/info/exclude`. `doctor` also warns when the imported `.agentignore` block is stale.
|
|
860
|
+
|
|
861
|
+
---
|
|
862
|
+
|
|
859
863
|
### `agentpack watch`
|
|
860
864
|
|
|
861
865
|
Watch for file and task changes, refresh context automatically.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentpack-cli"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.8"
|
|
4
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 = ["ai-coding-agents", "developer-tools", "repo-analysis", "context-engine", "context-packing", "prompt-context", "mcp", "ci", "
|
|
8
|
+
keywords = ["ai-coding-agents", "developer-tools", "repo-analysis", "context-engine", "context-packing", "prompt-context", "mcp", "ci", "codex", "cursor", "windsurf", "antigravity", "ai", "llm", "context", "packing"]
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Development Status :: 3 - Alpha",
|
|
11
11
|
"Intended Audience :: Developers",
|
|
@@ -21,10 +21,12 @@ _GENERIC_TASK_TERMS = {
|
|
|
21
21
|
"add", "added", "change", "changed", "changes", "clean", "cleanup",
|
|
22
22
|
"code", "commit", "context", "debug", "dev", "development", "doc",
|
|
23
23
|
"docs", "eval", "evals", "feature", "fix", "freshness", "general",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
24
|
+
"gap", "gaps", "generic", "impl", "implement", "implementation", "improve",
|
|
25
|
+
"issue", "metric", "metrics", "noise", "noisy", "package", "pack", "packs",
|
|
26
|
+
"quality", "release", "remaining", "repo", "root", "rule", "rules",
|
|
27
|
+
"source", "stat", "stats", "sync", "task", "tasks", "test", "tests",
|
|
28
|
+
"text", "update", "use", "useful", "usefulness", "version", "visibility",
|
|
29
|
+
"workflow", "workflows", "wording",
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
_CONCEPT_MAP: dict[str, frozenset[str]] = {
|
|
@@ -223,7 +223,12 @@ class FileRanker:
|
|
|
223
223
|
scored = boost_cross_layer_related(scored, keyword_weights, weights=cfg.scoring)
|
|
224
224
|
scored = boost_paired_tests(scored, weights=cfg.scoring)
|
|
225
225
|
if root is not None:
|
|
226
|
-
scored = _apply_history_penalties(
|
|
226
|
+
scored = _apply_history_penalties(
|
|
227
|
+
root,
|
|
228
|
+
scored,
|
|
229
|
+
changes.all_changed,
|
|
230
|
+
generic_ratio=generic_ratio,
|
|
231
|
+
)
|
|
227
232
|
return RankResult(
|
|
228
233
|
keywords=keywords,
|
|
229
234
|
generic_ratio=generic_ratio,
|
|
@@ -324,6 +329,13 @@ class PackPlanner:
|
|
|
324
329
|
no_live_changes=not changes.all_changed,
|
|
325
330
|
effective_budget=effective_budget,
|
|
326
331
|
),
|
|
332
|
+
max_weak_signal_files=_guarded_weak_signal_cap(
|
|
333
|
+
root,
|
|
334
|
+
request.mode,
|
|
335
|
+
rank_result.generic_ratio,
|
|
336
|
+
no_live_changes=not changes.all_changed,
|
|
337
|
+
effective_budget=effective_budget,
|
|
338
|
+
),
|
|
327
339
|
)
|
|
328
340
|
phase_times["select"] = time.perf_counter() - t0
|
|
329
341
|
|
|
@@ -581,6 +593,7 @@ def _apply_history_penalties(
|
|
|
581
593
|
scored: list[tuple[Any, float, list[str]]],
|
|
582
594
|
changed_paths: set[str],
|
|
583
595
|
*,
|
|
596
|
+
generic_ratio: float = 0.0,
|
|
584
597
|
window: int = 20,
|
|
585
598
|
) -> list[tuple[Any, float, list[str]]]:
|
|
586
599
|
"""Downrank paths that recent packs proved noisy for later edits."""
|
|
@@ -597,7 +610,11 @@ def _apply_history_penalties(
|
|
|
597
610
|
if count <= 0:
|
|
598
611
|
adjusted.append((fi, score, reasons))
|
|
599
612
|
continue
|
|
600
|
-
|
|
613
|
+
has_strong = any(reason.startswith(_NO_LIVE_STRONG_SIGNALS) for reason in reasons)
|
|
614
|
+
if generic_ratio >= 0.35 and count >= 4 and not has_strong:
|
|
615
|
+
adjusted.append((fi, 0.0, [*reasons, "repeat noise path suppressed"]))
|
|
616
|
+
continue
|
|
617
|
+
penalty = min(45.0, count * 6.0 + max(0, count - 2) * 4.0)
|
|
601
618
|
adjusted.append((fi, max(0.0, score - penalty), [*reasons, f"history noise penalty -{penalty:.0f}"]))
|
|
602
619
|
return adjusted
|
|
603
620
|
|
|
@@ -649,10 +666,7 @@ _NO_LIVE_STRONG_SIGNALS = (
|
|
|
649
666
|
"content keyword match",
|
|
650
667
|
"matched entrypoint",
|
|
651
668
|
"matched external system",
|
|
652
|
-
"matched role keyword",
|
|
653
669
|
"matched domain",
|
|
654
|
-
"matched ranking keyword",
|
|
655
|
-
"matched define",
|
|
656
670
|
"matched env read",
|
|
657
671
|
"matched side effect",
|
|
658
672
|
"direct dependency",
|
|
@@ -663,6 +677,11 @@ _NO_LIVE_STRONG_SIGNALS = (
|
|
|
663
677
|
"knowledge/architecture doc",
|
|
664
678
|
"historically co-changed",
|
|
665
679
|
)
|
|
680
|
+
_NO_LIVE_META_ONLY_SIGNALS = (
|
|
681
|
+
"matched role keyword",
|
|
682
|
+
"matched ranking keyword",
|
|
683
|
+
"matched define",
|
|
684
|
+
)
|
|
666
685
|
|
|
667
686
|
|
|
668
687
|
def _apply_no_live_precision_guard(
|
|
@@ -676,19 +695,22 @@ def _apply_no_live_precision_guard(
|
|
|
676
695
|
filename-only hits, and avoid letting broad task words fan out across repo.
|
|
677
696
|
"""
|
|
678
697
|
adjusted: list[tuple[Any, float, list[str]]] = []
|
|
679
|
-
broad_task = generic_ratio >= 0.
|
|
698
|
+
broad_task = generic_ratio >= 0.3
|
|
680
699
|
for fi, score, reasons in scored:
|
|
681
700
|
has_filename = any(reason.startswith("filename keyword match") for reason in reasons)
|
|
682
701
|
has_strong = any(reason.startswith(_NO_LIVE_STRONG_SIGNALS) for reason in reasons)
|
|
702
|
+
has_meta_only = any(reason.startswith(_NO_LIVE_META_ONLY_SIGNALS) for reason in reasons)
|
|
703
|
+
if broad_task and has_filename and not has_strong:
|
|
704
|
+
damped = min(score, max(0.0, score * 0.2))
|
|
705
|
+
adjusted.append((fi, damped, [*reasons, "broad-task weak-signal dampening"]))
|
|
706
|
+
continue
|
|
683
707
|
if has_filename and not has_strong:
|
|
684
708
|
damped = min(score, max(0.0, score * 0.35))
|
|
685
709
|
adjusted.append((fi, damped, [*reasons, "no-live filename-only dampening"]))
|
|
686
710
|
continue
|
|
687
|
-
if broad_task and
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
):
|
|
691
|
-
adjusted.append((fi, max(0.0, score - 30), [*reasons, "broad-task filename dampening"]))
|
|
711
|
+
if broad_task and has_meta_only and not has_strong:
|
|
712
|
+
damped = max(0.0, score * 0.45 - 15)
|
|
713
|
+
adjusted.append((fi, damped, [*reasons, "broad-task meta-summary dampening"]))
|
|
692
714
|
continue
|
|
693
715
|
adjusted.append((fi, score, reasons))
|
|
694
716
|
return adjusted
|
|
@@ -813,6 +835,57 @@ def _guarded_summary_cap(
|
|
|
813
835
|
return min(cap, strict_cap)
|
|
814
836
|
|
|
815
837
|
|
|
838
|
+
def _recent_token_precision(root: Path, window: int = 10) -> tuple[float, int]:
|
|
839
|
+
metrics_path = root / ".agentpack" / "metrics.jsonl"
|
|
840
|
+
if not metrics_path.exists():
|
|
841
|
+
return 1.0, 0
|
|
842
|
+
values: list[float] = []
|
|
843
|
+
try:
|
|
844
|
+
lines = metrics_path.read_text(encoding="utf-8").splitlines()
|
|
845
|
+
except OSError:
|
|
846
|
+
return 1.0, 0
|
|
847
|
+
for line in reversed(lines):
|
|
848
|
+
try:
|
|
849
|
+
rec = json.loads(line)
|
|
850
|
+
except json.JSONDecodeError:
|
|
851
|
+
continue
|
|
852
|
+
value = rec.get("selection_token_precision")
|
|
853
|
+
if isinstance(value, int | float):
|
|
854
|
+
values.append(float(value))
|
|
855
|
+
if len(values) >= window:
|
|
856
|
+
break
|
|
857
|
+
if not values:
|
|
858
|
+
return 1.0, 0
|
|
859
|
+
return sum(values) / len(values), len(values)
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
def _guarded_weak_signal_cap(
|
|
863
|
+
root: Path,
|
|
864
|
+
mode: str,
|
|
865
|
+
generic_ratio: float,
|
|
866
|
+
*,
|
|
867
|
+
no_live_changes: bool = False,
|
|
868
|
+
effective_budget: int = 0,
|
|
869
|
+
) -> int:
|
|
870
|
+
if not no_live_changes:
|
|
871
|
+
return 0
|
|
872
|
+
if generic_ratio >= 0.5:
|
|
873
|
+
base = {"minimal": 0, "balanced": 1, "deep": 2}.get(mode, 1)
|
|
874
|
+
elif generic_ratio >= 0.35:
|
|
875
|
+
base = {"minimal": 1, "balanced": 2, "deep": 3}.get(mode, 2)
|
|
876
|
+
else:
|
|
877
|
+
base = {"minimal": 2, "balanced": 4, "deep": 6}.get(mode, 3)
|
|
878
|
+
avg_precision, rows = _recent_token_precision(root)
|
|
879
|
+
if rows >= 3:
|
|
880
|
+
if avg_precision <= 0.1:
|
|
881
|
+
base = min(base, 0 if mode == "minimal" else 1)
|
|
882
|
+
elif avg_precision <= 0.2:
|
|
883
|
+
base = min(base, 1 if mode != "deep" else 2)
|
|
884
|
+
if effective_budget and effective_budget <= 2500:
|
|
885
|
+
base = min(base, 1)
|
|
886
|
+
return max(0, base)
|
|
887
|
+
|
|
888
|
+
|
|
816
889
|
def _recent_summary_token_precision(root: Path, window: int = 10) -> tuple[float, int]:
|
|
817
890
|
metrics_path = root / ".agentpack" / "metrics.jsonl"
|
|
818
891
|
if not metrics_path.exists():
|
|
@@ -18,6 +18,7 @@ from agentpack.integrations.global_install import (
|
|
|
18
18
|
)
|
|
19
19
|
from agentpack.commands._shared import console, _root
|
|
20
20
|
from agentpack.core.context_pack import load_pack_metadata
|
|
21
|
+
from agentpack.core.ignore import agentignore_sync_status, format_import_summary
|
|
21
22
|
from agentpack.core.task_freshness import task_freshness
|
|
22
23
|
from agentpack.integrations.agents import SUPPORTED_AGENTS, check_agent_integration, expand_agents
|
|
23
24
|
|
|
@@ -121,6 +122,12 @@ def register(app: typer.Typer) -> None:
|
|
|
121
122
|
console.print(f" [yellow]![/] Not initialized in {root} — run: agentpack init")
|
|
122
123
|
else:
|
|
123
124
|
console.print(" [green]✓[/] .agentpack/config.toml present")
|
|
125
|
+
for finding in _agentignore_sync_findings(root):
|
|
126
|
+
if finding.startswith("synced:"):
|
|
127
|
+
console.print(f" [green]✓[/] {finding.split(':', 1)[1].strip()}")
|
|
128
|
+
else:
|
|
129
|
+
console.print(f" [yellow]![/] {finding}")
|
|
130
|
+
ok = False
|
|
124
131
|
context_path = _latest_context_path(root)
|
|
125
132
|
if context_path.exists():
|
|
126
133
|
import time
|
|
@@ -405,6 +412,17 @@ def _publish_secret_findings(root: Path, env: Mapping[str, str] | None = None) -
|
|
|
405
412
|
return findings
|
|
406
413
|
|
|
407
414
|
|
|
415
|
+
def _agentignore_sync_findings(root: Path) -> list[str]:
|
|
416
|
+
status = agentignore_sync_status(root)
|
|
417
|
+
if status.action == "create":
|
|
418
|
+
return ["missing .agentignore; run `agentpack init` or `agentpack ignore sync`."]
|
|
419
|
+
if status.is_stale:
|
|
420
|
+
return ["imported .agentignore rules are stale; run `agentpack ignore sync`."]
|
|
421
|
+
if status.imported_rules:
|
|
422
|
+
return [f"synced: {format_import_summary(status)}"]
|
|
423
|
+
return ["synced: .agentignore present; no imported generated/noisy rules detected."]
|
|
424
|
+
|
|
425
|
+
|
|
408
426
|
def _print_summary(ok: bool) -> None:
|
|
409
427
|
console.print("")
|
|
410
428
|
if ok:
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from agentpack.commands._shared import console, _root
|
|
6
|
+
from agentpack.core.ignore import agentignore_sync_status, format_import_summary
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def register(app: typer.Typer) -> None:
|
|
10
|
+
ignore_app = typer.Typer(help="Inspect and sync AgentPack ignore rules.")
|
|
11
|
+
|
|
12
|
+
@ignore_app.command("sync")
|
|
13
|
+
def sync(
|
|
14
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Show the planned .agentignore update without writing."),
|
|
15
|
+
check: bool = typer.Option(False, "--check", help="Exit non-zero when .agentignore is stale."),
|
|
16
|
+
) -> None:
|
|
17
|
+
"""Sync imported generated/noisy rules into .agentignore."""
|
|
18
|
+
root = _root()
|
|
19
|
+
status = agentignore_sync_status(root)
|
|
20
|
+
|
|
21
|
+
if dry_run:
|
|
22
|
+
console.print(f"[bold]Action:[/] {status.action}")
|
|
23
|
+
if status.imported_rules:
|
|
24
|
+
console.print(f"[dim]{format_import_summary(status)}[/]")
|
|
25
|
+
else:
|
|
26
|
+
console.print("[dim]Imported 0 generated/noisy rules.[/]")
|
|
27
|
+
raise typer.Exit(0)
|
|
28
|
+
|
|
29
|
+
if check:
|
|
30
|
+
if status.action == "unchanged":
|
|
31
|
+
console.print("[green].agentignore is in sync.[/]")
|
|
32
|
+
raise typer.Exit(0)
|
|
33
|
+
console.print("[yellow].agentignore is stale; run `agentpack ignore sync`.[/]")
|
|
34
|
+
raise typer.Exit(1)
|
|
35
|
+
|
|
36
|
+
previous_action = status.action
|
|
37
|
+
if previous_action != "unchanged":
|
|
38
|
+
status.path.parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
status.path.write_text(status.desired_content, encoding="utf-8")
|
|
40
|
+
status = agentignore_sync_status(root)
|
|
41
|
+
|
|
42
|
+
if previous_action == "create":
|
|
43
|
+
console.print("[green]Created .agentignore.[/]")
|
|
44
|
+
elif previous_action == "update":
|
|
45
|
+
console.print("[green]Updated .agentignore.[/]")
|
|
46
|
+
else:
|
|
47
|
+
console.print("[green].agentignore already in sync.[/]")
|
|
48
|
+
if status.imported_rules:
|
|
49
|
+
console.print(f"[dim]{format_import_summary(status)}[/]")
|
|
50
|
+
|
|
51
|
+
app.add_typer(ignore_app, name="ignore")
|
|
@@ -8,7 +8,11 @@ from typing import Optional
|
|
|
8
8
|
import typer
|
|
9
9
|
|
|
10
10
|
from agentpack.core.config import DEFAULT_CONFIG, CONFIG_TEMPLATE
|
|
11
|
-
from agentpack.core.ignore import
|
|
11
|
+
from agentpack.core.ignore import (
|
|
12
|
+
AgentIgnoreSyncStatus,
|
|
13
|
+
agentignore_sync_status,
|
|
14
|
+
format_import_summary,
|
|
15
|
+
)
|
|
12
16
|
from agentpack.commands._shared import console, _root
|
|
13
17
|
from agentpack.integrations.agents import check_agent_integration, install_agent_integration
|
|
14
18
|
from agentpack.session.state import load_session, create_session, SESSION_FILE, TASK_FILE
|
|
@@ -147,6 +151,24 @@ def _patch_repo_gitignore(root: Path, share_cache: bool = False, agent: str = "g
|
|
|
147
151
|
return "updated"
|
|
148
152
|
|
|
149
153
|
|
|
154
|
+
def _patch_agentignore(
|
|
155
|
+
root: Path,
|
|
156
|
+
*,
|
|
157
|
+
force: bool = False,
|
|
158
|
+
backups: list[InitResult] | None = None,
|
|
159
|
+
) -> tuple[str, AgentIgnoreSyncStatus]:
|
|
160
|
+
status = agentignore_sync_status(root)
|
|
161
|
+
if force and status.path.exists() and backups is not None:
|
|
162
|
+
backup = _backup_file(status.path)
|
|
163
|
+
backups.append(InitResult(str(backup.relative_to(root)), "created"))
|
|
164
|
+
if status.action == "unchanged":
|
|
165
|
+
return "unchanged", status
|
|
166
|
+
status.path.parent.mkdir(parents=True, exist_ok=True)
|
|
167
|
+
status.path.write_text(status.desired_content, encoding="utf-8")
|
|
168
|
+
action = "created" if status.action == "create" else "updated"
|
|
169
|
+
return action, agentignore_sync_status(root)
|
|
170
|
+
|
|
171
|
+
|
|
150
172
|
def _install_agent_integration(root, agent: str) -> dict[str, str]:
|
|
151
173
|
"""Install repo-local agent integration files after `agentpack init`."""
|
|
152
174
|
return install_agent_integration(root, agent)
|
|
@@ -222,6 +244,7 @@ def _planned_action(path: Path, expected: str | None = None) -> str:
|
|
|
222
244
|
|
|
223
245
|
def _print_dry_run(root: Path, agent: str, share_cache: bool, mode: str | None, budget: int) -> None:
|
|
224
246
|
console.print("[bold yellow]Dry run — no files will be changed.[/]\n")
|
|
247
|
+
ignore_status = agentignore_sync_status(root)
|
|
225
248
|
items = [
|
|
226
249
|
InitResult(".agentpack/", "ensure"),
|
|
227
250
|
InitResult(".agentpack/snapshots/", "ensure"),
|
|
@@ -229,7 +252,7 @@ def _print_dry_run(root: Path, agent: str, share_cache: bool, mode: str | None,
|
|
|
229
252
|
InitResult(".agentpack/.gitignore", _planned_action(root / ".agentpack" / ".gitignore")),
|
|
230
253
|
InitResult(".gitignore", _planned_action(root / ".gitignore")),
|
|
231
254
|
InitResult(".agentpack/config.toml", _planned_action(root / ".agentpack" / "config.toml")),
|
|
232
|
-
InitResult(".agentignore",
|
|
255
|
+
InitResult(".agentignore", ignore_status.action),
|
|
233
256
|
InitResult(SESSION_FILE, _planned_action(root / SESSION_FILE)),
|
|
234
257
|
InitResult(TASK_FILE, _planned_action(root / TASK_FILE)),
|
|
235
258
|
]
|
|
@@ -240,6 +263,8 @@ def _print_dry_run(root: Path, agent: str, share_cache: bool, mode: str | None,
|
|
|
240
263
|
console.print(f" Mode: {mode or DEFAULT_CONFIG.context.default_mode}")
|
|
241
264
|
console.print(f" Budget: {budget or DEFAULT_CONFIG.context.default_budget:,}")
|
|
242
265
|
console.print(f" Share cache: {'yes' if share_cache else 'no'}")
|
|
266
|
+
if ignore_status.imported_rules:
|
|
267
|
+
console.print(f" {format_import_summary(ignore_status)}")
|
|
243
268
|
|
|
244
269
|
|
|
245
270
|
def _print_init_summary(title: str, results: list[InitResult]) -> None:
|
|
@@ -369,12 +394,8 @@ def register(app: typer.Typer) -> None:
|
|
|
369
394
|
else:
|
|
370
395
|
results.append(InitResult(".agentpack/config.toml", "unchanged"))
|
|
371
396
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
action = _write_text(root, ignore_path, DEFAULT_AGENTIGNORE, force=force, backups=backups)
|
|
375
|
-
results.append(InitResult(".agentignore", action))
|
|
376
|
-
else:
|
|
377
|
-
results.append(InitResult(".agentignore", "unchanged"))
|
|
397
|
+
ignore_action, ignore_status = _patch_agentignore(root, force=force, backups=backups)
|
|
398
|
+
results.append(InitResult(".agentignore", ignore_action))
|
|
378
399
|
|
|
379
400
|
# Bootstrap session so `agentpack watch` works immediately — no separate `session start` needed
|
|
380
401
|
from agentpack.core.config import load_config
|
|
@@ -402,6 +423,8 @@ def register(app: typer.Typer) -> None:
|
|
|
402
423
|
if backups:
|
|
403
424
|
_print_init_summary("Backups", backups)
|
|
404
425
|
_print_init_summary("Init Summary", results)
|
|
426
|
+
if ignore_status.imported_rules:
|
|
427
|
+
console.print(f" [dim]{format_import_summary(ignore_status)}[/]")
|
|
405
428
|
if health_check:
|
|
406
429
|
_print_health(root, resolved_agent)
|
|
407
430
|
console.print(f"\n[bold green]AgentPack initialized.[/] [dim]agent={resolved_agent} mode={resolved_mode}[/]")
|
|
@@ -233,8 +233,11 @@ def _pack_diagnostics(result: PackResult) -> list[str]:
|
|
|
233
233
|
part for part in result.pack.task.replace("_", " ").replace("-", " ").split()
|
|
234
234
|
if len(part) >= 3
|
|
235
235
|
]
|
|
236
|
+
generic_ratio = float((result.pack.freshness or {}).get("generic_task_ratio") or 0.0)
|
|
236
237
|
if len(task_words) <= 3:
|
|
237
238
|
diagnostics.append("Task is very short; add subsystem, file, or symptom words for better precision.")
|
|
239
|
+
if generic_ratio >= 0.5:
|
|
240
|
+
diagnostics.append("Task terms are broad/generic; name concrete file, route, service, or symptom words.")
|
|
238
241
|
if not result.changed_files:
|
|
239
242
|
diagnostics.append("No changed files detected; pack relies mostly on task keywords and cached summaries.")
|
|
240
243
|
if selected and not strong_live_signal and filename_matches / len(selected) >= 0.6:
|
|
@@ -346,6 +346,7 @@ def _noise_diagnostics(
|
|
|
346
346
|
diagnostics.append("Latest pack is mostly summaries; use minimal mode or a narrower task for edit work.")
|
|
347
347
|
if filename_matches / len(visible_top) >= 0.6:
|
|
348
348
|
diagnostics.append("Top files mostly matched by filename; task terms may be broad.")
|
|
349
|
+
diagnostics.append("Rewrite `.agentpack/task.md` with concrete file, route, service, or symptom words.")
|
|
349
350
|
|
|
350
351
|
if accuracy_rows:
|
|
351
352
|
avg_precision = sum(r["selection_precision"] for r in accuracy_rows) / len(accuracy_rows)
|
|
@@ -380,9 +381,9 @@ def _noise_diagnostics(
|
|
|
380
381
|
first_path = noisy[0][0]
|
|
381
382
|
diagnostics.append(
|
|
382
383
|
f"Inspect top noisy path: `agentpack explain --file {first_path} --task auto`; "
|
|
383
|
-
"add generated/vendor paths to `.agentignore` or tighten task wording if it is not useful."
|
|
384
|
+
"add generated/vendor paths to `.agentignore`, run `agentpack ignore sync`, or tighten task wording if it is not useful."
|
|
384
385
|
)
|
|
385
|
-
return diagnostics[:
|
|
386
|
+
return diagnostics[:9]
|
|
386
387
|
|
|
387
388
|
|
|
388
389
|
def _top_files_from_metadata(meta: dict) -> list[tuple[str, str, str]]:
|