dotagents-cli 0.3.4__tar.gz → 0.4.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.3.4 → dotagents_cli-0.4.0}/CHANGELOG.md +339 -6
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/PKG-INFO +6 -6
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/README.md +5 -5
- dotagents_cli-0.4.0/docs/api/fs.md +3 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/reference.md +4 -3
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/guide/commands.md +93 -24
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/guide/install.md +1 -1
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/guide/overlays.md +28 -11
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/index.md +1 -1
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/mkdocs.yml +1 -1
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/pyproject.toml +1 -1
- dotagents_cli-0.4.0/src/dotagents/AGENTS.md +364 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/__init__.py +1 -1
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_agents.py +251 -94
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_context.py +133 -133
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_env.py +212 -74
- dotagents_cli-0.4.0/src/dotagents/_fs.py +43 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_hooks.py +58 -24
- dotagents_cli-0.4.0/src/dotagents/_merge.py +222 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_overlay/AGENTS.md +5 -3
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_overlay/README.md +16 -9
- dotagents_cli-0.4.0/src/dotagents/_overlay/dotagents/DECISIONS.md +24 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_overlay/dotagents/cmds/README.md +12 -9
- dotagents_cli-0.4.0/src/dotagents/_overlay/dotagents/cmds/findings.py +579 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_overlay/dotagents/hooks/preinvocation_antigravity_context.py +34 -5
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_overlay/dotagents/hooks/pretooluse_codex_env.py +8 -2
- dotagents_cli-0.4.0/src/dotagents/_overlays.py +707 -0
- dotagents_cli-0.4.0/src/dotagents/_scope.py +445 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_skills.py +37 -16
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/cli/__init__.py +84 -44
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/cli/_common.py +139 -75
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/cli/build_pyz.py +13 -5
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/cli/context.py +43 -33
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/cli/env.py +109 -31
- dotagents_cli-0.4.0/src/dotagents/cli/overlays.py +531 -0
- dotagents_cli-0.4.0/tests/_shell.py +50 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_agents.py +3 -1
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_audit_leak.py +13 -6
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_cmds_discovery.py +50 -16
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_context.py +107 -31
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_env.py +190 -18
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_env_format.py +140 -10
- dotagents_cli-0.4.0/tests/test_env_safety.py +203 -0
- dotagents_cli-0.4.0/tests/test_findings_cmd.py +280 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_hooks.py +27 -0
- dotagents_cli-0.4.0/tests/test_last_mile.py +256 -0
- dotagents_cli-0.4.0/tests/test_overlays_cli.py +358 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_overlays_command.py +157 -16
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_scope.py +7 -25
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_wire_hooks.py +116 -11
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tools/audit.py +34 -23
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tools/cloud-setup.sh +10 -6
- dotagents_cli-0.3.4/docs/api/resolve.md +0 -3
- dotagents_cli-0.3.4/src/dotagents/AGENTS.md +0 -220
- dotagents_cli-0.3.4/src/dotagents/_merge.py +0 -126
- dotagents_cli-0.3.4/src/dotagents/_overlay/dotagents/DECISIONS.md +0 -20
- dotagents_cli-0.3.4/src/dotagents/_overlays.py +0 -412
- dotagents_cli-0.3.4/src/dotagents/_resolve.py +0 -81
- dotagents_cli-0.3.4/src/dotagents/_scope.py +0 -265
- dotagents_cli-0.3.4/src/dotagents/cli/overlays.py +0 -334
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/.gitignore +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/LICENSE +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/build.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/agents.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/cli.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/context.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/env.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/hooks.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/merge.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/overlays.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/scope.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/api/skills.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/changelog.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/guide/authoring.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/docs/guide/private-sync.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/install.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/__main__.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_overlay/CLAUDE.md +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/_wrappers.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/src/dotagents/cli/init.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_build_pyz.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_env_cli_scope.py +0 -0
- {dotagents_cli-0.3.4 → dotagents_cli-0.4.0}/tests/test_wrappers.py +0 -0
|
@@ -7,6 +7,339 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-09-09
|
|
11
|
+
|
|
12
|
+
### Security
|
|
13
|
+
|
|
14
|
+
- `env --format export` (the form the SessionStart hook writes into
|
|
15
|
+
`$CLAUDE_ENV_FILE`) now single-quotes every value (`'` → `'\''`, control
|
|
16
|
+
characters via bash's `$'...'`). Values were JSON-quoted, i.e. inside DOUBLE
|
|
17
|
+
quotes, so `$(...)`, backticks and `$VAR` in any env value were executed or
|
|
18
|
+
expanded when the file was sourced, while `\n` and non-ASCII (`\u00e9`)
|
|
19
|
+
arrived as literal escape text.
|
|
20
|
+
- The env chain no longer executes or sources a project's own top-level
|
|
21
|
+
`env.py` / `env`: only `<project>/.agents/*` and the user-local
|
|
22
|
+
`local.env` / `pre.local.env` run at the project levels. Every session start
|
|
23
|
+
ran the chain, so opening a session in a cloned repository with a top-level
|
|
24
|
+
`env.py` was code execution from that checkout.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- feat: **`dotagents findings`** — a per-scope findings queue, shipped as the
|
|
29
|
+
one bundled command module (`_overlay/dotagents/cmds/findings.py`). A
|
|
30
|
+
finding is one markdown file shaped like an agent memory (frontmatter
|
|
31
|
+
`name`/`description`/`status`/`created` for the index line, details in the
|
|
32
|
+
body) under `<scope-root>/findings/`: the project's `.agents/findings/` by
|
|
33
|
+
default, the user store's with `-g`, anywhere with `--dir`. `add` records
|
|
34
|
+
one (`--body`/`--body-file`, `-` = stdin), `list` prints the active ones
|
|
35
|
+
(`--all`, `--processed`, `--json`), `show` prints one (`--json`), `done`
|
|
36
|
+
appends a required `## Resolution` and MOVES the file to `processed/`
|
|
37
|
+
(never deletes), `reopen` moves it back, `remove` deletes a mistaken one,
|
|
38
|
+
`index` regenerates `INDEX.md` (active first, then processed — every
|
|
39
|
+
mutating command rewrites it), `path` prints the queue's location.
|
|
40
|
+
Hand-written notes without a frontmatter are listed too and gain one when
|
|
41
|
+
first rewritten. Files are written LF-only on every platform.
|
|
42
|
+
- chore: `init` no longer copies bundled command modules (`*.py`) from the
|
|
43
|
+
package's `dotagents/cmds/` into the store — only the README. The bundled
|
|
44
|
+
dir is always a discovery source, so a copy added nothing, and being
|
|
45
|
+
create-if-absent it would have pinned the first-installed version of
|
|
46
|
+
`findings` and shadowed every later one. A same-named module dropped into a
|
|
47
|
+
scope's `dotagents/cmds/` still overrides the bundled one.
|
|
48
|
+
- feat: `env` prepends every level's existing **`lib/`** dir to `PYTHONPATH`,
|
|
49
|
+
the way it already prepends every level's `bin/` to `PATH` — overlays first,
|
|
50
|
+
then the store, then the project's `.agents/`, never the project root — and
|
|
51
|
+
does so before the env-file chain, so an `env.py` (and every subprocess that
|
|
52
|
+
inherits the env) can `import` an overlay's `lib/` module. Only dirs that
|
|
53
|
+
exist are added, and `PYTHONPATH` is untouched when there are none. The
|
|
54
|
+
formatter already converts any `*PATH` variable between Windows and POSIX
|
|
55
|
+
forms, so `PYTHONPATH` gets the same treatment as `PATH`.
|
|
56
|
+
- feat: `env` emits one **`<NAME>_OVERLAY_ROOT`** per installed overlay (the
|
|
57
|
+
overlay's install dir), seeded before the env-file chain like the two scope
|
|
58
|
+
roots and, like them, only if unset. `NAME` is the overlay's directory name
|
|
59
|
+
upper-cased with every non-alphanumeric character turned into `_`
|
|
60
|
+
(`my-ov.v2` → `MY_OV_V2_OVERLAY_ROOT`). This is the same name `context`
|
|
61
|
+
already expanded as a `<NAME_OVERLAY_ROOT>` placeholder; the two now share
|
|
62
|
+
one naming function, so an env file and a context file name an overlay's
|
|
63
|
+
install dir identically. The variable is derived from the same normalized
|
|
64
|
+
name `overlays add` installs under (`Overlay.normalize_name`), so the var
|
|
65
|
+
for `overlays/<n>/` is always `Overlay.root_var_for(n)`.
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
|
|
69
|
+
- The overlay-root note `overlays add` writes above routing lines cites
|
|
70
|
+
`$ENGINEERING_OVERLAY_ROOT` as its example; the docs and CI install the
|
|
71
|
+
`engineering` overlay, which now carries the flows, references, and tools that
|
|
72
|
+
were separate overlays (each is a category dir under it, never `<name>/<name>/`).
|
|
73
|
+
- The contract-A walk is `Scope.paths(*names, include_missing=False)`; the
|
|
74
|
+
`_resolve` module (and its API docs page) is gone, its `LEVEL_NAMES` live in
|
|
75
|
+
`_scope`.
|
|
76
|
+
- The system store is a store like the others. `Scope.system_root`
|
|
77
|
+
(`/etc/agents`, or `$AGENTS_SYSTEM_ROOT`) heads `Scope.stores`, and the
|
|
78
|
+
contract-A walk goes store by store -- system, user, project -- each store's
|
|
79
|
+
overlays first, then the store itself, then the project root; the hardcoded
|
|
80
|
+
`/etc/agents` tier and its odd position (after the user store's overlays,
|
|
81
|
+
before the user store) are gone. A system overlay is shadowed by a same-named
|
|
82
|
+
user or project one. `overlays list` prints one `installed (<level>)` block
|
|
83
|
+
per store that has anything, most specific first.
|
|
84
|
+
- The library walk takes one object. `Scope` now carries the whole picture
|
|
85
|
+
(`user_root`, `project_root`, `stores`, `overlays`, `files(*names)`), and
|
|
86
|
+
`get_file_paths`, `get_environment`, `get_diff`, `resolve_env_files`,
|
|
87
|
+
`get_bin_paths`, `get_lib_paths`, `get_overlay_roots`, `assemble_context` and
|
|
88
|
+
`assemble_context_data` take a `Scope` instead of the
|
|
89
|
+
`(agents_dir, project_root, global_scope)` keyword triple ported from the
|
|
90
|
+
precursor. `Scope.of(agents_dir=, project_root=, global_scope=)` builds one
|
|
91
|
+
from resolved parts. No compatibility form: the CLI is the public surface.
|
|
92
|
+
- **One overlay name, two scopes = one overlay, the project's.** A project
|
|
93
|
+
session uses the user store's overlays AND the project's (`<project>/.agents/
|
|
94
|
+
overlays/`); an overlay installed in both under the same name is the
|
|
95
|
+
project's copy only, which shadows the store's for bin, lib, env files,
|
|
96
|
+
cmds, `CONTEXT.md` and the `<NAME>_OVERLAY_ROOT` var (a store root the
|
|
97
|
+
session had already pinned is re-pointed). `-g` sees the user store alone.
|
|
98
|
+
`Overlay.installed(*stores)` is the one discovery behind the contract-A
|
|
99
|
+
walk, `env`, `context` and `overlays list` / `show`; the `_scope`
|
|
100
|
+
`discover_overlays` pass-through is gone (`Overlay.discover(root)` is the
|
|
101
|
+
single-root form). `overlays list` in a project scope prints both
|
|
102
|
+
`installed (project)` and `installed (user)`, marking shadowed store copies;
|
|
103
|
+
`overlays show` falls back to the user store's copy before the source.
|
|
104
|
+
- Overlay routing lines refer to overlay files through `$<NAME>_OVERLAY_ROOT`
|
|
105
|
+
(the variable `env` exports per installed overlay), not a hard `~/.agents/`
|
|
106
|
+
path; when a merged block carries such lines, `AGENTS.md` gets one line
|
|
107
|
+
above them saying what the token is and how to resolve it. The example
|
|
108
|
+
overlays on the `overlays` branch follow this convention and ship no setup
|
|
109
|
+
scripts any more (PATH, PYTHONPATH and the root var are `env`'s job; an
|
|
110
|
+
overlay's own env belongs in its `env.py`). `tools/cloud-setup.sh` finds
|
|
111
|
+
the private-sync settings snippet inside the installed overlay.
|
|
112
|
+
- The base overlay's findings workflow now goes through the command. The
|
|
113
|
+
managed `AGENTS.md` rule ("Global-config misses"), `dotagents/DECISIONS.md`
|
|
114
|
+
("How findings become config") and the skeleton README say
|
|
115
|
+
`dotagents findings add -g ...` to record a miss, `list -g` / `show -g` to
|
|
116
|
+
triage and `done -g <name> -r ...` to close one, instead of "drop a note in
|
|
117
|
+
`~/.agents/dotagents/findings/`". With that, the user store's queue is
|
|
118
|
+
**`~/.agents/findings/`** (the command's `-g` default), no longer
|
|
119
|
+
`~/.agents/dotagents/findings/`. An existing queue at the old path keeps
|
|
120
|
+
working with `--dir ~/.agents/dotagents/findings`, or move it once:
|
|
121
|
+
`mv ~/.agents/dotagents/findings ~/.agents/findings`. Re-run `dotagents init`
|
|
122
|
+
to refresh the managed block.
|
|
123
|
+
- refactor: `dotagents._overlays` is now built around an **`Overlay`** class —
|
|
124
|
+
one overlay is one directory, and everything that depends on a single
|
|
125
|
+
overlay is a method or property on it: `.path` / `.name` / `.normalized_name`
|
|
126
|
+
/ `.root_var` / `.is_valid` / `.manifest_path`, `.read_manifest()` /
|
|
127
|
+
`.priority` / `.sort_key`, `.find_setup_script()` / `.run_setup(...)`,
|
|
128
|
+
`.files()` / `.rule_blocks(...)` / `.apply_to(...)` / `.install_to(...)` /
|
|
129
|
+
`.merge_rules_into(...)`. The name rules are static methods
|
|
130
|
+
(`Overlay.is_valid_name` / `.normalize_name` / `.root_var_for`), so a caller
|
|
131
|
+
holding only a name uses the same rule as one holding a directory;
|
|
132
|
+
`Overlay.discover(root)` is the single discovery routine that `_scope`,
|
|
133
|
+
the contract-A resolver and `env` all share, and `Overlay.sort_by_priority`
|
|
134
|
+
the single merge order. The module-level functions they replace
|
|
135
|
+
(`read_manifest`, `find_setup_script`, `run_overlay_setup`, `overlay_files`,
|
|
136
|
+
`rule_blocks`, `apply_overlay`, `install_overlay_dir`, `merge_overlay_rules`,
|
|
137
|
+
`overlay_sort_key`, `sort_overlays_by_priority`, `normalize_name`,
|
|
138
|
+
`overlay_root_var`) are gone, as are `_scope.is_valid_overlay_name` and
|
|
139
|
+
`_scope.normalize_overlay_name`. `recompose_overlay_block` stays a module
|
|
140
|
+
function (it works over a set of overlays) and now accepts `Overlay`
|
|
141
|
+
instances or directories. `_overlays` is a private module, so no public
|
|
142
|
+
version signal.
|
|
143
|
+
|
|
144
|
+
- fix: an `env.py` may now print its changes as one JSON object **per line**,
|
|
145
|
+
merged in order (a later line wins), as well as a single object. Each
|
|
146
|
+
overlay's `setup.py` appends its own managed block to the store's `env.py`
|
|
147
|
+
and each block prints its own object, so a store with two such overlays
|
|
148
|
+
(e.g. `net` + `private-sync`) emitted two lines — and the single-object
|
|
149
|
+
reader rejected the whole output, silently dropping both overlays' vars. A
|
|
150
|
+
line that is not a JSON object still voids the whole script's contribution,
|
|
151
|
+
so a half-applied change set is impossible.
|
|
152
|
+
- fix: `init --agents codex` run from a session whose environment already
|
|
153
|
+
carried dotagents' identity vars (which its own env-loader hook exports —
|
|
154
|
+
`AGENT=claude-code` and friends in every command a Claude session runs)
|
|
155
|
+
wrote a Codex env block with no identity at all: the identity stamp never
|
|
156
|
+
overrides a value already present, so every key counted as "already set",
|
|
157
|
+
to Claude's values. When the agent is named explicitly the identity is now
|
|
158
|
+
that agent's, overriding the base env; without an explicit agent a pinned
|
|
159
|
+
value is respected as before.
|
|
160
|
+
- fix: the built `.pyz` lost the help text of the umbrella's own `--cmdspath`
|
|
161
|
+
flag (every subcommand's help survived). The zipapp source-repoint shim
|
|
162
|
+
covered each `dotagents.cli.<x>` command module but not the `dotagents.cli`
|
|
163
|
+
package itself, and it resolved a package's source as `cli.py` instead of
|
|
164
|
+
`cli/__init__.py`, so the umbrella kept its zip-internal `__file__` and duho
|
|
165
|
+
fell back to a bare flag. Both fixed; the top-level help in a `.pyz` now
|
|
166
|
+
matches a plain install.
|
|
167
|
+
- fix: `context`'s `<NAME_OVERLAY_ROOT>` placeholder now also maps `.` (and any
|
|
168
|
+
other non-alphanumeric character) in an overlay name to `_`, not only `-` —
|
|
169
|
+
the name has to be a legal shell variable to be emitted by `env`, and the
|
|
170
|
+
placeholder follows the same rule. Overlays whose names contain only letters,
|
|
171
|
+
digits, `_` and `-` are unaffected.
|
|
172
|
+
|
|
173
|
+
### Fixed
|
|
174
|
+
|
|
175
|
+
- **One broken command module no longer breaks every `dotagents` call.**
|
|
176
|
+
Discovery skips a source that fails to import for any reason (a
|
|
177
|
+
`SyntaxError`, an exception at import time) with a warning naming it. It
|
|
178
|
+
caught `ImportError` only, and duho propagates the rest on purpose, so a
|
|
179
|
+
typo in `~/.agents/dotagents/cmds/foo.py` made `env`, `context`, `init` and
|
|
180
|
+
even `--version` traceback, i.e. the hooks delivered nothing.
|
|
181
|
+
- **No more temp-directory litter from the `.pyz`.** Everything a zipapp run
|
|
182
|
+
extracts (package data, the repointed module sources) lives under one
|
|
183
|
+
per-process scratch directory removed at exit; a `mkdtemp` per item with no
|
|
184
|
+
cleanup had left 632 `dotagents-*` directories in one machine's `%TEMP%`.
|
|
185
|
+
- `overlays add` installs a source dir spelled `my_overlay` (it normalized to
|
|
186
|
+
`my-overlay` and looked only that up), validates and resolves EVERY name
|
|
187
|
+
against the source before touching anything (`add good bad` used to install
|
|
188
|
+
`good`, run its setup, then fail), installs each manifest's `requires`
|
|
189
|
+
first (transitively; `--no-requires` to skip; a missing requirement warns, a
|
|
190
|
+
cycle errors), publishes skills from the INSTALLED copy (a symlink into the
|
|
191
|
+
source dies with a temporary checkout and could never be matched by
|
|
192
|
+
`remove`), and reports the setup script on a dry run.
|
|
193
|
+
- `overlays remove` normalizes names (`add My_Ov` + `remove My_Ov` said "not
|
|
194
|
+
installed") and recomposes the managed block over the overlays that remain,
|
|
195
|
+
so an overlay's rules and routing leave `AGENTS.md` with it; the warning
|
|
196
|
+
that pointed at the removed `dotagents install` is gone.
|
|
197
|
+
- `overlays sync` honours `--copy` (declared and ignored) and gains
|
|
198
|
+
`--overwrite`, which replaces installed files whose content differs from the
|
|
199
|
+
source; without it a sync never updated an upstream change to an existing
|
|
200
|
+
file.
|
|
201
|
+
- New `overlays show <name>` describes an overlay (installed copy first, else
|
|
202
|
+
the source): description, priority, requires, routing, rules, setup script,
|
|
203
|
+
skills, file count, root var; `--json`.
|
|
204
|
+
- The manifest reader strips trailing `#` comments quote-aware and finds an
|
|
205
|
+
array's closing `]` by scanning, so `routing = ["a"] # note` no longer
|
|
206
|
+
swallows the NEXT array (a rules path became a routing line), an indented
|
|
207
|
+
`]` no longer yields `[]`, `'single-quoted'` strings parse, and
|
|
208
|
+
`priority = 5 # low` is 5, not 500. `description` and `requires` are read.
|
|
209
|
+
- `_compose_block` with a base that has no `## Load on demand` heading appends
|
|
210
|
+
the overlay rules at the end of the block, as its warning always claimed;
|
|
211
|
+
they were dropped.
|
|
212
|
+
- `build-pyz` outside a source checkout is a clear error instead of a
|
|
213
|
+
`FileNotFoundError`.
|
|
214
|
+
- `dotagents`, `overlays` and `findings` invoked with no subcommand print
|
|
215
|
+
their help and exit 2 instead of logging a hint and exiting 0.
|
|
216
|
+
- `--agents-dir X` on the command line is honoured by command discovery, so
|
|
217
|
+
the store the command is about to use is the one whose `cmds/` are found.
|
|
218
|
+
- `findings add` rejects a name already carried by another note's frontmatter
|
|
219
|
+
(`get` matches frontmatter names first, so `done` would have processed the
|
|
220
|
+
wrong file).
|
|
221
|
+
- Two overlay dirs with the same manifest `name` sort deterministically (dir
|
|
222
|
+
name is the final tiebreaker).
|
|
223
|
+
- **SessionStart context is no longer injected twice.** The PowerShell
|
|
224
|
+
variants of Claude's `SessionStart` / `CwdChanged` handlers run only when
|
|
225
|
+
`bash` is not on PATH. Both handlers fire on every session, and on a Windows
|
|
226
|
+
box that has both Git Bash and PowerShell both succeeded, so the same
|
|
227
|
+
payload landed twice at every session start (two identical 100 KB
|
|
228
|
+
payloads, measured).
|
|
229
|
+
- The Codex `PreToolUse` env-loader prefix is quoted correctly: inside
|
|
230
|
+
`"$(...)"` its `\"` were literal quote characters, so `PATH` became
|
|
231
|
+
`".agents/bin:...:<last>"` with the quotes, the project `.agents/bin` was
|
|
232
|
+
never found and the last original entry was broken. The rewritten command
|
|
233
|
+
is now executed in bash by a test.
|
|
234
|
+
- Hook merging keeps a user's hook that shares a matcher-object with an older
|
|
235
|
+
shape of ours (the whole object used to be dropped), and a revised `shell`
|
|
236
|
+
/ `matcher` / `commandWindows` / status on an unchanged command text now
|
|
237
|
+
reaches existing users instead of being kept as-is.
|
|
238
|
+
- Claude's skills link is per skill into `<config>/skills/<name>`: linking the
|
|
239
|
+
whole directory failed with "conflict" for anyone who already had their own
|
|
240
|
+
`~/.claude/skills`, so overlay skills never reached them. A same-named skill
|
|
241
|
+
the user placed there stays.
|
|
242
|
+
- Every hook command resolves the store as `$AGENTS_HOME` when set (bash:
|
|
243
|
+
`${AGENTS_HOME:-$HOME/.agents}`), so a custom store gets hooks that can find
|
|
244
|
+
`dotagents`; the PowerShell SessionStart variant prefers the project's own
|
|
245
|
+
`.agents\bin` like the bash one. The PowerShell tool env-loader runs
|
|
246
|
+
`env --diff` instead of re-assigning the whole environment on every call.
|
|
247
|
+
- The bash `CwdChanged` handler re-pins `AGENTS_PROJECT_ROOT` into
|
|
248
|
+
`$CLAUDE_ENV_FILE` when the new directory carries a `.agents/`; the
|
|
249
|
+
SessionStart pin is only-if-unset, so a `cd` into another project used to
|
|
250
|
+
keep the first project's root for the rest of the session.
|
|
251
|
+
- The Antigravity hook pins the project root from `workspacePaths` (cwd and
|
|
252
|
+
`AGENTS_PROJECT_ROOT` of the `dotagents context` spawn), as its docstring
|
|
253
|
+
already claimed, honours `$AGENTS_HOME` when locating `dotagents`, and
|
|
254
|
+
injects nothing when the assembly exits non-zero. Its constant is
|
|
255
|
+
`PREINVOCATION_HOOK_SCRIPT` (it wires a `PreInvocation` hook).
|
|
256
|
+
- Unpublishing an overlay's skills compares file CONTENT, not just names: a
|
|
257
|
+
copy the user had edited (same file set, different bytes) was deleted as
|
|
258
|
+
the overlay's.
|
|
259
|
+
- **The store's rules now reach Claude on a fresh install.** `init` writes the
|
|
260
|
+
`@` include where Claude Code reads it -- `~/.claude/CLAUDE.md` for the user
|
|
261
|
+
store, `<project>/.claude/CLAUDE.md` for a project -- as an appended managed
|
|
262
|
+
block, skipped when the include line is already there by hand. Before, it
|
|
263
|
+
wrote `<store>/CLAUDE.md` (which Claude never reads) while `context`
|
|
264
|
+
subtracted `~/.agents/AGENTS.md` as "already loaded" on a static assumption,
|
|
265
|
+
so nothing delivered the base rules. `context` now subtracts exactly what
|
|
266
|
+
the harness's entry files actually `@`-include (`Agent.loaded_paths`),
|
|
267
|
+
recursively, on this machine.
|
|
268
|
+
- `context` no longer inlines every `.md` file the sources mention. Inlining is
|
|
269
|
+
opt-in (`--inline` / `inline=True`): the base rules say to read those files
|
|
270
|
+
only when a task needs them, and inlining every mention made a 100 KB
|
|
271
|
+
SessionStart payload, most of it a changelog and an API header that
|
|
272
|
+
happened to be named in prose. With `--inline`, sources and harness-loaded
|
|
273
|
+
files are never inlined a second time, and placeholders inside inlined
|
|
274
|
+
files expand.
|
|
275
|
+
- Overlay priority ordering and `<NAME_OVERLAY_ROOT>` placeholder expansion in
|
|
276
|
+
`context` never worked: the resolver labels an overlay entry with the
|
|
277
|
+
overlay's name and the code compared it to the literal `"overlay"`. Every
|
|
278
|
+
installed overlay now gets a placeholder (matching `env`), not only one that
|
|
279
|
+
ships a `CONTEXT.md`.
|
|
280
|
+
- `context --write-agent` merges the context into the harness's own
|
|
281
|
+
instruction file under the PROJECT root -- Claude `.claude/CLAUDE.md`, Codex
|
|
282
|
+
`AGENTS.md`, Gemini `GEMINI.md`, Cursor `.cursorrules`, Copilot
|
|
283
|
+
`.github/copilot-instructions.md`, Antigravity `.agents/rules/dotagents.md`
|
|
284
|
+
-- as a managed `dotagents:context` block that is refreshed in place. It
|
|
285
|
+
used to overwrite a file under the user STORE; for Codex that was
|
|
286
|
+
`<store>/AGENTS.md`, a context source, so every run re-inlined the previous
|
|
287
|
+
run's output. `--format` is validated, and `--write-agent` refuses `--format
|
|
288
|
+
json` or an output path instead of silently ignoring one.
|
|
289
|
+
- Project-scope overlays (`<project>/.agents/overlays/`, where `overlays add`
|
|
290
|
+
installs by default) are now part of the contract-A walk: their `bin`,
|
|
291
|
+
`lib`, env files, `cmds` and `CONTEXT.md` resolve, after the user store's,
|
|
292
|
+
and each gets a `<NAME>_OVERLAY_ROOT` (a project overlay wins a name clash).
|
|
293
|
+
Nothing consumed them before except the `AGENTS.md` recompose.
|
|
294
|
+
- Managed-block markers must be a line of their own: a prose MENTION of the
|
|
295
|
+
markers (the base `AGENTS.md` carries one) was matched as the block, so the
|
|
296
|
+
sentence around it was replaced and a second block appeared. A begin marker
|
|
297
|
+
with no end after it is refused with a clear error instead of gaining a
|
|
298
|
+
second block; a `--from` base without markers is a usage error, not a
|
|
299
|
+
traceback.
|
|
300
|
+
- Every managed file (`AGENTS.md`, the includes, `settings.json`, `hooks.json`,
|
|
301
|
+
context targets) is written LF-only on every platform; `settings.json` /
|
|
302
|
+
`hooks.json` are written atomically and keep non-ASCII values as-is.
|
|
303
|
+
- The user scope is recognized by the configurable store (`$AGENTS_HOME`), not
|
|
304
|
+
the literal `~/.agents`: `init -g` with a custom store used to wire Claude's
|
|
305
|
+
hooks into `<store-parent>/.claude/settings.local.json`, which nothing reads.
|
|
306
|
+
- `CODEX_HOME` no longer marks a running Codex session (it is the user's
|
|
307
|
+
persistent state-dir override, exported from a shell profile); the
|
|
308
|
+
`CODEX_SANDBOX*` vars still do, and `CODEX_HOME` still locates the config.
|
|
309
|
+
- An unknown `--agents` name no longer overrides a pinned identity in `env`.
|
|
310
|
+
- An overlay cannot be named like a contract-A level (`user`, `project`,
|
|
311
|
+
`system`, `project-root`, `default`, `overlay`); its dir name is its level
|
|
312
|
+
label in the walk and would collide with the per-level filename keys.
|
|
313
|
+
- A directory named `env` (a common virtualenv name) is no longer "sourced" as
|
|
314
|
+
an env file; only regular files resolve.
|
|
315
|
+
- Sourcing a plain env file that fails (missing, a directory, a syntax error)
|
|
316
|
+
now contributes nothing and warns, as documented. The bash command was a
|
|
317
|
+
`;` list, so `env -0` ran regardless and reported rc 0 with whatever had
|
|
318
|
+
been assigned before the error.
|
|
319
|
+
- Bash's own `PWD` (in `/c/...` form), `OLDPWD`, `SHLVL` and `MSYSTEM*` are no
|
|
320
|
+
longer reported as a sourced file's changes; a non-UTF-8 byte in a sourced
|
|
321
|
+
value no longer aborts the whole assembly.
|
|
322
|
+
- `env --format auto` returned `cmd` when invoked through the `dotagents.cmd`
|
|
323
|
+
wrapper from PowerShell (the wrapper cannot exec, so `cmd.exe` sits between
|
|
324
|
+
Python and the shell); a `cmd` whose own parent is a shell is now skipped.
|
|
325
|
+
- `env` formats: `fish` escapes backslashes; `cmd` doubles `%` and flattens
|
|
326
|
+
newlines; `yaml` quotes values a reader would type (`true`, `123`, `null`,
|
|
327
|
+
`1e3`, leading indicators); `powershell`/`cmd` no longer mangle a
|
|
328
|
+
forward-slash native path (`C:/a/tools` became `C;A:\tools`); output is
|
|
329
|
+
written as UTF-8 bytes so a non-Latin-1 value cannot crash on a cp1252
|
|
330
|
+
console.
|
|
331
|
+
- `init -g`, `overlays ... -g` and every other `resolve_scope` caller honour
|
|
332
|
+
`$AGENTS_HOME` (the var `env` itself emits) instead of the literal `~/.agents`,
|
|
333
|
+
and `--agents-dir` overrides the store in the project scope too (it was
|
|
334
|
+
silently ignored without `-g`). `resolve_user_store` moved to `_scope`
|
|
335
|
+
(still re-exported from `dotagents.cli`); the `findings` command's local
|
|
336
|
+
workaround is gone.
|
|
337
|
+
- `overlays list` / `overlays add` apply the one overlay-name rule when listing
|
|
338
|
+
a source (`__pycache__`, `2fast`, dotdirs are no longer "available"), and a
|
|
339
|
+
bad source path names whether it came from `--source` or the env var.
|
|
340
|
+
- `findings list` / `show` write UTF-8 bytes, so a description with a
|
|
341
|
+
non-Latin-1 character no longer raises on a cp1252 console.
|
|
342
|
+
|
|
10
343
|
## [0.3.4] - 2026-08-16
|
|
11
344
|
|
|
12
345
|
### Changed
|
|
@@ -46,8 +379,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
46
379
|
|
|
47
380
|
- **`build-pyz` no longer bundles the repo's `tools/`** as `dotagents/_tools`
|
|
48
381
|
inside the built `.pyz`, and the `--tools-dir` flag is gone with it. Nothing
|
|
49
|
-
read `_tools`: the compiled `audit
|
|
50
|
-
it no longer exist. Every shipped artifact carried the dead weight while
|
|
382
|
+
read `_tools`: the compiled `audit` wrapper and a personal scanner's wrapper that
|
|
383
|
+
shelled out to it no longer exist. Every shipped artifact carried the dead weight while
|
|
51
384
|
`tools/audit.py` claimed it was "not shipped in the `.pyz`" — now true.
|
|
52
385
|
- **`dotagents._sync`** — a `pathlib_next.PathSyncer` wrapper that existed only
|
|
53
386
|
to back the `install` subcommand's backup/copy report. `install` was removed
|
|
@@ -62,8 +395,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
62
395
|
no longer claims to ship as a bundled `audit` command module (it is repo CI
|
|
63
396
|
tooling and there is no `dotagents audit`) and its `--root` help names the
|
|
64
397
|
real default; `install.py`'s usage line drops the removed `install` and the
|
|
65
|
-
never-existing `audit`; the README's `tools/` row says where
|
|
66
|
-
actually lives; the API header names the real `_overlays` exports
|
|
398
|
+
never-existing `audit`; the README's `tools/` row says where a personal
|
|
399
|
+
command module actually lives; the API header names the real `_overlays` exports
|
|
67
400
|
(`install_overlay_dir` / `apply_overlay` / `run_overlay_setup`) and the real
|
|
68
401
|
package-data dirs (`_overlay` / `_overlays_src`, never a `skeleton/`); and
|
|
69
402
|
`_merge._extract_block`'s docstring now says it returns the block *including*
|
|
@@ -248,7 +581,7 @@ Patch release: the PATH/POSIX-conversion fix above (the only change since 0.3.0)
|
|
|
248
581
|
directory. Symlink where the OS permits, copy otherwise (a copy is a snapshot;
|
|
249
582
|
re-run `init` to refresh).
|
|
250
583
|
|
|
251
|
-
- feat: `tools
|
|
584
|
+
- feat: the personal leak scanner (then in `tools/`) now also scans commit messages (current branch history)
|
|
252
585
|
for agent-session trailers/URLs — a `Claude-Session:` trailer or `claude.ai/code/session`
|
|
253
586
|
link — and exits 1 on any hit. The trailer is auto-added by the agent harness and
|
|
254
587
|
exposes a session id in public history if it slips through; the pre-existing tracked-file
|
|
@@ -387,7 +720,7 @@ Patch release: the PATH/POSIX-conversion fix above (the only change since 0.3.0)
|
|
|
387
720
|
`recovery`, `references`, `python`/`node`/`rust`, `agents`, `tools`. Each carries
|
|
388
721
|
an `overlay.toml` manifest for a future `dotagents overlays` subcommand.
|
|
389
722
|
- Repo layout: the CLI in `src/dotagents/`, config overlays in `overlays/`, required
|
|
390
|
-
tooling in top-level `tools/` (`audit_config.py
|
|
723
|
+
tooling in top-level `tools/` (`audit_config.py` and a personal leak scanner); repo root holds
|
|
391
724
|
the installer, CI, repo-development directives, and the tracked, sanitized
|
|
392
725
|
`.agents/` design log (index + per-decision files) + plans. `audit_config.py` has
|
|
393
726
|
`--repo-hygiene` (scans tracked files for personal/machine-specific leftovers).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: dotagents-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -102,7 +102,7 @@ them. Everything else is repo infrastructure.
|
|
|
102
102
|
| --- | --- |
|
|
103
103
|
| `src/dotagents/` | The installable `dotagents` CLI (`init`/`overlays`/`context`/`env`/`build-pyz`) — that is the whole shipped surface; commands beyond it come from overlays or your own `cmds/` modules |
|
|
104
104
|
| `src/dotagents/_overlay/` | The **base overlay** `init` writes: `AGENTS.md` scaffolding, `CLAUDE.md`, `dotagents/DECISIONS.md` (empty design-log index), and an empty `dotagents/cmds/` dir — your drop-in point for your own command modules. Neutral — imposes no flows, ships no command |
|
|
105
|
-
| `tools/` | Repo tooling, not shipped: `audit.py` (CI structure check) and `cloud-setup.sh`.
|
|
105
|
+
| `tools/` | Repo tooling, not shipped: `audit.py` (CI structure check) and `cloud-setup.sh`. Personal scanning tools are not here either — keep them as command modules in your own private `.agents/dotagents/cmds/` |
|
|
106
106
|
| `install.py` | Thin shim over `dotagents.cli.main()`, kept at this filename for muscle memory |
|
|
107
107
|
|
|
108
108
|
The **example overlays** — the `flows` workflow set, per-language `kb/` + templates,
|
|
@@ -167,7 +167,7 @@ where the example overlays live. Installed overlays are *discovered* by their pr
|
|
|
167
167
|
under `<scope>/.agents/overlays/` — there is no registry file.
|
|
168
168
|
|
|
169
169
|
```bash
|
|
170
|
-
dotagents overlays add python
|
|
170
|
+
dotagents overlays add python engineering # install into the scope, publish skills, merge D59 rules/routing
|
|
171
171
|
dotagents overlays list # installed (discovered) + available (from source)
|
|
172
172
|
dotagents overlays sync 'py*' # refresh installed overlays matching a glob, resync their skills
|
|
173
173
|
dotagents overlays remove python # delete the overlay dir + unpublish its skills
|
|
@@ -214,7 +214,7 @@ Then wire your runner to it — e.g. Claude Code: put `@AGENTS.md` in
|
|
|
214
214
|
`~/.claude/CLAUDE.md`... which is exactly what the installed `CLAUDE.md` contains.
|
|
215
215
|
|
|
216
216
|
**Or let your agent do it:** point it at this repo and say —
|
|
217
|
-
> Read README.md, run `python install.py init && python install.py overlays add
|
|
217
|
+
> Read README.md, run `python install.py init && python install.py overlays add engineering -g`,
|
|
218
218
|
> and confirm `~/.agents/overlays/flows/flows/PLAN.md` exists.
|
|
219
219
|
|
|
220
220
|
## Private sync (per-user + per-project, one private repo)
|
|
@@ -283,8 +283,8 @@ committed — so what's public here is only the CLI, the base overlay, and the o
|
|
|
283
283
|
overlays. If you fork, keep the tracked surface free of personal paths and private
|
|
284
284
|
project names. `dotagents audit` validates config *structure* only; personal-leak
|
|
285
285
|
scanning (machine paths, private plan names, session trailers) is a separate,
|
|
286
|
-
personal
|
|
287
|
-
|
|
286
|
+
personal tool you run locally before a push — it lives in your private `.agents/`,
|
|
287
|
+
not shipped in this repo.
|
|
288
288
|
|
|
289
289
|
## Documentation
|
|
290
290
|
|
|
@@ -41,7 +41,7 @@ them. Everything else is repo infrastructure.
|
|
|
41
41
|
| --- | --- |
|
|
42
42
|
| `src/dotagents/` | The installable `dotagents` CLI (`init`/`overlays`/`context`/`env`/`build-pyz`) — that is the whole shipped surface; commands beyond it come from overlays or your own `cmds/` modules |
|
|
43
43
|
| `src/dotagents/_overlay/` | The **base overlay** `init` writes: `AGENTS.md` scaffolding, `CLAUDE.md`, `dotagents/DECISIONS.md` (empty design-log index), and an empty `dotagents/cmds/` dir — your drop-in point for your own command modules. Neutral — imposes no flows, ships no command |
|
|
44
|
-
| `tools/` | Repo tooling, not shipped: `audit.py` (CI structure check) and `cloud-setup.sh`.
|
|
44
|
+
| `tools/` | Repo tooling, not shipped: `audit.py` (CI structure check) and `cloud-setup.sh`. Personal scanning tools are not here either — keep them as command modules in your own private `.agents/dotagents/cmds/` |
|
|
45
45
|
| `install.py` | Thin shim over `dotagents.cli.main()`, kept at this filename for muscle memory |
|
|
46
46
|
|
|
47
47
|
The **example overlays** — the `flows` workflow set, per-language `kb/` + templates,
|
|
@@ -106,7 +106,7 @@ where the example overlays live. Installed overlays are *discovered* by their pr
|
|
|
106
106
|
under `<scope>/.agents/overlays/` — there is no registry file.
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
dotagents overlays add python
|
|
109
|
+
dotagents overlays add python engineering # install into the scope, publish skills, merge D59 rules/routing
|
|
110
110
|
dotagents overlays list # installed (discovered) + available (from source)
|
|
111
111
|
dotagents overlays sync 'py*' # refresh installed overlays matching a glob, resync their skills
|
|
112
112
|
dotagents overlays remove python # delete the overlay dir + unpublish its skills
|
|
@@ -153,7 +153,7 @@ Then wire your runner to it — e.g. Claude Code: put `@AGENTS.md` in
|
|
|
153
153
|
`~/.claude/CLAUDE.md`... which is exactly what the installed `CLAUDE.md` contains.
|
|
154
154
|
|
|
155
155
|
**Or let your agent do it:** point it at this repo and say —
|
|
156
|
-
> Read README.md, run `python install.py init && python install.py overlays add
|
|
156
|
+
> Read README.md, run `python install.py init && python install.py overlays add engineering -g`,
|
|
157
157
|
> and confirm `~/.agents/overlays/flows/flows/PLAN.md` exists.
|
|
158
158
|
|
|
159
159
|
## Private sync (per-user + per-project, one private repo)
|
|
@@ -222,8 +222,8 @@ committed — so what's public here is only the CLI, the base overlay, and the o
|
|
|
222
222
|
overlays. If you fork, keep the tracked surface free of personal paths and private
|
|
223
223
|
project names. `dotagents audit` validates config *structure* only; personal-leak
|
|
224
224
|
scanning (machine paths, private plan names, session trailers) is a separate,
|
|
225
|
-
personal
|
|
226
|
-
|
|
225
|
+
personal tool you run locally before a push — it lives in your private `.agents/`,
|
|
226
|
+
not shipped in this repo.
|
|
227
227
|
|
|
228
228
|
## Documentation
|
|
229
229
|
|
|
@@ -13,11 +13,12 @@ form its API. Generated from docstrings, organized by module:
|
|
|
13
13
|
command.
|
|
14
14
|
- **[Context](context.md)** — assembling the effective context for agents.
|
|
15
15
|
- **[Environment](env.md)** — chained env-file assembly and `env.py` execution.
|
|
16
|
-
- **[Resolution](resolve.md)** — the precedence walk / filename resolution
|
|
17
|
-
(Contract A).
|
|
18
16
|
- **[Merge](merge.md)** — the managed-block merge for `init`'s `AGENTS.md` /
|
|
19
|
-
`CLAUDE.md`,
|
|
17
|
+
`CLAUDE.md`, the harness-entry `@` include, the `context --write-agent`
|
|
18
|
+
block, and other comment syntaxes (e.g. TOML) via `begin_marker`/
|
|
20
19
|
`end_marker`/`append`.
|
|
20
|
+
- **[Filesystem](fs.md)** — the one text-file writer every module uses:
|
|
21
|
+
LF-only on every platform, optionally atomic.
|
|
21
22
|
- **[Hooks](hooks.md)** — additive, idempotent merge of dotagents' hooks into an
|
|
22
23
|
agent's own settings/config file.
|
|
23
24
|
- **[Skills](skills.md)** — publishing an overlay's skills into a scope's shared dir.
|