feat(agent): add Antigravity (agy) CLI agent - #1287
Merged
Merged
Conversation
Adds AntigravityAgent (Agent + HookSupport surface), registry constants, camelCase stdin/stdout types for the five Antigravity hook events (PreToolUse, PostToolUse, PreInvocation, PostInvocation, Stop), transcript JSONL passthrough via shared agent.ChunkJSONL helpers, GenerateText for summary-provider integration, and a DiscoverReviewSkills stub. Layout matches docs/architecture/agent-guide.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: b1371f1a4c7c
Writes .agents/hooks.json with five event handlers and translates Antigravity's PreToolUse/PostToolUse/PreInvocation/PostInvocation/Stop into Entire's normalized lifecycle events. PreInvocation always emits TurnStart; the framework's idempotent strategy.InitializeSession (cli/lifecycle.go:406) handles first-arrival state creation. Stop with fullyIdle=false returns nil to avoid finalizing while background tasks run. Also restores two //nolint:ireturn directives removed in Chunk 1 that were blocking golangci-lint on NewCommittedReader and committedCheckpointStore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 6e0dacb51f81
End-to-end integration test drives the five Antigravity hook events (pre-invocation, pre-tool-use, post-tool-use, post-invocation, stop) via synthetic stdin payloads against a real git repo. Verifies session state lazy-inits on first PreInvocation, write_to_file PreToolUse populates state.FilesTouched, and stop with fullyIdle=true completes the SessionEnd flow cleanly. Documents the real Antigravity 2.0 transcript layout in transcript.go (~/.gemini/antigravity-cli/brain/<conv-id>/.system_generated/logs/transcript.jsonl with a step_index/source/type/status/created_at/content/tool_calls schema) based on a captured fixture. The on-disk decoder remains deferred per the deferred-table; v1 ships only the JSONL passthrough. Drops the dead .gemini/jetski/ branch from DetectPresence since agy stores runtime data user-scope, not workspace-scope. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: a422980bd082
Adds the e2e/agents/Antigravity runner so the existing agent-agnostic test suite (clean, disable, doctor, attach, resume, rewind, explain, interactive, multi_session, edge_cases) automatically parameterizes over antigravity via ForEachAgent when E2E_AGENT=antigravity. Mirrors the droid/gemini patterns: -p prompt flag, --dangerously-skip-permissions, tmux-backed StartSession. PromptPattern is a placeholder (`>`); the real interactive prompt pattern will be observed and refined once `agy --print` is reliable. Antigravity-specific test cases (hook-config-location, first-prompt checkpoint, rewind) are deferred to the same follow-up since they require a working interactive agy session. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 3b02d2cbf01a
Real-agy smoke testing showed our PreInvocation gate inverted: agy 1.0.0 ships invocationNum 0-indexed, so the actual first model call carries invocationNum=0 and the follow-up carries invocationNum=1. The old `!= 1` gate dropped the real turn-start and re-fired TurnStart on the follow-up, clobbering preState after tool calls had already mutated files — surfacing as "no files modified during session, skipping checkpoint" at commit time. Captured wire format: PreInvocation #1: {"invocationNum":0,"initialNumSteps":1,...} ← turn start PreInvocation #2: {"invocationNum":1,"initialNumSteps":5,...} ← follow-up The gate is now `invocationNum != 0`. Test fixtures (synthesized payload in lifecycle_test, captured fixture in testdata, integration test in integration_test) all updated to mirror the real wire shape so the test pyramid no longer agrees with the wrong invariant. transcript.go has a gofmt-only reformat of an existing doc comment. Verified end-to-end against real agy: shadow branch created, files_touched captured, `Entire-Checkpoint: <hex>` trailer appears on `git commit`, matching `Checkpoint: <hex>` lands on entire/checkpoints/v1. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Entire-Checkpoint: 7bfaeb05bf4d
Contributor
There was a problem hiding this comment.
Pull request overview
Adds first-class preview support for the Antigravity (agy) CLI agent, wiring it into Entire’s agent registry, hook handling, transcript lifecycle, text generation, integration tests, and optional E2E coverage.
Changes:
- Introduces a new
agent/antigravitypackage with identity, hook install/uninstall, lifecycle parsing, transcript handling, text generation, and discovery stubs. - Registers Antigravity in hook routing, agent constants, tests, and E2E agent support.
- Adds fixtures and unit/integration coverage for Antigravity hook payloads, lifecycle behavior, hook config management, and transcript preparation.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
e2e/agents/antigravity.go |
Adds E2E runner support for agy. |
e2e/agents/antigravity_test.go |
Adds basic E2E agent identity tests. |
cmd/entire/cli/integration_test/antigravity_test.go |
Adds integration coverage for Antigravity hook flow. |
cmd/entire/cli/hooks_cmd.go |
Registers Antigravity hooks command package. |
cmd/entire/cli/agent/registry.go |
Adds Antigravity agent name/type constants. |
cmd/entire/cli/agent/generate_external_test.go |
Adds Antigravity text generation test coverage. |
cmd/entire/cli/agent/antigravity/antigravity.go |
Defines Antigravity agent identity and core methods. |
cmd/entire/cli/agent/antigravity/antigravity_test.go |
Tests agent registration, interfaces, and presence detection. |
cmd/entire/cli/agent/antigravity/discovery.go |
Adds review skill discovery stub. |
cmd/entire/cli/agent/antigravity/generate.go |
Adds non-interactive agy text generation. |
cmd/entire/cli/agent/antigravity/hooks.go |
Adds .agents/hooks.json install/uninstall/status handling. |
cmd/entire/cli/agent/antigravity/hooks_test.go |
Tests hook config installation behavior. |
cmd/entire/cli/agent/antigravity/lifecycle.go |
Maps Antigravity hook payloads to Entire lifecycle events. |
cmd/entire/cli/agent/antigravity/lifecycle_test.go |
Tests lifecycle parsing and file extraction edge cases. |
cmd/entire/cli/agent/antigravity/transcript.go |
Adds JSONL transcript read/chunk/reassemble and preparation. |
cmd/entire/cli/agent/antigravity/transcript_test.go |
Tests transcript round-trip and placeholder creation. |
cmd/entire/cli/agent/antigravity/types.go |
Defines Antigravity hook payload/config types. |
cmd/entire/cli/agent/antigravity/types_test.go |
Tests fixture decoding for hook payload types. |
cmd/entire/cli/agent/antigravity/testdata/hook_stdin_pre_invocation.json |
Adds PreInvocation fixture. |
cmd/entire/cli/agent/antigravity/testdata/hook_stdin_post_invocation.json |
Adds PostInvocation fixture. |
cmd/entire/cli/agent/antigravity/testdata/hook_stdin_pre_tool_use.json |
Adds PreToolUse fixture. |
cmd/entire/cli/agent/antigravity/testdata/hook_stdin_post_tool_use.json |
Adds PostToolUse fixture. |
cmd/entire/cli/agent/antigravity/testdata/hook_stdin_stop.json |
Adds Stop fixture. |
cmd/entire/cli/agent/antigravity/testdata/transcript_sample.jsonl |
Adds sample Antigravity JSONL transcript fixture. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit f141838. Configure here.
Three correctness fixes surfaced by Copilot and Cursor Bugbot review: 1. Register antigravity in summaryProviderBinaries. The GenerateText implementation in cmd/entire/cli/agent/antigravity/generate.go was dead code because IsSummaryCLIAvailable filtered antigravity out even when `agy` was installed on PATH. Adding the map entry makes `entire explain` and summary-provider selection see it. Matches the pattern for the other five agents that ship a generate.go. 2. resolveAgySymlinks now walks up to the deepest existing ancestor. The previous implementation only EvalSymlinks'd the immediate parent and silently returned the unresolved path if that parent didn't exist — which fires the moment agy creates a file inside a new nested directory (e.g. /tmp/repo/newdir/file.txt). The unresolved path then gets filtered as "outside repo" on macOS via the /tmp → /private/tmp symlink, silently breaking files_touched capture. Added two regression tests: one for the new-nested-dir case, one pinning the "no resolvable ancestor → return input" fallback. 3. Filter HOME before appending the test-home override in antigravityPromptEnv. The previous code appended HOME=... to an env that already contained HOME, and getenv returns the first match — so agy ran under the user's real home, defeating E2E test isolation. Mirrors codex.go's filtering of CODEX_HOME and pi.go's filtering of PI_CODING_AGENT_DIR. Two further bot comments about hooks.go install/uninstall over-eagerly owning the "entire" top-level key in .agents/hooks.json are skipped intentionally: by convention "entire" IS our bucket name, and the idempotency comparison in InstallHooks already protects against clobbering an identical config. Other agents (claude-code, gemini-cli) use a per-handler `entire-` prefix model because their hook schema is a flat array; antigravity's nested top-level-bucket schema is sufficiently different that adopting the prefix dance would add complexity without a real-world payoff. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Entire-Checkpoint: 58eff1cb1cf5
Three issues prevented `mise run test:e2e --agent antigravity` from actually exercising the integration: 1. Drop `--model gemini-2.5-flash`. agy 1.0.2 has no --model flag, so passing it made agy exit 2 with "flags provided but not defined". Model selection lives in settings.json; tests accept agy's default for now. 2. Drop HOME isolation. Pointing HOME at a fresh per-test dir stranded agy's auth, install id, and onboarding state under HOME/.gemini/, causing agy to re-trigger the browser auth flow on every run. Selective symlink-seeding chases a moving target as agy adds new state files. Sharing the real HOME lets agy authenticate; the test repo (cmd.Dir) still scopes workspace mutations. CI will need a proper HOME-isolation surface (or a dedicated test account) before the real-agy suite is wired into CI — out of scope here. 3. Pass `--add-dir <dir>` in print mode. Without it, agy ignores cwd and falls back to ~/.gemini/antigravity-cli/scratch/ — it init'd a brand-new git repo there and committed the test file there while the actual test repo stayed empty. Validated locally: a 14.8s real-agy run of TestSingleSessionAgentCommitInTurn now passes (hooks fire, files_touched captured, checkpoint advances on user commit). Entire-Checkpoint: 6a895268cec9
Adds two components that let entire capture agy token usage — the only surface where agy exposes token data is the JSON payload it pipes to the user-configured title/statusline command on every agent state change. Task 1 — Snapshot store (statusline.go / statusline_test.go): - AppendStatusSnapshot() parses the agy state JSON, deduplicates against the last persisted line (by compact-remarshaling the context_window), and appends a timestamped JSONL line to <ENTIRE_ANTIGRAVITY_STATUS_DIR|XDG_CACHE>/entire/antigravity/status/<conv_id>.jsonl. - Silently ignores malformed/incomplete payloads; only genuine I/O errors propagate. - Dedup reads only the last line of the file (seek-free linear scan) for O(file-size) worst-case but O(1) typical-case performance. - Prunes stale files (>14d) only when a new conversation file is first created, keeping the hot path to a single open+write. Task 2 — title-tee shim (hooks_antigravity_title.go / _test.go): - `entire hooks antigravity title-tee [--wrap '<cmd>']` reads stdin, calls AppendStatusSnapshot (best-effort), then optionally chains the user's original title command via sh -c so their window title is preserved. - Never exits non-zero; never writes noise to stdout (agy renders stdout verbatim as the terminal window title). - Registered on the antigravity hooks subtree, not through executeAgentHook, so it works outside git repos and without entire being enabled. Perf numbers (Apple M4 Pro, arm64, macOS 25.3): - End-to-end shim: 20-run warm avg = 41ms (budget ≤50ms); total = 830ms (budget ≤1000ms). - BenchmarkAppendStatusSnapshot_GrownFile (500-line file, dedup path, 100x): ~79µs/op (budget ≤2ms/op). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5 tasks done
…lDev + comments Addresses PR #1356 review (Cursor Bugbot + Copilot): - InstallHooks now runs InstallTitleTee BEFORE the repo-hooks idempotency early-return, so re-running setup repairs a missing/stale global title slot (upgrade, failed first install, or 'agent add' without --force). Regression test added. - localDev title command bakes the absolute main.go path at install time instead of a runtime $(git rev-parse) that would resolve against the wrong repo (the title slot is global). Falls back to the PATH form if unresolved. - Fix shellSingleQuote doc comment (stray curly quote) and the dedup comment to accurately describe the whole-file streaming read. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… comments) - condensation: gate out-of-band token fallback on AsOutOfBandTokenSource (purpose-built capability) instead of the !AsTokenCalculator inverse, so only OOB agents inherit accumulated SessionState.TokenUsage; add a negative-branch test proving a non-OOB agent (Cursor) does not. - title-tee: log a debug breadcrumb on AppendStatusSnapshot failure instead of discarding the error; contract unchanged (no stdout, returns nil). - comments: correct readLastContextWindow doc (streams the file), reframe AsOutOfBandTokenSource exclusion rationale, note sh -c wrap is the user's own settings.json command (not an injection surface). - lifecycle: use slog.String for the OOB warn log to match the file's local convention. - tests: current_usage change is not deduped; --wrap path still captures the snapshot; delta is zero (nil) when baseline is the latest snapshot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test-auditor pass: - Remove TestTitleTee_WrapPipesPayloadThrough — a strict subset of TestTitleTee_WrapStillCapturesSnapshot (which makes the same passthrough assertion plus the snapshot-capture check). Zero coverage lost. - Rewrite TestCalculateTokenUsageSince_ClampsWhenTotalsGoBackwards to assert usage == nil directly (the actual all-zero path) instead of guarded conditionals that never executed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…T steps Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fixture Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion is implemented Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on for late-flush agents Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…file extraction) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n dedup in TranscriptAnalyzer
…n commit checkpointing - GetSessionDir/ResolveSessionFile compute the real agy brain-dir transcript path (~/.gemini/antigravity-cli/brain/<id>/.system_generated/logs/ transcript_full.jsonl) instead of returning empty, with a test-override env for isolation. - Implement WriteSession (was a no-op) with validation so restore/rewind can materialise transcripts. - Add USER_INPUT prompt extraction and PrepareTranscript to handle agy's asynchronous transcript write (briefly wait, then placeholder) before the framework's fileExists check, so Stop does not exit 1 and kill the turn. - Skip the redundant TurnEnd checkpoint when a mid-turn commit already condensed all tracked files (agy fires Stop after PostCommit). Verified offline against 376 real agy transcripts (0 parse errors) plus unit and integration tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
resolvePendingTranscriptOffset logs at Info when it completes a deferred advance, but returned silently when the phase is not ACTIVE. That is the branch worth seeing: the checkpoint scope then keeps the previous turn's already-condensed tail, which reaches the summary as duplicated content. The doc comment acknowledged the bloat; nothing made an occurrence observable. Same level as the advance, so the two are equally visible. Finding: 01M373FQ00E2 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M3782H66PSMH4XF38K8FW3G4
title-tee is attached to the per-agent hooks command, which defined a PersistentPreRun that loads settings, scans every session state file via ResolveCallerSession and builds the secret scanners. agy fires its title command on every state change, unserialized, so that ran roughly once a second to append one JSON line: a real 35-second turn logged 32 "redaction configured" lines. Fixed by moving the PersistentPreRun onto the per-verb commands. The lifecycle verbs keep exactly today's behaviour; title-tee, which is not one of them, inherits nothing. Not by re-parenting title-tee, and not by giving it a no-op hook of its own. The exact string `entire hooks antigravity title-tee` is persisted in users' agy settings.json by InstallTitleTee and matched by shape on uninstall, so moving it would leave every installed tee invoking a command that no longer exists — token capture silently to zero, and uninstall no longer recognising the old entry. And a no-op cannot shadow an ancestor: root.go sets cobra.EnableTraverseRunHooks, which in cobra v1.10.2 runs every ancestor's PersistentPreRun from the root down rather than only the nearest. TestTitleTee_InheritsNoPersistentPreRun pins both halves: the command path, and that no ancestor below the root defines a hook. The two tests that asserted the hook's old location now assert the new one, keeping their real invariants. Finding: 01M376TTRSTZ Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M379E46MGE5S80V5HQHDV6MW
InstallHooks called InstallTitleTee with no check that agy is on PATH. The title slot lives in agy's machine-global settings.json, so a repo-local `entire agent add antigravity` — in a teammate's checkout, say — wrote a shared user-level file on a machine that has never run agy. `entire doctor` already gates its matching check on the same lookup. The call keeps its position ahead of the idempotency early-return: that ordering is what makes stale-slot repair work, and only the binary check was missing. Finding: 01M376Y1T4CG Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M379EMNTA0QRB1QZXZF2GAB4
internal/flock sat in the flat allowedPrefixes list, beside genuinely shared utilities, so it silently permitted the import for every agent package. The reason it exists is specific to one: agy fires its title command on every state change without serializing, so the Antigravity title-tee takes a per-conversation flock. scopedPrefixes keys such an exception by agent package, the same per-path shape unconfinedTranscriptReads and allowedRootBases already use. A second agent that wants flock now has to say so and give its reason, instead of inheriting one agent's answer. Finding: 01M376VAJ85Y Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M379EPQG8C7R49H7XVKBVHRH
The hint named ~/.gemini/skills, which antigravity/discovery.go documents as a pre-1.1 layout; the current global root is ~/.gemini/config/skills. Not cosmetic, and the comment now says why: Entire scans all three layouts, so a skill placed at the old path still reaches Entire's prompt and looks like it worked — but agy itself will not load it, which is the half the hint was getting wrong. Finding: 01M376V84NXJ Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M379ERRNP0W0N7728W2RXS2P
parseHooksProbeOutput decoded the envelope's status and never read it. agy can exit 0 while reporting a non-success status with an empty command.data.hooks array, which is byte-identical to a genuine "no hooks loaded" response — and doctor's remediation for that case tells the user their hooks are NOT LOADED, the wrong advice for someone whose probe never ran. A status agy actually reported and did not set to SUCCESS is now an error. An absent status is left alone: only a reported status is evidence about the probe. Finding: 01M36QMB0KXY Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M379Q4VXA3RBE93C85H7DK63
ead34ed moved the hook-session PersistentPreRun from the shared per-agent command onto each verb, but executeAgentHook's doc still said built-in subcommands pass stampSession=false because "their parent command's PersistentPreRun already did it". Worth more than tidiness: that sentence teaches the stamping is inherited, which is the belief that makes the title-tee bug easy to reintroduce — attach another non-verb command to the agent command and it would not be stamped, contrary to what the doc promised. Finding: 01M37AC1240K Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M37ARAK7SMZ7QFZAA57XP4ZB
The snapshot prune stat'd a file, found it older than the retention window, and unlinked it without taking that conversation's lock — while the lock-file loop right below it is careful about exactly this. A dormant conversation resumed between the stat and the unlink is mid-append, and the file goes out from under its open fd. The prune now takes the conversation's own lock first, non-blocking: a held lock means that conversation is alive right now, which is reason enough to leave its file for the next run. Scope of the bug, since it is easy to overstate: the recorded token counts are NOT at risk. agy's totals are cumulative per conversation and CalculateTokenUsageSince subtracts a baseline held in PrePromptState, so a lost file is followed by a fresh snapshot carrying the same cumulative totals and the delta still comes out right. What is lost is the per-line detail between baseline and now — the cache fields and APICallCount that the same function already documents as best-effort. A documented approximation getting more approximate, in a window needing three coincidences. Taken because the fix is cheap and matches its sibling loop, not because the consequence is severe. Finding: 01M37A5Y47WN Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M37AXPNXBX5WEBPTM5NARRQQ
2b193e4 took the conversation's lock before unlinking its snapshot, which is the right shape, but reached for it unconditionally. The try-lock is not a free probe: flock opens with O_CREATE|O_EXCL, so asking for a lock that does not exist creates one — left behind for a conversation that was just deleted. The orphan-lock loop cannot collect it in the same pass, since it walks an entries snapshot taken before the lock existed, and on the next pass it must first age past the retention cutoff. Each pruned conversation could leak a lock file for another retention window: the accumulation 01M341AX1V6D removed from the read path, reintroduced on the prune path. The lock is now attempted only when the lock file already exists. Absence is evidence rather than missing evidence: AppendStatusSnapshot takes the lock BEFORE creating the .jsonl — the ordering the orphan-lock loop already relies on — so a snapshot with no lock beside it has never had a tee mid-append, and unlinking it directly is safe. The decision now lives in pruneStaleSnapshot rather than inline, so the loop reads as intent and the reasoning has one home. Finding: 01M37B28RP6R Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M37B6Y0GH68QRZ3N37CNMM8J
The comment here promised the merge gate was protected from third-party agy regressions. It was not. agy self-updates in place: the updater replaces the executable at its own path — in CI, the file this step installs — and is spawned on essentially every launch, ~0.4s in, with auth not gating it and its only brake a 15-minute check keyed on state a fresh CI home never has. So the pin governed only the first agy spawn of the job, and the harness spawns agy once per prompt, so every prompt after the first already ran whatever the updater had fetched. Measured on Windows 11 ARM64: 1.2.7 installed, one headless prompt, 1.2.9 at the same path afterwards, with the original moved aside as agy.exe.<ns>.old. There is no opt-out — not a flag, a settings key, or an env var. Dropping the pin changes almost nothing in practice (one prompt out of many) and stops the tree asserting a guarantee it does not provide. The exposure is now written down instead: this job's agy version floats, and an agy regression can redden PRs that never touched Antigravity. Closing the exposure for real needs the updater blocked — an unwritable install path, or no egress for this step — and neither is tested, so neither is adopted here rather than trading a known exposure for an untested merge-gate hack. With the pin gone the hand-rolled tarball had no remaining purpose, so this uses agy's official installer like every other install in the tree. Finding: 01M37BP8MN8Q Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M37BZMWDMNKNRJT3XYFMFRDR
…ected InstallHooks now claims agy's global title slot only where `agy` resolves on PATH (41fdeae). TestInstallHooks_IdempotentStillRepairsTitleTee still asserted the tee after the first install on a machine with no agy, which is exactly the case that commit stopped installing it. The test now puts a stand-in agy on PATH, so it keeps guarding the stale-slot repair it was written for. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37JE28VJTQNA67KZVXQ6036
boundTranscriptText caps the transcript at 96 KiB so the whole prompt stays under Linux's 128 KiB single-argument limit, since Antigravity takes the prompt in argv. The [Files Modified] list appended after it was unbounded, so a session touching many files could push the prompt back over the limit and reproduce the E2BIG the bound exists to prevent. The list now keeps whole lines up to 16 KiB and closes with how many paths were left out. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37JE7DHXPK7YYSQ4BYK8105
antigravityTestHomeDir is a sibling of the repo temp dir and held agy's settings, session and log state; nothing removed it, since PrepareRepo has no *testing.T. An optional RepoCleaner hook, registered by SetupRepo after the repo's own cleanup and before artifact capture, now removes it when the test ends (kept under E2E_KEEP_REPOS, like the repo). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37JEDAQFE9AVCVB382WTRPW
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37JGJPADYJ2470RFSDSPQXR
…n the fast path sessionLacksCondensableContent classed every stat failure on a late-writer transcript as "no content", so an EACCES, ENOTDIR or I/O error silently dropped that session from the commit's trailer. Now only an absent file, or a path the session store refuses (a symlink at any component, a non-regular leaf, which the full path refuses too), reads as no content; anything else fails toward condensing, where the read reports what is wrong. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37K972CZEZGQ44W361569Y0
agy hands its global title slot to cmd.exe on Windows. The tee preserved a pre-existing user title command as --wrap '<original>' and re-ran it with `sh -c`, both POSIX-only: cmd.exe reads the single quotes as literal text and a stock Windows PATH has no sh, so on such a machine the tee failed on every model call — no token snapshots, and the user's own title gone. An earlier finding on this code was closed with "revisit if agy ships on Windows"; it does, and this branch claims Windows support. On Windows hosts InstallTitleTee now writes --wrap-b64 <base64url(original)>, an encoding no shell touches, and the tee re-runs the decoded original through cmd.exe (/d /s /c, the whole line passed verbatim via CmdLine) — the same shell agy would have used. Unix keeps the quoted form. Uninstall parses both forms and restores the original byte for byte; the quoted form is tried first because only its payload can contain either flag's text. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37M4XF1BCE823AJQTCR4Z13
… agy's first Stop sessionHasNewContentFromLiveTranscript required transcript growth before it looked at FilesTouched. For a late-transcript writer the file is still an empty placeholder mid-turn — position and CheckpointTranscriptStart are both zero — so a user committing from a terminal during agy's first turn lost the Entire-Checkpoint trailer even though PreToolUse had recorded the edit. The no-TTY fast path never reaches this function, which is why the integration test for that scenario kept passing. FilesTouched is cleared by condensation, so anything in it is uncondensed work; transcript growth is now consulted only when the hooks recorded nothing. The staged-file overlap check is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37NG3Q2A8WJHTK3FFZD7F0B
boundTranscriptText and the file-list bound exist to keep Antigravity's single-argv summary prompt under Linux's 128 KiB limit, but they were applied inside FormatCondensedTranscript, which `entire explain --full` also uses to show a reader the whole transcript. FormatCondensedTranscript is unbounded again; the two LLM callers use FormatCondensedTranscriptForPrompt. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37NG5HT3F2JFAQ308MQR354
The picker renders these through huh, which treats backtick spans as markdown and mangles them — the rule stated four lines above the entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M37NG7DP20JP9KVTWB317288
On the shadow-branch path the whole prompt ladder — the tree's prompt.txt, the filesystem copy, and the late-flush transcript rung — sat inside `if fullTranscript != ""`. None of those rungs needs transcript content to answer: prompt.txt is written at turn start, and resolveCondensationPrompts falls back to the transcript path when the bytes are empty. So a checkpoint condensed while the transcript was empty carried no prompt from ANY source, including the prompt.txt sitting in the very tree being read. For a LateTranscriptWriter that is not a rare race: agy flushes after Stop, PrepareTranscript materialises a 0-byte placeholder, SaveStep checkpoints it, and a commit before the flush lands takes this path. logCondensationPrompts was inside the same block, so the breadcrumb added to make an empty prompt diagnosable was absent exactly when it was needed. The rungs now run regardless; only the transcript assignment stays gated. This is the shadow-path twin of the live-path fix in 165b0ad, which already resolves prompts independently of transcript content. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M396JCC5EMGD71P29N0Z2RX8
cobra.EnableTraverseRunHooks is on, so root's PersistentPreRunE runs for every command including `entire hooks antigravity title-tee`, and paths.RequireEntireDir answers nil only for ErrNotARepository. An unresolvable repository (git's safe.directory refusal, git absent from PATH) or a `.entire` that is not a real directory therefore made the tee print the multi-line remedy to stderr and exit non-zero — once per agy agent state change, against this command's documented NEVER-exit-non-zero contract, with token capture silently dead and only agy's own log to show for it. The tee writes to the per-user cache and never under `.entire`, so it has nothing the guard protects. The exemption is scoped to this one command rather than the `hooks` tree: the lifecycle verbs are the checkpoint-writing path and must keep failing closed. TestEntireDirCheckExemptions requires every exempt command to carry a written justification, so the ledger gains one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M396JX6BMJH0H5AYE9V2QFZC
…lves resolvePendingTranscriptOffset cleared TranscriptOffsetPending before attempting the advance, so every outcome consumed the one-shot flag — including the one it exists for. An ACTIVE session whose transcript still has not flushed cannot compute the advance (GetTranscriptPosition fails, or returns a position no later than the stale offset), and a second commit made inside that same unflushed window therefore discarded the deferral. Once the flush landed, the next checkpoint scoped from an offset inside the previous, already-condensed turn: the previous turn's prompt attributed to it and a duplicated tail in the stored transcript — precisely the shift the flag was added to prevent. The flag now survives only that case, and the unresolved attempt is logged like the advance and the non-ACTIVE skip already are. Everything else still consumes it: outside ACTIVE the file may hold the current turn's uncondensed content, and the capability checks can never come true for the session, so a flag left set there would be re-read forever. Letting it outlive a successful condensation is harmless — that rewrites CheckpointTranscriptStart to the transcript end, so the next pass finds pos <= start and no-ops. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M396JYM2XHTVCNZPGBT2DCHQ
…anscript agents sessionHasNewContentFromLiveTranscript began treating a non-empty FilesTouched as sufficient evidence of new work, skipping the transcript growth check. The justification is specific to a LateTranscriptWriter: only such an agent has an empty transcript mid-turn, where the growth check would veto genuinely hook-captured edits and drop the trailer from a user's mid-turn commit. Applied to every agent, it also removed the growth precondition from the eight streaming-transcript agents' TTY commit path, where that check is meaningful evidence rather than a false veto. Adding an agent to the registry should not change the commit path of the agents already in it, and every other behavioural change in this integration is gated through agent.AsLateTranscriptWriter — this one now is too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M396KAV831Y7R2EZ8Y7QJXQH
Antigravity's two truncated-step warnings logged through context.Background(). logging.log resolves its logger from the context and falls back to slog.Default() when there is none, and nothing outside tests calls slog.SetDefault — so those warnings went to the stdlib text handler on stderr, not to .entire/logs/entire.log where the integration says they are recorded. ExtractModifiedFilesFromOffset runs inside prepare-commit-msg and post-commit condensation, whose stderr the user sees, so a transcript with truncated replace_file_content steps (measured at roughly 0.8% of such calls) printed unstructured `level=WARN msg=...` lines into `git commit` output, without session_id. The method had no context to log through, so the interface gains one. The other ten implementations ignore it; only the call sites, which all had a context in scope, and the antigravity implementation change behaviour. Mechanical apart from those two log calls, and separable from the rest of this branch if it is better carried by the prompt-resolution follow-up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M396KXK11H1DRDMZ9R131KPR
The import guard built its per-package allowlist with `append(allowedPrefixes, scopedPrefixes[pkgName]...)` inside the loop. That is safe only because allowedPrefixes is a composite literal whose cap equals its len, forcing a copy. Build it any other way — make() with spare capacity, or one more appended entry — and append writes the antigravity-scoped internal/flock entry into its backing array, handing every package checked afterwards the exception scopedPrefixes exists to contain, with no test failure to signal it. slices.Clone makes that independent of how the slice is built, and hoisting it out of the inner loop drops a re-allocation per import. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M396KYVETYG282B0SZZZ0ZSV
main removed Gemini CLI support while this branch was adding Antigravity, so every conflict was the same collision: both sides edit the lists of supported agents. Resolved by taking main's list and restoring Antigravity to it, keeping main's other additions (Codex, where it had been added alongside). Substantive resolutions: - generateSummary: kept this branch's sliceByAgentMetric delegation and took main's geminilegacy call inside the fallback switch. The branch's inner Gemini case still named the geminicli package, which main deleted, so it could not have compiled either way. - agent/geminicli: accepted main's deletion of the package. This branch had only touched it to thread ctx through ExtractModifiedFilesFromOffset. - e2e/testutil/repo.go: kept RepoPreparer/RepoCleaner, dropped the gemini-cli branch — setupGeminiTestHome no longer exists. - antigravity_test.go: the "wrong agent" sentinel named AgentNameGemini, a constant main deleted. Now AgentNameClaudeCode. This one is a semantic conflict git resolved cleanly and only vet caught. Verified on the merged tree: go build, go vet (including GOOS=windows), gofmt, mise run lint (0 issues) and mise run test:ci, all green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M39RV7DGXVXPKTJRE1KGKEZ8
Both comments described the secret as shared with the gemini-cli E2E leg. That leg no longer exists — main removed Gemini CLI support — so the only consumer is agy's API-key mode, and "shared" now points a reader at an agent that is not there. Comment-only; the secret, the workflow and the fallback behaviour are unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M39S2GZKTWB0KJFM3TQ86THA
gtrrz-victor
approved these changes
Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

