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.
@@ -9,16 +9,18 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
  const repoRoot = path.resolve(__dirname, "..");
10
10
  const binDir = path.join(repoRoot, "bin");
11
11
 
12
- export const RTK_VERSION = "v0.51.0";
13
- export const MIN_COMPATIBLE_RTK_VERSION = "0.50.0";
14
- export const MAX_COMPATIBLE_RTK_VERSION = "0.52.0";
12
+ export const RTK_VERSION = "v1.1.0";
13
+ export const MIN_RTK_VERSION = "1.1.0";
14
+ export const MIN_COMPATIBLE_RTK_VERSION = MIN_RTK_VERSION;
15
15
 
16
+ // Pinned SHA-256 checksums per release asset from https://github.com/rtk-ai/rtk/releases/download/v1.1.0/checksums.txt;
17
+ // ensureRtkInstalled verifies the downloaded archive before extraction and fails closed on any mismatch.
16
18
  export const RTK_CHECKSUMS = {
17
- "rtk-x86_64-pc-windows-msvc.zip": "1623e9b45d28b15122d69e7314776e1123a804224885ce07e7182fb40080f05c",
18
- "rtk-aarch64-apple-darwin.tar.gz": "8817d8b71afc02ac8bf06eb24bcc41c306592ab735b68e8fee9db1ba0de7cb59",
19
- "rtk-x86_64-apple-darwin.tar.gz": "bd39c8153f4147358360c7dc51665a8131cc9ee16f81f69a9402ffa500be3cc2",
20
- "rtk-x86_64-unknown-linux-musl.tar.gz": "5028d3b19a8f0990d30fec9fbb07e32782bc5698e618fb1861aad8a9ccba4eb5",
21
- "rtk-aarch64-unknown-linux-gnu.tar.gz": "8d6d1aad9e69b42481eda7039507d1f7ee93698f87713cecd873d287c1931632"
19
+ "rtk-x86_64-pc-windows-msvc.zip": "c9a8f7a8bad471e64a343314168f38d2399a06fa327cdf5772fb0e645d99ea6f",
20
+ "rtk-aarch64-apple-darwin.tar.gz": "8da773b0954cf90b115ec95c4e4eb420f04c39de233c5db102246a6caf073ba7",
21
+ "rtk-x86_64-apple-darwin.tar.gz": "1e23e8b9542b58428e6409c49b1c3fb92c4c0d5125da72e80f002a46086a6c20",
22
+ "rtk-x86_64-unknown-linux-musl.tar.gz": "9454ad1b9489daa57ab0a9f4ebe2faaf4dc82b8a0f26c9e5135151abd7c9378d",
23
+ "rtk-aarch64-unknown-linux-gnu.tar.gz": "a5c00c3ab0129884bcb757d348afc1a650efa0f4f0769da97c341f28f89719ed"
22
24
  };
23
25
 
