dotagents-cli 0.8.2__tar.gz → 0.9.0__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.
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/CHANGELOG.md +179 -1
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/PKG-INFO +46 -28
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/README.md +41 -26
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/guide/authoring.md +119 -39
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/guide/commands.md +68 -49
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/guide/install.md +11 -6
- dotagents_cli-0.9.0/docs/guide/overlays.md +520 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/pyproject.toml +4 -3
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/AGENTS.md +453 -152
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/__init__.py +1 -1
- dotagents_cli-0.9.0/src/dotagents/_activate.py +231 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_agents.py +2 -1
- dotagents_cli-0.9.0/src/dotagents/_aos.py +2492 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_context.py +39 -27
- dotagents_cli-0.9.0/src/dotagents/_deps.py +393 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_env.py +417 -134
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_launchers.py +6 -5
- dotagents_cli-0.9.0/src/dotagents/_mcp_gateway.py +116 -0
- dotagents_cli-0.9.0/src/dotagents/_mcp_gateway_clients.py +402 -0
- dotagents_cli-0.9.0/src/dotagents/_mcp_gateway_config.py +215 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/templates/AGENTS.md +2 -2
- dotagents_cli-0.9.0/src/dotagents/_overlays.py +990 -0
- dotagents_cli-0.9.0/src/dotagents/_policy.py +189 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_pyvenv.py +98 -64
- dotagents_cli-0.9.0/src/dotagents/_run.py +228 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_scope.py +14 -5
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_skills.py +26 -6
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_sources.py +90 -10
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/__init__.py +25 -6
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/build_pyz.py +3 -2
- dotagents_cli-0.9.0/src/dotagents/cli/mcp.py +36 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/overlays.py +473 -125
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/path.py +5 -3
- dotagents_cli-0.9.0/tests/aos_vectors/README.md +31 -0
- dotagents_cli-0.9.0/tests/aos_vectors/REVISION +1 -0
- dotagents_cli-0.9.0/tests/aos_vectors/compose.json +1998 -0
- dotagents_cli-0.9.0/tests/aos_vectors/digest.json +641 -0
- dotagents_cli-0.9.0/tests/aos_vectors/effective.json +5210 -0
- dotagents_cli-0.9.0/tests/aos_vectors/names.json +192 -0
- dotagents_cli-0.9.0/tests/aos_vectors/reading.json +2019 -0
- dotagents_cli-0.9.0/tests/aos_vectors/source.json +269 -0
- dotagents_cli-0.9.0/tests/aos_vectors/validation.json +2052 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/conftest.py +5 -4
- dotagents_cli-0.9.0/tests/test_aos_consumer.py +526 -0
- dotagents_cli-0.9.0/tests/test_aos_vectors.py +333 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_audit_leak.py +2 -2
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_cli_main.py +5 -4
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_cmds_discovery.py +6 -4
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_context.py +24 -7
- dotagents_cli-0.9.0/tests/test_deps.py +212 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_env.py +82 -14
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_env_regressions.py +1 -1
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_env_safety.py +7 -6
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_env.py +3 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_overlays.py +57 -58
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_scope_context.py +9 -4
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_skills_adapters.py +11 -3
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_git_ssl_revoke.py +4 -1
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_init_base.py +1 -1
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_launchers.py +37 -30
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_local_additions.py +18 -2
- dotagents_cli-0.9.0/tests/test_mcp.py +373 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_no_internal_labels.py +5 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_overlay_libs.py +20 -11
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_overlays_cli.py +42 -22
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_overlays_command.py +199 -38
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_path_timeout_frontmatter.py +41 -19
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_pyvenv_core.py +27 -21
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_sources.py +13 -13
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_sources_uri.py +4 -4
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tools/audit.py +21 -15
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tools/pyz_smoke.sh +1 -1
- dotagents_cli-0.8.2/docs/guide/overlays.md +0 -295
- dotagents_cli-0.8.2/src/dotagents/_ignore.py +0 -146
- dotagents_cli-0.8.2/src/dotagents/_overlays.py +0 -1226
- dotagents_cli-0.8.2/tests/test_ignore.py +0 -58
- dotagents_cli-0.8.2/tests/test_mcp.py +0 -60
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/.gitignore +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/LICENSE +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/agents.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/cli.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/commands.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/context.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/env.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/fs.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/hooks.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/merge.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/overlays.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/reference.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/resources.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/scope.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/skills.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/sources.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/api/wrappers.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/changelog.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/guide/private-sync.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/docs/index.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/install.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/mkdocs.yml +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/__main__.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_fs.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_hooks.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_merge.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/cmds/findings.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/cmds/launch.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/hooks/preinvocation_antigravity_context.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/hooks/pretooluse_codex_env.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/hooks/sessionstart_codex_context.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_overlay/dotagents/templates/PROJECT.md +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_pipwheel.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_resources.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/_wrappers.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/_common.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/about.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/context.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/env.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/cli/init.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/src/dotagents/py.typed +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/_helpers.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/_shell.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_about.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_agents.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_api_header.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_build_pyz.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_cloud_setup.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_env_cli_scope.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_env_format.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_env_into.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_findings_cmd.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_adapters.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_cli.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_hooks.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_init.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_fix_packaging.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_hooks.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_last_mile.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_launch_cmd.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_pipwheel.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_powershell_env_hook.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_quoting_injection_safety.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_scope.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_wire_hooks.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tests/test_wrappers.py +0 -0
- {dotagents_cli-0.8.2 → dotagents_cli-0.9.0}/tools/cloud-setup.sh +0 -0
|
@@ -7,6 +7,182 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-11-04
|
|
11
|
+
|
|
12
|
+
dotagents implements the [Agent Overlay Specification](https://boriken-dev.github.io/agent-overlay-spec/)
|
|
13
|
+
(AOS, edition `0.1.0-draft`) and passes its conformance vectors.
|
|
14
|
+
|
|
15
|
+
### Changed (breaking)
|
|
16
|
+
|
|
17
|
+
- An overlay's manifest is `overlay.cfg` (TOML by default; `#!json` or `#!yaml` on
|
|
18
|
+
its first line for JSON or YAML, the latter with the `yaml` extra). `overlay.toml`
|
|
19
|
+
is not read any more; an overlay that still has one gets a warning naming it.
|
|
20
|
+
- A manifest that does not validate against AOS is ignored whole, with a warning
|
|
21
|
+
naming where it is wrong, and `overlays add` / `sync` refuse it. It used to keep
|
|
22
|
+
its valid fields and drop the others. The small built-in TOML reader is gone: below
|
|
23
|
+
Python 3.11 manifests need `tomli` (a declared dependency, vendored in the `.pyz`).
|
|
24
|
+
- An overlay's Python modules go in `lib/python/`, prepended to `PYTHONPATH`; a
|
|
25
|
+
bare `lib/` is not on any path any more. `bin/` and `lib/python/` count only when
|
|
26
|
+
they hold a file.
|
|
27
|
+
- A `bin/<name>.py` no longer gets a launcher by its name: a command is a
|
|
28
|
+
`[scripts]` entry (`curl = "bin/curl.py"`). `bin/` itself stays on `PATH`.
|
|
29
|
+
- An overlay's setup is the first `[[setup]]` variant it declares for the OS, else
|
|
30
|
+
one `setup.<ext>` at its root -- the first, in the order `.py`, `.js`, `.mjs`,
|
|
31
|
+
`.cjs`, then `.ps1` on Windows, then `.bash`, `.sh` elsewhere, that this machine
|
|
32
|
+
can run -- taken to need the network. It is told its phase as its first argument
|
|
33
|
+
and `AOS_SETUP_PHASE`: `install` on the first `add`, `sync` on every `add` or
|
|
34
|
+
`sync` after one succeeded, and `remove` when `overlays remove` deletes the
|
|
35
|
+
overlay (new: setup used to run with no argument, and never on removal). A script
|
|
36
|
+
must treat a phase it does not know as success. It runs after the overlay's
|
|
37
|
+
dependencies are installed, in the overlay's own environment, with
|
|
38
|
+
`AOS_OVERLAY_ROOT`, `AOS_OVERLAY_NAME` and `AOS_OVERLAY_STATE` (where it writes,
|
|
39
|
+
kept across syncs, emptied before `install` and deleted on removal; sessions see
|
|
40
|
+
it as `<NAME>_OVERLAY_STATE`). `AGENTS_OVERLAY_DIR` is gone (it is
|
|
41
|
+
`AOS_OVERLAY_ROOT`). `setup_timeout` is now a variant's `timeout`.
|
|
42
|
+
- An overlay with dependencies or a setup is activated only for the digest its last
|
|
43
|
+
preparation succeeded for on this machine (recorded in
|
|
44
|
+
`<store>/overlays/.dotagents-state/<name>/<os>.prepared.json`). One dotagents finds
|
|
45
|
+
at another digest -- an install that failed, a copy made without dotagents, or one
|
|
46
|
+
installed with `--no-setup` -- is refused until `overlays sync` prepares it; a
|
|
47
|
+
failed sync of the digest already prepared keeps it active. A failed `remove`
|
|
48
|
+
phase is reported and the removal goes ahead.
|
|
49
|
+
- An overlay's `env.py` runs as an AOS env script: one `env.<ext>`, chosen in the
|
|
50
|
+
same order, with the overlay's own environment and no arguments, a 60-second
|
|
51
|
+
timeout, printing one JSON object (over one or several lines) or one object per
|
|
52
|
+
line. An overlay's root `env` file is read as a dotenv file -- `NAME=value`
|
|
53
|
+
lines with `${NAME}` substituted, no shell -- not sourced by bash. An overlay's `pre.env.py`,
|
|
54
|
+
`pre.env` and `local.env` mean nothing; the stores keep all of theirs. A store's
|
|
55
|
+
`pre.*` files run before every overlay, its `env.py` / `env` / `local.env` after.
|
|
56
|
+
- An overlay's `rules/<name>.md` files are always-on rules files by default,
|
|
57
|
+
before the ones `rules` lists.
|
|
58
|
+
- `<NAME>_OVERLAY_ROOT` always names the overlay copy in play; an inherited value
|
|
59
|
+
used to hold.
|
|
60
|
+
- The overlays of every store are applied in one composition order, `(priority,
|
|
61
|
+
name)`, as AOS orders them: a project's overlay no longer comes before a user
|
|
62
|
+
store's overlay because it is the project's (a same-named one still shadows the
|
|
63
|
+
store's copy). Every store's own `bin/` and `lib/` lead all the overlays' dirs on
|
|
64
|
+
`PATH` and `PYTHONPATH`, and `dotagents path` and `AGENTS_PYTHONPATH` list them in
|
|
65
|
+
that order.
|
|
66
|
+
- An overlay's root `env` is applied before its `env.py` (which used to run first),
|
|
67
|
+
and its `lib/python/` is on the session's `PYTHONPATH` for every Python, also when
|
|
68
|
+
the store venv layers it (it used to reach only `$AGENTS_PYTHON` then).
|
|
69
|
+
- An overlay's `CONTEXT.md` comes after the stores' `AGENTS.md` in `context`, as AOS
|
|
70
|
+
orders the base context first.
|
|
71
|
+
- Dependencies install by default from `lib/python/requirements.txt` and
|
|
72
|
+
`lib/node/package.json`, on `add` and every `sync`, before setup, into an
|
|
73
|
+
environment: `shared` (the default, one per runtime per store; dotagents' store
|
|
74
|
+
venv layers the shared Python one), a name, or `isolated`, chosen with
|
|
75
|
+
`environment` in a `[[runtime.python]]` / `[[runtime.node]]` variant, which may
|
|
76
|
+
also name another file (`requirements`, `lock` with `lock_digest`, `package`). A
|
|
77
|
+
root `requirements.txt` means nothing by its name, and overlays' packages are no
|
|
78
|
+
longer installed into the venv itself. A requirements file is a lock when every
|
|
79
|
+
requirement has a `--hash` (hashed in part: refused), installed with
|
|
80
|
+
`--require-hashes --no-deps --only-binary=:all:`; a `package.json` with a
|
|
81
|
+
`package-lock.json` beside it installs with `npm ci`, else `npm install`. Every
|
|
82
|
+
install is reported `deps-network`, and an unpinned file `unlocked-dependencies`.
|
|
83
|
+
Overlays of one environment install together and the environment is rebuilt from
|
|
84
|
+
the remaining members on every add, sync and removal; two members pinning one
|
|
85
|
+
package to two versions are both refused, the package named. `lib/node/` goes on
|
|
86
|
+
`NODE_PATH`, each environment's packages after the overlay's `lib/<runtime>/`.
|
|
87
|
+
`[defaults] deps = false` turns the default files off.
|
|
88
|
+
- The installed copy holds exactly the overlay's files, so it keeps the overlay's tree
|
|
89
|
+
digest: the install record moved beside it, to
|
|
90
|
+
`<store>/overlays/.dotagents-install/<name>.json` (with the commit and the tree
|
|
91
|
+
digest), and caches and setup output inside an installed overlay are removed by
|
|
92
|
+
`add` / `sync`. `--prune` is gone, and so are the `.gitignore` / `.ignore` rules
|
|
93
|
+
that protected files inside an install (`dotagents._ignore`).
|
|
94
|
+
- `overlays add` / `sync` refuse an overlay before writing anything when its tree has
|
|
95
|
+
a symbolic link or a name AOS refuses, its git commit holds a link or a submodule,
|
|
96
|
+
or this machine lacks what its `runtime`, setup or scripts need (an OS, a command,
|
|
97
|
+
an interpreter, a Python or Node version). A launcher is made only for python
|
|
98
|
+
scripts; an overlay declaring a script for another interpreter is refused.
|
|
99
|
+
- MCP: a stdio server starts in its overlay's root; `env_passthrough` and
|
|
100
|
+
`headers_env` pass a variable only when the store grants it; a `command` with a
|
|
101
|
+
separator is a path inside the overlay. An overlay with an invalid `[mcp]` table
|
|
102
|
+
declares nothing, instead of stopping `dotagents mcp` from starting.
|
|
103
|
+
- An overlay source refuses `::` in a git location, a host starting with `-`, a git
|
|
104
|
+
URL scheme other than https, http, ssh, git or file, and a `#path` that is not a
|
|
105
|
+
relative path.
|
|
106
|
+
|
|
107
|
+
### Added
|
|
108
|
+
|
|
109
|
+
- `env`, `env_files` (AOS or dotenv files), `paths` (prepend or append, per OS),
|
|
110
|
+
`env_scripts`, `context`, `skills`, `runtime`, `setup`, `harness` and `defaults` in
|
|
111
|
+
`overlay.cfg`. Each field's defaults come first and what it declares adds to them;
|
|
112
|
+
an entry naming a default's file or directory replaces that default entry, in its
|
|
113
|
+
place; `[defaults]` turns one off (`bin`, `lib`, `env`, `env_scripts`, `setup`,
|
|
114
|
+
`context`, `skills`, `rules = false`; any other key is refused). Env values can be
|
|
115
|
+
secret references, resolved only when granted.
|
|
116
|
+
- Substitution in env values: a text value in `env`, an `aos` or `dotenv` env file
|
|
117
|
+
or an MCP server's `env` reads other variables as `${NAME}` and its operators
|
|
118
|
+
(`${NAME:-default}`, `${NAME:+alt}`, `${#NAME}`, slices, replacements, trims,
|
|
119
|
+
case), `$$` for a `$`. Each value is substituted once, when it is set, in the order
|
|
120
|
+
of application: a `dotenv` file line by line, one mapping's entries against the
|
|
121
|
+
environment from before it, with the overlay's own `AOS_OVERLAY_ROOT`,
|
|
122
|
+
`AOS_OVERLAY_NAME` and `AOS_OVERLAY_STATE` readable. An undefined name without a
|
|
123
|
+
default, or a placeholder reading a variable that holds a secret, refuses the
|
|
124
|
+
overlay's environment; a single-quoted `dotenv` value is kept as written.
|
|
125
|
+
- Pins, grants and settings in a store's registry document (`dotagents.toml`,
|
|
126
|
+
`overlays` form): `[overlays.<name>] pin = "sha256:..."` refuses any other tree
|
|
127
|
+
digest, at install and at every activation; `grants` lets an overlay read a host
|
|
128
|
+
variable, a named secret (`[secrets.<name>]`) or a file under `secrets_dir`;
|
|
129
|
+
`env_scripts = false` stops an overlay's env scripts. A registry entry may be a
|
|
130
|
+
table with a `source`.
|
|
131
|
+
- Weakenings (`unpinned`, `env-sensitive`, `env-passthrough`, `secret-read`,
|
|
132
|
+
`env-script`, `script-not-run`, `setup-network`, `network-not-enforced`,
|
|
133
|
+
`no-timeout`, `unlocked-dependencies`, `insecure-transport`) are reported each
|
|
134
|
+
time an overlay is activated, and by `overlays show`, which also prints the tree
|
|
135
|
+
digest, the pin, what this machine lacks and the declarations.
|
|
136
|
+
- Setup and env scripts run with their interpreter found on `PATH` (never a `.cmd` or
|
|
137
|
+
`.bat`), arguments as a list, and in a process group or job object, so nothing they
|
|
138
|
+
start outlives them. Python run for an overlay keeps its bytecode under
|
|
139
|
+
`<user store>/.cache/pycache` (`PYTHONPYCACHEPREFIX`).
|
|
140
|
+
- `[harness.<id>]`: `context` for that harness, and `skills = false` to keep the
|
|
141
|
+
overlay's skills out of that harness's own skills dir.
|
|
142
|
+
- Git checkouts hold the blobs' bytes (no line-ending or filter conversion), so a
|
|
143
|
+
digest computed here agrees with any other AOS implementation.
|
|
144
|
+
|
|
145
|
+
### Upgrading an existing store
|
|
146
|
+
|
|
147
|
+
1. In each overlay you author, rename `overlay.toml` to `overlay.cfg`, and move its
|
|
148
|
+
Python modules from `lib/` to `lib/python/` (fix anything that names the old
|
|
149
|
+
path), and a root `requirements.txt` to `lib/python/requirements.txt` (or declare
|
|
150
|
+
it as `[[runtime.python]] requirements = "requirements.txt"`). Declare what is
|
|
151
|
+
not a default: a `bin/<name>.py` command
|
|
152
|
+
as `[scripts] <name> = "bin/<name>.py"`, `setup_timeout` as a `[[setup]]`
|
|
153
|
+
entry's `timeout`. Make a root `env` file plain `NAME=value` lines (or an
|
|
154
|
+
`env.py`); write a literal `${` in one as `$${`, or single-quote the value. Have
|
|
155
|
+
setup write only into `$AOS_OVERLAY_STATE`, and accept its phase (`install`,
|
|
156
|
+
`sync`, `remove`) as its first argument, exiting 0 for one it does not know.
|
|
157
|
+
2. Install the new dotagents, then `dotagents overlays sync -g` (and in each project
|
|
158
|
+
with overlays, `dotagents overlays sync`): it installs the `overlay.cfg` overlays,
|
|
159
|
+
moves the install records beside them, builds their dependency environments and
|
|
160
|
+
runs each setup in its `install` phase (nothing is recorded as prepared yet;
|
|
161
|
+
until this sync, an overlay with dependencies or a setup is refused). To drop the
|
|
162
|
+
packages an older dotagents installed into the store venv itself, delete
|
|
163
|
+
`<store>/.pyvenv/` just before this sync, which makes it again; deleting it later
|
|
164
|
+
takes the dependency environments with it, so sync again after.
|
|
165
|
+
3. Optionally pin what you trust: `dotagents overlays show <name>` prints its digest;
|
|
166
|
+
put it in the store's `dotagents.toml` as `[overlays.<name>] pin = "..."`.
|
|
167
|
+
|
|
168
|
+
## [0.8.3] - 2026-10-30
|
|
169
|
+
|
|
170
|
+
### Added
|
|
171
|
+
|
|
172
|
+
- `dotagents mcp` starts the stdio MCP gateway and can forward tools from
|
|
173
|
+
overlay-declared stdio and Streamable HTTP servers. Forwarded names default
|
|
174
|
+
to `<skill-or-server-name>.<tool>`; `--prefix` accepts a `{name}` template.
|
|
175
|
+
`dotagents.mcp.refresh` reloads active overlay declarations and reconnects
|
|
176
|
+
servers without restarting dotagents.
|
|
177
|
+
Overlays declare servers and skill mappings in `overlay.toml` under `[mcp]`;
|
|
178
|
+
Streamable HTTP requires the `mcp-http` extra, and credentials are read from
|
|
179
|
+
named environment variables.
|
|
180
|
+
|
|
181
|
+
### Changed
|
|
182
|
+
|
|
183
|
+
- Requires duho 0.7.9 (its `ToolProvider` serves the forwarded tools), also in
|
|
184
|
+
the scope venvs and the `.pyz`.
|
|
185
|
+
|
|
10
186
|
## [0.8.2] - 2026-10-25
|
|
11
187
|
|
|
12
188
|
### Fixed
|
|
@@ -1567,7 +1743,9 @@ Patch release: the PATH/POSIX-conversion fix above (the only change since 0.3.0)
|
|
|
1567
1743
|
affected module sources (`dotagents.cli`, `duho.presets`) to extracted temp files
|
|
1568
1744
|
before dispatch; a no-op for a plain install.
|
|
1569
1745
|
|
|
1570
|
-
[Unreleased]: https://github.com/jose-pr/dotagents/compare/v0.
|
|
1746
|
+
[Unreleased]: https://github.com/jose-pr/dotagents/compare/v0.9.0...HEAD
|
|
1747
|
+
[0.9.0]: https://github.com/jose-pr/dotagents/compare/v0.8.3...v0.9.0
|
|
1748
|
+
[0.8.3]: https://github.com/jose-pr/dotagents/compare/v0.8.2...v0.8.3
|
|
1571
1749
|
[0.8.2]: https://github.com/jose-pr/dotagents/compare/v0.8.1...v0.8.2
|
|
1572
1750
|
[0.8.1]: https://github.com/jose-pr/dotagents/compare/v0.8.0...v0.8.1
|
|
1573
1751
|
[0.8.0]: https://github.com/jose-pr/dotagents/compare/v0.7.6...v0.8.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: dotagents-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
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
|
|
@@ -24,7 +24,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
24
24
|
Classifier: Typing :: Typed
|
|
25
25
|
Requires-Python: >=3.9
|
|
26
26
|
Requires-Dist: distlib<0.5,>=0.4.0
|
|
27
|
-
Requires-Dist: duho<0.8,>=0.7.
|
|
27
|
+
Requires-Dist: duho<0.8,>=0.7.9
|
|
28
28
|
Requires-Dist: pathapi<0.2,>=0.1.0
|
|
29
29
|
Requires-Dist: tomli>=1.1.0; python_version < '3.11'
|
|
30
30
|
Provides-Extra: dev
|
|
@@ -33,12 +33,15 @@ Requires-Dist: hatchling>=1.27; extra == 'dev'
|
|
|
33
33
|
Requires-Dist: pathapi-uri<0.2,>=0.1.0; extra == 'dev'
|
|
34
34
|
Requires-Dist: pytest; extra == 'dev'
|
|
35
35
|
Requires-Dist: pyyaml; extra == 'dev'
|
|
36
|
+
Requires-Dist: syshttp<0.2,>=0.1.0; extra == 'dev'
|
|
36
37
|
Provides-Extra: docs
|
|
37
38
|
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
38
39
|
Requires-Dist: mkdocs>=1.5; extra == 'docs'
|
|
39
40
|
Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
|
|
40
41
|
Provides-Extra: http
|
|
41
42
|
Requires-Dist: pathapi-uri<0.2,>=0.1.0; extra == 'http'
|
|
43
|
+
Provides-Extra: mcp-http
|
|
44
|
+
Requires-Dist: syshttp<0.2,>=0.1.0; extra == 'mcp-http'
|
|
42
45
|
Provides-Extra: repo
|
|
43
46
|
Requires-Dist: pathapi-uri<0.2,>=0.1.0; extra == 'repo'
|
|
44
47
|
Requires-Dist: repopath[uri]<0.2,>=0.1.0; extra == 'repo'
|
|
@@ -111,8 +114,10 @@ tree: they are swappable payloads, not part of the tool. Name that branch as a r
|
|
|
111
114
|
This repo's own working material (decisions, findings, plans) lives **privately** in
|
|
112
115
|
its untracked `.agents/` — like every project, `.agents/` is never tracked or pushed.
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
Overlays follow the [Agent Overlay Specification](https://boriken-dev.github.io/agent-overlay-spec/)
|
|
118
|
+
(AOS): each may carry an `overlay.cfg` manifest (`name`/`description`/`requires`/`routing`,
|
|
119
|
+
and what it needs that is not a default: environment, path additions, setup,
|
|
120
|
+
runtime), read by the `dotagents overlays` subcommand, which manages overlays by name
|
|
116
121
|
(`add`/`remove`/`list`/`sync`/`show`) — see [Managing overlays](#managing-overlays) below.
|
|
117
122
|
|
|
118
123
|
## Install
|
|
@@ -211,13 +216,21 @@ installed first, its `routing`/`rules` merge into `AGENTS.md`'s managed block, a
|
|
|
211
216
|
store's shared `skills/` so every agent sees the same skills.
|
|
212
217
|
|
|
213
218
|
- `add` and `sync` keep an installed overlay exactly as its source ships it: changed
|
|
214
|
-
files are replaced and
|
|
215
|
-
there backed up under `<store>/install_backup/` first
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
+
files are replaced and everything else is removed (tool caches and setup output
|
|
220
|
+
included), anything edited there backed up under `<store>/install_backup/` first,
|
|
221
|
+
so the copy keeps the overlay's AOS tree digest. A source is refused before
|
|
222
|
+
anything is written when its manifest does not validate, this machine lacks what
|
|
223
|
+
its `runtime` needs, or the store pins it to another digest. A fresh `add` whose
|
|
224
|
+
preparation (dependencies, then setup) fails is rolled back.
|
|
225
|
+
- An overlay's packages install by default: `lib/python/requirements.txt` (a lock when
|
|
226
|
+
every requirement has a `--hash`) and `lib/node/package.json` (locked by the
|
|
227
|
+
`package-lock.json` beside it), on `add` and every `sync`, before setup. They go
|
|
228
|
+
into the store's **shared** environment, a named one, or the overlay's own
|
|
229
|
+
(`[[runtime.python]] environment = "isolated"`); two overlays pinning one package
|
|
230
|
+
to two versions in one environment are both refused, naming the package.
|
|
231
|
+
`[defaults] deps = false` turns this off.
|
|
219
232
|
- Each store has a Python venv, `<store>/.pyvenv/<version>-<os>-<arch>/`, where skills
|
|
220
|
-
run (`$AGENTS_PYTHON`): duho,
|
|
233
|
+
run (`$AGENTS_PYTHON`): duho, the store's shared Python environment and every agent
|
|
221
234
|
`lib/` import there, layered project > user > system. pip comes from the
|
|
222
235
|
interpreter, else its pinned wheel (cache, `AGENTS_PIP_SOURCE`, your index mirror,
|
|
223
236
|
or a `.pyz` built `--with-pip`).
|
|
@@ -230,24 +243,29 @@ store's shared `skills/` so every agent sees the same skills.
|
|
|
230
243
|
- `list` and `show` flag a `requires` no installed overlay provides; `show` names the
|
|
231
244
|
repo an installed overlay came from.
|
|
232
245
|
|
|
233
|
-
**Overlay setup
|
|
234
|
-
(
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- **
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
246
|
+
**Overlay setup.** An overlay is activated only for the digest its last preparation
|
|
247
|
+
(dependencies, then setup) succeeded for on this machine; `overlays sync` prepares it.
|
|
248
|
+
An overlay's setup is the `[[setup]]` variant its `overlay.cfg`
|
|
249
|
+
declares for this OS (interpreter, args, timeout, network), else one `setup.<ext>` at its
|
|
250
|
+
root, the first this machine can run (`.py`, `.js`, `.mjs`, `.cjs`, then `.ps1` on
|
|
251
|
+
Windows, `.bash`, `.sh` elsewhere), taken to need the network. dotagents runs it
|
|
252
|
+
after `add`/`sync` copies the overlay in and before `remove` deletes it, telling it the
|
|
253
|
+
**phase** as its first argument and `$AOS_SETUP_PHASE`: `install` the first time, `sync`
|
|
254
|
+
on every add or sync after that, `remove` on removal. `--no-setup` skips it. The
|
|
255
|
+
contract for authors:
|
|
256
|
+
|
|
257
|
+
- **Idempotent**, and a phase it does not know is success with nothing to do (exit 0).
|
|
258
|
+
- An `install` or `sync` that fails keeps the overlay from being activated until a
|
|
259
|
+
setup succeeds; a `remove` that fails is reported and the removal goes ahead.
|
|
260
|
+
- **cwd** is the installed overlay root; **write only into `$AOS_OVERLAY_STATE`**, a
|
|
261
|
+
directory outside the root, kept across syncs and deleted on removal, that sessions
|
|
262
|
+
see as `$<NAME>_OVERLAY_STATE`.
|
|
263
|
+
- **Env** is your environment, every overlay's root variable, the overlay's own
|
|
264
|
+
declarations, `AOS_OVERLAY_ROOT` / `AOS_OVERLAY_NAME` / `AOS_OVERLAY_STATE`, and
|
|
265
|
+
`AGENTS_HOME` (the user store — never hardcode `~/.agents`), `AGENTS_SCOPE_ROOT`,
|
|
266
|
+
`AGENTS_SCOPE`.
|
|
267
|
+
- A **non-zero exit or the timeout fails the install** with a clear error, and
|
|
268
|
+
everything the step started is stopped with it.
|
|
251
269
|
|
|
252
270
|
### Downloadable `dotagents.pyz`
|
|
253
271
|
|
|
@@ -55,8 +55,10 @@ tree: they are swappable payloads, not part of the tool. Name that branch as a r
|
|
|
55
55
|
This repo's own working material (decisions, findings, plans) lives **privately** in
|
|
56
56
|
its untracked `.agents/` — like every project, `.agents/` is never tracked or pushed.
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
Overlays follow the [Agent Overlay Specification](https://boriken-dev.github.io/agent-overlay-spec/)
|
|
59
|
+
(AOS): each may carry an `overlay.cfg` manifest (`name`/`description`/`requires`/`routing`,
|
|
60
|
+
and what it needs that is not a default: environment, path additions, setup,
|
|
61
|
+
runtime), read by the `dotagents overlays` subcommand, which manages overlays by name
|
|
60
62
|
(`add`/`remove`/`list`/`sync`/`show`) — see [Managing overlays](#managing-overlays) below.
|
|
61
63
|
|
|
62
64
|
## Install
|
|
@@ -155,13 +157,21 @@ installed first, its `routing`/`rules` merge into `AGENTS.md`'s managed block, a
|
|
|
155
157
|
store's shared `skills/` so every agent sees the same skills.
|
|
156
158
|
|
|
157
159
|
- `add` and `sync` keep an installed overlay exactly as its source ships it: changed
|
|
158
|
-
files are replaced and
|
|
159
|
-
there backed up under `<store>/install_backup/` first
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
files are replaced and everything else is removed (tool caches and setup output
|
|
161
|
+
included), anything edited there backed up under `<store>/install_backup/` first,
|
|
162
|
+
so the copy keeps the overlay's AOS tree digest. A source is refused before
|
|
163
|
+
anything is written when its manifest does not validate, this machine lacks what
|
|
164
|
+
its `runtime` needs, or the store pins it to another digest. A fresh `add` whose
|
|
165
|
+
preparation (dependencies, then setup) fails is rolled back.
|
|
166
|
+
- An overlay's packages install by default: `lib/python/requirements.txt` (a lock when
|
|
167
|
+
every requirement has a `--hash`) and `lib/node/package.json` (locked by the
|
|
168
|
+
`package-lock.json` beside it), on `add` and every `sync`, before setup. They go
|
|
169
|
+
into the store's **shared** environment, a named one, or the overlay's own
|
|
170
|
+
(`[[runtime.python]] environment = "isolated"`); two overlays pinning one package
|
|
171
|
+
to two versions in one environment are both refused, naming the package.
|
|
172
|
+
`[defaults] deps = false` turns this off.
|
|
163
173
|
- Each store has a Python venv, `<store>/.pyvenv/<version>-<os>-<arch>/`, where skills
|
|
164
|
-
run (`$AGENTS_PYTHON`): duho,
|
|
174
|
+
run (`$AGENTS_PYTHON`): duho, the store's shared Python environment and every agent
|
|
165
175
|
`lib/` import there, layered project > user > system. pip comes from the
|
|
166
176
|
interpreter, else its pinned wheel (cache, `AGENTS_PIP_SOURCE`, your index mirror,
|
|
167
177
|
or a `.pyz` built `--with-pip`).
|
|
@@ -174,24 +184,29 @@ store's shared `skills/` so every agent sees the same skills.
|
|
|
174
184
|
- `list` and `show` flag a `requires` no installed overlay provides; `show` names the
|
|
175
185
|
repo an installed overlay came from.
|
|
176
186
|
|
|
177
|
-
**Overlay setup
|
|
178
|
-
(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
- **
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
187
|
+
**Overlay setup.** An overlay is activated only for the digest its last preparation
|
|
188
|
+
(dependencies, then setup) succeeded for on this machine; `overlays sync` prepares it.
|
|
189
|
+
An overlay's setup is the `[[setup]]` variant its `overlay.cfg`
|
|
190
|
+
declares for this OS (interpreter, args, timeout, network), else one `setup.<ext>` at its
|
|
191
|
+
root, the first this machine can run (`.py`, `.js`, `.mjs`, `.cjs`, then `.ps1` on
|
|
192
|
+
Windows, `.bash`, `.sh` elsewhere), taken to need the network. dotagents runs it
|
|
193
|
+
after `add`/`sync` copies the overlay in and before `remove` deletes it, telling it the
|
|
194
|
+
**phase** as its first argument and `$AOS_SETUP_PHASE`: `install` the first time, `sync`
|
|
195
|
+
on every add or sync after that, `remove` on removal. `--no-setup` skips it. The
|
|
196
|
+
contract for authors:
|
|
197
|
+
|
|
198
|
+
- **Idempotent**, and a phase it does not know is success with nothing to do (exit 0).
|
|
199
|
+
- An `install` or `sync` that fails keeps the overlay from being activated until a
|
|
200
|
+
setup succeeds; a `remove` that fails is reported and the removal goes ahead.
|
|
201
|
+
- **cwd** is the installed overlay root; **write only into `$AOS_OVERLAY_STATE`**, a
|
|
202
|
+
directory outside the root, kept across syncs and deleted on removal, that sessions
|
|
203
|
+
see as `$<NAME>_OVERLAY_STATE`.
|
|
204
|
+
- **Env** is your environment, every overlay's root variable, the overlay's own
|
|
205
|
+
declarations, `AOS_OVERLAY_ROOT` / `AOS_OVERLAY_NAME` / `AOS_OVERLAY_STATE`, and
|
|
206
|
+
`AGENTS_HOME` (the user store — never hardcode `~/.agents`), `AGENTS_SCOPE_ROOT`,
|
|
207
|
+
`AGENTS_SCOPE`.
|
|
208
|
+
- A **non-zero exit or the timeout fails the install** with a clear error, and
|
|
209
|
+
everything the step started is stopped with it.
|
|
195
210
|
|
|
196
211
|
### Downloadable `dotagents.pyz`
|
|
197
212
|
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
# Authoring an overlay
|
|
2
2
|
|
|
3
3
|
An overlay is just a directory with the files you want installed into a scope, plus an
|
|
4
|
-
optional `overlay.
|
|
4
|
+
optional `overlay.cfg` manifest: an
|
|
5
|
+
[AOS](https://boriken-dev.github.io/agent-overlay-spec/) overlay, readable by any
|
|
6
|
+
consumer of the format. The basics need no manifest: `bin/` goes on `PATH`,
|
|
7
|
+
`lib/python/` on `PYTHONPATH`, `skills/<name>/SKILL.md` are skills, `CONTEXT.md` is
|
|
8
|
+
context, `rules/<name>.md` are always-on rules, an `env` file (dotenv) and one
|
|
9
|
+
`env.<ext>` set variables, and one `setup.<ext>` is the setup. Declare only what is
|
|
10
|
+
not a default -- a declaration adds to the defaults, and one naming a default's file
|
|
11
|
+
replaces that default -- and turn a default off in `[defaults]` (`bin`, `lib`, `env`,
|
|
12
|
+
`env_scripts`, `setup`, `context`, `skills`, `rules = false`). Anyone can write one; name its parent directory (a
|
|
5
13
|
directory of overlays), a registry, or a git repo with `--repo` — see the
|
|
6
14
|
[overlays guide](overlays.md). Keep the source outside `<store>/overlays/`:
|
|
7
15
|
`overlays remove` deletes the installed directory outright.
|
|
@@ -10,12 +18,12 @@ directory of overlays), a registry, or a git repo with `--repo` — see the
|
|
|
10
18
|
|
|
11
19
|
```
|
|
12
20
|
my-overlay/
|
|
13
|
-
overlay.
|
|
21
|
+
overlay.cfg
|
|
14
22
|
kb/MY_TOPIC.md
|
|
15
23
|
```
|
|
16
24
|
|
|
17
25
|
```toml
|
|
18
|
-
# my-overlay/overlay.
|
|
26
|
+
# my-overlay/overlay.cfg (TOML; `#!json` or `#!yaml` on the first line for those)
|
|
19
27
|
name = "my-overlay"
|
|
20
28
|
description = "My team's conventions for topic X."
|
|
21
29
|
routing = [
|
|
@@ -64,37 +72,70 @@ yours needs it.
|
|
|
64
72
|
|
|
65
73
|
## Libraries and launchers
|
|
66
74
|
|
|
67
|
-
Put importable Python in `lib
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
do not mean to replace.
|
|
75
|
+
Put importable Python in `lib/python/` (a bare `lib/` means nothing). Every Python a
|
|
76
|
+
session starts sees it on `PYTHONPATH` (prepended, and listed in
|
|
77
|
+
`$AGENTS_PYTHONPATH`), so a skill script or another overlay can `import` your module.
|
|
78
|
+
So can your command modules, which dotagents starts with the libs in place whatever
|
|
79
|
+
shell it runs from, and the setup of an overlay that `requires` yours. Another
|
|
80
|
+
directory goes there with a path addition:
|
|
74
81
|
|
|
75
|
-
|
|
82
|
+
```toml
|
|
83
|
+
[[paths]]
|
|
84
|
+
variable = "PYTHONPATH"
|
|
85
|
+
path = "src"
|
|
86
|
+
position = "append" # or "prepend", the default
|
|
87
|
+
os = ["linux", "macos"] # optional
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
An overlay's packages are `lib/python/requirements.txt` and `lib/node/package.json`,
|
|
91
|
+
installed by default on `add` and every `sync`, before setup. A requirements file is a
|
|
92
|
+
lock when every requirement carries a `--hash` (one hashed in part is refused); a
|
|
93
|
+
`package.json` is locked by the `package-lock.json` beside it (`npm ci`; without it
|
|
94
|
+
`npm install`, reported `unlocked-dependencies`). A variant can name another file or
|
|
95
|
+
another environment:
|
|
96
|
+
|
|
97
|
+
```toml
|
|
98
|
+
[[runtime.python]]
|
|
99
|
+
version = "3.9"
|
|
100
|
+
requirements = "deps/requirements.txt" # or lock = "locks/all.txt" + lock_digest = "sha256:..."
|
|
101
|
+
environment = "isolated" # "shared" (default), a name, or "isolated"
|
|
76
102
|
|
|
77
|
-
|
|
78
|
-
|
|
103
|
+
[[runtime.node]]
|
|
104
|
+
package = "web/package.json"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Overlays in one shared or named environment install together; if two pin one package
|
|
108
|
+
to two versions, neither is activated. Choose `isolated` (or a name of your own) to
|
|
109
|
+
keep yours apart. `lib/python/` is on `PYTHONPATH` and `lib/node/` on `NODE_PATH`,
|
|
110
|
+
each before the environment's packages; `[defaults] deps = false` turns the default
|
|
111
|
+
files off.
|
|
112
|
+
|
|
113
|
+
## Commands on PATH: `[scripts]`
|
|
114
|
+
|
|
115
|
+
A Python command needs no launcher of your own. Name it under `[scripts]` and it
|
|
116
|
+
gets one named after the key; `bin/` itself is only on `PATH`, and no file there is a
|
|
117
|
+
command by its name. Each launcher is `<name>.exe` on Windows (distlib's `ScriptMaker`, the
|
|
79
118
|
launcher pip gives console scripts) and a `/bin/sh` script elsewhere, made in the
|
|
80
119
|
agents' venv, in `<venv>/overlays/`, whenever `overlays add` / `sync` / `remove` or
|
|
81
120
|
`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`
|
|
83
|
-
ahead of the system's, and drops any other venv's.
|
|
121
|
+
`PATH` for the venv `$AGENTS_PYTHON` names, so with `curl = "bin/curl.py"` the
|
|
122
|
+
overlay's `curl` answers ahead of the system's, and drops any other venv's.
|
|
84
123
|
|
|
85
|
-
The launcher runs your script under the venv's interpreter, as `python
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
starts with `_` is not a command. Name other scripts, rename one, or opt one out
|
|
90
|
-
in `overlay.toml`:
|
|
124
|
+
The launcher runs your script under the venv's interpreter, as `python <script>`
|
|
125
|
+
would, found when it runs through `$<NAME>_OVERLAY_ROOT`: editing the script or
|
|
126
|
+
moving the store needs nothing regenerated, only a new interpreter does. Unset, or
|
|
127
|
+
with the script missing, it exits 2 and says so.
|
|
91
128
|
|
|
92
129
|
```toml
|
|
93
130
|
[scripts]
|
|
94
|
-
|
|
95
|
-
|
|
131
|
+
curl = "bin/curl.py"
|
|
132
|
+
tool = "lib/tool/main.py"
|
|
133
|
+
check = { path = "tools/check.py", interpreter = "python", os = ["windows"] }
|
|
96
134
|
```
|
|
97
135
|
|
|
136
|
+
dotagents launches python scripts; an overlay naming another interpreter for a
|
|
137
|
+
script is refused by `overlays add`.
|
|
138
|
+
|
|
98
139
|
Two overlays with one script name is an error naming both. A launcher no overlay
|
|
99
140
|
has any more is deleted at the next sync.
|
|
100
141
|
|
|
@@ -108,23 +149,61 @@ for what it starts, if anything needs the libs: its own `lib/`, then
|
|
|
108
149
|
`$AGENTS_PYTHONPATH`, then the caller's, leaving empty parts out (an empty entry
|
|
109
150
|
means the current directory). The net overlay's `bin/curl.py` does this.
|
|
110
151
|
|
|
111
|
-
##
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
152
|
+
## Environment
|
|
153
|
+
|
|
154
|
+
An `env` file at the root (`NAME=value` lines, optionally `export `; `${NAME}` is
|
|
155
|
+
substituted from the lines above and the environment, a single-quoted value is kept as
|
|
156
|
+
written)
|
|
157
|
+
and an `env.py` (or `.js`, `.mjs`, `.cjs`, `.ps1` on Windows, `.bash`, `.sh` elsewhere: the first this machine can run) set your
|
|
158
|
+
overlay's variables by default; `[defaults] env = false` turns off the `env` file
|
|
159
|
+
and `env_scripts = false` the script. The script prints one JSON object (across
|
|
160
|
+
several lines if it likes) or one per line (`{"NAME": "value"}`, `null` to unset),
|
|
161
|
+
and gets no arguments unless an `[[env_scripts]]` entry naming it gives some.
|
|
162
|
+
Static values are better declared:
|
|
163
|
+
|
|
164
|
+
```toml
|
|
165
|
+
[env]
|
|
166
|
+
TOOL_MODE = "read-only"
|
|
167
|
+
TOOL_CONFIG = { path = "conf/tool.toml" } # an absolute path in the overlay
|
|
168
|
+
SYSHTTP_PREFIX = { value = "AGENTS_", if_unset = true }
|
|
169
|
+
DOCS_TOKEN = { provider = "env", key = "DOCS_TOKEN" } # needs the store's grant
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
No overlay sets `AOS_*`, `*_OVERLAY_ROOT` or `*_OVERLAY_STATE`. A secret is never a
|
|
173
|
+
value in the overlay: reference it, and the user grants it (see
|
|
174
|
+
[Overlays → Pins, grants and env scripts](overlays.md#pins-grants-and-env-scripts-the-stores-own-settings)).
|
|
175
|
+
|
|
176
|
+
## Setup
|
|
177
|
+
|
|
178
|
+
A `setup.py` (or `.js`, `.mjs`, `.cjs`, `.ps1` on Windows, `.bash`, `.sh` elsewhere) at the root is your setup -- taken to need the network unless a `[[setup]]` entry naming it says `network = false` -- or declare
|
|
179
|
+
variants per OS with `[[setup]]`. See the contract in
|
|
180
|
+
[Overlays → Setup](overlays.md#setup). The essentials:
|
|
181
|
+
|
|
182
|
+
- idempotent; it gets the phase as its first argument and `$AOS_SETUP_PHASE`:
|
|
183
|
+
`install` the first time, `sync` on every add or sync after that, `remove` before
|
|
184
|
+
the overlay is deleted; a phase it does not know is success (exit 0); your
|
|
185
|
+
dependencies are installed before it runs;
|
|
186
|
+
- cwd is your installed overlay root; write only into `$AOS_OVERLAY_STATE`, kept
|
|
187
|
+
across syncs;
|
|
188
|
+
- the environment is the user's, the overlays' root variables, your own declarations,
|
|
189
|
+
`AOS_OVERLAY_ROOT` / `_NAME` / `_STATE`, the user store (`AGENTS_HOME`) and the
|
|
190
|
+
store you are installed into (`AGENTS_SCOPE_ROOT`, `AGENTS_SCOPE`);
|
|
191
|
+
- 300 seconds unless the variant's `timeout` (or the user's `--setup-timeout`) says
|
|
192
|
+
otherwise; `0` means no limit;
|
|
193
|
+
- declare `network = true` when it needs the network: it is reported;
|
|
126
194
|
- a non-zero exit fails the install loudly; confirm any irreversible action yourself.
|
|
127
195
|
|
|
196
|
+
## Needs
|
|
197
|
+
|
|
198
|
+
Say what must exist where your overlay goes; `overlays add` refuses a machine that
|
|
199
|
+
lacks it, naming what is missing:
|
|
200
|
+
|
|
201
|
+
```toml
|
|
202
|
+
[runtime]
|
|
203
|
+
os = ["linux", "macos", "windows"]
|
|
204
|
+
commands = ["git", { name = "gh", os = ["linux", "macos"] }]
|
|
205
|
+
```
|
|
206
|
+
|
|
128
207
|
## Custom commands
|
|
129
208
|
|
|
130
209
|
A **command module** is a `*.py` file defining a `duho` command class with a
|
|
@@ -195,7 +274,8 @@ a good tool:
|
|
|
195
274
|
## Skills
|
|
196
275
|
|
|
197
276
|
Put `skills/<skill-name>/` directories in your overlay to publish shared skills into
|
|
198
|
-
the scope on install
|
|
277
|
+
the scope on install (`skills = [...]` lists them when not all are). See
|
|
278
|
+
[Overlays → Skills](overlays.md#skills).
|
|
199
279
|
|
|
200
280
|
A skill that relies on commands says so, in its own text: which `dotagents` commands
|
|
201
281
|
it uses, that they are available as MCP tools (`dotagents.<command>`) when the
|