dotagents-cli 0.7.6__tar.gz → 0.8.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/CHANGELOG.md +79 -1
  2. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/PKG-INFO +7 -1
  3. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/README.md +5 -0
  4. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/guide/authoring.md +35 -6
  5. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/guide/commands.md +23 -3
  6. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/guide/overlays.md +48 -7
  7. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/guide/private-sync.md +12 -1
  8. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/pyproject.toml +2 -0
  9. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/AGENTS.md +153 -25
  10. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/__init__.py +1 -1
  11. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_context.py +16 -0
  12. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_env.py +65 -4
  13. dotagents_cli-0.8.1/src/dotagents/_launchers.py +241 -0
  14. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/templates/AGENTS.md +7 -0
  15. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlays.py +105 -8
  16. dotagents_cli-0.8.1/src/dotagents/_pipwheel.py +319 -0
  17. dotagents_cli-0.8.1/src/dotagents/_pyvenv.py +359 -0
  18. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_resources.py +16 -3
  19. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/build_pyz.py +21 -0
  20. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/init.py +16 -0
  21. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/overlays.py +135 -24
  22. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/conftest.py +21 -1
  23. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_build_pyz.py +2 -1
  24. dotagents_cli-0.8.1/tests/test_cloud_setup.py +97 -0
  25. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_skills_adapters.py +16 -0
  26. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_init_base.py +15 -0
  27. dotagents_cli-0.8.1/tests/test_launchers.py +322 -0
  28. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_overlays_cli.py +61 -0
  29. dotagents_cli-0.8.1/tests/test_pipwheel.py +102 -0
  30. dotagents_cli-0.8.1/tests/test_pyvenv_core.py +224 -0
  31. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tools/cloud-setup.sh +18 -4
  32. dotagents_cli-0.7.6/tests/test_cloud_setup.py +0 -55
  33. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/.gitignore +0 -0
  34. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/LICENSE +0 -0
  35. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/agents.md +0 -0
  36. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/cli.md +0 -0
  37. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/commands.md +0 -0
  38. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/context.md +0 -0
  39. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/env.md +0 -0
  40. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/fs.md +0 -0
  41. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/hooks.md +0 -0
  42. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/merge.md +0 -0
  43. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/overlays.md +0 -0
  44. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/reference.md +0 -0
  45. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/resources.md +0 -0
  46. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/scope.md +0 -0
  47. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/skills.md +0 -0
  48. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/sources.md +0 -0
  49. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/api/wrappers.md +0 -0
  50. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/changelog.md +0 -0
  51. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/guide/install.md +0 -0
  52. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/docs/index.md +0 -0
  53. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/install.py +0 -0
  54. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/mkdocs.yml +0 -0
  55. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/__main__.py +0 -0
  56. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_agents.py +0 -0
  57. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_fs.py +0 -0
  58. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_hooks.py +0 -0
  59. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_ignore.py +0 -0
  60. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_merge.py +0 -0
  61. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/cmds/findings.py +0 -0
  62. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/cmds/launch.py +0 -0
  63. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/hooks/preinvocation_antigravity_context.py +0 -0
  64. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/hooks/pretooluse_codex_env.py +0 -0
  65. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/hooks/sessionstart_codex_context.py +0 -0
  66. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_overlay/dotagents/templates/PROJECT.md +0 -0
  67. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_scope.py +0 -0
  68. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_skills.py +0 -0
  69. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_sources.py +0 -0
  70. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/_wrappers.py +0 -0
  71. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/__init__.py +0 -0
  72. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/_common.py +0 -0
  73. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/about.py +0 -0
  74. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/context.py +0 -0
  75. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/env.py +0 -0
  76. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/cli/path.py +0 -0
  77. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/src/dotagents/py.typed +0 -0
  78. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/_helpers.py +0 -0
  79. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/_shell.py +0 -0
  80. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_about.py +0 -0
  81. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_agents.py +0 -0
  82. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_api_header.py +0 -0
  83. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_audit_leak.py +0 -0
  84. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_cli_main.py +0 -0
  85. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_cmds_discovery.py +0 -0
  86. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_context.py +0 -0
  87. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_env.py +0 -0
  88. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_env_cli_scope.py +0 -0
  89. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_env_format.py +0 -0
  90. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_env_into.py +0 -0
  91. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_env_regressions.py +0 -0
  92. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_env_safety.py +0 -0
  93. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_findings_cmd.py +0 -0
  94. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_adapters.py +0 -0
  95. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_cli.py +0 -0
  96. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_env.py +0 -0
  97. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_hooks.py +0 -0
  98. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_init.py +0 -0
  99. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_overlays.py +0 -0
  100. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_packaging.py +0 -0
  101. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_fix_scope_context.py +0 -0
  102. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_git_ssl_revoke.py +0 -0
  103. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_hooks.py +0 -0
  104. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_ignore.py +0 -0
  105. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_last_mile.py +0 -0
  106. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_launch_cmd.py +0 -0
  107. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_local_additions.py +0 -0
  108. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_mcp.py +0 -0
  109. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_no_internal_labels.py +0 -0
  110. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_overlay_libs.py +0 -0
  111. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_overlays_command.py +0 -0
  112. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_path_timeout_frontmatter.py +0 -0
  113. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_powershell_env_hook.py +0 -0
  114. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_quoting_injection_safety.py +0 -0
  115. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_scope.py +0 -0
  116. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_sources.py +0 -0
  117. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_sources_uri.py +0 -0
  118. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_wire_hooks.py +0 -0
  119. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tests/test_wrappers.py +0 -0
  120. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tools/audit.py +0 -0
  121. {dotagents_cli-0.7.6 → dotagents_cli-0.8.1}/tools/pyz_smoke.sh +0 -0