24
26
  export function isCompatibleRtkVersion(versionStr) {
@@ -27,8 +29,7 @@ export function isCompatibleRtkVersion(versionStr) {
27
29
  if (!match) return false;
28
30
  const major = parseInt(match[1], 10);
29
31
  const minor = parseInt(match[2], 10);
30
- // Compatible if 0.50.x or 0.51.x (>= 0.50.0 and < 0.52.0)
31
- return major === 0 && (minor === 50 || minor === 51);
32
+ return major > 1 || (major === 1 && minor >= 1);
32
33
  }
33
34
 
34
35
  export function getRtkPlatformAsset() {
@@ -59,6 +60,17 @@ export function findExistingRtk(options = {}) {
59
60
  const pluginBinDir = path.join(profileHome, ".gemini", "config", "plugins", "agy-context-saver", "bin");
60
61
  const candidateDirs = [binDir, pluginBinDir];
61
62
 
63
+ // Check PATH first so a system rtk >= 1.1.0 is preferred over bundled binaries
64
+ try {
65
+ const out = execSync("rtk --version", { encoding: "utf-8", timeout: 5000, stdio: ["ignore", "pipe", "ignore"] }).trim();
66
+ if (isCompatibleRtkVersion(out)) {
67
+ return { path: "rtk", version: out, isLocal: false };
68
+ }
69
+ if (!options.silent) {
70
+ console.warn(`[WARN] System RTK version '${out}' is below minimum supported version >=${MIN_RTK_VERSION}. Local or manual ${RTK_VERSION} installation is required.`);
71
+ }
72
+ } catch {}
73
+
62
74
  for (const dir of candidateDirs) {
63
75
  for (const exeName of names) {
64
76
  const localExe = path.join(dir, exeName);
@@ -73,18 +85,6 @@ export function findExistingRtk(options = {}) {
73
85
  }
74
86
  }
75
87
 
76
- // Check PATH
77
- try {
78
- const out = execSync("rtk --version", { encoding: "utf-8", timeout: 5000, stdio: ["ignore", "pipe", "ignore"] }).trim();
79
- if (isCompatibleRtkVersion(out)) {
80
- return { path: "rtk", version: out, isLocal: false };
81
- } else {
82
- if (!options.silent) {
83
- console.warn(`[WARN] System RTK version '${out}' is outside supported range [>=${MIN_COMPATIBLE_RTK_VERSION} <${MAX_COMPATIBLE_RTK_VERSION}]. Local pinned ${RTK_VERSION} will be required.`);
84
- }
85
- }
86
- } catch {}
87
-
88
88
  return null;
89
89
  }
90
90
 
@@ -102,6 +102,19 @@ export async function ensureRtkInstalled(options = {}) {
102
102
  throw new Error(`Unsupported platform/architecture for prebuilt RTK: ${os.platform()} ${os.arch()}`);
103
103
  }
104
104
 
105
+ // Fail closed when the target release asset checksum is unpinned/missing instead of trusting stale hashes
106
+ const expectedHash = RTK_CHECKSUMS[assetInfo.asset];
107
+ if (!expectedHash) {
108
+ throw new Error(
109
+ `Integrity error: No pinned SHA-256 checksum configured for RTK ${RTK_VERSION} asset '${assetInfo.asset}'.\n` +
110
+ `Automated download aborted (fail-closed). Please install RTK >= ${MIN_RTK_VERSION} manually and ensure 'rtk' is on your PATH:\n` +
111
+ ` - macOS (Homebrew): brew install rtk\n` +
112
+ ` - Cargo: cargo install --locked rtk\n` +
113
+ ` - Official script: curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh\n` +
114
+ ` - GitHub Releases: https://github.com/rtk-ai/rtk/releases/tag/${RTK_VERSION}`
115
+ );
116
+ }
117
+
105
118
  if (!fs.existsSync(binDir)) {
106
119
  fs.mkdirSync(binDir, { recursive: true });
107
120
  }
@@ -118,10 +131,6 @@ export async function ensureRtkInstalled(options = {}) {
118
131
  const buffer = Buffer.from(await response.arrayBuffer());
119
132
 
120
133
  // Fail-closed SHA-256 verification before writing archive to disk or extracting
121
- const expectedHash = RTK_CHECKSUMS[assetInfo.asset];
122
- if (!expectedHash) {
123
- throw new Error(`Integrity error: No pinned SHA-256 checksum found for asset '${assetInfo.asset}'`);
124
- }
125
134
  const actualHash = crypto.createHash("sha256").update(buffer).digest("hex");
126
135
  if (actualHash !== expectedHash) {
127
136
  throw new Error(
@@ -27,10 +27,13 @@ function exists(relativePath) {
27
27
  }
28
28
 
29
29
  let pkg;
30
- try {
31
- pkg = JSON.parse(readText('package.json'));
32
- } catch (error) {
33
- errors.push(`package.json is not valid JSON: ${error.message}`);
30
+ const pkgText = readText('package.json');
31
+ if (pkgText) {
32
+ try {
33
+ pkg = JSON.parse(pkgText);
34
+ } catch (error) {
35
+ errors.push(`package.json is not valid JSON: ${error.message}`);
36
+ }
34
37
  }
35
38
 
36
39
  if (pkg) {
@@ -41,6 +44,26 @@ if (pkg) {
41
44
  errors.push(`package.json version is not a valid semver release version: ${JSON.stringify(pkg.version)}.`);
42
45
  }
43
46
 
47
+ const pluginText = readText('plugin.json');
48
+ if (pluginText) {
49
+ try {
50
+ const pluginManifest = JSON.parse(pluginText);
51
+ if (pluginManifest.name !== pkg.name) {
52
+ errors.push(`plugin.json name ${JSON.stringify(pluginManifest.name)} does not match package.json name ${JSON.stringify(pkg.name)}.`);
53
+ }
54
+ if (pluginManifest.version !== pkg.version) {
55
+ errors.push(`plugin.json version ${JSON.stringify(pluginManifest.version)} does not match package.json version ${JSON.stringify(pkg.version)}.`);
56
+ }
57
+ } catch (error) {
58
+ errors.push(`plugin.json is not valid JSON: ${error.message}`);
59
+ }
60
+ }
61
+
62
+ const changelogText = readText('CHANGELOG.md');
63
+ if (changelogText && pkg.version && !changelogText.includes(`## [${pkg.version}]`)) {
64
+ errors.push(`CHANGELOG.md is missing a release heading for current version "## [${pkg.version}]".`);
65
+ }
66
+
44
67
  const requiredMetadata = [
45
68
  ['repository.url', pkg.repository?.url],
46
69
  ['homepage', pkg.homepage],
@@ -57,17 +80,45 @@ if (pkg) {
57
80
  }
58
81
 
59
82
  const requiredPackageFiles = [
60
- 'mcp/index.js',
83
+ 'lib/transcript-core.mjs',
84
+ 'bin/agy-context.mjs',
61
85
  'scripts/install-register.mjs',
62
86
  'scripts/provision-rtk.mjs',
63
87
  'plugin.json',
64
88
  'hooks.json',
65
- 'mcp_config.json',
66
89
  'README.md',
67
90
  'CHANGELOG.md',
68
91
  'LICENSE',
69
92
  ];
70
93
 
94
+ if (exists('mcp_config.json')) {
95
+ errors.push('Legacy mcp_config.json is still present at repository root; remove it for 2.0 CLI-first release.');
96
+ }
97
+ if (exists('mcp')) {
98
+ errors.push('Legacy mcp/ directory is still present at repository root; remove it for 2.0 CLI-first release.');
99
+ }
100
+
101
+ const hooksText = readText('hooks.json');
102
+ if (hooksText) {
103
+ try {
104
+ const pluginHooks = JSON.parse(hooksText);
105
+ const hookCmd = pluginHooks?.['agy-context-saver']?.PreToolUse?.[0]?.hooks?.[0]?.command ?? '';
106
+ const hookMatcher = pluginHooks?.['agy-context-saver']?.PreToolUse?.[0]?.matcher ?? '';
107
+ if (!hookCmd) {
108
+ errors.push('hooks.json must define "agy-context-saver".PreToolUse[0].hooks[0].command.');
109
+ } else if (hookCmd.includes('ANTIGRAVITY_PLUGIN_ROOT')) {
110
+ errors.push('hooks.json command must not use unexpanded ${ANTIGRAVITY_PLUGIN_ROOT}; use ./scripts/execution-guard-hook.mjs (cwd is plugin root).');
111
+ }
112
+ for (const tool of ['read_file', 'edit_file', 'write_file', 'run_command']) {
113
+ if (!hookMatcher.includes(tool)) {
114
+ errors.push(`hooks.json PreToolUse matcher must include ${tool}.`);
115
+ }
116
+ }
117
+ } catch (error) {
118
+ errors.push(`hooks.json is not valid JSON: ${error.message}`);
119
+ }
120
+ }
121
+
71
122
  for (const relativePath of requiredPackageFiles) {
72
123
  if (!exists(relativePath)) errors.push(`Required runtime/release file is missing: ${relativePath}`);
73
124
  const coveredByFiles = (pkg.files ?? []).some((entry) => {
@@ -105,7 +156,7 @@ if (pkg) {
105
156
  const readme = readText('README.md');
106
157
  const countMatch = readme.match(/Runs all\s+(\d+)\s+test suites?/i);
107
158
  if (!countMatch) {
108
- errors.push('README.md must state the exact suite count using a sentence such as "Runs all 8 test suites".');
159
+ errors.push('README.md must state the exact suite count using a sentence such as "Runs all 11 test suites".');
109
160
  } else if (Number(countMatch[1]) !== suitePaths.length) {
110
161
  errors.push(`README.md says ${countMatch[1]} test suites, but package.json scripts.test runs ${suitePaths.length}.`);
111
162
  }
@@ -121,11 +172,24 @@ if (pkg) {
121
172
  }
122
173
 
123
174
  const rtkProvisioner = readText('scripts/provision-rtk.mjs');
124
- const rtkVersionMatch = rtkProvisioner.match(/RTK_VERSION\s*=\s*['"]([^'"]+)['"]/);
125
- if (!rtkVersionMatch) {
126
- errors.push('Could not locate a pinned RTK_VERSION in scripts/provision-rtk.mjs.');
175
+ const minRtkMatch = rtkProvisioner.match(/MIN_(?:COMPATIBLE_)?RTK_VERSION\s*=\s*['"]v?([^'"]+)['"]/);
176
+ const rtkVersionMatch = rtkProvisioner.match(/RTK_VERSION\s*=\s*['"]v?([^'"]+)['"]/);
177
+ const detectedRtkVersion = minRtkMatch?.[1] || rtkVersionMatch?.[1];
178
+ if (!detectedRtkVersion) {
179
+ errors.push('Could not locate MIN_RTK_VERSION or RTK_VERSION in scripts/provision-rtk.mjs.');
127
180
  } else {
128
- console.log(`RTK provisioner pin found: ${rtkVersionMatch[1]}`);
181
+ const semverMatch = detectedRtkVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
182
+ if (!semverMatch) {
183
+ errors.push(`Invalid RTK version format in scripts/provision-rtk.mjs: ${detectedRtkVersion}`);
184
+ } else {
185
+ const major = Number(semverMatch[1]);
186
+ const minor = Number(semverMatch[2]);
187
+ if (major < 1 || (major === 1 && minor < 1)) {
188
+ errors.push(`RTK version requirement must be >= 1.1.0; found ${detectedRtkVersion} in scripts/provision-rtk.mjs.`);
189
+ } else {
190
+ console.log(`RTK provisioner requirement found: ${detectedRtkVersion} (>= 1.1.0)`);
191
+ }
192
+ }
129
193
  }
130
194
 
131
195
  if (!pkg.scripts?.setup || !pkg.scripts?.status || !pkg.scripts?.test) {
@@ -4,6 +4,7 @@
4
4
  * State lives in a folder owned by this user, never in the shared os.tmpdir():
5
5
  * Windows: %LOCALAPPDATA%\agy-context-saver
6
6
  * POSIX: $XDG_STATE_HOME/agy-context-saver (default ~/.local/state/agy-context-saver)
7
+ * Legacy versions (<= 1.7.0) left session JSON files in os.tmpdir(); cleaned on setup/uninstall.
7
8
  * Under AGY_TEST_PROFILE_DIR the same layout is rooted in the test profile.
8
9
  *
9
10
  * The hook is mirrored into ~/.gemini/config/scripts as a standalone file, so it keeps an
@@ -1,100 +1,106 @@
1
1
  ---
2
2
  name: context-governance
3
3
  description: >-
4
- Use when running shell commands with large outputs, inspecting session transcript health,
5
- preventing repetitive background polling loops, or inspecting codebases with RTK.
4
+ Use when running shell commands with large outputs, inspecting session transcript health
5
+ via agy-context, preventing repetitive background polling loops, or inspecting codebases with RTK.
6
6
  ---
7
7
 
8
8
  # Context Governance & Execution Guard (Agy-Context-Saver + RTK)
9
9
 
10
- Agy-Context-Saver and RTK protect session transcript health and LLM attention by transparently compressing command outputs, preventing repetitive background polling loops, and routing native inspection to compact CLI interfaces.
10
+ `Agy-Context-Saver` and `RTK` compress shell output, enforce bounded workspace file reads, stop background-task busy-polling, and provide CLI commands for conversation transcript inspection and access control.
11
11
 
12
- ## Architectural Boundaries
12
+ ## Architectural Boundary
13
13
 
14
- - **RTK (Rust Token Killer)**: Owns shell command rewriting, terminal output compression, and canonical codebase inspection (`rtk read`, `rtk grep`, `rtk find`, `rtk ls`, `rtk err`, `rtk summary`).
15
- - **Agy-Context-Saver**: Owns Antigravity lifecycle governance, Reactive Wakeup enforcement, transcript forensics, and session integrity.
14
+ - **RTK (`>= 1.1.0`)**: Rewrites shell commands (`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`).
15
+ - **Agy-Context-Saver (`v2.0.0`)**: Enforces Reactive Wakeup backoff, bounds `read_file` slices, protects `.system_generated/` and the state directory, and exposes `agy-context transcript`.
16
16
 
17
17
  ---
18
18
 
19
- ## Unified 3-Tier Codebase & File Inspection
19
+ ## Workspace File & Codebase Inspection
20
20
 
21
- Unbounded full-file `view_file` calls and unoptimized search tools (`grep_search`, `find_by_name`, `list_dir`) bypass token compression and are guarded:
21
+ Unbounded full-file `read_file` calls on workspace files are blocked by the `PreToolUse` hook:
22
22
 
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.
23
+ 1. **Tier 1 (Search and discovery: `rtk grep`, `rtk find`, `rtk ls`)**:
24
+ - **Pattern and symbol search**: Run `rtk grep -rnE "<pattern>" <path>` via `run_command` to locate `[StartLine, EndLine]` coordinates. Always pass an explicit target path (such as `.` or `src/`) so `rtk grep` does not wait on stdin.
25
+ - **Directory and file listing**: Run `rtk find <path>`, `rtk ls <path>`, or `rtk tree` (or PowerShell `dir` / `Get-ChildItem` on Windows).
26
+ 2. **Tier 2 (Workspace file reading: `read_file` slice policy)**:
27
+ - Pass `StartLine` and `EndLine` into `read_file` in bounded slices of `1-150` lines to preserve 1-indexed line numbers for `edit_file` and `write_file`.
28
+ - Partial slices of `151-800` lines and `ByteOffset`-only unbounded reads are denied. An explicit full-file read (`StartLine: 1, EndLine: <TotalLines>`) is allowed when the file on disk is $\le 800$ lines and $\le 45\text{ KiB}$ (`46,080` bytes).
29
+ 3. **Tier 3 (Spillovers and diagnostics: `rtk read`, `rtk err`, `rtk summary`)**:
30
+ - **Spillovers and task logs**: Read `.system_generated/steps/<step>/output.txt` spillovers (via bounded `read_file` $\le 150$ lines or `rtk read <path>`) 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 `edit_file` or `write_file`.
31
+ - `rtk err <cmd>`: Runs a command and prints only errors and warnings.
32
+ - `rtk summary <cmd>`: Runs a command and prints a 2-line summary.
37
33
 
38
- *Safe Harbor*: Documented Antigravity special files (`SKILL.md`, brain artifacts, `.gemini/config/`) may be viewed directly via `view_file` without slice bounds.
34
+ *Safe harbor*: Antigravity special files (`SKILL.md`, `AGENTS.md`, brain artifacts, `.gemini/config/`) may be read via `read_file` without slice bounds, and `.system_generated/steps/<n>/output.txt` supports bounded `read_file` ($\le 150$ lines).
39
35
 
40
36
  ---
41
37
 
42
- ## Available Agy MCP Tools
43
-
44
- ### 1. `check_context_health`
45
- Performs streaming inspection of `transcript.jsonl` to calculate turn budgets, step counts, raw payload size, RTK status, and detect busy-polling loops.
46
- - **Parameters**:
47
- - `transcriptPath` (string, required): Absolute path to `transcript.jsonl`.
48
-
49
- ### 2. `read_transcript`
50
- Quickly reads recent conversation turns from an Antigravity transcript in clean Markdown format with zero JSON noise.
51
- - **Parameters**:
52
- - `conversationId` (string, required): Conversation UUID or path.
53
- - `mode` (string, default: "compact"): "compact" or "full".
54
- - `lastTurns` (number, default: 3): Number of turns to display.
55
-
56
- ### 3. `query_transcript`
57
- Granular query and forensic filtering engine for transcripts with keyword/regex search, auto-dereferencing of truncated payloads, and surgical step projection.
58
- - **Parameters**:
59
- - `conversationId` (string, required): Conversation UUID or path.
60
- - `query` (string, optional): Search keyword or regex.
61
- - `roles` (array, default: ["user", "assistant"]): Filter by role (`"user"`, `"assistant"`, `"subagent"`, `"tool"`, `"error"`, `"all"`).
62
- - `stepIndex` (number, optional): Specific step to dereference from `transcript_full.jsonl`.
63
- - `field` (string, optional): Field projection (`"content"`, `"thinking"`, `"tool_calls"`).
64
-
65
- ### 4. `get_installation_status`
66
- Audits the Antigravity integration layers (Native Plugin Link, Lifecycle Hook in `hooks.json`, MCP Server in `mcp_config.json`, Tool Schemas, and RTK binary/hook).
67
-
68
- ### 5. `sync_installation`
69
- Re-verifies, repairs, and synchronizes the installation and tool schemas in ~25ms.
70
- - **Parameters**:
71
- - `checkOnly` (boolean, default: false): Dry-run audit mode.
38
+ ## `agy-context` CLI Commands
39
+
40
+ Run `agy-context` via `run_command` (`~/.gemini/antigravity/bin/agy-context`). Invoke `agy-context transcript ...` as a single unchained command without `&&`, `||`, `;`, `|`, or redirects:
41
+
42
+ ### 1. `agy-context transcript health` (aliases: `stats`, `info`)
43
+ Checks turn counts, step counts, raw transcript size, RTK status, and busy-polling events.
44
+ ```bash
45
+ agy-context transcript health [<id>] [--id <conv>] [--json] [--file <path>]
46
+ ```
47
+
48
+ ### 2. `agy-context transcript read` (aliases: `outline`, `summary`)
49
+ Streams recent conversation turns in Markdown, or prints a 1-line-per-step outline when `--outline` (or `outline` / `summary`) is used.
50
+ ```bash
51
+ agy-context transcript read [<id>] [--id <conv>] [--mode compact|full] [--last-turns N] [--offset N] [--limit N] [--outline] [--include-thinking] [--json] [--file <path>]
52
+ ```
53
+
54
+ ### 3. `agy-context transcript query` (aliases: `grep`, `search`, `find`, `tools`)
55
+ Searches transcripts by regex or substring with automatic dereferencing of truncated fields, role filtering (`user`, `assistant`, `subagent`, `tool`, `generic`, `system`, `error`, `all`), and `--full-args` / `--field` projection. The `tools` alias defaults to `--roles assistant --field tool_args --include-tools`.
56
+ - **Multi-step forensic workflow**:
57
+ 1. `agy-context transcript outline [<conv>] --start 0 --end 100` (1-line-per-step index with `[ERROR]` and `[tools: ...]` tags)
58
+ 2. `agy-context transcript tools [<conv>] --start 0 --end 100` (all untruncated tool call arguments in one call)
59
+ 3. `agy-context transcript step <N,M,K|N-M> [<conv>] --field content` (batch-extract specific step outputs without 1-by-1 `--step <N>` loops)
60
+ ```bash
61
+ agy-context transcript query [<pattern>] [<id>] [--id <conv>] [--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] [--file <path>]
62
+ ```
63
+
64
+ ### 4. `agy-context transcript step`
65
+ Extracts untruncated content or specific fields (`content`, `thinking`, `tool_calls`, `tool_args`, `tool_args:<Key>`, `all`) for one step or a batch/range of steps (`2,8,14`, `2-10`, `2..10`, or `--start 2 --end 10`) from `transcript_full.jsonl`, with optional `--head <N>`, `--tail <N>`, and `--full` slicing.
66
+ ```bash
67
+ agy-context transcript step [<N|N,M|N-M|N..M>] [<id>] [--id <conv>] (--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] [--file <path>]
68
+ ```
69
+
70
+ ### 5. `agy-context transcript list` (alias: `ls`)
71
+ Lists recent conversations in the Antigravity brain directory sorted by modification time.
72
+ ```bash
73
+ agy-context transcript list [--limit N] [--json]
74
+ ```
75
+
76
+ ### 6. `agy-context transcript access` (alias: `policy`)
77
+ Controls parent transcript access policies for child subagents and `/swarm` workers.
78
+ ```bash
79
+ 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]
80
+ ```
81
+ - **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).
82
+ - **5-tier 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`.
83
+ - **Stale-lock protection**: Policies (`policies[ownerId]`) expire after a 1-hour default TTL, Step 0 `USER_INPUT` top-level user sessions bypass child locks automatically, Step 0/1 `sender=<parentConvId>` binds child agents to their parent policy, and `agy-context status` displays the active `Transcript Access Policy`.
84
+
85
+ ### 7. `agy-context status` & `agy-context setup`
86
+ Audits or synchronizes the plugin link, `PreToolUse` hook, CLI shims, RTK (`>= 1.1.0`), and `Transcript Access Policy`.
87
+ ```bash
88
+ agy-context status [--json]
89
+ agy-context setup [--check] [--allow-degraded]
90
+ agy-context uninstall [--restore-backups]
91
+ ```
72
92
 
73
93
  ---
74
94
 
75
- ## 3-Layer Governance Invariants
76
-
77
- 1. **Layer 1: Reactive Lifecycle & Polling Immunity**:
78
- - Never busy-wait on `manage_task(Action='status')` or rapid polling timers.
79
- - Stop calling tools and yield the turn for native Reactive Wakeup (`<SYSTEM_MESSAGE>`).
80
- - Diagnostic status inspections follow exponential backoff: $\min(600, \text{round}(30 \times 2.5^{\text{pollCount}-1}))$.
81
- - 5 cumulative denials trigger the `force_ask` circuit breaker.
82
- - For operations $>15\text{s}$, schedule coordinated watchdog timers: `schedule(DurationSeconds=45, TimerCondition="task-X")` and output a structured Pre-Yield Status Card.
83
-
84
- 2. **Layer 2: Transparent CLI & Codebase Streamlining**:
85
- - Shell commands transparently rewrite via RTK (`rtk git`, `rtk pytest`, `rtk cargo`, etc.).
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.
87
- - Direct access to `.system_generated/` is strictly denied; use `read_transcript` and `query_transcript`.
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.
89
-
90
- 3. **Layer 3: Synchronous Execution**:
91
- - Synchronous wait window expands to 10,000ms to eliminate unnecessary detachment.
92
-
93
- ---
94
-
95
- ## Quick Verification & Health Check
96
-
97
- To verify installation health and run test validation:
98
- - **Health Check**: `npm run status` (verifies plugin link, hook, MCP config, schemas, RTK).
99
- - **Test Suite**: `npm test` (runs all 10 test suites).
100
- - Detailed verification playbooks and release steps reside in `docs/publishing.md`.
95
+ ## Governance Summary
96
+
97
+ 1. **Layer 1 (Reactive lifecycle and backoff)**:
98
+ - Do not busy-wait on `manage_task(Action='status')` or short polling timers; end the turn and wait for Reactive Wakeup (`<SYSTEM_MESSAGE>`).
99
+ - Status checks follow exponential backoff: $\min(600, \text{round}(30 \times 2.5^{\text{pollCount}-1}))$. 5 cumulative denials trigger the `force_ask` circuit breaker.
100
+ - For background shell tasks $>15\text{s}$, schedule `schedule(DurationSeconds=45, TimerCondition="task-X")` and output a Pre-Yield Status Card. Never pair `swarm_wait` or subagents with a one-shot `schedule` timer.
101
+ 2. **Layer 2 (Shell rewriting, file slices, and transcript access)**:
102
+ - Shell commands rewrite via `rtk hook antigravity`.
103
+ - Workspace inspection uses `rtk grep` / `rtk find` -> bounded `read_file(StartLine, EndLine)` -> `edit_file` / `write_file`, while `rtk read` reads step spillovers and completed task logs.
104
+ - Direct access to `.system_generated/` or `getStateDir()` is denied; use `agy-context transcript` when permitted by the parent's access policy.
105
+ 3. **Layer 3 (Synchronous window)**:
106
+ - Non-daemon `run_command` calls without an explicit `WaitMsBeforeAsync` default to 10,000ms.