agy-context-saver 1.8.1 → 2.0.1
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.
- package/CHANGELOG.md +27 -1
- package/README.md +52 -220
- package/assets/architecture-overview.svg +39 -0
- package/bin/agy-context.mjs +616 -0
- package/hooks.json +3 -3
- package/install.ps1 +1 -1
- package/lib/transcript-core.mjs +2310 -0
- package/package.json +11 -10
- package/plugin.json +6 -6
- package/rules/AGENTS.md +47 -79
- package/scripts/execution-guard-hook.mjs +3239 -375
- package/scripts/install-register.mjs +465 -323
- package/scripts/provision-rtk.mjs +35 -26
- package/scripts/release-preflight.mjs +75 -11
- package/scripts/state-dir.mjs +1 -0
- package/skills/context-governance/SKILL.md +85 -79
- package/mcp/index.js +0 -1332
- package/mcp/instructions.md +0 -33
- package/mcp_config.json +0 -8
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agy-context-saver",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "PreToolUse execution hook and transcript CLI (agy-context) for Google Antigravity, paired with RTK",
|
|
5
|
+
"main": "lib/transcript-core.mjs",
|
|
6
6
|
"bin": {
|
|
7
|
-
"agy-context
|
|
7
|
+
"agy-context": "bin/agy-context.mjs",
|
|
8
|
+
"agy-context-saver": "bin/agy-context.mjs"
|
|
8
9
|
},
|
|
9
10
|
"type": "module",
|
|
10
11
|
"scripts": {
|
|
11
|
-
"start": "node
|
|
12
|
+
"start": "node bin/agy-context.mjs --help",
|
|
12
13
|
"setup": "node scripts/install-register.mjs",
|
|
13
14
|
"uninstall": "node scripts/install-register.mjs --uninstall",
|
|
14
15
|
"status": "node scripts/install-register.mjs --status",
|
|
15
16
|
"preflight": "node scripts/release-preflight.mjs",
|
|
16
|
-
"test": "node tests/test-hook.mjs && node tests/test-
|
|
17
|
+
"test": "node tests/test-hook.mjs && node tests/test-transcript.mjs && node tests/test-rtk-integration.mjs && node tests/test-output-governance.mjs && node tests/test-e2e-probes.mjs && node tests/test-performance-probes.mjs && node tests/test-installed-verification.mjs && node tests/test-lifecycle-rollback.mjs && node tests/test-check-only-readonly.mjs && node tests/test-malformed-config-preservation.mjs && node tests/test-rtk-ledger-fresh-install.mjs"
|
|
17
18
|
},
|
|
18
19
|
"repository": {
|
|
19
20
|
"type": "git",
|
|
@@ -31,8 +32,8 @@
|
|
|
31
32
|
},
|
|
32
33
|
"keywords": [
|
|
33
34
|
"antigravity",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
35
|
+
"cli",
|
|
36
|
+
"rtk",
|
|
36
37
|
"gemini",
|
|
37
38
|
"context-window",
|
|
38
39
|
"lifecycle-hooks",
|
|
@@ -40,13 +41,13 @@
|
|
|
40
41
|
],
|
|
41
42
|
"files": [
|
|
42
43
|
"assets",
|
|
43
|
-
"
|
|
44
|
+
"bin/agy-context.mjs",
|
|
45
|
+
"lib",
|
|
44
46
|
"scripts",
|
|
45
47
|
"rules",
|
|
46
48
|
"skills",
|
|
47
49
|
"hooks.json",
|
|
48
50
|
"plugin.json",
|
|
49
|
-
"mcp_config.json",
|
|
50
51
|
"install.ps1",
|
|
51
52
|
"install.sh",
|
|
52
53
|
"README.md",
|
package/plugin.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agy-context-saver",
|
|
3
|
-
"displayName": "
|
|
4
|
-
"version": "
|
|
5
|
-
"description": "
|
|
3
|
+
"displayName": "Agy-Context-Saver",
|
|
4
|
+
"version": "2.0.1",
|
|
5
|
+
"description": "PreToolUse execution hook, background polling governor, and transcript CLI (agy-context) for Google Antigravity, paired with RTK.",
|
|
6
6
|
"logo": "assets/logo.svg",
|
|
7
7
|
"suggestedPrompts": [
|
|
8
|
-
"
|
|
9
|
-
"Search this conversation's transcript for earlier tool errors",
|
|
10
|
-
"Inspect recent conversation turns without raw JSON transcript
|
|
8
|
+
"Run agy-context transcript health to audit context health and token consumption for this session",
|
|
9
|
+
"Search this conversation's transcript for earlier tool errors using agy-context transcript query",
|
|
10
|
+
"Inspect recent conversation turns cleanly without raw JSON bloat using agy-context transcript read"
|
|
11
11
|
]
|
|
12
12
|
}
|
package/rules/AGENTS.md
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
# Antigravity Execution & Context Governance (Agy-Context-Saver + RTK)
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
- **RTK (
|
|
5
|
-
- **Agy-Context-Saver**:
|
|
3
|
+
## Architectural Boundary
|
|
4
|
+
- **RTK (`>= 1.1.0`)**: Rewrites shell commands via `rtk hook antigravity`, compresses command output, and provides workspace search and file listing (`rtk grep`, `rtk find`, `rtk ls`, `rtk read`, `rtk err`, `rtk summary`).
|
|
5
|
+
- **Agy-Context-Saver (`v2.0.0`)**: Governs background task polling and Reactive Wakeup, bounds `read_file` slices, protects `.system_generated/` and the state directory, and provides transcript inspection and access control via `agy-context transcript`.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## Layer 1: Background Tasks & Proportional Backoff
|
|
10
|
-
- **
|
|
11
|
-
- **Proportional
|
|
9
|
+
## Layer 1: Background Tasks & Proportional Backoff
|
|
10
|
+
- **No busy-polling**: Do not call `manage_task(Action='status')` in loops or schedule short timers to poll running background tasks. Background tasks resume the agent automatically via **Reactive Wakeup** (`<SYSTEM_MESSAGE>`).
|
|
11
|
+
- **Proportional backoff**: Diagnostic status checks follow an exponential cooldown curve:
|
|
12
12
|
$\text{Cooldown} = \min(600, \text{round}(30 \times 2.5^{\text{pollCount} - 1})) \quad [0\text{s} \to 30\text{s} \to 75\text{s} \to 188\text{s} \to 469\text{s} \to 600\text{s}]$
|
|
13
|
-
- Check #1 (
|
|
14
|
-
- Premature
|
|
15
|
-
-
|
|
16
|
-
- **Coordinated
|
|
17
|
-
- Schedule a
|
|
18
|
-
- Watchdog timers must satisfy `DurationSeconds >= Math.max(30, requiredBackoffSec)`.
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
- **Mandatory Pre-Yield Status Card**: When a command moves to the background, NEVER yield with a silent or generic one-liner. Output a structured Markdown card so the user is never left wondering if the IDE has stalled:
|
|
13
|
+
- Check #1 (immediate upon launch): permitted ($0\text{s}$).
|
|
14
|
+
- Premature checks inside an active backoff window are denied. 5 cumulative denials trip the `force_ask` circuit breaker.
|
|
15
|
+
- Once a backoff window elapses, one diagnostic check is permitted to inspect logs or issue `manage_task(Action='kill')`.
|
|
16
|
+
- **Coordinated watchdog timers (`schedule`)**: For background shell tasks (`run_command` builds, migrations, full test runs) expected to take $> 15\text{s}$:
|
|
17
|
+
- Schedule a watchdog timer: `schedule(DurationSeconds=45, Prompt="Check status of background task-X", TimerCondition="task-X")`.
|
|
18
|
+
- Watchdog timers must satisfy `DurationSeconds >= Math.max(30, requiredBackoffSec)`. Each task watchdog advances the backoff level ($30\text{s} \to 75\text{s} \to 188\text{s} \to 469\text{s} \to 600\text{s}$), so repeated $45\text{s}/60\text{s}$ timers are denied.
|
|
19
|
+
- **Swarm and subagent exemption (`swarm_wait` only)**: Never pair `swarm_wait` or subagent launches with a one-shot `schedule` timer. `swarm_wait` sleeps at zero token cost and wakes on board posts; one-shot `schedule` timers polling a swarm or subagent are denied.
|
|
20
|
+
- **Pre-yield status card**: When a command moves to the background, output a status card before ending your turn:
|
|
22
21
|
```markdown
|
|
23
22
|
### ⏳ Background Execution Started
|
|
24
23
|
- **Command**: `<cmd>`
|
|
@@ -26,74 +25,43 @@
|
|
|
26
25
|
- **Estimated Duration**: `~X minutes`
|
|
27
26
|
- **Watchdog Active**: Coordinated check scheduled in 45s via Reactive Wakeup.
|
|
28
27
|
```
|
|
29
|
-
- **
|
|
28
|
+
- **Immediate kill and stdin**: `manage_task(Action='kill')` and `manage_task(Action='send_input')` are always allowed immediately ($0\text{s}$ cooldown, zero penalties).
|
|
30
29
|
|
|
31
30
|
---
|
|
32
31
|
|
|
33
|
-
## Layer 2:
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
1. **Tier 1
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
- **
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
32
|
+
## Layer 2: Shell Execution, Workspace Inspection & Transcript Governance
|
|
33
|
+
- **Shell commands**: Run commands via `run_command`. The `PreToolUse` hook delegates command rewriting to `rtk hook antigravity` (`git`, `pytest`, `cargo`, `npm`, etc.).
|
|
34
|
+
- **Workspace file and codebase inspection**: Unbounded full-file reads are blocked on workspace files. Follow this 3-tier workflow:
|
|
35
|
+
1. **Tier 1 (Search and discovery: `rtk grep`, `rtk find`, `rtk ls`)**:
|
|
36
|
+
- **Pattern and symbol search**: Run `rtk grep -rnE "<pattern>" <path>` via `run_command` to locate `[StartLine, EndLine]` line numbers. Always pass an explicit path (such as `.` or `src/`) so `rtk grep` does not wait on stdin.
|
|
37
|
+
- **Directory and file listing**: Run `rtk find <path>`, `rtk ls <path>`, or `rtk tree` (or PowerShell `dir` / `Get-ChildItem` on Windows).
|
|
38
|
+
2. **Tier 2 (Workspace file reading: `read_file` slice policy)**:
|
|
39
|
+
- Pass `StartLine` and `EndLine` to `read_file` in bounded slices of `1-150` lines to preserve 1-indexed line numbers for `edit_file` and `write_file`.
|
|
40
|
+
- Partial slices of `151-800` lines and `ByteOffset`-only unbounded reads are denied. A single-pass full-file read (`StartLine: 1, EndLine: <TotalLines>`) is permitted when the file on disk is $\le 800$ lines and $\le 45\text{ KiB}$ (`46,080` bytes).
|
|
41
|
+
3. **Tier 3 (Spillovers and diagnostics: `rtk read`, `rtk err`, `rtk summary`)**:
|
|
42
|
+
- **Spillovers and task logs**: Read `.system_generated/steps/<step>/output.txt` spillovers via bounded `read_file` ($\le 150$ lines) or `rtk read --tail-lines 150 <path>` / `--head-lines 150 <path>`, and completed `tasks/<taskId>.log` files via `rtk read <path>`. Do not use `rtk read -l minimal|aggressive` or `-m` to derive line numbers for `edit_file` or `write_file`.
|
|
43
|
+
- **Command diagnostics**: Use `rtk err <cmd>` (errors and warnings only) and `rtk summary <cmd>` (2-line summary).
|
|
44
|
+
- **Safe harbor files**: Antigravity special files (`SKILL.md`, `AGENTS.md`, brain artifacts, `.gemini/config/` files) are allowed via `read_file` without slice bounds.
|
|
45
|
+
- **Transcript forensics (`agy-context transcript`)**: Direct file or shell access to `.system_generated/` transcripts, task logs, progress files, or `getStateDir()` (`~/.local/state/agy-context-saver`) is blocked. Run `agy-context transcript` as a single unchained `run_command` (no `&&`, `||`, `;`, `|`, redirects, or `..` traversal; prefer batch step ranges `step <N,M|N-M>` and `query --start N --end M` over single-step loops):
|
|
46
|
+
- `agy-context transcript read [<id>] [--id <uuid>] [--mode compact|full] [--last-turns N] [--offset N] [--limit N] [--outline] [--include-thinking] [--json]` (aliases: `outline`, `summary`)
|
|
47
|
+
- `agy-context transcript query [<pattern>] [<id>] [--id <uuid>] [--query <regex>] [--roles csv] [--mode auto|compact|full] [--start N] [--end N] [--last-turns N] [--limit N] [--summary] [--include-tools] [--full-args] [--field content|thinking|tool_calls|tool_args|tool_args:Key|all] [--include-thinking] [--json]` (aliases: `grep`, `search`, `find`, `tools`)
|
|
48
|
+
- `agy-context transcript step [<N|N,M|N-M|N..M>] [<id>] [--id <uuid>] (--step <N|N,M|N-M|N..M> | --start N --end M) [--field content|thinking|tool_calls|tool_args|tool_args:Key|all] [--head N] [--tail N] [--full] [--json]`
|
|
49
|
+
- `agy-context transcript health [<id>] [--id <uuid>] [--json]` (aliases: `stats`, `info`)
|
|
50
|
+
- `agy-context transcript list [--limit N] [--json]` (alias: `ls`)
|
|
51
|
+
- `agy-context transcript access [status|off|on|reset|self-only] [--status | --off (--deny-children) | --on (--reset) | --self-only | --mode <open|allowlist|self-only|deny> | --allow <id,@roster*...> | --deny <id,@roster*...> | --ttl <sec>] [--json]` (alias: `policy`)
|
|
52
|
+
- **Parent transcript access control**:
|
|
53
|
+
- **CLI policy**: Parents can restrict or scope child transcript access mid-session via `agy-context transcript access` (`policy`), using `--off` (`--deny-children`), `--self-only`, `--mode <open|allowlist|self-only|deny>`, `--allow <id,@roster*...>`, `--deny <id,@roster*...>`, `--ttl <sec>`, and `--on` (`--reset`).
|
|
54
|
+
- **First-line launch directives**: Place `[agy-transcript-access: deny]`, `[agy-transcript-access: self-only]`, or `[agy-transcript-access: allow]` on the first non-empty line of a `define_subagent` `SystemPrompt`, `invoke_subagent` `Prompt`, or `/swarm` worker `brief` (later lines and code blocks are ignored).
|
|
55
|
+
- **Precedence**: `1. Policy Owner` -> `2. Explicit CLI --deny` -> `3. Explicit CLI --allow` (supports `@roster*` prefix globs such as `@audit-squad*`) -> `4. First-Line Launch Directive` -> `5. Cohort Default Mode`.
|
|
56
|
+
- **When restricted**: If transcript access is denied for a child agent, do not retry `agy-context transcript` or probe `.system_generated` / `getStateDir()`; 5 blocked attempts trigger the `force_ask` circuit breaker.
|
|
57
|
+
- **Git line-ending warnings**: Suppress non-actionable Git CRLF/LF notices during repo operations (`git -c core.safecrlf=false`).
|
|
50
58
|
|
|
51
59
|
---
|
|
52
60
|
|
|
53
61
|
## Layer 3: Synchronous Execution
|
|
54
|
-
- **
|
|
55
|
-
- **Targeted
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
- **Benchmark
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Appendix: Zero-Guesswork Testing & Verification Playbook
|
|
64
|
-
When an agent or developer tests this framework, follow this exact sequence without guessing:
|
|
65
|
-
|
|
66
|
-
1. **Verify Live Registration & Health (Fast, non-blocking)**:
|
|
67
|
-
```bash
|
|
68
|
-
npm run status
|
|
69
|
-
# or
|
|
70
|
-
node mcp/index.js status
|
|
71
|
-
```
|
|
72
|
-
*Expected*: Reports `HEALTHY & ACTIVE 🛡️` across plugin link, hook, MCP config, schemas, and RTK.
|
|
73
|
-
|
|
74
|
-
2. **Execute Full Automated Test Suite**:
|
|
75
|
-
```bash
|
|
76
|
-
npm test
|
|
77
|
-
```
|
|
78
|
-
*Expected*: All 10 test suites pass (hook unit tests, MCP protocol tests, output governance, E2E probes, performance probes, live system validation, lifecycle rollback, check-only read-only safety, malformed config preservation, RTK ledger fresh install).
|
|
79
|
-
|
|
80
|
-
3. **Verify Individual Layers On-Demand**:
|
|
81
|
-
- Governance Hook: `node tests/test-hook.mjs`
|
|
82
|
-
- MCP Protocol & JSON-RPC: `node tests/test-mcp.mjs`
|
|
83
|
-
- Output Governance: `node tests/test-output-governance.mjs`
|
|
84
|
-
- E2E Probes: `node tests/test-e2e-probes.mjs`
|
|
85
|
-
- Performance Probes: `node tests/test-performance-probes.mjs`
|
|
86
|
-
- Live System Checks: `node tests/test-installed-verification.mjs`
|
|
87
|
-
- Lifecycle & Rollback: `node tests/test-lifecycle-rollback.mjs`
|
|
88
|
-
|
|
89
|
-
4. **Verify MCP Tools in Antigravity**:
|
|
90
|
-
- `get_installation_status`: Inspect live integration layers.
|
|
91
|
-
- `check_context_health`: Pass `{ "transcriptPath": "<path-to-transcript.jsonl>" }`.
|
|
92
|
-
- `read_transcript`: Pass `{ "conversationId": "<uuid>", "lastTurns": 3, "mode": "compact" }`.
|
|
93
|
-
- `query_transcript`: Pass `{ "conversationId": "<uuid>", "query": "<pattern>", "summaryOnly": true }`.
|
|
94
|
-
|
|
95
|
-
5. **Operational Anti-Patterns (What NOT to do)**:
|
|
96
|
-
- ❌ **Do NOT run `npm start` or `node mcp/index.js` interactively**: It starts the stdio JSON-RPC daemon and waits indefinitely on stdin.
|
|
97
|
-
- ❌ **Do NOT run `manage_task(Action='status')` loops**: Status polling is governed; 5 polls trigger the `force_ask` circuit breaker.
|
|
98
|
-
- ❌ **Do NOT run `npm run uninstall` as an isolated test**: It strips the live hook from `~/.gemini/config/`. If run, immediately re-run `npm run setup`.
|
|
99
|
-
- ❌ **Do NOT omit explicit target paths with `rtk rg`**: Always provide a path (e.g. `rtk rg "pattern" .`) to prevent stdin blocking.
|
|
62
|
+
- **Default 10s synchronous window**: Non-daemon `run_command` calls default to `WaitMsBeforeAsync: 10000` when omitted so short commands complete in-turn (explicit caller values are preserved).
|
|
63
|
+
- **Targeted test execution**:
|
|
64
|
+
- In interactive turns, target specific test files or directories rather than running multi-minute full-repo suites.
|
|
65
|
+
- Use fail-fast flags (`-x`, `--maxfail=1`) when debugging a localized failure; omit them when checking full blast radius.
|
|
66
|
+
- Pair multi-minute test sweeps with a `schedule(DurationSeconds=45, ...)` watchdog timer and a Pre-Yield Status Card.
|
|
67
|
+
- **Benchmark integrity**: Never modify benchmark definitions, prompt templates, or scoring files (`edit_file`, `write_file`, or shell writes) during an evaluation without user confirmation.
|