https://entire.io/gh/entireio/cli/trails/444
Summary
First-class support for Antigravity CLI (
agy), Google's successor to Gemini CLI, as a new Entire agent — the complete integration: lifecycle hooks, transcript decoding, native token counts, review-skill discovery, resume tracking, docs, and E2E wiring. Consolidates the previously stacked PRs #1356 (tokens) and #1381 (transcript decode) plus the gap-fix and review-fix rounds into this single parent.Scope map (~7.2k insertions; ~60% tests):
cmd/entire/cli/agent/antigravity/pre-tool-use,pre-invocation,stop), transcript analyzers (prompts, positions, modified files), async-transcript handling, token tee (statusline.go/title_install.go), review-skill discoverycmd/entire/cli/lifecycle.go,state.go,event.gocmd/entire/cli/strategy/agent/skilldiscovery/GEMINI_API_KEY→ OAuth), trusted-workspace seeding, fatal-vs-transient classification, agy-log + hook-probe artifact capture; dispatch-only in workflows (see limitations)Real-agy quirks (all hardened in code + tests)
invocationNumis 0-indexed; PreInvocation fires per model invocation.invocationNum > 0emits a conditional TurnStart (Event.SuppressIfSessionActive) the dispatcher drops only when a turn is genuinely mid-flight — so resumes (agy --conversation) are tracked and follow-up invocations don't clobber the pre-prompt baseline.Stop.PrepareTranscriptbriefly waits then materializes a placeholder; condensation degrades to a files/prompt-only checkpoint (agy-scoped) and prompts are re-extracted late (resolvePromptsFromLateFlushedTranscript).titleslot is claimed byentire hooks antigravity title-tee(wrap-preserving, doctor-checked); TurnStart snapshots a baseline, TurnEnd computes the delta (OutOfBandTokenSource).decodeAgyString/decodeAgyBooltolerate both shapes. macOS/tmpsymlinks resolved.Review & verification
entire agent add antigravity→ real hook wiring → mid-turn commit with unwritten transcript → checkpoint + trailer + scoped tokens +entire statusall correct. Realagyfired PreInvocation live (session state created); the model call itself is quota-gated (below).TestSingleSessionManualCommitpassed live with real token counts; fresh-repo smoke verified install → live turn → commit → condensation → resume (agy --conversation) → token scoping across two commits. agy auto-updated 1.0.16→1.1.1 mid-session; hook wire contract re-verified unchanged, but agy 1.1 moved the skill-discovery directories — fixed, along with the ADC-mode quota-log peek, a doctor false-positive for non-agy teammates, an explicit Stop-hook timeout, and anagent removewarning about the global title-tee. Deferred minors are tracked as findings on trail 444.Known limitations (preview)
GEMINI_API_KEYsecret). agy ≤ 1.1.24 loaded.agents/hooks.jsonon that route but never executed the hooks (Hooks from .agents/hooks.json are loaded but never executed when authenticated via GEMINI_API_KEY (headless -p, 1.1.22) google-antigravity/antigravity-cli#893, still open upstream); bisecting the release binaries with a probe hook shows agy ≥ 1.1.25 executes them, and CI installsreleases/latest(1.2.7 as of 2026-09-21). The optionalANTIGRAVITY_GOOGLE_APPLICATION_CREDENTIALS_JSONsecret still switches the leg to ADC; thecloudcode-pabackend remains entitlement-gated (subject 110002). Fail-fast classification covers quota/entitlement walls plusGEMINI_API_KEY … not set/API_KEY_INVALID. Details ine2e/README.md.truncated_fieldsand dropsTargetFile(reported by @ecgang, ~0.8% ofreplace_file_contentcalls in their corpus). Now logged as a WARN per dropped call instead of a silent skip; live PreToolUse stdin is never truncated so only the late-flush / first-turn fallbacks are affected. Awaiting a real fixture.entire statusis the visibility surface.entire hooks antigravity title-teeowning/wrapping agy's globaltitleslot (doctor-checked, setup-repaired).Stop/PostInvocationfire reliably, 1.1.12 answers-p "/hooks"locally (used byentire doctorto verify the workspace hooks actually load, zero quota).2026-08-27/28 update
origin/main(was 3 months behind): ported to local-dev removal,IsManagedHookCommand(cmd),AreHooksInstalled → (bool, error), 4-valueRunIsolatedTextGeneratorCLI, main'sskilldiscoveryextraction.antigravity, so the leg had never started in CI.GEMINI_API_KEYe2e mode, optional ADC, trusted-workspace seeding, agy-log + hook-probe artifacts (agy emits no log line for hook execution — the probe is how Fix external agents detection #893 was found).entire doctor: "Antigravity hooks: LOADED/NOT LOADED by agy" viaagy -p /hooks --add-dir <root> --output-format json(version-gated ≥ 1.1.12), plus the untrusted-workspace trap from the test report.truncated_fieldsdegrade path (above). Docs refreshed for 1.1.22.2026-09-22 update (trail-444 review rounds after real Windows/macOS testing)
agent.WrapWindowsProductionSilentHookCommandDirect) whenHookHostIsWindows(). The status store's root-relative names were backslash-joined on Windows and never created; they are slash-separated now andosroot.MkdirAllNoSymlinkrefuses backslash names.entire doctor: theagy -p /hooksprobe was observed to run a full model turn on Windows and only proved agy parsed hooks.json, so it is opt-in (ENTIRE_ANTIGRAVITY_DOCTOR_PROBE=1). By default doctor now checks, at zero cost, that the installed hook entry is the shape this host needs (HooksEntryMatchesHost) and says how to reinstall. An unparseable agy version no longer produces "runagy update".agent.TranscriptPromptExtractor) instead of re-reading the live path, and condensation logs which rung supplied the prompts. A new integration test runs two turns in agy's real order and commits each manually.--add-dirmust be absolute (documented, and the probe refuses a relative root); the merge-gatinge2e.ymlpins agy to 1.2.7 while nightly keepslatest.entireio/entire-sandbox— both checkpoints carry the right prompt (the later turn at transcript offset 4), tokens recorded, status store under~/.cache/entire/antigravity/statuswith no orphan locks, doctor clean without the probe. Full antigravity e2e suite: 48 pass / 3 skipped both locally and in CI; the 5TestInteractive*failures were the harness, not the CLI — interactive agy in a never-run HOME shows a color-scheme chooser and a Terms consent before the prompt. The isolated HOME now seedscache/onboarding.jsonas complete (established by walking onboarding in a scratch HOME and diffing), and the runner clicks through both screens as a fallback.agent list/add/remove,status(+--json),session list/current/info/tokens/stop,checkpoint list/explain/tokens/search,search,recap --static,activity,agent-help,doctor(default and with the probe opt-in),configure --summarize-provider antigravity,checkpoint explain --generate,dispatch --local --agent antigravity,clean --dry-run,disable/enable. Two real bugs found and fixed: agy 1.2.x ignores stdin in print mode, soGenerateTextnow passes the prompt in argv (dispatch --localhad handed agy an empty prompt); and the summarizer had no condenser for agy's step JSONL, soexplain --generatereported an empty transcript —antigravity.CondenseTranscriptnow feeds it. Both re-verified live.sessionHasShadowContent: files, written steps, or task checkpoints); the ghost still has none of those. Table test covers files-only and steps-only.origin/maina third time (session-store tests; no code conflicts).e2e-windows.yml(agy 1.2.7 fromagy_cli_windows_x64.zip, API-key mode; the harness redirectsUSERPROFILEwithHOMEso agy and theentirehooks it spawns agree on the isolated home).TestSingleSessionManualCommitpassed onwindows-latest(run 35803986610): the cmd.exe wrapper fired PreInvocation/PreToolUse/Stop, agy wrote the file through a PreToolUse hook, the Stop hook saved the shadow checkpoint, and the commit carries itsEntire-Checkpointtrailer. The first run failed only on the harness'ssh -cprobe hook, which cmd.exe cannot run and which made agy refuse the tool call; the probe now skips itself on Windows. Runner is x64; ARM64 remains the reviewer's manual evidence. Follow-up: add antigravity to the nightly Windows leg.[Files Modified]list is bounded like the transcript; the e2e harness removes Antigravity's isolated home with the repo; the commit fast path treats only a missing or store-refused transcript as "no content" (any other stat error fails toward condensing); and the title-tee now preserves a pre-existing user title command on Windows —--wrap-b64 <base64url>where agy runs the slot through cmd.exe, re-run through cmd.exe by the tee, with uninstall restoring either form byte for byte. Previously that case failed on every model call on Windows (no tokens, user title gone); an older finding had deferred it with "revisit if agy ships on Windows". Review round on that head: a TTY mid-turn commit before agy's first Stop lost its trailer because the slow path required transcript growth before looking at hook-captured files (fixed: files carry the decision, growth is the fallback); the summary-prompt bounds had leaked intoexplain --full(display formatter is unbounded again, LLM callers useFormatCondensedTranscriptForPrompt); the Antigravity install hint used backticks the picker mangles.agent.IsPreviewis gone, so Antigravity's preview status is documentation only (AGENT.md, agent-guide.md); this branch's own selector/list preview labels were reverted before that.2026-09-21 update
Merged
origin/mainagain (~905 commits; 14 conflicts). Main deletede2e-isolated.yml/e2e-checkpoints-v2.ymland gavee2e.ymlatestregex input, so the antigravity CI wiring now lives only ine2e.yml. Adapted to main's checks:StepContext.MetadataDirAbsremoval, thewriteTestFilehelper removal,goconston the hook type literal, the transcript-read ratchet (transcript_read_guard_test.go; antigravity registers one read like every other agent), the e2e prompt-timeout chain (boundPrompt), theuserdirsconsumer audit (the statusline tee now resolves throughuserdirs.CacheDirChecked), and the summary-capable provider pin (antigravity hasGenerateText, so it joins the list and the README).Fix external agents detection #893 verified fixed upstream in agy 1.1.25 by bisecting real release binaries in an isolated HOME with
modelProvider: geminiand a probehooks.json: 1.1.22/1.1.23/1.1.24 fire nothing, 1.1.25/1.2.0/1.2.7 fire PreInvocation + Stop. The release notes never mention it. The antigravity leg is back in the defaulte2e.ymlmatrix and the dispatch-only caveats are rewritten (AGENT.md,agent-guide.md,e2e/README.md).Nightly install smoke (
nightly-e2e.yml) gains an antigravity leg on Linux and macOS (agy from the latest release tarball, API-key mode, 25-minute step cap for the 2.5x multiplier). It can only go green once this PR is in a published nightly, since that workflow checks out the nightly tag.Model bump: agy 1.2.x dropped
gemini-3.5-flash-lowfromagy models(both auth modes) and rejects it withinvalid model selection; the harness default is nowgemini-3.8-flash-low.CI run 35650998214 then passed
TestSingleSessionManualCommitfor antigravity in API-key mode (no ADC secret present, agy fromreleases/latest): the orgGEMINI_API_KEYis valid and the full hook set, PreToolUse included, executes on that route.Live smoke on entire.io (2026-09-21):
entirebuilt from this branch drove real agy 1.2.7 sessions in API-key mode againstentireio/entire-sandboxon both checkpoint backends — git-branch session (checkpoint593b557e273d) and git-refs session (checkpoint01M33B0YNF2RDS4ANXE7H8PZ2E). Hooks, title-tee, trailer, condensation, push and ingestion all worked; the three trail-444 findings (dedup/append race, bareos.Removein prune,os.Staton the transcript path) are fixed in9f688a8763by anchoring the status store onuserdirs.CacheRootand locking the dedup-append.Follow-ups (deliberately out of scope)
modelName, but checkpoint metadata leavesmodelempty today.Antigravity— a web-side display mapping, not this repo.entire doctorcould warn when agy < 1.1.25 runs in API-key mode (hooks load but never execute there).Test plan
mise run checkgreen locally (fmt, lint 0 issues, unit + integration + canary) — re-run 2026-09-21 on the merged treee2e.ymlantigravity leg green in API-key mode on agy latest, no ADC secret — run 35650998214 (TestSingleSessionManualCommit, 2026-09-21)mise run test:e2e --agent antigravity TestSingleSessionManualCommit— passed live 2026-07-13 (real agy, real tokens in the condensed checkpoint)agy --conversation→ checkpoint-scoped token deltas across two commits🤖 Generated with Claude Code
Note
Medium Risk
New agent code paths affect session lifecycle, hook-installed repo files, and checkpoint condensation; risk is mitigated by extensive tests but behavior depends on undocumented agy wire formats.
Overview
Adds preview first-class support for Antigravity CLI (
agy): a newantigravityagent package that registers with Entire, installs five workspace hooks into.agents/hooks.json(entireentry →entire hooks antigravity <verb>), and maps hook stdin to lifecycle events (TurnStart,ToolUse,TurnEnd).Lifecycle behavior is tailored to real
agyquirks:TurnStartonly wheninvocationNum == 0(follow-up pre-invocations are ignored so baselines aren’t reset);StopwithfullyIdle→TurnEnd(soSaveStep/checkpoints run); post-invocation is a no-op because transcripts aren’t ready yet;PrepareTranscriptcreates an empty placeholder when the transcript file is still missing after stop. Pre-tool-use records touched files from mutating tools, including double-encoded args and parent-dir symlink normalization (macOS/tmp).Also wires non-interactive
GenerateTextviaagy -p, JSONL transcript chunk/reassemble (passthrough v1), registry/hooks CLI imports, integration tests over subprocess hooks, and optional E2E registration whenagyis onPATH.Reviewed by Cursor Bugbot for commit f141838. Configure here.