agy-context-saver 1.8.0 → 1.8.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 +16 -0
- package/README.md +17 -14
- package/mcp/index.js +25 -19
- package/mcp/instructions.md +8 -5
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/rules/AGENTS.md +14 -13
- package/scripts/execution-guard-hook.mjs +76 -11
- package/scripts/install-register.mjs +4 -34
- package/skills/context-governance/SKILL.md +17 -13
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to `Agy-Context-Saver` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.8.1] - 2026-10-16
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Hybrid `view_file` Slice Governance (`scripts/execution-guard-hook.mjs`)**: Retains the 150-line default slice ceiling (`1–150` lines allowed; partial slices of `151–800` lines denied) while adding a guarded full-file audit exception: explicit `StartLine: 1, EndLine: <TotalFileLines>` reads are permitted when the file on disk is $\le 800$ lines and $\le 45\text{ KiB}$ (`46,080` bytes). `.system_generated/` protections continue to take unconditional precedence.
|
|
12
|
+
- **Waymark-First Denial Routing**: When `waymark-engine` is installed, `view_file` hook denials now recommend `waymark_ask(..., plain: true)` across all 23 supported formats followed by a bounded `view_file(StartLine, EndLine)` slice, falling back to `rtk read` when Waymark is unavailable.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Single-Source-of-Truth MCP Instructions (`scripts/install-register.mjs`)**: Replaced the hardcoded pre-v1.7 `instructions.md` template in `install-register.mjs` with a direct read of `mcp/instructions.md`, eliminating the split-brain discrepancy between repository docs and `~/.gemini/antigravity/mcp/agy-context-saver/instructions.md`.
|
|
16
|
+
- **Unified 3-Tier Inspection Documentation**: Reconciled `README.md`, `mcp/instructions.md`, `rules/AGENTS.md`, `skills/context-governance/SKILL.md`, `mcp/index.js`, and `docs/*.md` around the 3-tier hierarchy (`waymark_ask(..., plain: true)` $\to$ hybrid `view_file` $\to$ `rtk` for spillovers, task logs, and directory/prose search) and standardized references to all 10 automated test files.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **Inline `read_transcript` Payload Cap (`mcp/index.js`)**: Bounded `compact` mode transcript output to `3,800` characters (`< 4 KB`) and clamped intermediate non-dialogue step bodies so `read_transcript(mode: "compact")` never triggers an Antigravity host spillover file.
|
|
20
|
+
- **Complete `query_transcript` Role Schema**: Documented `'subagent'` in the `roles` filter description across `mcp/index.js`, `scripts/install-register.mjs`, `skills/context-governance/SKILL.md`, and `docs/tools.md`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
8
24
|
## [1.8.0] - 2026-10-15
|
|
9
25
|
|
|
10
26
|
### Removed
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ It permanently eliminates session degradation, memory bloat, and context window
|
|
|
18
18
|
| Metric / Capability | Without Governor | With Agy-Context-Saver + RTK |
|
|
19
19
|
| :--- | :--- | :--- |
|
|
20
20
|
| **Command Output Bloat** | Unlimited raw test dots, ANSI dumps | RTK transparent reduction (60–90% token savings) |
|
|
21
|
-
| **Workspace File Inspection** | Massive uncompressed view_file dumps |
|
|
21
|
+
| **Workspace File Inspection** | Massive uncompressed `view_file` dumps | `waymark_ask(..., plain: true)` $\to$ bounded `view_file` slices ($\le 150$ lines) + `rtk find` / `rtk rg` |
|
|
22
22
|
| **Long Command Execution** | Detached after 5s $\to$ busy-wait loop | Synchronous window expanded to 10s $\to$ finishes in-turn |
|
|
23
23
|
| **Background Task Monitoring** | Repetitive busy-polling loops | Enforced Reactive Wakeup with 5-strike circuit breaker |
|
|
24
24
|
| **Configuration Safety** | Risk of third-party config clobber | Non-destructive preservation of foreign hooks/MCP with `.bak` backups |
|
|
@@ -30,7 +30,7 @@ It permanently eliminates session degradation, memory bloat, and context window
|
|
|
30
30
|
## Canonical 3-Layer Governance Architecture
|
|
31
31
|
|
|
32
32
|
1. **Layer 1: Reactive Lifecycle & Polling Immunity**: Replaces destructive busy-polling loops with native Antigravity **Reactive Wakeup**, governed by an exponential Proportional Backoff curve and a 5-strike circuit breaker.
|
|
33
|
-
2. **Layer 2: Transparent CLI & Codebase Streamlining**: Intercepts shell execution via PreToolUse hooks, transparently rewriting commands to RTK (`rtk git`, `rtk pytest`),
|
|
33
|
+
2. **Layer 2: Transparent CLI & Codebase Streamlining**: Intercepts shell execution via PreToolUse hooks, transparently rewriting commands to RTK (`rtk git`, `rtk pytest`), enforcing bounded `view_file` slices paired with `waymark_ask(..., plain: true)`, routing spillovers/task logs to `rtk read` and directory/prose searches to `rtk find`/`rg`, and shielding internal `.system_generated` state.
|
|
34
34
|
3. **Layer 3: Synchronous Execution**: Expands synchronous execution windows to 10s so routine commands finish in-turn instead of detaching.
|
|
35
35
|
|
|
36
36
|
> **Subagent tools moved.** `subagent_brief` and squad dispatch now live in the separate [Agy-Squad](https://github.com/paragon-ux/agy-squad) package (under construction). Agy-Context-Saver is complete without them, and the two will install side by side.
|
|
@@ -107,24 +107,27 @@ npm run status
|
|
|
107
107
|
1. **The Polling Trap**: When shell tasks detach to background jobs (`task-XYZ`), agents waste tokens repeatedly polling `manage_task(Action='status')` or scheduling artificial timers. Agy enforces native **Reactive Wakeup** (`<SYSTEM_MESSAGE>`).
|
|
108
108
|
2. **The Terminal Bloat Trap**: Routine test runs and git operations dump hundreds of lines of noise into context. RTK compresses these outputs natively before they enter model context.
|
|
109
109
|
3. **The Raw Transcript Trap**: Reading `transcript.jsonl` dumps megabytes of raw JSON into context. Agy blocks direct reads of `.system_generated` and provides high-density Markdown streaming tools.
|
|
110
|
-
4. **Native Inspection Bypass**:
|
|
110
|
+
4. **Native Inspection Bypass**: Unbounded native inspection tools (`view_file` without slices, `grep_search`, `find_by_name`, `list_dir`) bypass token reduction. Agy enforces bounded `view_file` slices (`StartLine` / `EndLine <= 150`, paired with `waymark_ask(..., plain: true)`) and routes directory/prose search and spillover reads to RTK's canonical CLI (`rtk find`, `rtk rg`, `rtk grep`, `rtk read`).
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
114
114
|
## Key Capabilities
|
|
115
115
|
|
|
116
116
|
- **Transparent RTK Rewriting**: Native `run_command` calls are automatically rewritten (e.g. `pytest` $\to$ `rtk pytest`) via Antigravity PreToolUse hooks.
|
|
117
|
-
- **
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
- **Unified 3-Tier Codebase & File Inspection**:
|
|
118
|
+
1. **Tier 1 — Structural Discovery (`waymark_ask(..., plain: true)`)**: Locate exact `[StartLine, EndLine]` coordinates across all 23 supported formats (code ASTs + `markdown`, `yaml`, `json`, `toml`, `bash`) in ~19–466 tokens.
|
|
119
|
+
2. **Tier 2 — Precision Workspace Reading (`view_file` Hybrid Slice Policy)**: Pass `StartLine` and `EndLine` (`1–150` lines default; or explicit `StartLine: 1, EndLine: <TotalLines>` full-file audit when $\le 800$ lines and $\le 45\text{ KiB}$) into `view_file` to preserve 1-indexed line numbers for `replace_file_content` without terminal stdout truncation.
|
|
120
|
+
3. **Tier 3 — RTK CLI Boundaries**:
|
|
121
|
+
- `rtk read <path>`: Inspect runtime step spillovers (`.system_generated/steps/<step>/output.txt`) and completed background task logs (`tasks/<taskId>.log`) with `--head-lines` / `--tail-lines`.
|
|
122
|
+
- `rtk find <path>`: Compact file search tree and directory listing (cross-platform, works on Windows & POSIX).
|
|
123
|
+
- Prose / Regex Search (when symbol, heading, or config key is unknown):
|
|
124
|
+
- **Windows**: `rtk rg "<pattern>" .` (explicit target `.` prevents child process stdin stalls) or `rg "<pattern>" .`.
|
|
125
|
+
- **POSIX / Linux / macOS**: `rtk grep "<pattern>"` or `rtk rg "<pattern>"`.
|
|
126
|
+
- Directory listing by platform:
|
|
127
|
+
- **Windows**: `rtk find <path>` or PowerShell `dir` / `Get-ChildItem`. (Avoid `rtk ls` / `rtk tree` on Windows as they rely on POSIX binaries/flags).
|
|
128
|
+
- **POSIX / Linux / macOS**: `rtk ls <path>` or `rtk tree`.
|
|
129
|
+
- `rtk err <cmd>`: Run command and show only errors/warnings.
|
|
130
|
+
- `rtk summary <cmd>`: Run command and produce a 2-line heuristic summary.
|
|
128
131
|
- **Antigravity Special Files Safe Harbor**: Direct `view_file` access to `SKILL.md`, brain artifacts, and config files is preserved.
|
|
129
132
|
- **Protected Internal State**: Root-based guard prevents reading `.system_generated/` (transcripts, task logs, progress).
|
|
130
133
|
- **Session-Wide Lifecycle Ledger**: Polling checks are tracked globally per session; changing task IDs or waiting does not reset governance.
|
package/mcp/index.js
CHANGED
|
@@ -80,7 +80,7 @@ if (isEntryPoint) {
|
|
|
80
80
|
|
|
81
81
|
function printHelp() {
|
|
82
82
|
console.log(`
|
|
83
|
-
Agy-Context-Saver 🛡️ (v1.8.
|
|
83
|
+
Agy-Context-Saver 🛡️ (v1.8.1)
|
|
84
84
|
Universal MCP Server & Lifecycle Governor for Google Antigravity (Powered by RTK)
|
|
85
85
|
|
|
86
86
|
Usage:
|
|
@@ -107,19 +107,17 @@ MCP Server Stdio Mode:
|
|
|
107
107
|
|
|
108
108
|
Testing & Verification Playbook:
|
|
109
109
|
npm run status Verify live 4-layer integration status
|
|
110
|
-
npm test Run complete
|
|
111
|
-
node tests/test-hook.mjs Run
|
|
110
|
+
npm test Run complete 10-suite automated test suite
|
|
111
|
+
node tests/test-hook.mjs Run 27 closed-topology governance rule tests
|
|
112
112
|
node tests/test-mcp.mjs Run MCP protocol, method, and schema tests
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
- Search:
|
|
121
|
-
- Read: rtk read <file>
|
|
122
|
-
- Directory: rtk ls <path> or rtk tree
|
|
114
|
+
Unified 3-Tier Inspection Directives (Waymark + Hybrid view_file + RTK):
|
|
115
|
+
Tier 1 (Structure): waymark_ask(..., plain: true) across all 23 supported formats
|
|
116
|
+
Tier 2 (Read/Edit): view_file(StartLine, EndLine) (1-150L default; or explicit 1..TotalLines full-file audit <= 800L & <= 45 KiB)
|
|
117
|
+
Tier 3 (RTK CLI):
|
|
118
|
+
- Spillovers/Logs: rtk read <path> (--head-lines / --tail-lines)
|
|
119
|
+
- Directory: rtk find <path> (Windows & POSIX) or rtk ls <path> (POSIX)
|
|
120
|
+
- Prose Search: rtk rg "<pattern>" . (Windows trailing dot required) or rtk grep "<pattern>" (POSIX)
|
|
123
121
|
`);
|
|
124
122
|
}
|
|
125
123
|
|
|
@@ -127,7 +125,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
127
125
|
const rulesPath = path.resolve(__dirname, "../rules/AGENTS.md");
|
|
128
126
|
|
|
129
127
|
const SERVER_NAME = "agy-context-saver";
|
|
130
|
-
const SERVER_VERSION = "1.8.
|
|
128
|
+
const SERVER_VERSION = "1.8.1";
|
|
131
129
|
|
|
132
130
|
// --- Tools Specification ---
|
|
133
131
|
const TOOLS = [
|
|
@@ -200,7 +198,7 @@ const TOOLS = [
|
|
|
200
198
|
},
|
|
201
199
|
{
|
|
202
200
|
name: "query_transcript",
|
|
203
|
-
description: "Granular query and forensic filtering engine for Antigravity conversation transcripts. Searches by keyword or regex, filters by role (user, assistant, tool, error), slices step ranges, and automatically dereferences full content when truncated.",
|
|
201
|
+
description: "Granular query and forensic filtering engine for Antigravity conversation transcripts. Searches by keyword or regex, filters by role (user, assistant, subagent, tool, error), slices step ranges, and automatically dereferences full content when truncated.",
|
|
204
202
|
inputSchema: {
|
|
205
203
|
type: "object",
|
|
206
204
|
properties: {
|
|
@@ -215,7 +213,7 @@ const TOOLS = [
|
|
|
215
213
|
roles: {
|
|
216
214
|
type: "array",
|
|
217
215
|
items: { type: "string" },
|
|
218
|
-
description: "Filter steps by role/source: 'user', 'assistant', 'tool', 'error', or 'all' (default: ['user', 'assistant'])."
|
|
216
|
+
description: "Filter steps by role/source: 'user', 'assistant', 'subagent', 'tool', 'error', or 'all' (default: ['user', 'assistant'])."
|
|
219
217
|
},
|
|
220
218
|
mode: {
|
|
221
219
|
type: "string",
|
|
@@ -811,13 +809,20 @@ async function handleReadTranscript({ conversationId, mode = "compact", lastTurn
|
|
|
811
809
|
const formattedBlocks = [];
|
|
812
810
|
let currentLength = header.length;
|
|
813
811
|
let clamped = false;
|
|
812
|
+
const maxWindowChars = mode === "compact" ? 3800 : MAX_OUTPUT_CHARS;
|
|
814
813
|
|
|
815
814
|
for (let i = selected.length - 1; i >= 0; i--) {
|
|
816
|
-
const
|
|
815
|
+
const item = selected[i];
|
|
816
|
+
const isDialogueTurn =
|
|
817
|
+
item.type === "USER_INPUT" ||
|
|
818
|
+
item.type === "PLANNER_RESPONSE" ||
|
|
819
|
+
item.type === "SUBAGENT_RESPONSE";
|
|
820
|
+
const block = formatTranscriptItem(item, {
|
|
817
821
|
includeThinking,
|
|
818
|
-
includeToolCalls: true
|
|
822
|
+
includeToolCalls: true,
|
|
823
|
+
maxContentChars: mode === "compact" && !isDialogueTurn ? 300 : MAX_TURN_CHARS
|
|
819
824
|
});
|
|
820
|
-
if (currentLength + block.length + 6 >
|
|
825
|
+
if (currentLength + block.length + 6 > maxWindowChars && formattedBlocks.length > 0) {
|
|
821
826
|
clamped = true;
|
|
822
827
|
break;
|
|
823
828
|
}
|
|
@@ -827,7 +832,8 @@ async function handleReadTranscript({ conversationId, mode = "compact", lastTurn
|
|
|
827
832
|
|
|
828
833
|
let fullOutput = header + formattedBlocks.join("\n\n---\n\n");
|
|
829
834
|
if (clamped) {
|
|
830
|
-
|
|
835
|
+
const ceilingLabel = mode === "compact" ? "3.8 KB inline" : "24 KB";
|
|
836
|
+
fullOutput += `\n\n... [Transcript display clamped at ${ceilingLabel} safety ceiling; use query_transcript(stepIndex: N) for specific steps] ...`;
|
|
831
837
|
}
|
|
832
838
|
|
|
833
839
|
return { content: [{ type: "text", text: fullOutput }] };
|
package/mcp/instructions.md
CHANGED
|
@@ -11,15 +11,18 @@ Agy-Context-Saver is the universal Model Context Protocol server and lifecycle g
|
|
|
11
11
|
2. **Never Read Internal State Directly**:
|
|
12
12
|
- Access to `.system_generated/` via `view_file` is strictly denied to prevent transcript explosion.
|
|
13
13
|
- Use `read_transcript` or `query_transcript` to inspect conversation history cleanly.
|
|
14
|
-
3. **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
14
|
+
3. **Unified 3-Tier Codebase & File Inspection**:
|
|
15
|
+
- **Tier 1 — Structural Discovery (`waymark_ask` with `plain: true`)**: First locate exact `[StartLine, EndLine]` coordinates via `waymark_ask(..., plain: true)` across all 23 supported formats (code ASTs + `markdown`, `yaml`, `json`, `toml`, `bash`). Always set `plain: true` (~19–466 tokens, zero shell quoting or stdin hazards).
|
|
16
|
+
- **Tier 2 — Precision Workspace File Reading (`view_file` Hybrid Slice Policy)**: Pass the `StartLine` and `EndLine` span from `waymark_ask` into `view_file` (bounded slices of `1–150` lines) to preserve 1-indexed line coordinates for `replace_file_content` and avoid terminal stdout truncation. Partial slices of `151–800` lines are denied; an explicit one-pass full-file audit (`StartLine: 1, EndLine: <TotalLines>`) is permitted only when the file on disk is $\le 800$ lines and $\le 45\text{ KiB}$ (`46,080` bytes).
|
|
17
|
+
- **Tier 3 — RTK Boundaries (`rtk read`, `rtk find`, `rtk rg`)**:
|
|
18
|
+
- **Spillovers & Task Logs**: Read `.system_generated/steps/<step>/output.txt` spillovers and completed `tasks/<taskId>.log` files via `rtk read <path>` (with `--head-lines` / `--tail-lines`). Never use `rtk read -l minimal|aggressive` or `-m` to derive line numbers for edits.
|
|
19
|
+
- **Directory/File Discovery**: Use `rtk find <path>` (Windows & POSIX) or `rtk ls <path>` (POSIX).
|
|
20
|
+
- **Prose / Regex Search**: Use `rtk rg "<pattern>" <path>` (explicit `<path>` required on Windows to avoid stdin stalls) strictly for free-text/regex searches inside body prose or string values when the symbol, heading, or config key name is unknown.
|
|
18
21
|
|
|
19
22
|
## Available MCP Tools
|
|
20
23
|
- `check_context_health`: Diagnoses transcript turn counts, byte payload, and polling loops. Accepts `transcriptPath` or `conversationId`.
|
|
21
24
|
- `read_transcript`: Streams recent turns from `transcript.jsonl` or `transcript_full.jsonl` formatted as clean Markdown.
|
|
22
|
-
- `query_transcript`: Forensic regex search and filtering engine across transcript steps with optional `summaryOnly: true`.
|
|
25
|
+
- `query_transcript`: Forensic regex search and filtering engine across transcript steps with optional `summaryOnly: true`, plus surgical step extraction via `stepIndex` and `field`.
|
|
23
26
|
- `get_installation_status`: Audits live health of the plugin link, hook, MCP server, tool schemas, and RTK.
|
|
24
27
|
- `sync_installation`: Synchronizes and repairs all 4 integration layers in ~25ms.
|
|
25
28
|
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agy-context-saver",
|
|
3
3
|
"displayName": "Antigravity Context Shield & Governor",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.1",
|
|
5
5
|
"description": "Deterministic background polling governor, RTK terminal optimizer, and transcript context shield for Antigravity.",
|
|
6
6
|
"logo": "assets/logo.svg",
|
|
7
7
|
"suggestedPrompts": [
|
package/rules/AGENTS.md
CHANGED
|
@@ -30,22 +30,23 @@
|
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
## Layer 2: Transparent Shell Execution & Codebase Inspection
|
|
33
|
+
## Layer 2: Transparent Shell Execution & Unified 3-Tier Codebase Inspection
|
|
34
34
|
- **Native Shell Commands**: Run shell commands normally using `run_command`. The PreToolUse hook transparently rewrites supported commands via RTK (`git`, `pytest`, `cargo`, `npm`, etc.) to produce ultra-compact outputs.
|
|
35
|
-
- **Canonical Codebase Inspection**: Unbounded full-file reads and unoptimized search tools (`grep_search`, `find_by_name`, `list_dir`) are blocked for workspace files.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
- **Canonical 3-Tier Codebase & File Inspection**: Unbounded full-file reads and unoptimized search tools (`grep_search`, `find_by_name`, `list_dir`) are blocked for workspace files. Follow the 3-tier hierarchy:
|
|
36
|
+
1. **Tier 1 — Structural Discovery (`waymark_ask` with `plain: true`)**: Locate exact `[StartLine, EndLine]` coordinates via `waymark_ask(..., plain: true)` across all 23 supported formats (code ASTs + `markdown`, `yaml`, `json`, `toml`, `bash`). Always pass `plain: true` (~19–466 tokens, zero shell quoting or stdin hazards).
|
|
37
|
+
2. **Tier 2 — Precision Workspace File Reading (`view_file` Hybrid Slice Policy)**: Pass the exact `StartLine` and `EndLine` from `waymark_ask` into `view_file` (bounded slices of `1–150` lines) to preserve 1-indexed line numbers for `replace_file_content` and avoid terminal stdout truncation. Partial slices of `151–800` lines are denied; an explicit one-pass full-file audit (`StartLine: 1, EndLine: <TotalLines>`) is permitted only when the file on disk is $\le 800$ lines and $\le 45\text{ KiB}$ (`46,080` bytes).
|
|
38
|
+
3. **Tier 3 — RTK Boundaries (`rtk read`, `rtk find`, `rtk rg`, `rtk err`, `rtk summary`)**:
|
|
39
|
+
- **Spillovers & Task Logs**: Read `.system_generated/steps/<step>/output.txt` spillovers and completed `tasks/<taskId>.log` files via `rtk read <path>` (with `--head-lines` / `--tail-lines`). Never use `rtk read -l minimal|aggressive` or `-m` to derive line numbers for edits.
|
|
40
|
+
- **Directory / File Discovery**:
|
|
41
|
+
- **Windows**: Use `rtk find <path>` or PowerShell `dir` / `Get-ChildItem`. (Avoid `rtk ls` or `rtk tree` on Windows as they rely on POSIX binaries/flags).
|
|
42
|
+
- **POSIX / Linux / macOS**: Use `rtk find <path>`, `rtk ls <path>`, or `rtk tree`.
|
|
43
|
+
- **Prose / Regex Search (when symbol, heading, or config key is unknown)**:
|
|
44
|
+
- **Windows**: Use `rtk rg "<pattern>" .` (explicit target `.` is required to prevent stdin pipe hanging) or `rg "<pattern>" .`.
|
|
45
|
+
- **POSIX / Linux / macOS**: Use `rtk grep "<pattern>"` or `rtk rg "<pattern>"`.
|
|
46
|
+
- **Command Diagnostics**: `rtk err <cmd>` (errors/warnings only) and `rtk summary <cmd>` (2-line heuristic summary).
|
|
46
47
|
- **Antigravity Special Files Safe Harbor**: Documented Antigravity special files (`SKILL.md`, brain artifacts, `.gemini/config/` configs) are permitted via `view_file` without slice bounds.
|
|
47
48
|
- **Protected Internal State**: Direct native inspection of `.system_generated/` (transcripts, task logs, progress files) is strictly forbidden. Use Agy MCP tools `read_transcript` and `query_transcript`.
|
|
48
|
-
- **Git CRLF/LF Warning Hygiene**: Git's line-ending conversion notices (`warning: LF will be replaced by CRLF the next time Git touches it` / `warning: CRLF will be replaced by LF...`) are non-actionable diagnostic noise. Suppress them during repo operations (via `git -c core.safecrlf=false` or `git config --global core.safecrlf false`) and do not propagate them into
|
|
49
|
+
- **Git CRLF/LF Warning Hygiene**: Git's line-ending conversion notices (`warning: LF will be replaced by CRLF the next time Git touches it` / `warning: CRLF will be replaced by LF...`) are non-actionable diagnostic noise. Suppress them during repo operations (via `git -c core.safecrlf=false` or `git config --global core.safecrlf false`) and do not propagate them into task outputs or conversation context.
|
|
49
50
|
|
|
50
51
|
---
|
|
51
52
|
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
* - Intercepts native run_command and calls `rtk rewrite <cmd>`.
|
|
10
10
|
* - Non-daemon commands maintain WaitMsBeforeAsync=10000 for synchronous completion.
|
|
11
11
|
* 2. Hard-Routed Native File/Search Inspection (LH-07):
|
|
12
|
-
* - view_file
|
|
13
|
-
* -
|
|
12
|
+
* - view_file -> Allow bounded slices (<= 150 lines, paired with waymark_ask); deny unbounded dumps.
|
|
13
|
+
* - read_file, read_many_files -> Deny and route to bounded view_file or `rtk read <file>`.
|
|
14
|
+
* - grep_search -> Deny and route to `rtk rg "<pattern>" .` / `rtk grep <pattern>`.
|
|
14
15
|
* - find_by_name -> Deny and route to `rtk find <path>`.
|
|
15
|
-
* - list_dir -> Deny and route to `rtk
|
|
16
|
+
* - list_dir -> Deny and route to `rtk find` (Win) or `rtk ls` / `rtk tree` (POSIX).
|
|
16
17
|
* - Safe Harbor: Documented Antigravity special files (SKILL.md, brain artifacts, configs) are allowed.
|
|
17
18
|
* 3. Root-Based Antigravity Internal State Protection (LH-02):
|
|
18
19
|
* - Hard denial for any inspection of `.system_generated/` (transcripts, task logs, progress).
|
|
@@ -789,9 +790,56 @@ try {
|
|
|
789
790
|
respond({ decision: "allow" });
|
|
790
791
|
}
|
|
791
792
|
|
|
792
|
-
// 2e.
|
|
793
|
-
//
|
|
793
|
+
// 2e. Hybrid Slice & Guarded Full-File Policy for view_file
|
|
794
|
+
// - 1..150 line slice -> ALLOW
|
|
795
|
+
// - Explicit full-file read (StartLine=1, EndLine=actualFileLines) of an existing file <= 800 lines AND <= 45 KiB -> ALLOW
|
|
796
|
+
// - Partial slice of 151..800+ lines -> DENY (discover target with waymark_ask and narrow the slice)
|
|
797
|
+
// - Explicit full-file read exceeding 800 lines or 45 KiB -> DENY
|
|
798
|
+
// - Unbounded view_file (missing StartLine/EndLine) -> DENY
|
|
794
799
|
if (toolName === "view_file") {
|
|
800
|
+
const MAX_SAFE_SLICE_LINES = 150;
|
|
801
|
+
const MAX_FULL_FILE_LINES = 800;
|
|
802
|
+
const MAX_FULL_FILE_BYTES = 45 * 1024; // 45 KiB (46,080 bytes)
|
|
803
|
+
|
|
804
|
+
const waymarkAvailable = (() => {
|
|
805
|
+
if (process.env.AGY_FORCE_WAYMARK === "0") return false;
|
|
806
|
+
if (process.env.AGY_FORCE_WAYMARK === "1") return true;
|
|
807
|
+
try {
|
|
808
|
+
const home = process.env.AGY_TEST_PROFILE_DIR || os.homedir();
|
|
809
|
+
const schemaPath = path.join(home, ".gemini", "antigravity", "mcp", "waymark-engine", "waymark_ask.json");
|
|
810
|
+
if (fs.existsSync(schemaPath)) return true;
|
|
811
|
+
const mcpConfigPath = path.join(home, ".gemini", "config", "mcp_config.json");
|
|
812
|
+
if (fs.existsSync(mcpConfigPath)) {
|
|
813
|
+
const raw = fs.readFileSync(mcpConfigPath, "utf-8");
|
|
814
|
+
if (raw.includes('"waymark-engine"')) return true;
|
|
815
|
+
}
|
|
816
|
+
} catch {}
|
|
817
|
+
return false;
|
|
818
|
+
})();
|
|
819
|
+
|
|
820
|
+
const getFileMetrics = (filePath) => {
|
|
821
|
+
if (!filePath || typeof filePath !== "string") return null;
|
|
822
|
+
try {
|
|
823
|
+
if (!fs.existsSync(filePath)) return null;
|
|
824
|
+
const stat = fs.statSync(filePath);
|
|
825
|
+
if (!stat.isFile()) return null;
|
|
826
|
+
const bytes = stat.size;
|
|
827
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
828
|
+
if (content.length === 0) {
|
|
829
|
+
return { bytes: 0, lineCount: 0, rawSplitCount: 1 };
|
|
830
|
+
}
|
|
831
|
+
const rawSplitCount = content.split(/\r?\n/).length;
|
|
832
|
+
const lineCount = /\r?\n$/.test(content) ? Math.max(1, rawSplitCount - 1) : rawSplitCount;
|
|
833
|
+
return { bytes, lineCount, rawSplitCount };
|
|
834
|
+
} catch {
|
|
835
|
+
return null;
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
const discoveryGuidance = waymarkAvailable
|
|
840
|
+
? `Locate the target symbol, heading, or config key first with 'waymark_ask(..., plain: true)' and pass a precise bounded slice ('StartLine' and 'EndLine', max ${MAX_SAFE_SLICE_LINES} lines) to 'view_file'`
|
|
841
|
+
: `Provide bounded slices ('StartLine' and 'EndLine', max ${MAX_SAFE_SLICE_LINES} lines) via 'view_file', or run 'rtk read ${target || "<file>"}' via run_command instead`;
|
|
842
|
+
|
|
795
843
|
const rawStart = args.StartLine !== undefined ? args.StartLine : args.start_line;
|
|
796
844
|
const rawEnd = args.EndLine !== undefined ? args.EndLine : args.end_line;
|
|
797
845
|
const hasSliceParams = typeof rawStart !== "undefined" || typeof rawEnd !== "undefined";
|
|
@@ -809,30 +857,47 @@ try {
|
|
|
809
857
|
endLine >= startLine
|
|
810
858
|
) {
|
|
811
859
|
const span = endLine - startLine + 1;
|
|
812
|
-
const MAX_SAFE_SLICE_LINES = 150;
|
|
813
860
|
if (span <= MAX_SAFE_SLICE_LINES) {
|
|
814
861
|
respond({ decision: "allow" });
|
|
815
862
|
}
|
|
863
|
+
|
|
864
|
+
const metrics = startLine === 1 ? getFileMetrics(target) : null;
|
|
865
|
+
const isExplicitFullFile = Boolean(
|
|
866
|
+
metrics &&
|
|
867
|
+
startLine === 1 &&
|
|
868
|
+
(endLine === metrics.lineCount || endLine === metrics.rawSplitCount)
|
|
869
|
+
);
|
|
870
|
+
|
|
871
|
+
if (isExplicitFullFile) {
|
|
872
|
+
if (metrics.lineCount <= MAX_FULL_FILE_LINES && metrics.bytes <= MAX_FULL_FILE_BYTES) {
|
|
873
|
+
respond({ decision: "allow" });
|
|
874
|
+
}
|
|
875
|
+
const kib = (metrics.bytes / 1024).toFixed(1);
|
|
876
|
+
respond({
|
|
877
|
+
decision: "deny",
|
|
878
|
+
reason: `Antigravity Governance: Explicit full-file read via 'view_file' (${metrics.lineCount} lines, ${kib} KiB) exceeds the full-file audit ceiling (max ${MAX_FULL_FILE_LINES} lines and 45 KiB). ${discoveryGuidance}.`
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
|
|
816
882
|
respond({
|
|
817
883
|
decision: "deny",
|
|
818
|
-
reason: `Antigravity Governance: Oversized file slice via 'view_file' (${span} lines > ${MAX_SAFE_SLICE_LINES} lines max safe window).
|
|
884
|
+
reason: `Antigravity Governance: Oversized partial file slice via 'view_file' (${span} lines > ${MAX_SAFE_SLICE_LINES} lines max safe slice window). Partial slices above ${MAX_SAFE_SLICE_LINES} lines are denied; full-file reads are only permitted when explicitly covering line 1 through the actual end of a file <= ${MAX_FULL_FILE_LINES} lines and <= 45 KiB. ${discoveryGuidance}.`
|
|
819
885
|
});
|
|
820
886
|
}
|
|
821
887
|
|
|
822
888
|
respond({
|
|
823
889
|
decision: "deny",
|
|
824
|
-
reason: `Antigravity Governance: Invalid slice range via 'view_file'. Ensure StartLine and EndLine are positive integers with EndLine >= StartLine
|
|
890
|
+
reason: `Antigravity Governance: Invalid slice range via 'view_file'. Ensure StartLine and EndLine are positive integers with EndLine >= StartLine. ${discoveryGuidance}.`
|
|
825
891
|
});
|
|
826
892
|
}
|
|
827
893
|
|
|
828
|
-
// Default when no slice attempted: guide agent/subagent to use bounded slices or rtk read
|
|
829
894
|
respond({
|
|
830
895
|
decision: "deny",
|
|
831
|
-
reason: `Antigravity Governance: Full-file inspection via '${toolName}'
|
|
896
|
+
reason: `Antigravity Governance: Full-file inspection via '${toolName}' without explicit bounds is denied. ${discoveryGuidance} (or pass explicit StartLine=1, EndLine=<TotalLines> for a one-pass audit when the file is <= ${MAX_FULL_FILE_LINES} lines and <= 45 KiB).`
|
|
832
897
|
});
|
|
833
898
|
}
|
|
834
899
|
|
|
835
|
-
// 2f. Hard-Route
|
|
900
|
+
// 2f. Hard-Route Other Native File/Search Tools (LH-07)
|
|
836
901
|
if (toolName === "read_file") {
|
|
837
902
|
respond({
|
|
838
903
|
decision: "deny",
|
|
@@ -358,38 +358,8 @@ export async function runInstall(options = {}) {
|
|
|
358
358
|
log(`[OK] Removed legacy temp-folder state: ${legacy}`);
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
## Overview
|
|
364
|
-
Agy-Context-Saver is the universal Model Context Protocol server and lifecycle governor for Google Antigravity, paired with RTK (Rust Token Killer) for transparent CLI output reduction.
|
|
365
|
-
|
|
366
|
-
## Core Rules for Antigravity Agents
|
|
367
|
-
1. **Reactive Wakeup (Zero Task Polling)**:
|
|
368
|
-
- When background tasks run, DO NOT call \`manage_task(Action='status')\` or \`schedule\` polling timers.
|
|
369
|
-
- Stop calling tools and yield the turn. The system notifies you automatically via \`<SYSTEM_MESSAGE>\`.
|
|
370
|
-
- Repeated polling triggers an escalating circuit breaker (frozen at 5 denials).
|
|
371
|
-
2. **Never Read Internal State Directly**:
|
|
372
|
-
- Access to \`.system_generated/\` via \`view_file\` is strictly denied to prevent transcript explosion.
|
|
373
|
-
- Use \`read_transcript\` or \`query_transcript\` to inspect conversation history cleanly.
|
|
374
|
-
3. **Inspect Output Files Directly with RTK**:
|
|
375
|
-
- Runtime step output spillovers (\`.system_generated/steps/<step>/output.txt\`) and completed background task logs (\`tasks/<taskId>.log\`) are read directly via \`rtk read <path>\` under hook governance.
|
|
376
|
-
4. **Platform-Aware Codebase Inspection**:
|
|
377
|
-
- **Windows**: Use \`rtk read <file>\`, \`rtk find <path>\`, and \`rtk rg "<pattern>" .\` (the trailing \`.\` is required to avoid stdin stalls).
|
|
378
|
-
- **POSIX**: Use \`rtk read <file>\`, \`rtk ls <path>\`, and \`rtk grep "<pattern>"\` or \`rtk rg "<pattern>"\`.
|
|
379
|
-
|
|
380
|
-
## Available MCP Tools
|
|
381
|
-
- \`check_context_health\`: Diagnoses transcript turn counts, byte payload, and polling loops. Accepts \`transcriptPath\` or \`conversationId\`.
|
|
382
|
-
- \`read_transcript\`: Streams recent turns from \`transcript.jsonl\` or \`transcript_full.jsonl\` formatted as clean Markdown.
|
|
383
|
-
- \`query_transcript\`: Forensic regex search and filtering engine across transcript steps with optional \`summaryOnly: true\`, and surgical step extraction via \`stepIndex\` and \`field\`.
|
|
384
|
-
- \`get_installation_status\`: Audits live health of the plugin link, hook, MCP server, tool schemas, and RTK.
|
|
385
|
-
- \`sync_installation\`: Synchronizes and repairs all 4 integration layers in ~25ms.
|
|
386
|
-
|
|
387
|
-
## Diagnostic & CLI Playbook
|
|
388
|
-
- Audit Status: \`npm run status\` or \`node mcp/index.js status\`
|
|
389
|
-
- Run Test Suite: \`npm test\`
|
|
390
|
-
- CLI Help: \`node mcp/index.js --help\`
|
|
391
|
-
- ⚠️ Warning: Do not run \`npm start\` or \`node mcp/index.js\` without subcommands interactively (it is a stdio JSON-RPC server).
|
|
392
|
-
`;
|
|
361
|
+
const instructionsSourcePath = path.join(repoRoot, "mcp", "instructions.md");
|
|
362
|
+
const instructionsContent = await fsPromises.readFile(instructionsSourcePath, "utf-8");
|
|
393
363
|
|
|
394
364
|
const checkHealthSchema = {
|
|
395
365
|
name: "check_context_health",
|
|
@@ -464,7 +434,7 @@ Agy-Context-Saver is the universal Model Context Protocol server and lifecycle g
|
|
|
464
434
|
|
|
465
435
|
const queryTranscriptSchema = {
|
|
466
436
|
name: "query_transcript",
|
|
467
|
-
description: "Granular query and forensic filtering engine for Antigravity conversation transcripts. Searches by keyword or regex, filters by role (user, assistant, tool, error), slices step ranges, and automatically dereferences full content when truncated.",
|
|
437
|
+
description: "Granular query and forensic filtering engine for Antigravity conversation transcripts. Searches by keyword or regex, filters by role (user, assistant, subagent, tool, error), slices step ranges, and automatically dereferences full content when truncated.",
|
|
468
438
|
parameters: {
|
|
469
439
|
type: "object",
|
|
470
440
|
properties: {
|
|
@@ -479,7 +449,7 @@ Agy-Context-Saver is the universal Model Context Protocol server and lifecycle g
|
|
|
479
449
|
roles: {
|
|
480
450
|
type: "array",
|
|
481
451
|
items: { type: "string" },
|
|
482
|
-
description: "Filter steps by role/source: 'user', 'assistant', 'tool', 'error', or 'all' (default: ['user', 'assistant'])."
|
|
452
|
+
description: "Filter steps by role/source: 'user', 'assistant', 'subagent', 'tool', 'error', or 'all' (default: ['user', 'assistant'])."
|
|
483
453
|
},
|
|
484
454
|
mode: {
|
|
485
455
|
type: "string",
|
|
@@ -16,20 +16,24 @@ Agy-Context-Saver and RTK protect session transcript health and LLM attention by
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
## Codebase
|
|
19
|
+
## Unified 3-Tier Codebase & File Inspection
|
|
20
20
|
|
|
21
21
|
Unbounded full-file `view_file` calls and unoptimized search tools (`grep_search`, `find_by_name`, `list_dir`) bypass token compression and are guarded:
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- `
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- `rtk
|
|
32
|
-
-
|
|
23
|
+
1. **Tier 1 — Structural Discovery (`waymark_ask` with `plain: true`)**:
|
|
24
|
+
- Locate exact `[StartLine, EndLine]` coordinates via `waymark_ask(..., plain: true)` across all 23 supported formats (code ASTs + `markdown`, `yaml`, `json`, `toml`, `bash`). Always set `plain: true` (~19–466 tokens, zero shell quoting or stdin hazards).
|
|
25
|
+
2. **Tier 2 — Precision Workspace File Reading (`view_file` Hybrid Slice Policy)**:
|
|
26
|
+
- Pass `StartLine` and `EndLine` from `waymark_ask` into `view_file` (bounded slices of `1–150` lines) to preserve exact 1-indexed line numbers for `replace_file_content` without terminal stdout truncation. Partial slices of `151–800` lines are denied; an explicit one-pass full-file audit (`StartLine: 1, EndLine: <TotalLines>`) is permitted only when the file on disk is $\le 800$ lines and $\le 45\text{ KiB}$ (`46,080` bytes).
|
|
27
|
+
3. **Tier 3 — RTK Boundaries (`rtk read`, `rtk find`, `rtk rg`, `rtk err`, `rtk summary`)**:
|
|
28
|
+
- **Spillovers & Task Logs**: Read `.system_generated/steps/<step>/output.txt` spillovers and completed `tasks/<taskId>.log` files via `rtk read <path>` (`--head-lines` / `--tail-lines`). Never use `rtk read -l minimal|aggressive` or `-m` to derive line numbers for edits.
|
|
29
|
+
- **Directory / File Discovery**:
|
|
30
|
+
- **Windows**: Use `rtk find <path>` or PowerShell `dir` / `Get-ChildItem`. (Avoid `rtk ls` or `rtk tree` on Windows as they rely on POSIX binaries/flags).
|
|
31
|
+
- **POSIX / Linux / macOS**: Use `rtk find <path>`, `rtk ls <path>`, or `rtk tree`.
|
|
32
|
+
- **Prose / Regex Search (when symbol, heading, or config key is unknown)**:
|
|
33
|
+
- **Windows**: Use `rtk rg "<pattern>" .` (explicit target `.` is required to avoid child process stdin pipe stalls) or `rg "<pattern>" .`.
|
|
34
|
+
- **POSIX / Linux / macOS**: Use `rtk grep "<pattern>"` or `rtk rg "<pattern>"`.
|
|
35
|
+
- `rtk err <cmd>`: Runs command and displays only errors/warnings.
|
|
36
|
+
- `rtk summary <cmd>`: Runs command and produces a 2-line technical summary.
|
|
33
37
|
|
|
34
38
|
*Safe Harbor*: Documented Antigravity special files (`SKILL.md`, brain artifacts, `.gemini/config/`) may be viewed directly via `view_file` without slice bounds.
|
|
35
39
|
|
|
@@ -54,7 +58,7 @@ Granular query and forensic filtering engine for transcripts with keyword/regex
|
|
|
54
58
|
- **Parameters**:
|
|
55
59
|
- `conversationId` (string, required): Conversation UUID or path.
|
|
56
60
|
- `query` (string, optional): Search keyword or regex.
|
|
57
|
-
- `roles` (array, default: ["user", "assistant"]): Filter by role.
|
|
61
|
+
- `roles` (array, default: ["user", "assistant"]): Filter by role (`"user"`, `"assistant"`, `"subagent"`, `"tool"`, `"error"`, `"all"`).
|
|
58
62
|
- `stepIndex` (number, optional): Specific step to dereference from `transcript_full.jsonl`.
|
|
59
63
|
- `field` (string, optional): Field projection (`"content"`, `"thinking"`, `"tool_calls"`).
|
|
60
64
|
|
|
@@ -79,7 +83,7 @@ Re-verifies, repairs, and synchronizes the installation and tool schemas in ~25m
|
|
|
79
83
|
|
|
80
84
|
2. **Layer 2: Transparent CLI & Codebase Streamlining**:
|
|
81
85
|
- Shell commands transparently rewrite via RTK (`rtk git`, `rtk pytest`, `rtk cargo`, etc.).
|
|
82
|
-
-
|
|
86
|
+
- Workspace file inspection follows `waymark_ask(..., plain: true)` $\to$ bounded `view_file(StartLine, EndLine)`, while `rtk read` handles step spillovers and completed task logs, and `rtk find` / `rtk rg "<pattern>" .` handle directory and free-text search.
|
|
83
87
|
- Direct access to `.system_generated/` is strictly denied; use `read_transcript` and `query_transcript`.
|
|
84
88
|
- **Log Hygiene (Git CRLF/LF Notice Stripping)**: Repetitive Git line-ending notices (`warning: LF will be replaced by CRLF` / `warning: CRLF will be replaced by LF...`) are non-actionable environment noise. Agy-Context-Saver automatically strips these warning lines across forensic transcript parsers, and agents suppress them at the source (`git -c core.safecrlf=false`) to protect context window tokens.
|
|
85
89
|
|