dotagents-cli 0.4.0__tar.gz → 0.5.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.4.0 → dotagents_cli-0.5.0}/.gitignore +1 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/CHANGELOG.md +83 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/PKG-INFO +18 -59
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/README.md +17 -58
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/reference.md +2 -0
- dotagents_cli-0.5.0/docs/api/sources.md +3 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/guide/authoring.md +4 -7
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/guide/commands.md +61 -10
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/guide/overlays.md +64 -9
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/guide/private-sync.md +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/index.md +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/mkdocs.yml +1 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/pyproject.toml +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/AGENTS.md +48 -25
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/__init__.py +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_agents.py +179 -52
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_env.py +33 -8
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_hooks.py +23 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/README.md +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/dotagents/cmds/README.md +10 -5
- dotagents_cli-0.5.0/src/dotagents/_overlay/dotagents/cmds/launch.py +203 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlays.py +12 -36
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_scope.py +38 -90
- dotagents_cli-0.5.0/src/dotagents/_sources.py +554 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/__init__.py +53 -24
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/_common.py +2 -3
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/context.py +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/env.py +1 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/overlays.py +58 -22
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_agents.py +43 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_cmds_discovery.py +44 -55
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_env.py +44 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_env_cli_scope.py +6 -12
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_env_safety.py +0 -1
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_last_mile.py +1 -1
- dotagents_cli-0.5.0/tests/test_launch_cmd.py +311 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_overlays_cli.py +53 -11
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_overlays_command.py +43 -50
- dotagents_cli-0.5.0/tests/test_sources.py +425 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_wire_hooks.py +59 -49
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tools/cloud-setup.sh +14 -17
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/LICENSE +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/build.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/agents.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/cli.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/context.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/env.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/fs.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/hooks.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/merge.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/overlays.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/scope.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/api/skills.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/changelog.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/docs/guide/install.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/install.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/__main__.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_context.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_fs.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_merge.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/AGENTS.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/CLAUDE.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/dotagents/DECISIONS.md +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/dotagents/cmds/findings.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/dotagents/hooks/preinvocation_antigravity_context.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_overlay/dotagents/hooks/pretooluse_codex_env.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_skills.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/_wrappers.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/build_pyz.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/src/dotagents/cli/init.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/_shell.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_audit_leak.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_build_pyz.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_context.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_env_format.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_findings_cmd.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_hooks.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_scope.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tests/test_wrappers.py +0 -0
- {dotagents_cli-0.4.0 → dotagents_cli-0.5.0}/tools/audit.py +0 -0
|
@@ -7,6 +7,89 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.0] - 2026-09-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Overlays can come from git repositories and registries. `overlays add` /
|
|
15
|
+
`sync` / `list` / `show` resolve a name against **repos** in order, the first
|
|
16
|
+
that offers it winning: `--repo <spec>` (repeatable), `$AGENTS_OVERLAYS_REPO_<KEY>`
|
|
17
|
+
(one repo per variable, by KEY), `$AGENTS_OVERLAYS_REPO` (the default repo),
|
|
18
|
+
the project store's `dotagents.{json,toml,yaml,yml}`, the user store's, then
|
|
19
|
+
the bundled `overlays/`. A repo is always a collection of overlays: a
|
|
20
|
+
directory (each subdirectory an overlay) or a registry file mapping names
|
|
21
|
+
(or aliases) to sources; it lives at a local path, an `http(s)://` URL (a
|
|
22
|
+
registry, fetched) or inside a git repository named
|
|
23
|
+
`<repo>[@<branch|tag|commit>][#<path>]`, the path picking the directory or
|
|
24
|
+
registry file in the checkout. A source is one overlay: a local directory,
|
|
25
|
+
or a git spec whose path is the overlay's root (no path: the repository root
|
|
26
|
+
is the overlay); a relative path is relative to the registry file, and for a
|
|
27
|
+
registry inside a git checkout it names the same repository at the same
|
|
28
|
+
ref. Checkouts are cached under `<user store>/.cache/overlays/`
|
|
29
|
+
and refreshed on every use; credentials in a repo URL never reach a log line.
|
|
30
|
+
- `dotagents launch [<agent>] [-- <the agent's arguments>]`, a bundled command
|
|
31
|
+
module like `findings`: starts an agent's CLI (`claude`, `codex`, `gemini`,
|
|
32
|
+
`cursor-agent`, `copilot`, `pi`, or `--command <program>`) with the full `env`
|
|
33
|
+
assembly exported to the process and the child, and the assembled `context`
|
|
34
|
+
written to a file (exported as `AGENTS_CONTEXT_FILE`) and handed over as
|
|
35
|
+
appended system-prompt text where the harness takes one (Claude Code:
|
|
36
|
+
`--append-system-prompt-file`), or merged into the harness's own instruction
|
|
37
|
+
file as the managed `dotagents:context` block otherwise. The program is
|
|
38
|
+
resolved on the exported PATH, so a harness an overlay's `bin/` provides is
|
|
39
|
+
found; `--dry-run` prints the command line and the exported names;
|
|
40
|
+
`--no-context` and `--inline` shape the context step; the exit code is the
|
|
41
|
+
harness's. Adapters gained `launch_command` and `launch_context_args()`.
|
|
42
|
+
- The `pi` agent (pi.dev, `@earendil-works/pi-coding-agent`): detected by its
|
|
43
|
+
documented `PI_CODING_AGENT` marker, model from `PI_MODEL`, no vendor (it is
|
|
44
|
+
multi-provider). Its config dir (`$PI_CODING_AGENT_DIR`, else `~/.pi/agent`)
|
|
45
|
+
and the project's `AGENTS.md` / `CLAUDE.md` count as loaded by the harness;
|
|
46
|
+
`context --write-agent` and `launch` hand the context over through
|
|
47
|
+
`.pi/APPEND_SYSTEM.md`, the file pi appends to its system prompt, and
|
|
48
|
+
`launch` uses `--append-system-prompt` directly on POSIX. `init -g` puts a
|
|
49
|
+
managed pointer to the store's `AGENTS.md` into the config dir's `AGENTS.md`
|
|
50
|
+
(pi has no include syntax), never a copy of the block.
|
|
51
|
+
- `env` exports `AGENTS_PYTHON`: the interpreter `dotagents` itself is running
|
|
52
|
+
under (`sys.executable`), seeded only if unset like the scope roots. Shims
|
|
53
|
+
and helper scripts now have a default Python they can trust, where a bare
|
|
54
|
+
`python`/`python3` on PATH may be a Store alias stub, an emulated build, a
|
|
55
|
+
venv's, or missing.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- `overlays add` no longer re-installs and re-runs the setup of a requirement
|
|
60
|
+
the scope already has (in its own store, or the user store when adding to a
|
|
61
|
+
project): it is satisfied and left alone, and the log says so. Each missing
|
|
62
|
+
requirement is still installed and set up before the overlay that needs it;
|
|
63
|
+
a name asked for explicitly is (re)installed and set up as before.
|
|
64
|
+
|
|
65
|
+
### Removed
|
|
66
|
+
|
|
67
|
+
- `overlays --source` and `$AGENTS_OVERLAYS_SRC`: a source directory is just a
|
|
68
|
+
repo now — `--repo <dir>` / `$AGENTS_OVERLAYS_REPO=<dir>`.
|
|
69
|
+
- The one-release `DOTAGENTS_*` fallbacks: `DOTAGENTS_AGENTS_DIR`,
|
|
70
|
+
`DOTAGENTS_OVERLAYS_SRC`, `DOTAGENTS_CMDS_PATH`, and the duplicate
|
|
71
|
+
`DOTAGENTS_AGENTS_DIR` / `DOTAGENTS_OVERLAY_DIR` an overlay's setup script
|
|
72
|
+
received. Only the `AGENTS_*` names are read or set.
|
|
73
|
+
- The extensionless POSIX `setup` script an overlay could ship: `setup.py` is
|
|
74
|
+
the one form, run under the interpreter running dotagents on every platform.
|
|
75
|
+
- The precursor's lowercase `session_start` hook key is no longer migrated.
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- `init` no longer registers the PowerShell hook variants on POSIX hosts, and
|
|
80
|
+
removes the ones an earlier `init` wrote there. A `shell: powershell` entry
|
|
81
|
+
on Linux or macOS is not harmless: Claude Code runs the text as bash and it
|
|
82
|
+
fails with a syntax error on every session (measured in WSL). Linux and
|
|
83
|
+
macOS get the bash handler only; Windows keeps both, and the PowerShell one
|
|
84
|
+
still selects itself only when `bash` is absent. Re-running `init -g` on an
|
|
85
|
+
existing POSIX install converges.
|
|
86
|
+
- Command discovery is resilient per module, not per directory: one broken
|
|
87
|
+
file in a `cmds/` dir (a syntax error, an import-time exception, or a
|
|
88
|
+
`sys.exit()` — which is not an `Exception` and used to escape the guard and
|
|
89
|
+
kill every invocation, `init -g` for a store that did not exist yet
|
|
90
|
+
included) is skipped with a warning that names the file, and its siblings
|
|
91
|
+
still load.
|
|
92
|
+
|
|
10
93
|
## [0.4.0] - 2026-09-09
|
|
11
94
|
|
|
12
95
|
### Security
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: dotagents-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.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
|
|
@@ -68,7 +68,7 @@ Description-Content-Type: text/markdown
|
|
|
68
68
|
|
|
69
69
|
Like dotfiles, but for AI coding agents: a portable, token-budgeted `~/.agents`
|
|
70
70
|
configuration that works across agent runners (Claude Code, Antigravity, Copilot,
|
|
71
|
-
Codex, ...). dotagents is the **mechanism** — install a neutral base, then layer in
|
|
71
|
+
Codex, pi, ...). dotagents is the **mechanism** — install a neutral base, then layer in
|
|
72
72
|
opt-in **overlays** that carry your standards (repo structure, CI/release discipline,
|
|
73
73
|
whatever workflows you want) — so you record them once instead of restating them every
|
|
74
74
|
session.
|
|
@@ -109,7 +109,7 @@ The **example overlays** — the `flows` workflow set, per-language `kb/` + temp
|
|
|
109
109
|
`references`, `release`, `private-sync`, `net`, `recovery`, `tools` — live on a separate
|
|
110
110
|
[`overlays` branch](https://github.com/jose-pr/dotagents/tree/overlays), not in `main`'s
|
|
111
111
|
tree: they are swappable payloads, not part of the tool. `dotagents overlays add <name>`
|
|
112
|
-
resolves them from there (or from any `--
|
|
112
|
+
resolves them from there (or from any `--repo`). See the
|
|
113
113
|
[docs](https://jose-pr.github.io/dotagents/) for what each ships.
|
|
114
114
|
|
|
115
115
|
Named-agent directives aren't a shipped overlay — a named agent (Claude, Antigravity,
|
|
@@ -160,11 +160,20 @@ overlay's skills into the shared skills dir. See below.
|
|
|
160
160
|
|
|
161
161
|
### Managing overlays
|
|
162
162
|
|
|
163
|
-
`dotagents overlays` manages opt-in overlays **by name**, resolving each name against
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
163
|
+
`dotagents overlays` manages opt-in overlays **by name**, resolving each name against
|
|
164
|
+
**repos** in order — the first that offers the name wins. A repo is always a
|
|
165
|
+
**collection** of overlays: a directory (each subdirectory an overlay, e.g. a checkout of
|
|
166
|
+
the [`overlays` branch](https://github.com/jose-pr/dotagents/tree/overlays)) or a
|
|
167
|
+
JSON/TOML/YAML registry file mapping names to **sources**. It lives at a local path, an
|
|
168
|
+
`http(s)://` URL (a registry file, fetched), or inside a git repository named
|
|
169
|
+
`<repo>[@<branch|tag|commit>][#<path>]`, where the path picks the directory or registry
|
|
170
|
+
file in the checkout (no path: the checkout root). A source names **one** overlay: a
|
|
171
|
+
local directory, or a git spec whose path is the overlay's root directory (no path: the
|
|
172
|
+
repository root is the overlay); a relative path is relative to the registry file, and
|
|
173
|
+
inside a git checkout stays in the same repository at the same ref. Name repos with `--repo`,
|
|
174
|
+
`$AGENTS_OVERLAYS_REPO_<KEY>` / `$AGENTS_OVERLAYS_REPO`, or a `dotagents.{json,toml,yaml}`
|
|
175
|
+
in the project or user store.
|
|
176
|
+
Installed overlays are *discovered* by their presence under `<scope>/.agents/overlays/`.
|
|
168
177
|
|
|
169
178
|
```bash
|
|
170
179
|
dotagents overlays add python engineering # install into the scope, publish skills, merge D59 rules/routing
|
|
@@ -185,9 +194,7 @@ at the manual edit, or re-run `install`).
|
|
|
185
194
|
|
|
186
195
|
**Overlay setup scripts.** An overlay may ship an **idempotent** `setup.py` at its root
|
|
187
196
|
(the recommended form: it runs under the same Python that runs dotagents, so it works on
|
|
188
|
-
every OS
|
|
189
|
-
shell script) is still honored as a legacy fallback, but it is discouraged: a shell
|
|
190
|
-
script isn't portable to Windows without a shell. After `add`/`sync` copies the overlay
|
|
197
|
+
every OS). After `add`/`sync` copies the overlay
|
|
191
198
|
in, dotagents runs the script automatically — so anything a human would otherwise
|
|
192
199
|
hand-follow (PATH/lib wiring, self-registration) is one script the tool runs, not a doc.
|
|
193
200
|
When both are present, `setup.py` wins. Presence of a script is the opt-in; skip it with
|
|
@@ -217,54 +224,6 @@ Then wire your runner to it — e.g. Claude Code: put `@AGENTS.md` in
|
|
|
217
224
|
> Read README.md, run `python install.py init && python install.py overlays add engineering -g`,
|
|
218
225
|
> and confirm `~/.agents/overlays/flows/flows/PLAN.md` exists.
|
|
219
226
|
|
|
220
|
-
## Private sync (per-user + per-project, one private repo)
|
|
221
|
-
|
|
222
|
-
Keep your global config **and** every project's private `.agents` (plans, kb, findings)
|
|
223
|
-
in a single private git repo — synced across machines and cloud sessions — without ever
|
|
224
|
-
committing any of it into the (often public) project repos.
|
|
225
|
-
|
|
226
|
-
The idea: your global `~/.agents` **is** a private git repo. Its root is the per-user
|
|
227
|
-
config; a `projects/<name>/` tree holds each project's private `.agents` payload. For a
|
|
228
|
-
checked-out project, `<project>/.agents` is a **symlink** to `~/.agents/projects/<name>`
|
|
229
|
-
(the project's `.gitignore` already excludes `.agents/` per the Leakage rule, so the
|
|
230
|
-
link never lands in the public repo). `<name>` defaults to the project's basename, so a
|
|
231
|
-
local `~/code/app` and a cloud `/home/user/app` resolve to the same store.
|
|
232
|
-
|
|
233
|
-
The `link-project` / `sync-project` commands are **supplied by the `private-sync`
|
|
234
|
-
overlay**, not by dotagents itself — installing the overlay is what makes them exist
|
|
235
|
-
(it ships the commands, their logic, the `kb/` walkthrough and the cloud hooks
|
|
236
|
-
together). So `overlays add private-sync` comes first:
|
|
237
|
-
|
|
238
|
-
```bash
|
|
239
|
-
dotagents init # base
|
|
240
|
-
dotagents overlays add private-sync --source <overlays-checkout> # commands + kb + hooks
|
|
241
|
-
dotagents link-project . # symlink this project's .agents into the private repo
|
|
242
|
-
# (an existing .agents/ is adopted in on the first link;
|
|
243
|
-
# --copy mirrors it as a real dir for no-symlink systems)
|
|
244
|
-
dotagents sync-project -m msg # git pull --rebase / commit / push the private repo
|
|
245
|
-
dotagents sync-project --remote git@github.com:<you>/.agents.git -m init # one-command bootstrap
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
In cloud sessions, the installed `~/.agents/hooks/private-sync-{start,stop}.sh` clone/pull
|
|
249
|
-
the private repo and link/sync the project per session — register them in
|
|
250
|
-
`~/.claude/settings.json` (see `~/.agents/hooks/settings.snippet.json`). For a **fresh
|
|
251
|
-
container** (no `~/.agents` yet), point the web environment's **setup-script** field at the
|
|
252
|
-
self-contained bootstrap in this repo — it fetches the latest each start, so there's
|
|
253
|
-
nothing to re-paste:
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
curl -fsSL https://raw.githubusercontent.com/<you>/dotagents/main/tools/cloud-setup.sh -o /tmp/dg-cloud-setup.sh && sh /tmp/dg-cloud-setup.sh
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Use `curl … -o file && sh file`, not `curl … | sh`: with a pipe the setup field's exit
|
|
260
|
-
code is `sh`'s (0 on empty stdin), so a failed fetch is silently logged as success; `&&`
|
|
261
|
-
propagates the curl failure instead.
|
|
262
|
-
|
|
263
|
-
It authenticates (bypassing a hosted-runner `github.com`→proxy git rewrite), clones/pulls
|
|
264
|
-
`~/.agents`, installs the CLI, and links the project — driven by `AGENTS_REMOTE`
|
|
265
|
-
/ `DOTAGENTS_AGENTS_TOKEN` / `DOTAGENTS_CLI_INSTALL` env vars (token never committed). Full
|
|
266
|
-
walkthrough: `~/.agents/kb/PRIVATE_SYNC.md`.
|
|
267
|
-
|
|
268
227
|
## Validate
|
|
269
228
|
|
|
270
229
|
```bash
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
Like dotfiles, but for AI coding agents: a portable, token-budgeted `~/.agents`
|
|
9
9
|
configuration that works across agent runners (Claude Code, Antigravity, Copilot,
|
|
10
|
-
Codex, ...). dotagents is the **mechanism** — install a neutral base, then layer in
|
|
10
|
+
Codex, pi, ...). dotagents is the **mechanism** — install a neutral base, then layer in
|
|
11
11
|
opt-in **overlays** that carry your standards (repo structure, CI/release discipline,
|
|
12
12
|
whatever workflows you want) — so you record them once instead of restating them every
|
|
13
13
|
session.
|
|
@@ -48,7 +48,7 @@ The **example overlays** — the `flows` workflow set, per-language `kb/` + temp
|
|
|
48
48
|
`references`, `release`, `private-sync`, `net`, `recovery`, `tools` — live on a separate
|
|
49
49
|
[`overlays` branch](https://github.com/jose-pr/dotagents/tree/overlays), not in `main`'s
|
|
50
50
|
tree: they are swappable payloads, not part of the tool. `dotagents overlays add <name>`
|
|
51
|
-
resolves them from there (or from any `--
|
|
51
|
+
resolves them from there (or from any `--repo`). See the
|
|
52
52
|
[docs](https://jose-pr.github.io/dotagents/) for what each ships.
|
|
53
53
|
|
|
54
54
|
Named-agent directives aren't a shipped overlay — a named agent (Claude, Antigravity,
|
|
@@ -99,11 +99,20 @@ overlay's skills into the shared skills dir. See below.
|
|
|
99
99
|
|
|
100
100
|
### Managing overlays
|
|
101
101
|
|
|
102
|
-
`dotagents overlays` manages opt-in overlays **by name**, resolving each name against
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
`dotagents overlays` manages opt-in overlays **by name**, resolving each name against
|
|
103
|
+
**repos** in order — the first that offers the name wins. A repo is always a
|
|
104
|
+
**collection** of overlays: a directory (each subdirectory an overlay, e.g. a checkout of
|
|
105
|
+
the [`overlays` branch](https://github.com/jose-pr/dotagents/tree/overlays)) or a
|
|
106
|
+
JSON/TOML/YAML registry file mapping names to **sources**. It lives at a local path, an
|
|
107
|
+
`http(s)://` URL (a registry file, fetched), or inside a git repository named
|
|
108
|
+
`<repo>[@<branch|tag|commit>][#<path>]`, where the path picks the directory or registry
|
|
109
|
+
file in the checkout (no path: the checkout root). A source names **one** overlay: a
|
|
110
|
+
local directory, or a git spec whose path is the overlay's root directory (no path: the
|
|
111
|
+
repository root is the overlay); a relative path is relative to the registry file, and
|
|
112
|
+
inside a git checkout stays in the same repository at the same ref. Name repos with `--repo`,
|
|
113
|
+
`$AGENTS_OVERLAYS_REPO_<KEY>` / `$AGENTS_OVERLAYS_REPO`, or a `dotagents.{json,toml,yaml}`
|
|
114
|
+
in the project or user store.
|
|
115
|
+
Installed overlays are *discovered* by their presence under `<scope>/.agents/overlays/`.
|
|
107
116
|
|
|
108
117
|
```bash
|
|
109
118
|
dotagents overlays add python engineering # install into the scope, publish skills, merge D59 rules/routing
|
|
@@ -124,9 +133,7 @@ at the manual edit, or re-run `install`).
|
|
|
124
133
|
|
|
125
134
|
**Overlay setup scripts.** An overlay may ship an **idempotent** `setup.py` at its root
|
|
126
135
|
(the recommended form: it runs under the same Python that runs dotagents, so it works on
|
|
127
|
-
every OS
|
|
128
|
-
shell script) is still honored as a legacy fallback, but it is discouraged: a shell
|
|
129
|
-
script isn't portable to Windows without a shell. After `add`/`sync` copies the overlay
|
|
136
|
+
every OS). After `add`/`sync` copies the overlay
|
|
130
137
|
in, dotagents runs the script automatically — so anything a human would otherwise
|
|
131
138
|
hand-follow (PATH/lib wiring, self-registration) is one script the tool runs, not a doc.
|
|
132
139
|
When both are present, `setup.py` wins. Presence of a script is the opt-in; skip it with
|
|
@@ -156,54 +163,6 @@ Then wire your runner to it — e.g. Claude Code: put `@AGENTS.md` in
|
|
|
156
163
|
> Read README.md, run `python install.py init && python install.py overlays add engineering -g`,
|
|
157
164
|
> and confirm `~/.agents/overlays/flows/flows/PLAN.md` exists.
|
|
158
165
|
|
|
159
|
-
## Private sync (per-user + per-project, one private repo)
|
|
160
|
-
|
|
161
|
-
Keep your global config **and** every project's private `.agents` (plans, kb, findings)
|
|
162
|
-
in a single private git repo — synced across machines and cloud sessions — without ever
|
|
163
|
-
committing any of it into the (often public) project repos.
|
|
164
|
-
|
|
165
|
-
The idea: your global `~/.agents` **is** a private git repo. Its root is the per-user
|
|
166
|
-
config; a `projects/<name>/` tree holds each project's private `.agents` payload. For a
|
|
167
|
-
checked-out project, `<project>/.agents` is a **symlink** to `~/.agents/projects/<name>`
|
|
168
|
-
(the project's `.gitignore` already excludes `.agents/` per the Leakage rule, so the
|
|
169
|
-
link never lands in the public repo). `<name>` defaults to the project's basename, so a
|
|
170
|
-
local `~/code/app` and a cloud `/home/user/app` resolve to the same store.
|
|
171
|
-
|
|
172
|
-
The `link-project` / `sync-project` commands are **supplied by the `private-sync`
|
|
173
|
-
overlay**, not by dotagents itself — installing the overlay is what makes them exist
|
|
174
|
-
(it ships the commands, their logic, the `kb/` walkthrough and the cloud hooks
|
|
175
|
-
together). So `overlays add private-sync` comes first:
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
dotagents init # base
|
|
179
|
-
dotagents overlays add private-sync --source <overlays-checkout> # commands + kb + hooks
|
|
180
|
-
dotagents link-project . # symlink this project's .agents into the private repo
|
|
181
|
-
# (an existing .agents/ is adopted in on the first link;
|
|
182
|
-
# --copy mirrors it as a real dir for no-symlink systems)
|
|
183
|
-
dotagents sync-project -m msg # git pull --rebase / commit / push the private repo
|
|
184
|
-
dotagents sync-project --remote git@github.com:<you>/.agents.git -m init # one-command bootstrap
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
In cloud sessions, the installed `~/.agents/hooks/private-sync-{start,stop}.sh` clone/pull
|
|
188
|
-
the private repo and link/sync the project per session — register them in
|
|
189
|
-
`~/.claude/settings.json` (see `~/.agents/hooks/settings.snippet.json`). For a **fresh
|
|
190
|
-
container** (no `~/.agents` yet), point the web environment's **setup-script** field at the
|
|
191
|
-
self-contained bootstrap in this repo — it fetches the latest each start, so there's
|
|
192
|
-
nothing to re-paste:
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
curl -fsSL https://raw.githubusercontent.com/<you>/dotagents/main/tools/cloud-setup.sh -o /tmp/dg-cloud-setup.sh && sh /tmp/dg-cloud-setup.sh
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Use `curl … -o file && sh file`, not `curl … | sh`: with a pipe the setup field's exit
|
|
199
|
-
code is `sh`'s (0 on empty stdin), so a failed fetch is silently logged as success; `&&`
|
|
200
|
-
propagates the curl failure instead.
|
|
201
|
-
|
|
202
|
-
It authenticates (bypassing a hosted-runner `github.com`→proxy git rewrite), clones/pulls
|
|
203
|
-
`~/.agents`, installs the CLI, and links the project — driven by `AGENTS_REMOTE`
|
|
204
|
-
/ `DOTAGENTS_AGENTS_TOKEN` / `DOTAGENTS_CLI_INSTALL` env vars (token never committed). Full
|
|
205
|
-
walkthrough: `~/.agents/kb/PRIVATE_SYNC.md`.
|
|
206
|
-
|
|
207
166
|
## Validate
|
|
208
167
|
|
|
209
168
|
```bash
|
|
@@ -11,6 +11,8 @@ form its API. Generated from docstrings, organized by module:
|
|
|
11
11
|
`AGENTS.md` contributions; setup-script discovery and the manifest reader.
|
|
12
12
|
- **[Scope](scope.md)** — scope and overlay-source resolution for the `overlays`
|
|
13
13
|
command.
|
|
14
|
+
- **[Sources](sources.md)** — overlay repos: directories of overlays, registry
|
|
15
|
+
files, git specs, and the precedence the `overlays` commands resolve names through.
|
|
14
16
|
- **[Context](context.md)** — assembling the effective context for agents.
|
|
15
17
|
- **[Environment](env.md)** — chained env-file assembly and `env.py` execution.
|
|
16
18
|
- **[Merge](merge.md)** — the managed-block merge for `init`'s `AGENTS.md` /
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Authoring an overlay
|
|
2
2
|
|
|
3
3
|
An overlay is just a directory with the files you want laid into a scope, plus an
|
|
4
|
-
optional `overlay.toml` manifest. Anyone can write one;
|
|
5
|
-
|
|
4
|
+
optional `overlay.toml` manifest. Anyone can write one; name its parent directory (a
|
|
5
|
+
directory of overlays), a registry, or a git repo with `--repo` — see the overlays guide.
|
|
6
6
|
|
|
7
7
|
## Minimal overlay
|
|
8
8
|
|
|
@@ -24,7 +24,7 @@ routing = [
|
|
|
24
24
|
Install it:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
python -m dotagents overlays add my-overlay --
|
|
27
|
+
python -m dotagents overlays add my-overlay --repo /path/to/parent -g
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
The overlay's files land at the same relative path in the scope, and each `routing`
|
|
@@ -54,10 +54,7 @@ matters.
|
|
|
54
54
|
|
|
55
55
|
Ship an idempotent `setup.py` at the overlay root to run install-time wiring
|
|
56
56
|
automatically — the recommended, OS-agnostic form (it runs under the same Python as
|
|
57
|
-
dotagents, so it works on every platform
|
|
58
|
-
extensionless `setup` (a POSIX shell script) still works as a legacy fallback but is
|
|
59
|
-
discouraged — it needs a shell, so it isn't portable to Windows. When both are present,
|
|
60
|
-
`setup.py` wins. See the contract in
|
|
57
|
+
dotagents, so it works on every platform). See the contract in
|
|
61
58
|
[Overlays → Setup scripts](overlays.md#setup-scripts). The essentials:
|
|
62
59
|
|
|
63
60
|
- idempotent, check-then-act;
|
|
@@ -17,10 +17,11 @@ by default (the `<cwd>/.agents` store, when run inside a project) or **user** wi
|
|
|
17
17
|
| `env` | Assemble the chained env-file layers + identity vars, in a chosen format. |
|
|
18
18
|
| `build-pyz` | Build the self-contained `dotagents.pyz` zipapp. |
|
|
19
19
|
| `findings` | Per-scope findings queue: `add` / `list` / `show` / `done` / `reopen` / `remove` / `index` / `path`. |
|
|
20
|
+
| `launch` | Start an agent's CLI with the `env` exported and the `context` handed over; everything after `--` goes to the agent. |
|
|
20
21
|
|
|
21
|
-
That table is the **whole** shipped surface; `findings`
|
|
22
|
-
|
|
23
|
-
scope's `cmds/`). Everything else is **discovered**, from each **installed overlay's** `cmds/`
|
|
22
|
+
That table is the **whole** shipped surface; `findings` and `launch` are the two bundled
|
|
23
|
+
command modules (discovered from the package itself, overridable by a same-named module
|
|
24
|
+
in a scope's `cmds/`). Everything else is **discovered**, from each **installed overlay's** `cmds/`
|
|
24
25
|
dir, each scope's command dir, `$AGENTS_CMDS_PATH` entries, and `--cmdspath` — one
|
|
25
26
|
Contract-A resolver walk covers the overlay + scope tiers (D84). Two consequences
|
|
26
27
|
worth knowing:
|
|
@@ -107,7 +108,7 @@ managed block into `config.toml`:
|
|
|
107
108
|
```toml
|
|
108
109
|
# dotagents:begin
|
|
109
110
|
[shell_environment_policy]
|
|
110
|
-
set = {AGENT = "codex", AGENTS_HARNESS = "codex", AGENTS_VENDOR = "openai", AGENTS_HOME = "...", AGENTS_PROJECT_ROOT = "..."}
|
|
111
|
+
set = {AGENT = "codex", AGENTS_HARNESS = "codex", AGENTS_VENDOR = "openai", AGENTS_HOME = "...", AGENTS_PROJECT_ROOT = "...", AGENTS_PYTHON = "..."}
|
|
111
112
|
# dotagents:end
|
|
112
113
|
```
|
|
113
114
|
|
|
@@ -142,9 +143,12 @@ dotagents overlays sync --overwrite # also replace installed files whose
|
|
|
142
143
|
dotagents overlays show python # describe one: manifest, requires, setup, skills (--json)
|
|
143
144
|
```
|
|
144
145
|
|
|
145
|
-
`add` installs what each manifest's `requires` names first
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
`add` installs what each manifest's `requires` names first, each requirement installed
|
|
147
|
+
and set up before the overlay that needs it (`--no-requires` to skip); a requirement
|
|
148
|
+
the scope already has, in its own store or the user store for a project, is satisfied
|
|
149
|
+
and left alone, while a name you ask for explicitly is always (re)installed and set up.
|
|
150
|
+
It validates every name before touching anything, and publishes skills from the
|
|
151
|
+
installed copy. `remove` recomposes `AGENTS.md`'s managed block over the overlays that remain, so
|
|
148
152
|
an overlay's rules and routing leave with it. `sync` never clobbers an installed file
|
|
149
153
|
unless `--overwrite`.
|
|
150
154
|
|
|
@@ -169,7 +173,8 @@ dotagents context --write-agent --agents codex # merge a managed block into <pro
|
|
|
169
173
|
- `--write-agent` — merge the context into each agent's own instruction file under
|
|
170
174
|
the project root, as a managed `dotagents:context` block refreshed in place:
|
|
171
175
|
Claude `.claude/CLAUDE.md`, Codex `AGENTS.md`, Gemini `GEMINI.md`, Cursor
|
|
172
|
-
`.cursorrules`, Copilot `.github/copilot-instructions.md`,
|
|
176
|
+
`.cursorrules`, Copilot `.github/copilot-instructions.md`, pi
|
|
177
|
+
`.pi/APPEND_SYSTEM.md` (the file pi appends to its system prompt), Antigravity
|
|
173
178
|
`.agents/rules/dotagents.md`. Prefer the hook where the harness has one; this is
|
|
174
179
|
the static alternative. Mutually exclusive with `[output]` and `--format json`.
|
|
175
180
|
- `--inline` — also append the on-demand `.md` files the sources reference (bare or
|
|
@@ -209,7 +214,11 @@ python -m dotagents env --diff --format json # only vars that differ from the
|
|
|
209
214
|
|
|
210
215
|
Roots resolve exactly as for `context` above (`$AGENTS_HOME` /
|
|
211
216
|
`$AGENTS_PROJECT_ROOT`, both of which `env` also emits — so a subprocess reading
|
|
212
|
-
them agrees with the parent that wrote them). `env` also emits
|
|
217
|
+
them agrees with the parent that wrote them). `env` also emits `AGENTS_PYTHON`,
|
|
218
|
+
the interpreter `dotagents` itself is running under — the Python a shim or helper
|
|
219
|
+
script should run with, since a bare `python`/`python3` on `PATH` may be a Store
|
|
220
|
+
stub, an emulated build, a venv's, or missing (only if unset, so a pin holds;
|
|
221
|
+
the env-layer `env.py` scripts run under a valid pin too). And `env` emits one
|
|
213
222
|
`<NAME>_OVERLAY_ROOT` per installed overlay, where `NAME` is the overlay's
|
|
214
223
|
directory name upper-cased with `-`/`.` turned into `_` (`my-ov` →
|
|
215
224
|
`MY_OV_OVERLAY_ROOT`). It is the same name `context` expands as a
|
|
@@ -267,6 +276,48 @@ dotagents findings path # where this scope's queue lives
|
|
|
267
276
|
- The command is bundled with dotagents and discovered from the package itself;
|
|
268
277
|
a same-named `findings.py` in a scope's `dotagents/cmds/` overrides it.
|
|
269
278
|
|
|
279
|
+
## launch
|
|
280
|
+
|
|
281
|
+
Start an agent's command-line harness the way a session wired by `init` would
|
|
282
|
+
find the world already: the full `env` exported, and the `context` handed over
|
|
283
|
+
up front.
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
dotagents launch claude -- --model sonnet # everything after `--` is the agent's
|
|
287
|
+
dotagents launch # the active agent, as `context` picks it
|
|
288
|
+
dotagents launch codex --dry-run # print the command line and the exported names
|
|
289
|
+
dotagents launch -g gemini # user-store tiers only (the env/context meaning of -g)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
What happens, in order:
|
|
293
|
+
|
|
294
|
+
1. **Environment** — the same assembly as `dotagents env` for this scope (identity
|
|
295
|
+
vars, `AGENTS_HOME` / `AGENTS_PROJECT_ROOT` / `AGENTS_PYTHON`, every
|
|
296
|
+
`<NAME>_OVERLAY_ROOT`, the `PATH` / `PYTHONPATH` prepends, the env-file chain)
|
|
297
|
+
is applied to the `dotagents` process and handed to the child, so the harness
|
|
298
|
+
and everything it spawns see it.
|
|
299
|
+
2. **Context** — `dotagents context` for that agent (what its harness does not
|
|
300
|
+
already load) is written to a file, exported as `AGENTS_CONTEXT_FILE`, and
|
|
301
|
+
passed the way the harness takes appended system-prompt text: Claude Code gets
|
|
302
|
+
`--append-system-prompt-file`, pi gets `--append-system-prompt` (on POSIX; on
|
|
303
|
+
Windows its npm `.cmd` shim cannot carry a multi-line argument, so it takes the
|
|
304
|
+
static route below). A harness with no append flag (Codex, Gemini,
|
|
305
|
+
Cursor, Copilot — their prompt-file options *replace* the built-in prompt, which
|
|
306
|
+
is not the same thing) gets it the static way instead: merged as the managed
|
|
307
|
+
`dotagents:context` block into its own instruction file in the project, exactly
|
|
308
|
+
what `context --write-agent` does. `--no-context` skips this; `--inline` also
|
|
309
|
+
inlines the on-demand files the sources reference.
|
|
310
|
+
3. **The harness** — the agent's program (`claude`, `codex`, `gemini`,
|
|
311
|
+
`cursor-agent`, `copilot`, `pi`), resolved on the PATH from step 1 so a harness an
|
|
312
|
+
overlay's `bin/` provides is found, or `--command <program>` for one under
|
|
313
|
+
another name. dotagents' flags come first and the passthrough after, so yours
|
|
314
|
+
win where the harness takes the last value. The exit code is the harness's.
|
|
315
|
+
|
|
316
|
+
`--dry-run` prints the command line and the names of the exported changes (never
|
|
317
|
+
their values) and runs nothing. Like `findings`, the command is bundled and
|
|
318
|
+
discovered from the package; a same-named `launch.py` in a scope's
|
|
319
|
+
`dotagents/cmds/` overrides it.
|
|
320
|
+
|
|
270
321
|
## audit — not a dotagents command
|
|
271
322
|
|
|
272
323
|
There is no `dotagents audit`. The dotagents source repo has its own
|
|
@@ -291,7 +342,7 @@ behind them, so a plain install carries no private-sync workflow at all. Install
|
|
|
291
342
|
overlay first and they become available like any other subcommand:
|
|
292
343
|
|
|
293
344
|
```bash
|
|
294
|
-
python -m dotagents overlays add private-sync --
|
|
345
|
+
python -m dotagents overlays add private-sync --repo <overlays-checkout>/overlays
|
|
295
346
|
|
|
296
347
|
python -m dotagents link-project . # symlink this project's .agents into its store
|
|
297
348
|
python -m dotagents link-project . --copy # real-dir copy (no-symlink systems)
|
|
@@ -8,10 +8,10 @@ opinionated ships as a named overlay you add explicitly.
|
|
|
8
8
|
|
|
9
9
|
An overlay is a directory (optionally carrying an `overlay.toml` manifest) whose files
|
|
10
10
|
install to the same relative path in the destination scope. `dotagents overlays`
|
|
11
|
-
resolves each overlay **by name** against
|
|
12
|
-
|
|
13
|
-
overlays
|
|
14
|
-
by their presence there.
|
|
11
|
+
resolves each overlay **by name** against the repos you name (`--repo`,
|
|
12
|
+
`$AGENTS_OVERLAYS_REPO`, a `dotagents.{json,toml,yaml}` in a store — see
|
|
13
|
+
"Where overlays come from" below), and installs it into the scope's overlays
|
|
14
|
+
directory. Installed overlays are then *discovered* by their presence there.
|
|
15
15
|
|
|
16
16
|
Overlays are **additive**. `add` / `sync` never clobber a file you hand-edited inside
|
|
17
17
|
an installed overlay — an already-present file is skipped.
|
|
@@ -21,8 +21,8 @@ an installed overlay — an already-present file is skipped.
|
|
|
21
21
|
The example overlays below live on this repo's separate
|
|
22
22
|
[`overlays` branch](https://github.com/jose-pr/dotagents/tree/overlays), not in `main` —
|
|
23
23
|
they are **payloads riding on dotagents**, not part of the tool, so you swap them for
|
|
24
|
-
your own.
|
|
25
|
-
`dotagents overlays add <name> --
|
|
24
|
+
your own. Name a checkout of that branch as a repo to install any with
|
|
25
|
+
`dotagents overlays add <name> --repo <overlays-checkout>/overlays`.
|
|
26
26
|
|
|
27
27
|
| Overlay | What it carries |
|
|
28
28
|
| --- | --- |
|
|
@@ -60,6 +60,63 @@ published (a copy the user edited is left alone). Its lines in `AGENTS.md`'s man
|
|
|
60
60
|
block leave with it: the block is recomposed from the pristine base over the overlays
|
|
61
61
|
that remain.
|
|
62
62
|
|
|
63
|
+
## Where overlays come from: repos
|
|
64
|
+
|
|
65
|
+
`add`, `sync`, `list` and `show` resolve a name against a list of **repos**, and the
|
|
66
|
+
first repo that offers the name wins. A repo is **always a collection** of overlays,
|
|
67
|
+
in one of two shapes:
|
|
68
|
+
|
|
69
|
+
- a **directory of overlays** — each subdirectory is an overlay, `<dir>/<name>/` (a
|
|
70
|
+
checkout of the `overlays` branch, any folder);
|
|
71
|
+
- a **registry** — a JSON, TOML or YAML file mapping `<name-or-alias>` to the
|
|
72
|
+
**source** of that one overlay (the whole document, or its `overlays` key).
|
|
73
|
+
|
|
74
|
+
Both the repo and each source are written as a spec, `<location>[@<ref>][#<path>]`:
|
|
75
|
+
`<location>` is a local path, an `http(s)://` URL, or a git repository
|
|
76
|
+
(`https://…/x.git`, `git@host:org/x.git`, `ssh://…`, a local `…/x.git`; prefix `git+` to
|
|
77
|
+
force git); `<ref>` is a branch, tag or commit; `<path>` is inside it. The two differ
|
|
78
|
+
in what the path names:
|
|
79
|
+
|
|
80
|
+
- for a **repo**, the collection: a directory (of overlays) or a registry file in the
|
|
81
|
+
checkout, the checkout root with no path; an `http(s)://` location is a registry
|
|
82
|
+
file, fetched;
|
|
83
|
+
- for a **source**, the overlay: the path is the overlay's root directory, and with no
|
|
84
|
+
path **the repository root is the overlay**.
|
|
85
|
+
|
|
86
|
+
A source written as a **relative path** (`./python`, `../shared/net`, `overlays/rust`)
|
|
87
|
+
is relative to the registry it is in: the registry file's directory for a local file,
|
|
88
|
+
and for a registry inside a git checkout the **same repository at the same ref**, with
|
|
89
|
+
the path joined onto the registry file's directory (`overlays/reg.toml` saying `./rust`
|
|
90
|
+
means `<repo>@<ref>#overlays/rust`). A registry fetched over `http(s)` has no overlays
|
|
91
|
+
beside it, so a relative entry there is an error.
|
|
92
|
+
|
|
93
|
+
Checkouts are cached under `<user store>/.cache/overlays/` and refreshed on every
|
|
94
|
+
`add`/`sync`.
|
|
95
|
+
|
|
96
|
+
The repos, in order:
|
|
97
|
+
|
|
98
|
+
1. `--repo <spec>` (repeatable);
|
|
99
|
+
2. `$AGENTS_OVERLAYS_REPO_<KEY>=<spec>`, sorted by `KEY`, then `$AGENTS_OVERLAYS_REPO`
|
|
100
|
+
(the default repo);
|
|
101
|
+
3. `<project store>/dotagents.{json,toml,yaml,yml}`, then the user store's;
|
|
102
|
+
4. the `overlays/` bundled with this build, if any.
|
|
103
|
+
|
|
104
|
+
```toml
|
|
105
|
+
# ~/.agents/dotagents.toml
|
|
106
|
+
[overlays]
|
|
107
|
+
engineering = "https://github.com/you/dotagents.git@overlays#overlays/engineering"
|
|
108
|
+
python = "https://github.com/you/dotagents.git@overlays#overlays/python"
|
|
109
|
+
mytool = "git@github.com:you/mytool-overlay.git@v2" # no path: the repo root is the overlay
|
|
110
|
+
local = "~/src/overlays/local" # a local overlay directory
|
|
111
|
+
mine = "./overlays/mine" # relative to this file: ~/.agents/overlays/mine
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
dotagents overlays add engineering -g # from the registry above
|
|
116
|
+
dotagents overlays add net --repo https://github.com/you/dotagents.git@overlays#overlays/net
|
|
117
|
+
dotagents overlays sync -g # refetches git-sourced overlays
|
|
118
|
+
```
|
|
119
|
+
|
|
63
120
|
## What `dotagents env` wires for every overlay
|
|
64
121
|
|
|
65
122
|
Nothing in an overlay has to set up its own paths. For every installed overlay,
|
|
@@ -98,9 +155,7 @@ only the skills it published, then sweeps any now-broken symlinks.
|
|
|
98
155
|
|
|
99
156
|
An overlay may ship an **idempotent** `setup.py` at its root — the recommended,
|
|
100
157
|
OS-agnostic form: it runs under the same Python that runs dotagents, so it works on
|
|
101
|
-
every platform.
|
|
102
|
-
**legacy fallback**, but discouraged — a shell script isn't portable to Windows without
|
|
103
|
-
a shell. When both are present, `setup.py` wins. After `add` / `sync` copies the overlay
|
|
158
|
+
every platform. After `add` / `sync` copies the overlay
|
|
104
159
|
in, dotagents runs the script automatically. Reserve it for real install-time work:
|
|
105
160
|
PATH / PYTHONPATH / `$<NAME>_OVERLAY_ROOT` are `dotagents env`'s job (above), and an
|
|
106
161
|
overlay's own env vars belong in its `env.py`, not in a script that writes one into the
|
|
@@ -24,7 +24,7 @@ entry.
|
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
dotagents init # base config
|
|
27
|
-
dotagents overlays add private-sync --
|
|
27
|
+
dotagents overlays add private-sync --repo <overlays-checkout>/overlays # commands + kb + hooks
|
|
28
28
|
|
|
29
29
|
# link-project / sync-project come FROM that overlay -- run `overlays add` first.
|
|
30
30
|
python -m dotagents link-project . # symlink this project's .agents into its store
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**dotagents** is dotfiles, but for AI coding agents: a portable, token-budgeted
|
|
4
4
|
`~/.agents` configuration that works across agent runners (Claude Code, Antigravity,
|
|
5
|
-
Copilot, Codex, …). dotagents is the **mechanism** — install a neutral base, then layer
|
|
5
|
+
Copilot, Codex, pi, …). dotagents is the **mechanism** — install a neutral base, then layer
|
|
6
6
|
in opt-in **overlays** that carry your standards (repo structure, CI/release discipline,
|
|
7
7
|
whatever workflows you want) — so you record them once instead of restating them every
|
|
8
8
|
session.
|
|
@@ -9,7 +9,7 @@ build-backend = "hatchling.build"
|
|
|
9
9
|
# redirect/placeholder before someone else does, but the CLI ships under -cli.
|
|
10
10
|
[project]
|
|
11
11
|
name = "dotagents-cli"
|
|
12
|
-
version = "0.
|
|
12
|
+
version = "0.5.0"
|
|
13
13
|
authors = [{ name = "Jose A." }]
|
|
14
14
|
description = "The dotagents CLI: install and manage a portable ~/.agents config for AI coding agents"
|
|
15
15
|
readme = "README.md"
|