@@ -7,6 +7,82 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.1] - 2026-10-21
11
+
12
+ ### Added
13
+
14
+ - Overlay commands get a launcher on `PATH`: each top-level `bin/<name>.py`, and
15
+ each `[scripts]` entry in `overlay.toml` (`name = "path"` adds or replaces one,
16
+ `name = false` opts a `bin/<name>.py` out). The launchers live in the agents'
17
+ venv, in `<venv>/overlays/`: `<name>.exe` on Windows, made with distlib's
18
+ `ScriptMaker` so no command interpreter parses the arguments, and a `/bin/sh`
19
+ script elsewhere. They run the script through `$<NAME>_OVERLAY_ROOT` when they
20
+ run, so only a new interpreter needs them made again. `init` and `overlays add` /
21
+ `sync` / `remove` keep them current and delete those no overlay has; two
22
+ overlays with one script name is an error naming both.
23
+ - `dotagents env` puts the launcher directory of the venv `AGENTS_PYTHON` names
24
+ first on `PATH`, ahead of the levels' `bin` dirs, and takes any other venv's
25
+ off it.
26
+ - A project gets its own venv when one of its overlays has scripts.
27
+ - New dependency: `distlib>=0.4.0,<0.5`, vendored in the `.pyz`.
28
+
29
+ ## [0.8.0] - 2026-10-16
30
+
31
+ ### Added
32
+
33
+ - `overlays add` takes globs: `overlays add '*' -g` installs every overlay the repos
34
+ offer, which for a store with a registry (`<store>/dotagents.toml`) is everything
35
+ it names. A glob matching nothing is an error.
36
+ - `tools/cloud-setup.sh` installs every overlay the store's registry names
37
+ (`overlays add '*'`) before falling back to installing `private-sync` alone.
38
+
39
+ - Each store has a Python venv, `<store>/.pyvenv/<X.Y.Z>-<os>-<arch>/`, made from
40
+ the Python that runs dotagents, where skills run. `init` and `overlays add` /
41
+ `sync` / `remove` keep it current: the user venv always has duho, and every
42
+ overlay's `requirements.txt` is installed (in one pip run, only when a file
43
+ changed, before the overlay's `setup.py`). A project gets its own venv when one of
44
+ its overlays ships requirements or a `lib/`. `--no-venv` skips it for a run;
45
+ `AGENTS_NO_PYVENV=1` turns it off. `.pyvenv/` holds the agents' venvs only: a
46
+ venv there that no sync completed is never used, and a project's own code keeps
47
+ its venvs in the project tree.
48
+ - The venvs layer project > user > system through a `.pth` file in each: the store's
49
+ own overlay libs, then each lower store's venv packages and libs, then dotagents
50
+ itself. A project venv imports the project's packages first, then the user's.
51
+ - `env` points `AGENTS_PYTHON` at the active venv and names it in `AGENTS_PYVENV`;
52
+ overlay `setup.py` scripts run under it. `context` prints it ("Python for
53
+ skills"), and its JSON form carries it as `python`. The managed block tells
54
+ agents to run skill scripts with `$AGENTS_PYTHON`.
55
+ - pip without ensurepip: a venv where the interpreter has no ensurepip is created
56
+ without pip, and pip runs from its wheel (25.3, the last for Python 3.9, checked
57
+ against a pinned sha256). The wheel is found in the store's cache, in a `.pyz`
58
+ built with the new `build-pyz --with-pip`, in `AGENTS_PIP_SOURCE` (a directory of
59
+ wheels, or any URI pathapi-uri reads) or pip's `find-links`, or on your index
60
+ (`PIP_INDEX_URL`, or the mirror in `pip.ini` / `pip.conf`). `AGENTS_PIP_SOURCE`
61
+ is also passed to pip as `--find-links` for the requirements.
62
+
63
+ ### Changed
64
+
65
+ - `overlays add` no longer stops at the first overlay that fails. Each failure is
66
+ logged, the overlays that require the failed one are skipped, every other overlay
67
+ is installed, and the command exits 1 naming each failure. A failed overlay this
68
+ run was installing for the first time is removed again, as before; the ones that
69
+ installed stay.
70
+ - With a scope venv, `env` no longer puts the overlay libs it layers on
71
+ `PYTHONPATH`: the venv's interpreter imports them, and no other Python in the
72
+ session should. Without a venv, `PYTHONPATH` carries them as before.
73
+ `AGENTS_PYTHONPATH` still lists every lib.
74
+ - The base block's "Startup: annotate that you read `…`" line names a store under
75
+ the home directory from there (`~/.agents/AGENTS.md`), and any other store by its
76
+ absolute path as before. A store kept in git and used on machines whose home
77
+ directories differ no longer shows `AGENTS.md` modified on all but one of them.
78
+
79
+ ### Fixed
80
+
81
+ - `env --cache` on Windows with Python before 3.13 could miss a cache it had just
82
+ written: `time.time()` there lags the file's own timestamp by up to one clock
83
+ tick, and a cache file dated after "now" was treated as stale. A cache file
84
+ dated up to 2 s in the future now counts as fresh.
85
+
10
86
  ## [0.7.6] - 2026-10-15
11
87
 
12
88
  ### Added
@@ -1470,7 +1546,9 @@ Patch release: the PATH/POSIX-conversion fix above (the only change since 0.3.0)
1470
1546
  affected module sources (`dotagents.cli`, `duho.presets`) to extracted temp files
1471
1547
  before dispatch; a no-op for a plain install.
1472
1548
 
1473
- [Unreleased]: https://github.com/jose-pr/dotagents/compare/v0.7.6...HEAD
1549
+ [Unreleased]: https://github.com/jose-pr/dotagents/compare/v0.8.1...HEAD
1550
+ [0.8.1]: https://github.com/jose-pr/dotagents/compare/v0.8.0...v0.8.1
1551
+ [0.8.0]: https://github.com/jose-pr/dotagents/compare/v0.7.6...v0.8.0
1474
1552
  [0.7.6]: https://github.com/jose-pr/dotagents/compare/v0.7.5...v0.7.6
1475
1553
  [0.7.5]: https://github.com/jose-pr/dotagents/compare/v0.7.4...v0.7.5
1476
1554
  [0.7.4]: https://github.com/jose-pr/dotagents/compare/v0.7.3...v0.7.4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: dotagents-cli
3
- Version: 0.7.6
3
+ Version: 0.8.1
4
4
  Summary: The dotagents CLI: install and manage a portable ~/.agents config for AI coding agents
5
5
  Project-URL: Homepage, https://github.com/jose-pr/dotagents/
6
6
  Project-URL: Repository, https://github.com/jose-pr/dotagents
@@ -23,6 +23,7 @@ Classifier: Programming Language :: Python :: 3.14
23
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
24
  Classifier: Typing :: Typed
25
25
  Requires-Python: >=3.9
26
+ Requires-Dist: distlib<0.5,>=0.4.0
26
27
  Requires-Dist: duho<0.8,>=0.7.5
27
28
  Requires-Dist: pathapi<0.2,>=0.1.0
28
29
  Requires-Dist: tomli>=1.1.0; python_version < '3.11'
@@ -215,6 +216,11 @@ store's shared `skills/` so every agent sees the same skills.
215
216
  `.ignore` at the overlay's root match (setup output, local state) and tool caches are left
216
217
  alone; `--prune` clears them too. A fresh `add` whose setup script fails is rolled
217
218
  back.
219
+ - Each store has a Python venv, `<store>/.pyvenv/<version>-<os>-<arch>/`, where skills
220
+ run (`$AGENTS_PYTHON`): duho, every overlay's `requirements.txt` and every overlay
221
+ `lib/` import there, layered project > user > system. pip comes from the
222
+ interpreter, else its pinned wheel (cache, `AGENTS_PIP_SOURCE`, your index mirror,
223
+ or a `.pyz` built `--with-pip`).
218
224
  - `sync` refreshes each overlay from the repo it was installed from (`--repo` replaces
219
225
  that source), installs a `requires` added upstream, and re-merges the managed block.
220
226
  - `remove` deletes the overlay's directory, unpublishes only the skills **it**
@@ -160,6 +160,11 @@ store's shared `skills/` so every agent sees the same skills.
160
160
  `.ignore` at the overlay's root match (setup output, local state) and tool caches are left
161
161
  alone; `--prune` clears them too. A fresh `add` whose setup script fails is rolled
162
162
  back.
163
+ - Each store has a Python venv, `<store>/.pyvenv/<version>-<os>-<arch>/`, where skills
164
+ run (`$AGENTS_PYTHON`): duho, every overlay's `requirements.txt` and every overlay
165
+ `lib/` import there, layered project > user > system. pip comes from the
166
+ interpreter, else its pinned wheel (cache, `AGENTS_PIP_SOURCE`, your index mirror,
167
+ or a `.pyz` built `--with-pip`).
163
168
  - `sync` refreshes each overlay from the repo it was installed from (`--repo` replaces
164
169
  that source), installs a `requires` added upstream, and re-merges the managed block.
165
170
  - `remove` deletes the overlay's directory, unpublishes only the skills **it**
@@ -72,12 +72,41 @@ dotagents starts with the libs in place whatever shell it runs from. A `lib/` mo
72
72
  comes before site-packages and the standard library: do not reuse a package name you
73
73
  do not mean to replace.
74
74
 
75
- A `bin/` launcher can also be run outside a `dotagents env` session (from cmd.exe or
76
- a PowerShell prompt, say), so it sets `PYTHONPATH` itself before starting Python:
77
- its own `lib/`, then `$AGENTS_PYTHONPATH`, then the caller's, leaving empty parts
78
- out (an empty entry means the current directory). The net overlay's `bin/curl` and
79
- `bin/curl.cmd` are the pattern: POSIX sh with no external commands, and a `.cmd`
80
- that uses `setlocal` so the caller's cmd session is not changed.
75
+ ## Commands on PATH: `bin/*.py` and `[scripts]`
76
+
77
+ A Python command needs no launcher of your own. Every top-level `bin/<name>.py`
78
+ gets one named `<name>`: `<name>.exe` on Windows (distlib's `ScriptMaker`, the
79
+ launcher pip gives console scripts) and a `/bin/sh` script elsewhere, made in the
80
+ agents' venv, in `<venv>/overlays/`, whenever `overlays add` / `sync` / `remove` or
81
+ `init` brings the venv up to date. `dotagents env` puts that directory first on
82
+ `PATH` for the venv `$AGENTS_PYTHON` names, so `bin/curl.py` answers to `curl`
83
+ ahead of the system's, and drops any other venv's.
84
+
85
+ The launcher runs your script under the venv's interpreter, as `python
86
+ bin/<name>.py` would, found when it runs through `$<NAME>_OVERLAY_ROOT`: editing
87
+ the script or moving the store needs nothing regenerated, only a new interpreter
88
+ does. Unset, or with the script missing, it exits 2 and says so. A file whose name
89
+ starts with `_` is not a command. Name other scripts, rename one, or opt one out
90
+ in `overlay.toml`:
91
+
92
+ ```toml
93
+ [scripts]
94
+ tool = "lib/tool/main.py" # a launcher `tool` for another path
95
+ helper = false # none for bin/helper.py
96
+ ```
97
+
98
+ Two overlays with one script name is an error naming both. A launcher no overlay
99
+ has any more is deleted at the next sync.
100
+
101
+ **Never ship a `.cmd` or `.bat` that takes arguments.** cmd.exe parses its command
102
+ line before the first line runs, so an argument's `&`, `|`, `>` or `%VAR%` acts:
103
+ from PowerShell, `curl "http://h/?a=1|hostname"` would run `hostname`. The `.exe`
104
+ above hands the arguments over as passed.
105
+
106
+ Your script may run outside a `dotagents env` session too, so set `PYTHONPATH`
107
+ for what it starts, if anything needs the libs: its own `lib/`, then
108
+ `$AGENTS_PYTHONPATH`, then the caller's, leaving empty parts out (an empty entry
109
+ means the current directory). The net overlay's `bin/curl.py` does this.
81
110
 
82
111
  ## Setup scripts
83
112
 
@@ -100,10 +100,15 @@ dotagents init # base config into ./.agents (project sc
100
100
  dotagents init -g # ...into ~/.agents (user scope)
101
101
  dotagents init --bin-dir ~/.local/bin # also write a `dotagents` command on PATH
102
102
  dotagents init --no-hooks # skip agent hook wiring + the skills links
103
+ dotagents init --no-venv # skip the store's Python venv (duho for skills)
103
104
  dotagents init --agents claude,codex # exactly these agents (default: detected + claude)
104
105
  dotagents init --dry-run
105
106
  ```
106
107
 
108
+ `init` also creates or updates the store's Python venv, where skills run (see
109
+ [the scope venv](overlays.md#python-dependencies-and-the-scope-venv)). Offline, or
110
+ with no pip to be had, that is a warning; `overlays sync` retries.
111
+
107
112
  ### Hook wiring
108
113
 
109
114
  For each active agent, `init` adds what that harness needs to load the config, and
@@ -198,6 +203,7 @@ Manages opt-in overlays **by name**. See [Overlays](overlays.md) for the full mo
198
203
 
199
204
  ```bash
200
205
  dotagents overlays add python engineering # install into the scope, publish skills, merge rules/routing
206
+ dotagents overlays add '*' -g # everything the repos offer (a store registry: all it names)
201
207
  dotagents overlays list # installed (discovered) + available from the repos
202
208
  dotagents overlays sync 'py*' # refresh installed overlays matching a glob
203
209
  dotagents overlays sync --prune # also clear what .gitignore/.ignore protect: exactly upstream
@@ -205,7 +211,14 @@ dotagents overlays remove python # delete the overlay dir, unpublish i
205
211
  dotagents overlays show python # describe one: manifest, requires, setup, skills, source (--json)
206
212
  ```
207
213
 
208
- - **`add`** installs what each manifest's `requires` names first, each requirement
214
+ - **`add`** takes names or globs: `'*'` is every overlay the repos offer, so with
215
+ a store registry it installs everything the registry names, and `'py*'` the ones
216
+ starting with `py`; a glob that matches nothing is an error. One overlay failing
217
+ (its copy, requirements or setup) does not stop the rest: it is logged, what
218
+ requires it is skipped, everything else installs, and the command exits 1 naming
219
+ each failure. A failed overlay this run was installing for the first time is
220
+ removed again; one that was already installed is left in place, not set up.
221
+ `add` installs what each manifest's `requires` names first, each requirement
209
222
  installed and set up before the overlay that needs it (`--no-requires` to skip); a
210
223
  requirement the scope already has, in its own store or the user store for a project,
211
224
  is satisfied and left alone, while a name you ask for explicitly is always
@@ -213,8 +226,11 @@ dotagents overlays show python # describe one: manifest, requires, s
213
226
  before touching anything — the first repo that offers a name wins — records where
214
227
  each overlay came from, and publishes skills from the installed copy, never
215
228
  replacing a skill already in the shared `skills/` dir (and links them into
216
- Claude's skills dir when `init` wired Claude for the store). A fresh install whose setup
217
- script fails is rolled back. A source inside the store's own `overlays/` directory
229
+ Claude's skills dir when `init` wired Claude for the store). Each overlay's
230
+ `requirements.txt` is installed into the scope venv before its setup script runs
231
+ (`--no-venv` skips it; see
232
+ [the scope venv](overlays.md#python-dependencies-and-the-scope-venv)). A fresh install
233
+ whose requirements or setup script fail is rolled back. A source inside the store's own `overlays/` directory
218
234
  is refused (by `sync` too): `remove` would delete the only copy.
219
235
  - `add`, `remove` and `show` without an overlay name are usage errors (exit 2), and
220
236
  a `--dry-run` says what it would write (`would recompose ...`) instead of reporting
@@ -590,6 +606,7 @@ is not listed.
590
606
  ```bash
591
607
  python -m dotagents build-pyz --out dist/dotagents.pyz
592
608
  python -m dotagents build-pyz --extras uri,repo # also vendor what those extras install
609
+ python -m dotagents build-pyz --with-pip # also carry pip, for machines without it
593
610
  ```
594
611
 
595
612
  Builds a self-contained zipapp from a source checkout, with `duho` and `pathapi`
@@ -608,6 +625,9 @@ vendored (plus what the dotagents-cli extras named by `--extras` install), so it
608
625
  vendored as pure-Python wheels resolved for Python 3.9, so the file does not
609
626
  depend on the machine that built it; `sftp` needs native modules and fails the
610
627
  build with a message saying so. The archive is compressed.
628
+ - `--with-pip` — also vendor the pinned pip wheel (about 1.8 MB), so the `.pyz` can
629
+ set up the scope venv where Python has no ensurepip and no index is reachable
630
+ (see [the scope venv](overlays.md#python-dependencies-and-the-scope-venv)).
611
631
 
612
632
  Each release attaches a built one:
613
633
  <https://github.com/jose-pr/dotagents/releases/latest/download/dotagents.pyz>.
@@ -48,7 +48,7 @@ or `--repo <checkout>/overlays` for a local checkout of the branch.
48
48
  | `python`, `node`, `rust` | Per-language `kb/` conventions + manifest templates + CI workflow templates. |
49
49
  | `release` | A host-agnostic release helper: an agent-driven commit-plan loop plus tag/CI monitoring across GitHub (`gh`) and GitLab. |
50
50
  | `private-sync` | The one-private-repo, per-project `.agents` model (`kb/PRIVATE_SYNC.md` + cloud hooks) — see [Private sync](private-sync.md). |
51
- | `net` | Dependency-free HTTP tooling (a drop-in `curl` shim, an OS-trust-store `certifi` shim, an `httplib` session toolkit reading `AGENTS_PROXY`). |
51
+ | `net` | HTTP tooling: a drop-in `curl` launcher (curlike), an OS-trust-store `certifi` shim, and syshttp (the system proxy and the OS verifier by default), both packages installed from the overlay's `requirements.txt`; settings are `AGENTS_*` (`AGENTS_PROXY` and kin). |
52
52
  | `recovery` | A config-recovery playbook for reconstructing a lost `~/.agents`. |
53
53
 
54
54
  ## Managing overlays
@@ -182,7 +182,9 @@ dotagents overlays sync -g # r
182
182
 
183
183
  Nothing in an overlay has to set up its own paths. For every installed overlay,
184
184
  `dotagents env` prepends `bin/` to `PATH` and an existing `lib/` to `PYTHONPATH`
185
- (listing the libs in `AGENTS_PYTHONPATH` too), and exports **`$<NAME>_OVERLAY_ROOT`** — the overlay's
185
+ (listing the libs in `AGENTS_PYTHONPATH` too), puts the launchers of its scripts
186
+ (`bin/*.py` and `[scripts]`, in `<venv>/overlays/` of the agents' venv) first on
187
+ `PATH`, and exports **`$<NAME>_OVERLAY_ROOT`** — the overlay's
186
188
  installed directory (`NAME` is the overlay's name upper-cased, `-` → `_`:
187
189
  `private-sync` → `PRIVATE_SYNC_OVERLAY_ROOT`).
188
190
  That variable is how overlay content refers to itself and to other overlays: a
@@ -214,6 +216,7 @@ small built-in reader that covers these keys. Keys:
214
216
  | `rules` | Overlay-relative markdown paths whose rule bullets append to "Always-on rules". |
215
217
  | `priority` | Merge order (lower sorts earlier; unprioritized default is 500). |
216
218
  | `setup_timeout` | Seconds the setup script may run before it is stopped (default 300; `0` = no limit). |
219
+ | `[scripts]` | Launchers on `PATH`: `name = "path/in/overlay.py"` adds or replaces one, `name = false` drops the one for a `bin/<name>.py`. See [Authoring → Commands on PATH](authoring.md#commands-on-path-binpy-and-scripts). |
217
220
 
218
221
  `overlay.toml` is the only manifest. A leading `---` frontmatter block in a
219
222
  `CONTEXT.md` (the `priority:` / `scope:` / `dependencies:` an older overlay format
@@ -226,12 +229,49 @@ copies, where symlinks are unavailable) into the scope's shared skills dir, so e
226
229
  agent that reads that dir picks up the same skills. Removing the overlay unpublishes
227
230
  only the skills it published, then sweeps any now-broken symlinks.
228
231
 
232
+ ## Python dependencies and the scope venv
233
+
234
+ Every store has a Python venv, `<store>/.pyvenv/<X.Y.Z>-<os>-<arch>/` (for example
235
+ `~/.agents/.pyvenv/3.14.7-nt-arm64`), made from the Python that runs dotagents.
236
+ A store's `.pyvenv/` holds these **agents' venvs only**: skills, overlay helpers and
237
+ setup scripts run there. A project's own code gets its venvs beside the store, in
238
+ the project root's `.pyvenv/` (`<project>/.pyvenv/<version>-<os>-<arch>/`, which the
239
+ python overlay's `dotagents pyvenv` creates); only a venv dotagents itself synced is
240
+ ever used as an agents' venv. `init` and every
241
+ `overlays add` / `sync` / `remove` keep it current:
242
+
243
+ - The user store's venv always has **duho**, so any skill can build a command line
244
+ on it, plus the packages each overlay installed there lists in a
245
+ **`requirements.txt`** at its root (pip's format). They are installed in one pip
246
+ run, so pip sees every constraint at once, and only when a file changed.
247
+ - A project gets its own venv only when one of its overlays ships a
248
+ `requirements.txt` or a `lib/`; otherwise a project session uses the user venv.
249
+ - The venvs **layer like everything else**. A `.pth` file in each venv lists, highest
250
+ precedence first: the store's own overlay libs, then the user venv's packages and
251
+ libs, then the system store's. dotagents itself comes last. So in a project venv,
252
+ the project's packages and libs win, then the user's, then the system's.
253
+ - `dotagents env` points **`AGENTS_PYTHON`** at the active venv (and names it in
254
+ `AGENTS_PYVENV`). Overlay `setup.py` and `env.py` run under it, and the managed
255
+ block tells agents to run skill scripts with it. Libs the venv layers stay off
256
+ `PYTHONPATH`, so no other Python in the session, such as a project's own venv,
257
+ imports them by accident.
258
+
259
+ **No ensurepip, no network?** pip runs from its wheel, pinned by version (25.3, the
260
+ last for Python 3.9) and hash, found in this order: the store's cache, a copy
261
+ vendored into the `.pyz` (`build-pyz --with-pip`), `AGENTS_PIP_SOURCE` (a directory
262
+ of wheels, or any URI pathapi-uri reads: `file:`, `s3:`, `sftp:`, ...), pip's own
263
+ `find-links`, then your index (`PIP_INDEX_URL` or the mirror in `pip.ini` /
264
+ `pip.conf`). `AGENTS_PIP_SOURCE` is also handed to pip as `--find-links` for the
265
+ requirements themselves.
266
+
267
+ Opt out per run with `--no-venv`, or for good with `AGENTS_NO_PYVENV=1`.
268
+
229
269
  ## Setup scripts
230
270
 
231
271
  An overlay may ship an **idempotent** `setup.py` at its root — the recommended,
232
- OS-agnostic form: it runs under the same Python that runs dotagents, so it works on
233
- every platform. After `add` / `sync` copies the overlay
234
- in, dotagents runs the script automatically. Reserve it for real install-time work:
272
+ OS-agnostic form: it runs under `AGENTS_PYTHON` (the scope venv above, with the
273
+ overlay's requirements installed first), so it works on every platform. After
274
+ `add` / `sync` copies the overlay in, dotagents runs the script automatically. Reserve it for real install-time work:
235
275
  `PATH`, `PYTHONPATH` and `$<NAME>_OVERLAY_ROOT` are `dotagents env`'s job
236
276
  (above), and an overlay's own env vars belong in its `env.py`, not in a script that
237
277
  writes one into the store — none of the example overlays ship a setup script any more.
@@ -242,8 +282,9 @@ Presence of a script is the opt-in; skip it with `--no-setup`. The author contra
242
282
  - **Environment** carries `AGENTS_HOME` (the user store), `AGENTS_SCOPE_ROOT` (the
243
283
  store the overlay is installed into), `AGENTS_SCOPE` (`user` or `project`) and
244
284
  `AGENTS_OVERLAY_DIR` (the overlay's own installed dir) — never hardcode a home path.
245
- - **Environment** is also the scope's assembled `dotagents env`: every overlay's `lib/`
246
- on `PYTHONPATH`, its `bin/` on `PATH`.
285
+ - **Environment** is also the scope's assembled `dotagents env`: every overlay's `bin/`
286
+ on `PATH`, and every overlay's `lib/` importable (through the venv's layering, or
287
+ `PYTHONPATH` without a venv).
247
288
  - **Time limit**: 300 seconds, or the manifest's `setup_timeout`, or the command's
248
289
  `--setup-timeout` (which wins); `0` means no limit. A script still running then is
249
290
  stopped, and that counts as a failure (exit 124).
@@ -19,6 +19,16 @@ never lands in the public repo). `<name>` defaults to the project's basename, so
19
19
  local checkout and a cloud checkout of the same project resolve to the same store
20
20
  entry.
21
21
 
22
+ The store's installed overlays can travel two ways:
23
+
24
+ - **Tracked copies**: `overlays/` is committed. Every machine and cloud session has
25
+ them with the clone, offline; every `overlays sync` is a diff in the private repo.
26
+ - **A registry**: `<store>/dotagents.toml` names one source per overlay and
27
+ `overlays/` is left out of the repo. `dotagents overlays add '*' -g` installs
28
+ everything it names, keeping going past one that fails; the bootstrap below runs
29
+ it in a cloud session. The repo stays small; each new machine fetches the
30
+ overlays once.
31
+
22
32
  ## Commands
23
33
 
24
34
  The overlay goes into the user store, since the store is what it syncs:
@@ -82,7 +92,8 @@ curl -fsSL https://raw.githubusercontent.com/<you>/dotagents/main/tools/cloud-se
82
92
  success. `&&` propagates the curl failure instead.
83
93
 
84
94
  The bootstrap authenticates (bypassing a hosted-runner `github.com` → proxy git
85
- rewrite), clones/pulls the store, installs the CLI, links the project, and wires the
95
+ rewrite), clones/pulls the store, installs the CLI, installs every overlay the store's
96
+ registry names (`overlays add '*'`, when it has one), links the project, and wires the
86
97
  hooks into `~/.claude/settings.json` — driven by `AGENTS_REMOTE` /
87
98
  `DOTAGENTS_AGENTS_TOKEN` / `DOTAGENTS_CLI_INSTALL` environment variables (the token is
88
99
  never committed). `AGENTS_OVERLAYS_REMOTE` / `AGENTS_OVERLAYS_REF` choose where it
@@ -37,6 +37,8 @@ classifiers = [
37
37
  dependencies = [
38
38
  "duho>=0.7.5,<0.8",
39
39
  "pathapi>=0.1.0,<0.2",
40
+ # The launchers of overlays' [scripts]: ScriptMaker writes the Windows .exe.
41
+ "distlib>=0.4.0,<0.5",
40
42
  # overlay.toml manifests and TOML registries; tomllib is stdlib from 3.11.
41
43
  'tomli>=1.1.0; python_version < "3.11"',
42
44
  ]