dotagents-cli 0.3.0__tar.gz → 0.3.2__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.0 → dotagents_cli-0.3.2}/.gitignore +4 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/CHANGELOG.md +100 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/PKG-INFO +9 -3
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/README.md +8 -2
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/pyproject.toml +1 -1
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/AGENTS.md +79 -6
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/__init__.py +1 -1
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_agents.py +373 -10
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_context.py +13 -6
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_hooks.py +22 -4
- dotagents_cli-0.3.2/src/dotagents/_overlay/dotagents/hooks/preinvocation_antigravity_context.py +123 -0
- dotagents_cli-0.3.2/src/dotagents/_overlay/dotagents/hooks/pretooluse_codex_env.py +90 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/cli/__init__.py +19 -4
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/cli/_common.py +42 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/cli/build_pyz.py +31 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/cli/context.py +6 -1
- dotagents_cli-0.3.2/src/dotagents/cli/env.py +435 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/cli/init.py +3 -15
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/cli/overlays.py +11 -43
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_agents.py +1 -1
- dotagents_cli-0.3.2/tests/test_build_pyz.py +51 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_context.py +72 -4
- dotagents_cli-0.3.2/tests/test_env_format.py +502 -0
- dotagents_cli-0.3.2/tests/test_wire_hooks.py +887 -0
- dotagents_cli-0.3.0/src/dotagents/cli/env.py +0 -168
- dotagents_cli-0.3.0/tests/test_env_format.py +0 -230
- dotagents_cli-0.3.0/tests/test_wire_hooks.py +0 -439
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/LICENSE +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/build.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/agents.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/cli.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/context.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/env.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/hooks.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/merge.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/overlays.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/reference.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/resolve.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/scope.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/skills.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/api/sync.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/changelog.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/guide/authoring.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/guide/commands.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/guide/install.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/guide/overlays.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/guide/private-sync.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/docs/index.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/install.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/mkdocs.yml +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/__main__.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_env.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_merge.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_overlay/AGENTS.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_overlay/CLAUDE.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_overlay/README.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_overlay/dotagents/DECISIONS.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_overlay/dotagents/cmds/README.md +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_overlays.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_resolve.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_scope.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_skills.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_sync.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/src/dotagents/_wrappers.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_audit_leak.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_cmds_discovery.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_env.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_hooks.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_overlays_command.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_scope.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tests/test_wrappers.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tools/audit.py +0 -0
- {dotagents_cli-0.3.0 → dotagents_cli-0.3.2}/tools/cloud-setup.sh +0 -0
|
@@ -7,6 +7,106 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.2] - 2026-07-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- feat: **`AntigravityAgent`** — context injection for Google's Antigravity
|
|
15
|
+
CLI/IDE (a separate product from Gemini CLI, despite sharing the `~/.gemini/`
|
|
16
|
+
namespace for some files). Antigravity's hooks have no `SessionStart`
|
|
17
|
+
equivalent — only `PreToolUse`/`PostToolUse`/`PreInvocation`/`PostInvocation`/
|
|
18
|
+
`Stop` — so a `PreInvocation` hook gated on `invocationNum == 0` behaves like a
|
|
19
|
+
one-shot context load instead of resending it every model turn. Wires into
|
|
20
|
+
`~/.gemini/config/hooks.json`. No detection marker exists for Antigravity, so
|
|
21
|
+
it's explicit-`--agents antigravity`-only, never auto-detected.
|
|
22
|
+
- feat: **Codex gets a `PreToolUse` env hook**, closing the one gap Codex had
|
|
23
|
+
versus Claude: Codex has no per-session env-persistence mechanism at any hook
|
|
24
|
+
event, so a deployed script prepends a guarded env-loader to every `Bash` tool
|
|
25
|
+
call via `updatedInput.command` — the same rewrite mechanism Claude's own
|
|
26
|
+
`PreToolUse` hook uses, confirmed directly against Codex's docs.
|
|
27
|
+
- feat: **`init` wires a PowerShell `PreToolUse` env hook on Windows**, closing
|
|
28
|
+
a real gap: `$CLAUDE_ENV_FILE` only reaches Claude's *Bash* tool
|
|
29
|
+
(`$env:CLAUDE_ENV_FILE` is empty inside a live PowerShell tool call, confirmed
|
|
30
|
+
directly) — a fresh PowerShell tool call gets none of the SessionStart env.
|
|
31
|
+
The hook prepends a guarded env-loader to a PowerShell tool call's own command,
|
|
32
|
+
shipped as an inline command string (never a `.ps1` file — a script file is
|
|
33
|
+
subject to PowerShell's execution policy, and dotagents has no code-signing
|
|
34
|
+
certificate; the inline form runs even under `Restricted`).
|
|
35
|
+
- feat: **`SessionStart`/`CwdChanged` now register two handlers each** — a
|
|
36
|
+
bash-syntax one and an explicit `shell: "powershell"` one — because Claude's
|
|
37
|
+
own hooks.md says the shell "defaults to bash, or to powershell on Windows
|
|
38
|
+
when Git Bash isn't installed": bash syntax fed to `powershell -Command` on
|
|
39
|
+
such a machine is a hard parse error, silently losing both env and context for
|
|
40
|
+
the whole session.
|
|
41
|
+
- feat: **`DotAgentsArgs`** (`dotagents.cli`, re-exported for overlay-shipped
|
|
42
|
+
commands) — one shared `-g/--global` + `--agents-dir` base class. `init` and
|
|
43
|
+
all four `overlays` subcommands now inherit it instead of independently
|
|
44
|
+
redeclaring the same fields, so scope resolution can't silently drift between
|
|
45
|
+
commands (one previously defaulted `agents_dir` eagerly to `Path.home() /
|
|
46
|
+
".agents"`; harmless in practice, but needless).
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- fix: **`dotagents env --format powershell`/`cmd` left an already-POSIX `PATH`
|
|
51
|
+
unconverted**, the mirror of the export/dotenv/fish fix below going the other
|
|
52
|
+
direction. Found live: run from a genuine Windows PowerShell terminal whose
|
|
53
|
+
own inherited `PATH` already held WSL/MSYS-mount-style entries
|
|
54
|
+
(`/mnt/c/Program Files/...`), the emitted `${env:PATH} = '...'` was
|
|
55
|
+
syntactically valid PowerShell but a single opaque colon-joined string, not
|
|
56
|
+
the `;`-split list PowerShell's own PATH lookup needs — every subsequent
|
|
57
|
+
bare-command lookup broke for that session. Also handles the MIXED case
|
|
58
|
+
(dotagents' own native bin dirs prepended onto an already-POSIX inherited
|
|
59
|
+
PATH, one string with both separators at once), caught by sourcing real
|
|
60
|
+
output into a live PowerShell session and watching `git.exe` fail to
|
|
61
|
+
resolve before the second fix. A WSL-only segment with no Windows equivalent
|
|
62
|
+
(`/usr/bin`) is dropped rather than mangled into a broken relative path.
|
|
63
|
+
- fix: **the built `.pyz` degraded `-g` on any discovered command inheriting a
|
|
64
|
+
dotagents-defined base class** (first hit by `DotAgentsArgs` above) — duho's
|
|
65
|
+
AST introspection walks the full MRO for a command's flags, but the zipapp
|
|
66
|
+
source-repoint shim only ever covered built-in command modules, not a base
|
|
67
|
+
class's own module (`dotagents.cli._common`). `--global` degraded to the
|
|
68
|
+
name-derived `--global-scope` and `-g` vanished silently. Fixed, with new CI
|
|
69
|
+
coverage asserting the exact short flag survives a real built pyz.
|
|
70
|
+
- fix: **`harness_loads` relative entries matched by bare filename, not full
|
|
71
|
+
path** — a relative entry like Codex's `"AGENTS.md"` wrongly suppressed ANY
|
|
72
|
+
file sharing that basename anywhere on disk, including the unrelated
|
|
73
|
+
`~/.agents/AGENTS.md` user-store file Codex's harness never reads.
|
|
74
|
+
`dotagents context --agents codex` emitted an empty `sources: []` even with
|
|
75
|
+
real content present. Now resolved against `project_root` and compared by
|
|
76
|
+
full path, like the absolute (`~/`, `/`) forms already were.
|
|
77
|
+
- fix: `dotagents context --format json` crashed with `UnicodeEncodeError` on
|
|
78
|
+
any character outside Latin-1 (a bare `print()` encoding with the console's
|
|
79
|
+
codepage) — the same class of bug already fixed for the markdown path, just
|
|
80
|
+
never covered for JSON.
|
|
81
|
+
- fix: PowerShell format uses `${env:NAME}` (curly-brace form), not the bare
|
|
82
|
+
`$env:NAME` sigil — a handful of real Windows env vars have parens in their
|
|
83
|
+
names (`ProgramFiles(x86)`), and `$env:FOO(X86) = ...` is a PowerShell parse
|
|
84
|
+
error; the curly-brace form is valid for every name.
|
|
85
|
+
|
|
86
|
+
## [0.3.1] - 2026-07-24
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- fix: **`dotagents env --format export`/`dotenv`/`fish` now emit a POSIX PATH on
|
|
91
|
+
Windows**, instead of the OS-native `C:\...;C:\...` form. This is the exact
|
|
92
|
+
command the Claude `SessionStart` hook appends into `$CLAUDE_ENV_FILE`, which
|
|
93
|
+
Claude sources before *every* subsequent Bash tool call in the session — an
|
|
94
|
+
unconverted PATH broke command lookup (`git`, `grep`, `head`, `python`, ...) for
|
|
95
|
+
the rest of the session once poisoned, not just once. PATH-shaped values are
|
|
96
|
+
now converted per segment: backslash to forward-slash, `;` to `:`, and a drive
|
|
97
|
+
letter to its MSYS mount point (`C:/...` -> `/c/...` — required for PATH
|
|
98
|
+
*lookups* specifically; slash direction alone does not work in MSYS2/Cygwin
|
|
99
|
+
bash). `PATHEXT` is dropped (no POSIX meaning). A handful of real Windows env
|
|
100
|
+
vars with parentheses in their names (`ProgramFiles(x86)`) are also dropped for
|
|
101
|
+
these formats — `export FOO(X86)=...` is a bash syntax error, not a bad value,
|
|
102
|
+
and aborts sourcing the rest of the file. `powershell`/`cmd`/`json`/`ini`/`yaml`
|
|
103
|
+
are unaffected.
|
|
104
|
+
- fix: a UNC PATH segment (`\\server\share\...`) no longer collapses to a single
|
|
105
|
+
leading slash (`/server/share/...`) during the POSIX conversion above — MSYS
|
|
106
|
+
requires the double-slash UNC root (`//server/share/...`) to resolve it.
|
|
107
|
+
|
|
108
|
+
Patch release: the PATH/POSIX-conversion fix above (the only change since 0.3.0).
|
|
109
|
+
|
|
10
110
|
## [0.3.0] - 2026-07-24
|
|
11
111
|
|
|
12
112
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotagents-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
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
|
|
@@ -62,6 +62,7 @@ Description-Content-Type: text/markdown
|
|
|
62
62
|
# dotagents
|
|
63
63
|
|
|
64
64
|
[](https://github.com/jose-pr/dotagents/actions/workflows/test.yml)
|
|
65
|
+
[](https://pypi.org/project/dotagents-cli/)
|
|
65
66
|
[](https://jose-pr.github.io/dotagents/)
|
|
66
67
|
[](https://github.com/jose-pr/dotagents/blob/main/LICENSE)
|
|
67
68
|
|
|
@@ -123,8 +124,13 @@ manifest read by the `dotagents overlays` subcommand, which manages overlays by
|
|
|
123
124
|
|
|
124
125
|
## Install
|
|
125
126
|
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
```bash
|
|
128
|
+
pip install dotagents-cli # gives you `import dotagents` and the `dotagents` command
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Or skip `pip` entirely with the self-contained downloadable `.pyz` (see below).
|
|
132
|
+
|
|
133
|
+
**`dotagents init`** lays down the neutral base config.
|
|
128
134
|
|
|
129
135
|
`init` writes the `.agents/` scaffolding — the `AGENTS.md` managed block, the per-agent
|
|
130
136
|
`<CLAUDE|ANTIGRAVITY|...>.md → @AGENTS.md` pattern, the design-log convention — and
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# dotagents
|
|
2
2
|
|
|
3
3
|
[](https://github.com/jose-pr/dotagents/actions/workflows/test.yml)
|
|
4
|
+
[](https://pypi.org/project/dotagents-cli/)
|
|
4
5
|
[](https://jose-pr.github.io/dotagents/)
|
|
5
6
|
[](https://github.com/jose-pr/dotagents/blob/main/LICENSE)
|
|
6
7
|
|
|
@@ -62,8 +63,13 @@ manifest read by the `dotagents overlays` subcommand, which manages overlays by
|
|
|
62
63
|
|
|
63
64
|
## Install
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
```bash
|
|
67
|
+
pip install dotagents-cli # gives you `import dotagents` and the `dotagents` command
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or skip `pip` entirely with the self-contained downloadable `.pyz` (see below).
|
|
71
|
+
|
|
72
|
+
**`dotagents init`** lays down the neutral base config.
|
|
67
73
|
|
|
68
74
|
`init` writes the `.agents/` scaffolding — the `AGENTS.md` managed block, the per-agent
|
|
69
75
|
`<CLAUDE|ANTIGRAVITY|...>.md → @AGENTS.md` pattern, the design-log convention — and
|
|
@@ -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.3.
|
|
12
|
+
version = "0.3.2"
|
|
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"
|
|
@@ -59,13 +59,86 @@ can read it without the source. Full docs: https://jose-pr.github.io/dotagents/
|
|
|
59
59
|
`hooks.<Event>` is a **list of matcher-objects** each holding its own `hooks` list,
|
|
60
60
|
not a flat command list. Foreign hooks are preserved verbatim, malformed entries
|
|
61
61
|
are dropped rather than raising, and invalid JSON raises `SystemExit` instead of
|
|
62
|
-
silently overwriting the user's file.
|
|
62
|
+
silently overwriting the user's file. `shell` (Claude: `"bash"`/`"powershell"`,
|
|
63
|
+
picks the interpreter for the hook's own command) and `command_windows`
|
|
64
|
+
(Codex: emitted as `commandWindows`, a separate Windows-only command OVERRIDE,
|
|
65
|
+
not an interpreter choice) are both supported. Pure stdlib. Consumed by
|
|
63
66
|
`ClaudeAgent.wire_hooks` (`~/.claude/settings.json`: env via `$CLAUDE_ENV_FILE`
|
|
64
|
-
+ context via stdout, plus `CwdChanged
|
|
65
|
-
(`<CODEX_HOME|~/.codex>/hooks.json
|
|
66
|
-
never `config.toml`
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
+ context via stdout, plus `CwdChanged`, plus a `PreToolUse` env-loader for the
|
|
68
|
+
PowerShell tool) and `CodexAgent.wire_hooks` (`<CODEX_HOME|~/.codex>/hooks.json`,
|
|
69
|
+
never `config.toml`: `SessionStart` context-only, plus a `PreToolUse` env-loader
|
|
70
|
+
matched on `matcher: "Bash"`). Codex's hook JSON is structurally identical to
|
|
71
|
+
Claude's, including the SAME `updatedInput.command` rewrite mechanism on
|
|
72
|
+
`PreToolUse` — confirmed directly against Codex's own docs
|
|
73
|
+
(learn.chatgpt.com/docs/hooks), not assumed from Claude parity.
|
|
74
|
+
Gemini/Cursor/Copilot keep the base no-op — Gemini CLI proper has no hook
|
|
75
|
+
mechanism documented at all (checked directly). **Antigravity is a separate
|
|
76
|
+
product** from Gemini CLI (Antigravity CLI/IDE/SDK family, shares only the
|
|
77
|
+
`~/.gemini/` namespace for some files) and DOES wire a hook: see
|
|
78
|
+
`AntigravityAgent.wire_hooks` below. `PreToolUse` there is still allow/deny/ask
|
|
79
|
+
only — no `updatedInput`, so no command-rewrite/env-loader path exists to hang
|
|
80
|
+
on it, unlike Claude/Codex. Revisit both conclusions if either framework changes.
|
|
81
|
+
- **`AntigravityAgent.wire_hooks`** (`<AGENTS_HOME_ANTIGRAVITY|~/.gemini/config>/hooks.json`,
|
|
82
|
+
keyed under a `"dotagents"` name per the docs' own example shape — a named-entry
|
|
83
|
+
object, not Claude/Codex's flat `hooks.<Event>`): wires a single `PreInvocation`
|
|
84
|
+
entry, context-only, no env mechanism. Antigravity's hooks
|
|
85
|
+
(antigravity.google/docs/hooks) have exactly five events — `PreToolUse`,
|
|
86
|
+
`PostToolUse`, `PreInvocation`, `PostInvocation`, `Stop` — no SessionStart
|
|
87
|
+
equivalent. `PreInvocation` fires every model turn (`invocationNum`, 0-indexed),
|
|
88
|
+
so the deployed script (`preinvocation_antigravity_context.py`,
|
|
89
|
+
`_overlay/dotagents/hooks/`) gates on `invocationNum == 0` to behave like a
|
|
90
|
+
one-shot SessionStart rather than resending context every turn. Output shape is
|
|
91
|
+
a bare `{"injectSteps": [{"ephemeralMessage": "..."}]}`, no `hookSpecificOutput`
|
|
92
|
+
wrapper — confirmed against the primary docs after an earlier pass here wrongly
|
|
93
|
+
concluded no useful injection was possible; `ephemeralMessage` is the one of the
|
|
94
|
+
three step types meant for free text (`toolCall` executes a tool,
|
|
95
|
+
`userMessage` impersonates the user). No detection marker exists anywhere in
|
|
96
|
+
Antigravity's docs, so `detect_env_vars = []` — explicit `--agents antigravity`
|
|
97
|
+
only, same posture as Codex's env-block precedent (writes touching an agent's
|
|
98
|
+
own live config are opt-in, never inferred).
|
|
99
|
+
- **`SessionStart`/`CwdChanged` register TWO handlers each**, bash-syntax
|
|
100
|
+
(default shell) and a PowerShell-native equivalent (`shell: "powershell"`).
|
|
101
|
+
hooks.md: `shell` "Defaults to bash, or to powershell on Windows when Git Bash
|
|
102
|
+
isn't installed" — verified directly that bash syntax fed to `powershell
|
|
103
|
+
-Command` on such a machine is a hard parse error, not a soft failure, so
|
|
104
|
+
every session there would silently get neither env nor context. Every handler
|
|
105
|
+
in a matched group fires unconditionally (hooks.md), so both always run; the
|
|
106
|
+
one whose interpreter is absent fails harmlessly. The PowerShell
|
|
107
|
+
`SessionStart` variant is context-only (`dotagents context`), not
|
|
108
|
+
env+context: `$CLAUDE_ENV_FILE`'s documented effect is "subsequent BASH
|
|
109
|
+
commands" regardless of which shell wrote it, so writing to it from a
|
|
110
|
+
PowerShell-shelled hook would feed nothing.
|
|
111
|
+
- **Windows only**: `ClaudeAgent._wire_powershell_pretooluse` additionally wires
|
|
112
|
+
a no-matcher `PreToolUse` hook (fires on every tool call), `shell:
|
|
113
|
+
"powershell"`, running `PRETOOLUSE_POWERSHELL_COMMAND` INLINE — deliberately
|
|
114
|
+
not a `.ps1` file, since a script file is subject to PowerShell's execution
|
|
115
|
+
policy (RemoteSigned/AllSigned/Restricted) and dotagents has no code-signing
|
|
116
|
+
certificate; verified directly that the inline form runs successfully even
|
|
117
|
+
under `Restricted`, which blocks every `.ps1` file outright. Closes a real
|
|
118
|
+
gap: `$CLAUDE_ENV_FILE` is Bash-tool-only (confirmed empirically that
|
|
119
|
+
`$env:CLAUDE_ENV_FILE` is empty inside a live PowerShell tool call), so the
|
|
120
|
+
SessionStart env half never reaches the PowerShell tool. Uses `PreToolUse`'s
|
|
121
|
+
`updatedInput` to prepend a guarded env-loader (`AGENTS_RUNTIME_SET`,
|
|
122
|
+
matching the precursor's convention) to a `PowerShell` tool call's own
|
|
123
|
+
command — not by trying to persist state across hook invocations, which are
|
|
124
|
+
each their own fresh process and cannot. Whether the guard is visible across
|
|
125
|
+
separate PowerShell tool calls is UNVERIFIED. Every literal `\` in the
|
|
126
|
+
command constant must be a raw string — a bare `\b` in a normal Python string
|
|
127
|
+
literal silently becomes a backspace character, corrupting the emitted path;
|
|
128
|
+
caught once by testing a draft through a real PowerShell spawn.
|
|
129
|
+
- **`CodexAgent._deploy_pretooluse_script`** covers the same env gap for Codex,
|
|
130
|
+
which has NO env-persistence mechanism at any hook event (not Bash-only like
|
|
131
|
+
Claude — none). Ships `pretooluse_codex_env.py` (`_overlay/dotagents/hooks/`),
|
|
132
|
+
deployed to `<codex-home>/hooks/` (create-or-refresh), wired as `PreToolUse`
|
|
133
|
+
with `matcher: "Bash"` — Codex's one shell tool, so (unlike Claude's
|
|
134
|
+
no-matcher hook) filtering happens at the settings level, no runtime
|
|
135
|
+
`tool_name` check needed in the script. A FILE, not inlined like Claude's:
|
|
136
|
+
Codex's docs show every hook example as `python3 <path>`, and a `.py` file
|
|
137
|
+
has no execution-policy/signing concern (PowerShell-specific). Sets
|
|
138
|
+
`commandWindows` to `python "<path>"` (not `python3`) — verified directly
|
|
139
|
+
that `python3` resolves to the Microsoft Store app-execution-alias stub and
|
|
140
|
+
fails outright on this dev machine (exit 49), the same trap noted elsewhere
|
|
141
|
+
for `py`/venv creation.
|
|
69
142
|
- `_sync` — `PathSyncer` wrapper reproducing `install`'s backup/copy/report; requires
|
|
70
143
|
`pathlib_next.Path` instances (not plain `pathlib.Path`) and a pre-created parent dir.
|
|
71
144
|
|