@jmylchreest/aide-plugin 0.0.37 → 0.0.39

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmylchreest/aide-plugin",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
4
4
  "description": "aide plugin for OpenCode — multi-agent orchestration, memory, skills, and persistence",
5
5
  "type": "module",
6
6
  "main": "./src/opencode/index.ts",
@@ -60,7 +60,21 @@ What functions are in src/auth.ts?
60
60
  → Returns: all functions, classes, types in that file
61
61
  ```
62
62
 
63
- ### 4. Check Index Status (`mcp__plugin_aide_aide__code_stats`)
63
+ ### 4. File Outline (`mcp__plugin_aide_aide__code_outline`)
64
+
65
+ Get a collapsed structural outline of a file — signatures preserved, bodies replaced with `{ ... }`.
66
+ Uses ~5-15% of the tokens of the full file. **Use this before reading a file** to understand its
67
+ structure, then use `Read` with offset/limit for specific sections.
68
+
69
+ **Example usage:**
70
+
71
+ ```
72
+ Outline src/auth.ts
73
+ → Uses code_outline tool
74
+ → Returns: collapsed view with signatures, line ranges, bodies collapsed
75
+ ```
76
+
77
+ ### 5. Check Index Status (`mcp__plugin_aide_aide__code_stats`)
64
78
 
65
79
  Check if the codebase has been indexed.
66
80
 
@@ -108,6 +122,20 @@ Is the code indexed?
108
122
  1. Use `code_references` with symbol "authenticateUser"
109
123
  2. Show all call sites grouped by file
110
124
 
125
+ ## What These Tools Cover
126
+
127
+ `code_search` and `code_references` work from the tree-sitter symbol index. They find:
128
+
129
+ - Function, method, class, interface, type definitions by name
130
+ - Symbol signatures (parameter types, return types)
131
+ - Doc comments attached to definitions
132
+ - Call sites for a specific symbol name (via `code_references`)
133
+
134
+ For anything else — patterns inside function bodies, method call chains, string literals,
135
+ SQL queries, imports, variable declarations — use **Grep**, which searches code content directly.
136
+
137
+ In short: `code_search` finds _where things are defined_; Grep finds _patterns in code content_.
138
+
111
139
  ## Notes
112
140
 
113
141
  - Code must be indexed first: `./.aide/bin/aide code index`
@@ -18,6 +18,7 @@ Systematic approach to identifying and fixing bugs.
18
18
  ## Prerequisites
19
19
 
20
20
  Before starting:
21
+
21
22
  - Get the exact error message or unexpected behavior description
22
23
  - Identify the entry point or trigger for the bug
23
24
  - Note any relevant environment details (Node version, OS, etc.)
@@ -36,12 +37,14 @@ node path/to/script.js
36
37
  ```
37
38
 
38
39
  Document:
40
+
39
41
  - Exact error message
40
42
  - Steps to trigger
41
43
  - Expected vs actual behavior
42
44
  - Is it consistent or intermittent?
43
45
 
44
46
  **If cannot reproduce:**
47
+
45
48
  - Check environment differences
46
49
  - Look for race conditions
47
50
  - Check for cached state
@@ -54,6 +57,9 @@ Use tools to find code related to the error:
54
57
  # Search for function mentioned in stack trace
55
58
  mcp__plugin_aide_aide__code_search query="functionName" kind="function"
56
59
 
60
+ # Get a structural overview of the suspect file (signatures + line ranges)
61
+ mcp__plugin_aide_aide__code_outline file="path/to/file.ts"
62
+
57
63
  # Get symbols in suspect file
58
64
  mcp__plugin_aide_aide__code_symbols file="path/to/file.ts"
59
65
 
@@ -65,23 +71,26 @@ Grep for "error message text"
65
71
 
66
72
  Follow the code flow from entry to error:
67
73
 
68
- 1. Start at the entry point (route handler, event listener, etc.)
69
- 2. Trace through each function call
70
- 3. Use `mcp__plugin_aide_aide__code_references` to find callers
71
- 4. Check type definitions with `mcp__plugin_aide_aide__code_search kind="interface"`
74
+ 1. Use `code_outline` on each file in the call chain to understand its structure
75
+ 2. Use `code_references` to find callers of the failing function
76
+ 3. Use `Read` with offset/limit to read specific functions in the execution path
77
+ (use line numbers from the outline)
78
+ 4. Check type definitions with `code_search kind="interface"`
79
+
80
+ Outlines help you identify which functions matter, so you can read just those sections.
72
81
 
73
82
  ### Step 4: Form Hypotheses
74
83
 
75
84
  Based on the error type, consider these causes:
76
85
 
77
- | Symptom | Likely Causes |
78
- |---------|---------------|
79
- | "undefined is not a function" | Variable is null/undefined, wrong import |
80
- | "Cannot read property of undefined" | Missing null check, async timing issue |
81
- | "Type error" | Type mismatch, wrong function signature |
82
- | "Maximum call stack" | Infinite recursion, circular reference |
83
- | "Network error" | Bad URL, CORS, timeout, server down |
84
- | "State not updating" | Mutation instead of new object, missing dependency |
86
+ | Symptom | Likely Causes |
87
+ | ----------------------------------- | -------------------------------------------------- |
88
+ | "undefined is not a function" | Variable is null/undefined, wrong import |
89
+ | "Cannot read property of undefined" | Missing null check, async timing issue |
90
+ | "Type error" | Type mismatch, wrong function signature |
91
+ | "Maximum call stack" | Infinite recursion, circular reference |
92
+ | "Network error" | Bad URL, CORS, timeout, server down |
93
+ | "State not updating" | Mutation instead of new object, missing dependency |
85
94
 
86
95
  ### Step 5: Validate Hypotheses
87
96
 
@@ -99,6 +108,7 @@ npm test -- --grep "test name"
99
108
  ```
100
109
 
101
110
  **Validation checklist:**
111
+
102
112
  - Check variable values at key points
103
113
  - Verify assumptions about input data
104
114
  - Test edge cases (null, empty, boundary values)
@@ -107,11 +117,13 @@ npm test -- --grep "test name"
107
117
  ### Step 6: Apply the Fix
108
118
 
109
119
  **Rules:**
120
+
110
121
  - Change only what's necessary to fix the bug
111
122
  - Don't refactor unrelated code
112
123
  - Match existing code patterns
113
124
 
114
125
  **Common fixes:**
126
+
115
127
  - Add null/undefined check
116
128
  - Fix type annotation
117
129
  - Correct async/await usage
@@ -132,24 +144,26 @@ npm test
132
144
  ```
133
145
 
134
146
  **Verification criteria:**
147
+
135
148
  - Original issue no longer occurs
136
149
  - Related tests still pass
137
150
  - No new errors introduced
138
151
 
139
152
  ## Failure Handling
140
153
 
141
- | Situation | Action |
142
- |-----------|--------|
143
- | Cannot reproduce | Check environment, add logging to narrow down |
144
- | Multiple bugs intertwined | Fix one at a time, verify after each |
145
- | Fix causes new failures | Revert, analyze dependencies, try different approach |
146
- | Root cause is in dependency | Check for updates, file issue, implement workaround |
147
- | Bug is in async code | Add proper await, check Promise chains |
154
+ | Situation | Action |
155
+ | --------------------------- | ---------------------------------------------------- |
156
+ | Cannot reproduce | Check environment, add logging to narrow down |
157
+ | Multiple bugs intertwined | Fix one at a time, verify after each |
158
+ | Fix causes new failures | Revert, analyze dependencies, try different approach |
159
+ | Root cause is in dependency | Check for updates, file issue, implement workaround |
160
+ | Bug is in async code | Add proper await, check Promise chains |
148
161
 
149
162
  ## MCP Tools
150
163
 
164
+ - `mcp__plugin_aide_aide__code_outline` - **Start here.** Get collapsed file skeleton to understand structure before reading
151
165
  - `mcp__plugin_aide_aide__code_search` - Find functions, classes, types involved in the bug
152
- - `mcp__plugin_aide_aide__code_symbols` - Understand file structure
166
+ - `mcp__plugin_aide_aide__code_symbols` - List all symbols in a file
153
167
  - `mcp__plugin_aide_aide__code_references` - Find all callers of a function
154
168
  - `mcp__plugin_aide_aide__memory_search` - Check for related past issues
155
169
 
@@ -159,24 +173,30 @@ npm test
159
173
  ## Debug Report: [Issue Title]
160
174
 
161
175
  ### Problem
176
+
162
177
  [What was happening vs what should happen]
163
178
 
164
179
  ### Reproduction
180
+
165
181
  [Steps to reproduce the issue]
166
182
 
167
183
  ### Root Cause
184
+
168
185
  [Identified cause with file:line reference]
169
186
  [Why the bug occurred]
170
187
 
171
188
  ### Fix Applied
189
+
172
190
  [What was changed and why]
173
191
 
174
192
  ### Verification
193
+
175
194
  - Original issue: FIXED
176
195
  - Related tests: PASS
177
196
  - Full suite: PASS
178
197
 
179
198
  ### Prevention
199
+
180
200
  [Optional: How to prevent similar bugs]
181
201
  ```
182
202
 
@@ -0,0 +1,224 @@
1
+ ---
2
+ name: forget
3
+ description: Soft-delete memories by adding/removing the forget tag, or hard-delete outdated memories
4
+ triggers:
5
+ - forget this
6
+ - forget that
7
+ - forget memory
8
+ - remove memory
9
+ - delete memory
10
+ - outdated memory
11
+ - wrong memory
12
+ - incorrect memory
13
+ - supersede memory
14
+ - obsolete
15
+ - no longer true
16
+ - no longer relevant
17
+ - not true anymore
18
+ - that was wrong
19
+ - disregard
20
+ allowed-tools: Bash(./.aide/bin/aide memory *)
21
+ ---
22
+
23
+ # Forget
24
+
25
+ **Recommended model tier:** balanced (sonnet) - this skill performs straightforward operations
26
+
27
+ Manage outdated, incorrect, or obsolete memories by soft-deleting (tagging with `forget`) or hard-deleting them.
28
+
29
+ ## Key Concepts
30
+
31
+ ### Soft Delete (Preferred)
32
+
33
+ Memories tagged with `forget` are **excluded by default** from search, list, and context injection. They remain in the database and can be recovered.
34
+
35
+ ```bash
36
+ ./.aide/bin/aide memory tag <MEMORY_ID> --add=forget
37
+ ```
38
+
39
+ ### Hard Delete (Permanent)
40
+
41
+ Permanently removes a memory from the database. Use when the memory is clearly wrong or contains sensitive data.
42
+
43
+ ```bash
44
+ ./.aide/bin/aide memory delete <MEMORY_ID>
45
+ ```
46
+
47
+ ### Unforget (Recover)
48
+
49
+ Remove the `forget` tag to restore a soft-deleted memory.
50
+
51
+ ```bash
52
+ ./.aide/bin/aide memory tag <MEMORY_ID> --remove=forget
53
+ ```
54
+
55
+ ## Workflow
56
+
57
+ When the user wants to forget, correct, or supersede a memory:
58
+
59
+ ### Step 1: Find the Memory
60
+
61
+ Search for the memory to identify its ID:
62
+
63
+ ```bash
64
+ # Search by content keywords
65
+ ./.aide/bin/aide memory search "<keywords>" --full --limit=10
66
+
67
+ # If the memory might already be forgotten, include all
68
+ ./.aide/bin/aide memory list --all
69
+ ```
70
+
71
+ ### Step 2: Confirm with User
72
+
73
+ Before deleting or forgetting, show the user what was found and confirm which memories to act on. Display the memory ID, content, and tags.
74
+
75
+ ### Step 3: Apply the Appropriate Action
76
+
77
+ Choose based on the situation:
78
+
79
+ | Situation | Action | Command |
80
+ | ------------------------------------ | --------------------------------------- | -------------------------------------- |
81
+ | Memory is outdated but was once true | Soft delete (forget) | `aide memory tag <ID> --add=forget` |
82
+ | Memory is factually wrong | Hard delete | `aide memory delete <ID>` |
83
+ | Memory is resolved (issue fixed) | Soft delete + optionally add resolution | See "Superseding" below |
84
+ | Memory contains sensitive data | Hard delete | `aide memory delete <ID>` |
85
+ | Memory was accidentally forgotten | Unforget | `aide memory tag <ID> --remove=forget` |
86
+
87
+ ### Step 4: Optionally Add a Replacement
88
+
89
+ If the memory is being superseded (not just deleted), add a new corrected memory **without** the `forget` tag:
90
+
91
+ ```bash
92
+ # 1. Forget the old memory
93
+ ./.aide/bin/aide memory tag <OLD_ID> --add=forget
94
+
95
+ # 2. Add the corrected memory (NO forget tag)
96
+ ./.aide/bin/aide memory add --category=<category> --tags=<relevant,tags> "<corrected content>"
97
+ ```
98
+
99
+ ### Step 5: Verify
100
+
101
+ Confirm the memory is no longer visible in normal searches:
102
+
103
+ ```bash
104
+ # Should NOT appear in normal search
105
+ ./.aide/bin/aide memory search "<keywords>"
106
+
107
+ # Should appear with --all flag
108
+ ./.aide/bin/aide memory list --all
109
+ ```
110
+
111
+ ## Anti-Patterns (AVOID)
112
+
113
+ ### DO NOT add a new memory with the forget tag to "supersede" an old one
114
+
115
+ This is the most common mistake. Adding a new memory tagged `forget` does nothing useful:
116
+
117
+ - The new "superseding" memory is immediately hidden (because it has the `forget` tag)
118
+ - The original incorrect memory remains visible and active
119
+
120
+ **Wrong:**
121
+
122
+ ```bash
123
+ # BAD - creates a hidden memory, leaves the original untouched
124
+ aide memory add --tags="forget,some-topic" "RESOLVED: the old issue is fixed"
125
+ ```
126
+
127
+ **Correct:**
128
+
129
+ ```bash
130
+ # GOOD - forget the original, add a visible replacement
131
+ aide memory tag <ORIGINAL_ID> --add=forget
132
+ aide memory add --tags="some-topic" "RESOLVED: the old issue is fixed"
133
+ ```
134
+
135
+ ### DO NOT guess memory IDs
136
+
137
+ Always search first to find the exact memory ID. Memory IDs are ULIDs (e.g., `01KJ3X7GMQET613WMPT7JT8GYD`).
138
+
139
+ ### DO NOT forget memories without user confirmation
140
+
141
+ Always show the user what will be affected and get confirmation before acting, especially for hard deletes.
142
+
143
+ ## Batch Operations
144
+
145
+ To forget multiple related memories:
146
+
147
+ ```bash
148
+ # Search for all related memories
149
+ ./.aide/bin/aide memory search "<topic>" --full --limit=50
150
+
151
+ # Forget each one (after user confirmation)
152
+ ./.aide/bin/aide memory tag <ID1> --add=forget
153
+ ./.aide/bin/aide memory tag <ID2> --add=forget
154
+ ```
155
+
156
+ To clear ALL memories (destructive, requires explicit user request):
157
+
158
+ ```bash
159
+ ./.aide/bin/aide memory clear
160
+ ```
161
+
162
+ ## Examples
163
+
164
+ ### User says "that thing about ESM imports is wrong"
165
+
166
+ ```bash
167
+ # 1. Find the memory
168
+ ./.aide/bin/aide memory search "ESM imports" --full
169
+
170
+ # 2. Show user and confirm
171
+ # "Found memory 01KJ... about ESM imports requiring .js extensions. Delete this?"
172
+
173
+ # 3. Soft delete
174
+ ./.aide/bin/aide memory tag 01KJ3XVFXBFTKKH1M500N6R5 --add=forget
175
+ ```
176
+
177
+ ### User says "we changed from JWT to sessions, update the memory"
178
+
179
+ ```bash
180
+ # 1. Find the old memory
181
+ ./.aide/bin/aide memory search "JWT auth" --full
182
+
183
+ # 2. Forget the old one
184
+ ./.aide/bin/aide memory tag <OLD_ID> --add=forget
185
+
186
+ # 3. Add the corrected one
187
+ ./.aide/bin/aide memory add --category=decision --tags=auth,sessions,project:myapp "Auth strategy changed from JWT to server-side sessions with Redis store"
188
+ ```
189
+
190
+ ### User says "recover that forgotten memory about testing"
191
+
192
+ ```bash
193
+ # 1. Find forgotten memories
194
+ ./.aide/bin/aide memory list --all
195
+
196
+ # 2. Unforget it
197
+ ./.aide/bin/aide memory tag <ID> --remove=forget
198
+ ```
199
+
200
+ ## Failure Handling
201
+
202
+ If `aide memory tag` fails:
203
+
204
+ 1. **"memory not found"** - The ID may be wrong. Re-search with `--all` flag to include forgotten memories.
205
+ 2. **Panic/crash** - If the tag command panics, fall back to delete + re-add:
206
+ ```bash
207
+ # Workaround: get memory content, delete, re-add with forget tag
208
+ ./.aide/bin/aide memory list --all # Find the memory content
209
+ ./.aide/bin/aide memory delete <ID>
210
+ ./.aide/bin/aide memory add --category=<cat> --tags=<existing-tags>,forget "<content>"
211
+ ```
212
+ 3. **Database locked** - Another process may hold the lock. Wait and retry, or ensure the aide daemon is running (CLI routes through gRPC when daemon is active).
213
+
214
+ ## Verification
215
+
216
+ After forgetting a memory, verify:
217
+
218
+ ```bash
219
+ # Memory should NOT appear here
220
+ ./.aide/bin/aide memory search "<term>"
221
+
222
+ # Memory SHOULD appear here (with forget tag)
223
+ ./.aide/bin/aide memory list --all
224
+ ```
@@ -51,10 +51,19 @@ Understand what the tests expect:
51
51
  - What edge cases are covered?
52
52
 
53
53
  ```bash
54
- # Read the test file
54
+ # For large test files, get the structure first
55
+ mcp__plugin_aide_aide__code_outline file="path/to/feature.test.ts"
56
+
57
+ # Then read specific test sections with offset/limit
58
+ Read path/to/feature.test.ts offset=<start> limit=<count>
59
+
60
+ # For small test files (<100 lines), reading the full file is fine
55
61
  Read path/to/feature.test.ts
56
62
  ```
57
63
 
64
+ When implementing, use `code_outline` on adjacent/related source files to understand
65
+ their structure before reading them fully. This preserves context for the implementation work.
66
+
58
67
  ### Step 3: Check Design Decisions
59
68
 
60
69
  Use `mcp__plugin_aide_aide__decision_get` with the feature topic to review decisions from DESIGN stage.
@@ -19,6 +19,7 @@ Systematic approach to identifying and fixing performance issues.
19
19
  ## Prerequisites
20
20
 
21
21
  Before starting:
22
+
22
23
  - Identify the specific operation or endpoint that is slow
23
24
  - Understand what "fast enough" means (target latency, throughput)
24
25
  - Ensure you can measure performance reproducibly
@@ -45,6 +46,7 @@ curl -w "@curl-format.txt" -o /dev/null -s "http://localhost:3000/api/endpoint"
45
46
  ```
46
47
 
47
48
  **Record baseline metrics:**
49
+
48
50
  - Execution time (p50, p95, p99 if available)
49
51
  - Memory usage
50
52
  - Number of operations per second
@@ -65,30 +67,42 @@ go tool pprof -http=:8080 cpu.prof
65
67
  ```
66
68
 
67
69
  ```
68
- # Search for common expensive patterns
69
- mcp__plugin_aide_aide__code_search query="forEach" kind="function"
70
- mcp__plugin_aide_aide__code_search query="map" kind="function"
70
+ # Get structural overview of suspect files (signatures + line ranges, not full content)
71
+ mcp__plugin_aide_aide__code_outline file="path/to/hotspot.ts"
71
72
 
72
- # Find database queries
73
- Grep for "SELECT", "find(", "query("
73
+ # Find functions/classes in suspect area by name
74
+ mcp__plugin_aide_aide__code_search query="processData" kind="function"
74
75
 
75
- # Find network calls
76
- Grep for "fetch", "axios", "http.Get"
76
+ # Find all callers of a hot function
77
+ mcp__plugin_aide_aide__code_references symbol="processData"
78
+
79
+ # Search for expensive patterns in code bodies (Grep is better here)
80
+ Grep for ".forEach(", ".map(", ".filter(" # Loop/iteration patterns
81
+ Grep for "SELECT", "find(", "query(" # Database queries
82
+ Grep for "fetch(", "axios", "http.Get" # Network calls
83
+ Grep for "setTimeout", "setInterval" # Timers
84
+ Grep for "JSON.parse", "JSON.stringify" # Serialization
77
85
  ```
78
86
 
87
+ Note: `code_search` finds function/class/type _definitions_ by name.
88
+ For patterns inside function bodies (loops, queries, call chains), use Grep.
89
+
90
+ After identifying hotspot functions via profiling and search, use `Read` with offset/limit to read
91
+ specific functions (use line numbers from `code_outline`).
92
+
79
93
  ### Step 3: Analyze Performance Patterns
80
94
 
81
95
  Look for these common issues:
82
96
 
83
- | Issue | Pattern | Solution |
84
- |-------|---------|----------|
85
- | N+1 queries | Loop containing DB call | Batch/eager load |
86
- | Repeated computation | Same calculation in loop | Memoize/cache |
87
- | Large allocations | Creating objects in loop | Reuse/pool objects |
88
- | Blocking I/O | Sync file/network ops | Make async/concurrent |
89
- | Missing indexes | Slow DB queries | Add database indexes |
90
- | Unnecessary work | Processing unused data | Filter/skip early |
91
- | Serial execution | Sequential independent ops | Parallelize |
97
+ | Issue | Pattern | Solution |
98
+ | -------------------- | -------------------------- | --------------------- |
99
+ | N+1 queries | Loop containing DB call | Batch/eager load |
100
+ | Repeated computation | Same calculation in loop | Memoize/cache |
101
+ | Large allocations | Creating objects in loop | Reuse/pool objects |
102
+ | Blocking I/O | Sync file/network ops | Make async/concurrent |
103
+ | Missing indexes | Slow DB queries | Add database indexes |
104
+ | Unnecessary work | Processing unused data | Filter/skip early |
105
+ | Serial execution | Sequential independent ops | Parallelize |
92
106
 
93
107
  ### Step 4: Apply Optimizations
94
108
 
@@ -111,6 +125,7 @@ go test -bench=. -benchmem ./...
111
125
  ```
112
126
 
113
127
  Compare:
128
+
114
129
  - Did the metric improve?
115
130
  - By how much (percentage)?
116
131
  - Any negative side effects?
@@ -130,13 +145,13 @@ go test ./...
130
145
 
131
146
  ## Failure Handling
132
147
 
133
- | Situation | Action |
134
- |-----------|--------|
135
- | Cannot measure reliably | Increase sample size, reduce variance sources |
136
- | Optimization made it slower | Revert, analyze why, profile more carefully |
137
- | Optimization broke tests | Fix tests or revert if behavior changed |
138
- | Bottleneck is external | Document, consider caching, async processing |
139
- | Memory improved but CPU worse | Evaluate trade-off for use case |
148
+ | Situation | Action |
149
+ | ----------------------------- | --------------------------------------------- |
150
+ | Cannot measure reliably | Increase sample size, reduce variance sources |
151
+ | Optimization made it slower | Revert, analyze why, profile more carefully |
152
+ | Optimization broke tests | Fix tests or revert if behavior changed |
153
+ | Bottleneck is external | Document, consider caching, async processing |
154
+ | Memory improved but CPU worse | Evaluate trade-off for use case |
140
155
 
141
156
  ## Common Optimizations
142
157
 
@@ -149,12 +164,12 @@ for (const user of users) {
149
164
  }
150
165
 
151
166
  // GOOD: Batch query
152
- const userIds = users.map(u => u.id);
167
+ const userIds = users.map((u) => u.id);
153
168
  const posts = await db.getPostsForUsers(userIds);
154
169
 
155
170
  // BAD: Repeated work
156
- const typeA = items.filter(x => x.type === 'a').map(x => x.value);
157
- const typeB = items.filter(x => x.type === 'b').map(x => x.value);
171
+ const typeA = items.filter((x) => x.type === "a").map((x) => x.value);
172
+ const typeB = items.filter((x) => x.type === "b").map((x) => x.value);
158
173
 
159
174
  // GOOD: Single pass
160
175
  const grouped = { a: [], b: [] };
@@ -167,10 +182,7 @@ const result1 = await fetch(url1);
167
182
  const result2 = await fetch(url2);
168
183
 
169
184
  // GOOD: Parallel async
170
- const [result1, result2] = await Promise.all([
171
- fetch(url1),
172
- fetch(url2)
173
- ]);
185
+ const [result1, result2] = await Promise.all([fetch(url1), fetch(url2)]);
174
186
  ```
175
187
 
176
188
  ### Go
@@ -225,13 +237,17 @@ SELECT * FROM posts WHERE user_id IN (?, ?, ?);
225
237
 
226
238
  ## MCP Tools
227
239
 
228
- - `mcp__plugin_aide_aide__code_search` - Find loops, queries, expensive operations
229
- - `mcp__plugin_aide_aide__code_symbols` - Understand function structure
240
+ - `mcp__plugin_aide_aide__code_outline` - **Start here.** Get collapsed file skeleton to identify functions before reading
241
+ - `mcp__plugin_aide_aide__code_search` - Find function/class/type definitions by name
242
+ - `mcp__plugin_aide_aide__code_symbols` - List all symbol definitions in a file
243
+ - `mcp__plugin_aide_aide__code_references` - Find all callers of a hot function (exact name match)
230
244
  - `mcp__plugin_aide_aide__memory_search` - Check past performance decisions
245
+ - **Grep** - Find code patterns in bodies: loops, queries, call chains, string literals
231
246
 
232
247
  ## Profiling Commands Reference
233
248
 
234
249
  ### Node.js
250
+
235
251
  ```bash
236
252
  # CPU profiling
237
253
  node --cpu-prof app.js
@@ -247,6 +263,7 @@ npx clinic flame -- node app.js
247
263
  ```
248
264
 
249
265
  ### Go
266
+
250
267
  ```bash
251
268
  # CPU profiling
252
269
  go test -cpuprofile=cpu.prof -bench=.
@@ -262,6 +279,7 @@ go tool trace trace.out
262
279
  ```
263
280
 
264
281
  ### Browser
282
+
265
283
  - DevTools -> Performance -> Record
266
284
  - DevTools -> Memory -> Heap snapshot
267
285
  - Lighthouse for overall page performance
@@ -269,6 +287,7 @@ go tool trace trace.out
269
287
  ## Verification Criteria
270
288
 
271
289
  Before completing:
290
+
272
291
  - [ ] Baseline measurement recorded
273
292
  - [ ] Improvement quantified (percentage)
274
293
  - [ ] All tests still pass
@@ -281,25 +300,30 @@ Before completing:
281
300
  ## Performance Analysis: [Operation/Endpoint Name]
282
301
 
283
302
  ### Baseline
303
+
284
304
  - Execution time: 450ms (p50), 680ms (p95)
285
305
  - Memory: 125MB peak
286
306
  - Database queries: 150
287
307
 
288
308
  ### Hotspots Identified
309
+
289
310
  1. `db.getUsers()` - 300ms (67% of total)
290
311
  2. `processData()` - 100ms (22% of total)
291
312
  3. `formatOutput()` - 50ms (11% of total)
292
313
 
293
314
  ### Optimizations Applied
315
+
294
316
  1. Batched user queries - 300ms -> 50ms
295
317
  2. Memoized processData for repeated calls - 100ms -> 5ms
296
318
 
297
319
  ### Results
320
+
298
321
  - Execution time: 450ms -> 105ms (77% faster)
299
322
  - Memory: 125MB -> 80MB (36% reduction)
300
323
  - Database queries: 150 -> 3 (98% reduction)
301
324
 
302
325
  ### Verification
326
+
303
327
  - All tests: PASS
304
328
  - Output correctness: VERIFIED
305
329
  ```
@@ -18,6 +18,7 @@ Comprehensive code review covering quality, security, and maintainability.
18
18
  ## Review Checklist
19
19
 
20
20
  ### Code Quality
21
+
21
22
  - [ ] Clear naming (variables, functions, classes)
22
23
  - [ ] Single responsibility (functions do one thing)
23
24
  - [ ] DRY (no unnecessary duplication)
@@ -26,6 +27,7 @@ Comprehensive code review covering quality, security, and maintainability.
26
27
  - [ ] Edge cases considered
27
28
 
28
29
  ### Security (OWASP Top 10)
30
+
29
31
  - [ ] Input validation (no injection vulnerabilities)
30
32
  - [ ] Authentication checks (routes protected)
31
33
  - [ ] Authorization (proper access control)
@@ -36,6 +38,7 @@ Comprehensive code review covering quality, security, and maintainability.
36
38
  - [ ] Secure dependencies (no known vulnerabilities)
37
39
 
38
40
  ### Maintainability
41
+
39
42
  - [ ] Code is readable without comments
40
43
  - [ ] Comments explain "why" not "what"
41
44
  - [ ] Consistent with codebase patterns
@@ -43,28 +46,47 @@ Comprehensive code review covering quality, security, and maintainability.
43
46
  - [ ] No dead code
44
47
 
45
48
  ### Performance
49
+
46
50
  - [ ] No N+1 queries
47
51
  - [ ] Appropriate caching
48
52
  - [ ] No memory leaks
49
53
  - [ ] Efficient algorithms
50
54
 
55
+ ## Context-Efficient Reading
56
+
57
+ Prefer lightweight tools first, then read in detail where needed:
58
+
59
+ - **`code_outline`** -- Collapsed skeleton with signatures and line ranges. Great first step for unfamiliar files.
60
+ - **`code_symbols`** -- Quick symbol list when you only need names and kinds.
61
+ - **`code_search`** / **`code_references`** -- Find symbol definitions or callers across the codebase.
62
+ - **`Read` with offset/limit** -- Read specific functions using line numbers from the outline.
63
+ - **Grep** -- Find patterns in code content (loops, queries, string literals) that the index doesn't cover.
64
+
65
+ For reviews spanning many files, consider using **Task sub-agents** (`explore` type) which run in their
66
+ own context and return summaries.
67
+
51
68
  ## Review Process
52
69
 
53
- 1. **Read the diff/files** - Understand what changed
54
- 2. **Search for context** - Use `code_search` MCP tool to find:
55
- - Related symbols that might be affected
56
- - Other usages of modified functions/classes
57
- - Similar patterns in the codebase
58
- 3. **Check integration** - How does it fit the larger system?
59
- 4. **Run static analysis** - Use lsp_diagnostics, ast_grep if available
60
- 5. **Document findings** - Use severity levels
70
+ 1. **Outline changed files** - Use `code_outline` on each changed file to understand structure.
71
+ Identify areas of concern from signatures and line ranges.
72
+ 2. **Read targeted sections** - Use `Read` with `offset`/`limit` to read only the specific
73
+ functions/sections that need detailed review (use line numbers from the outline).
74
+ 3. **Search for context** - Use `code_search`, `code_references`, and **Grep**:
75
+ - `code_search` Find related function/class/type _definitions_ by name
76
+ - `code_references` Find all callers/usages of a modified symbol (exact name match)
77
+ - **Grep** Find code _patterns_ in bodies (error handling, SQL queries, security-sensitive calls)
78
+ 4. **Check integration** - How does it fit the larger system?
79
+ 5. **Run static analysis** - Use lsp_diagnostics, ast_grep if available
80
+ 6. **Document findings** - Use severity levels
61
81
 
62
82
  ## MCP Tools
63
83
 
64
84
  Use these tools during review:
65
85
 
86
+ - `mcp__plugin_aide_aide__code_outline` - **Start here.** Get collapsed file skeleton with signatures and line ranges
66
87
  - `mcp__plugin_aide_aide__code_search` - Find symbols related to changes (e.g., `code_search query="getUserById"`)
67
88
  - `mcp__plugin_aide_aide__code_symbols` - List all symbols in a file being reviewed
89
+ - `mcp__plugin_aide_aide__code_references` - Find all callers/usages of a modified symbol
68
90
  - `mcp__plugin_aide_aide__memory_search` - Check for related past decisions or issues
69
91
 
70
92
  ## Output Format
@@ -73,28 +95,34 @@ Use these tools during review:
73
95
  ## Code Review: [Feature/PR Name]
74
96
 
75
97
  ### Summary
98
+
76
99
  [1-2 sentence overview]
77
100
 
78
101
  ### Findings
79
102
 
80
103
  #### 🔴 Critical (must fix)
104
+
81
105
  - **[Issue]** `file:line`
82
106
  - Problem: [description]
83
107
  - Fix: [recommendation]
84
108
 
85
109
  #### 🟡 Warning (should fix)
110
+
86
111
  - **[Issue]** `file:line`
87
112
  - Problem: [description]
88
113
  - Fix: [recommendation]
89
114
 
90
115
  #### 🔵 Suggestion (consider)
116
+
91
117
  - **[Issue]** `file:line`
92
118
  - Suggestion: [recommendation]
93
119
 
94
120
  ### Security Notes
121
+
95
122
  - [Any security-specific observations]
96
123
 
97
124
  ### Verdict
125
+
98
126
  [ ] ✅ Approve
99
127
  [ ] ⚠️ Approve with comments
100
128
  [ ] ❌ Request changes
@@ -102,11 +130,11 @@ Use these tools during review:
102
130
 
103
131
  ## Severity Guide
104
132
 
105
- | Level | Criteria |
106
- |-------|----------|
107
- | Critical | Security vulnerability, data loss risk, crash |
108
- | Warning | Bug potential, maintainability issue, performance |
109
- | Suggestion | Style, minor improvement, optional |
133
+ | Level | Criteria |
134
+ | ---------- | ------------------------------------------------- |
135
+ | Critical | Security vulnerability, data loss risk, crash |
136
+ | Warning | Bug potential, maintainability issue, performance |
137
+ | Suggestion | Style, minor improvement, optional |
110
138
 
111
139
  ## Failure Handling
112
140
 
@@ -122,10 +150,12 @@ Use these tools during review:
122
150
  ## Review Status: Incomplete
123
151
 
124
152
  ### Blockers
153
+
125
154
  - Could not access: `path/to/file.ts` (permission denied)
126
155
  - Missing context: Need to understand `AuthService` implementation
127
156
 
128
157
  ### Partial Findings
158
+
129
159
  [Include any findings from files that were reviewed]
130
160
  ```
131
161
 
@@ -133,14 +163,16 @@ Use these tools during review:
133
163
 
134
164
  A complete code review must:
135
165
 
136
- 1. **Read all changed files** - Verify each file was actually read
137
- 2. **Check for related code** - Use code search to find callers/callees
138
- 3. **Verify test coverage** - Check if tests exist for critical paths
139
- 4. **Document all findings** - Even if no issues found, state that explicitly
166
+ 1. **Outline all changed files** - Use `code_outline` on every file in scope
167
+ 2. **Read critical sections** - Use targeted `Read` with offset/limit on flagged areas
168
+ 3. **Check for related code** - Use `code_search` and `code_references` to find callers/callees
169
+ 4. **Verify test coverage** - Check if tests exist for critical paths
170
+ 5. **Document all findings** - Even if no issues found, state that explicitly
140
171
 
141
172
  ### Checklist before submitting review:
142
173
 
143
- - [ ] All files in diff/scope have been read
174
+ - [ ] All files in diff/scope have been outlined
175
+ - [ ] Critical functions/sections read in detail (with offset/limit)
144
176
  - [ ] Related symbols searched (callers, implementations)
145
177
  - [ ] Security checklist evaluated
146
178
  - [ ] Findings documented with file:line references
@@ -17,6 +17,7 @@ Write comprehensive tests and run test suites.
17
17
  ## Prerequisites
18
18
 
19
19
  Before starting:
20
+
20
21
  - Identify the code to be tested (function, module, feature)
21
22
  - Understand the testing framework used in the project
22
23
 
@@ -27,6 +28,7 @@ Before starting:
27
28
  Use the `mcp__plugin_aide_aide__decision_get` tool with topic `testing` to check for testing framework decisions.
28
29
 
29
30
  Common frameworks by language:
31
+
30
32
  - **TypeScript/JavaScript:** Vitest, Jest, Mocha
31
33
  - **Go:** built-in `go test`
32
34
  - **Python:** pytest, unittest
@@ -34,13 +36,18 @@ Common frameworks by language:
34
36
  ### Step 2: Discover Existing Test Patterns
35
37
 
36
38
  Use `Glob` to find test files:
39
+
37
40
  - Pattern: `**/*.test.ts`, `**/*.spec.ts` (TypeScript)
38
41
  - Pattern: `**/*_test.go` (Go)
39
42
  - Pattern: `**/test_*.py`, `**/*_test.py` (Python)
40
43
 
41
- Use `mcp__plugin_aide_aide__code_search` with query `describe` and `it` to find test patterns.
44
+ Use **Grep** to find test patterns in existing test files:
45
+
46
+ - `Grep pattern="describe\(" include="*.test.*"` — find test suites
47
+ - `Grep pattern="it\(|test\(" include="*.test.*"` — find test cases
42
48
 
43
49
  Read an existing test file to understand:
50
+
44
51
  - Import patterns
45
52
  - Setup/teardown patterns
46
53
  - Mocking approach
@@ -52,6 +59,7 @@ Use `mcp__plugin_aide_aide__code_symbols` with the target file path to get funct
52
59
  Use `mcp__plugin_aide_aide__code_search` to find related types.
53
60
 
54
61
  Identify:
62
+
55
63
  - Input parameters and types
56
64
  - Return type
57
65
  - Side effects
@@ -63,12 +71,14 @@ Identify:
63
71
  Follow the project's testing conventions. Cover these scenarios:
64
72
 
65
73
  **Test Categories:**
74
+
66
75
  1. **Happy path** - Normal, expected inputs
67
76
  2. **Edge cases** - Empty, null, boundary values
68
77
  3. **Error cases** - Invalid inputs, expected failures
69
78
  4. **Async behavior** - If applicable
70
79
 
71
80
  **Naming convention:**
81
+
72
82
  - Descriptive names that explain what is being tested
73
83
  - Format: "should [expected behavior] when [condition]"
74
84
 
@@ -103,51 +113,52 @@ go tool cover -html=coverage.out
103
113
  ```
104
114
 
105
115
  **Coverage targets:**
116
+
106
117
  - New code: aim for >80%
107
118
  - Critical paths: aim for >90%
108
119
  - Focus on meaningful tests, not just coverage numbers
109
120
 
110
121
  ## Failure Handling
111
122
 
112
- | Failure | Action |
113
- |---------|--------|
114
- | Test imports fail | Check path aliases, ensure test config matches main |
115
- | Mock not working | Verify mock setup, check dependency injection |
116
- | Async test timeout | Add proper await, increase timeout if needed |
117
- | Flaky test | Check for shared state, timing issues, or external deps |
118
- | Coverage too low | Add edge case tests, error path tests |
123
+ | Failure | Action |
124
+ | ------------------ | ------------------------------------------------------- |
125
+ | Test imports fail | Check path aliases, ensure test config matches main |
126
+ | Mock not working | Verify mock setup, check dependency injection |
127
+ | Async test timeout | Add proper await, increase timeout if needed |
128
+ | Flaky test | Check for shared state, timing issues, or external deps |
129
+ | Coverage too low | Add edge case tests, error path tests |
119
130
 
120
131
  ## Test Structure Templates
121
132
 
122
133
  ### TypeScript/JavaScript (Vitest/Jest)
123
134
 
124
135
  ```typescript
125
- import { describe, it, expect, beforeEach, vi } from 'vitest';
126
- import { functionToTest } from './module';
136
+ import { describe, it, expect, beforeEach, vi } from "vitest";
137
+ import { functionToTest } from "./module";
127
138
 
128
- describe('functionToTest', () => {
139
+ describe("functionToTest", () => {
129
140
  beforeEach(() => {
130
141
  // Reset state before each test
131
142
  vi.clearAllMocks();
132
143
  });
133
144
 
134
- it('should return expected result for valid input', () => {
135
- const result = functionToTest('valid input');
136
- expect(result).toBe('expected output');
145
+ it("should return expected result for valid input", () => {
146
+ const result = functionToTest("valid input");
147
+ expect(result).toBe("expected output");
137
148
  });
138
149
 
139
- it('should handle empty input', () => {
140
- const result = functionToTest('');
141
- expect(result).toBe('');
150
+ it("should handle empty input", () => {
151
+ const result = functionToTest("");
152
+ expect(result).toBe("");
142
153
  });
143
154
 
144
- it('should throw error for null input', () => {
145
- expect(() => functionToTest(null)).toThrow('Input required');
155
+ it("should throw error for null input", () => {
156
+ expect(() => functionToTest(null)).toThrow("Input required");
146
157
  });
147
158
 
148
- it('should handle async operation', async () => {
149
- const result = await functionToTest('async input');
150
- expect(result).resolves.toBe('async output');
159
+ it("should handle async operation", async () => {
160
+ const result = await functionToTest("async input");
161
+ expect(result).resolves.toBe("async output");
151
162
  });
152
163
  });
153
164
  ```
@@ -213,6 +224,7 @@ class TestFunctionToTest:
213
224
  ## Verification Criteria
214
225
 
215
226
  Before completing:
227
+
216
228
  - [ ] All new tests pass
217
229
  - [ ] Existing tests still pass
218
230
  - [ ] Coverage meets project standards
@@ -225,9 +237,11 @@ Before completing:
225
237
  ## Tests Added
226
238
 
227
239
  ### Files
240
+
228
241
  - `path/to/file.test.ts` - 5 tests for UserService
229
242
 
230
243
  ### Test Cases
244
+
231
245
  1. should create user with valid data
232
246
  2. should reject duplicate email
233
247
  3. should hash password before saving
@@ -235,10 +249,12 @@ Before completing:
235
249
  5. should validate email format
236
250
 
237
251
  ### Coverage
252
+
238
253
  - New code: 92%
239
254
  - Total project: 84%
240
255
 
241
256
  ### Verification
257
+
242
258
  - All tests: PASS
243
259
  - No flaky tests observed
244
260
  ```
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Context Guard — platform-agnostic core logic.
3
+ *
4
+ * Monitors Read tool calls and advises agents to use code_outline
5
+ * before reading large files. This preserves context window for
6
+ * the actual task by avoiding dumping entire files into conversation.
7
+ *
8
+ * Behaviour:
9
+ * - Triggers on Read tool calls for files > 5KB (~150 lines)
10
+ * - Tracks which files have been outlined (code_outline/code_symbols)
11
+ * - Returns an advisory message (never blocks)
12
+ * - Also tracks code_outline/code_symbols calls to mark files as "known"
13
+ *
14
+ * Used by both Claude Code hooks (PreToolUse) and OpenCode plugin.
15
+ */
16
+
17
+ import { statSync, readFileSync, writeFileSync, existsSync } from "fs";
18
+ import { resolve, isAbsolute, normalize } from "path";
19
+ import { tmpdir } from "os";
20
+ import { join } from "path";
21
+ import { debug } from "../lib/logger.js";
22
+
23
+ const SOURCE = "context-guard";
24
+
25
+ /** Default size threshold in bytes (~150 lines) */
26
+ const DEFAULT_SIZE_THRESHOLD = 5120;
27
+
28
+ /** File extensions that are typically not source code (skip advisory) */
29
+ const SKIP_EXTENSIONS = new Set([
30
+ ".json",
31
+ ".lock",
32
+ ".sum",
33
+ ".mod",
34
+ ".yaml",
35
+ ".yml",
36
+ ".toml",
37
+ ".env",
38
+ ".md",
39
+ ".txt",
40
+ ".csv",
41
+ ".svg",
42
+ ".png",
43
+ ".jpg",
44
+ ".gif",
45
+ ".ico",
46
+ ".woff",
47
+ ".woff2",
48
+ ".ttf",
49
+ ".eot",
50
+ ]);
51
+
52
+ export interface ContextGuardResult {
53
+ /** Whether to inject an advisory message */
54
+ shouldAdvise: boolean;
55
+ /** Advisory message to inject */
56
+ advisory?: string;
57
+ /** Whether this call should be tracked (code_outline/code_symbols) */
58
+ tracked?: boolean;
59
+ }
60
+
61
+ /**
62
+ * Get the path to the tracking file for this session.
63
+ */
64
+ function getTrackingPath(sessionId: string): string {
65
+ return join(tmpdir(), `aide-context-guard-${sessionId}.json`);
66
+ }
67
+
68
+ /**
69
+ * Load the set of files that have been outlined in this session.
70
+ */
71
+ function loadOutlinedFiles(sessionId: string): Set<string> {
72
+ const trackingPath = getTrackingPath(sessionId);
73
+ try {
74
+ if (existsSync(trackingPath)) {
75
+ const data = JSON.parse(readFileSync(trackingPath, "utf-8"));
76
+ return new Set(data.files || []);
77
+ }
78
+ } catch {
79
+ // Corrupted file, start fresh
80
+ }
81
+ return new Set();
82
+ }
83
+
84
+ /**
85
+ * Save a file as "outlined" in the tracking file.
86
+ */
87
+ function trackOutlinedFile(sessionId: string, filePath: string): void {
88
+ const files = loadOutlinedFiles(sessionId);
89
+ files.add(filePath);
90
+ const trackingPath = getTrackingPath(sessionId);
91
+ try {
92
+ writeFileSync(
93
+ trackingPath,
94
+ JSON.stringify({ files: Array.from(files) }),
95
+ "utf-8",
96
+ );
97
+ } catch (err) {
98
+ debug(SOURCE, `Failed to write tracking file: ${err}`);
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Estimate line count from file size (rough: ~35 bytes per line average).
104
+ */
105
+ function estimateLines(sizeBytes: number): number {
106
+ return Math.round(sizeBytes / 35);
107
+ }
108
+
109
+ /**
110
+ * Check whether a Read call should receive a context-efficiency advisory.
111
+ *
112
+ * Also handles tracking code_outline/code_symbols calls.
113
+ */
114
+ export function checkContextGuard(
115
+ toolName: string,
116
+ toolInput: Record<string, unknown>,
117
+ cwd: string,
118
+ sessionId: string,
119
+ ): ContextGuardResult {
120
+ const normalizedTool = toolName.toLowerCase();
121
+
122
+ // Track code_outline and code_symbols calls
123
+ if (
124
+ normalizedTool.includes("code_outline") ||
125
+ normalizedTool.includes("code_symbols")
126
+ ) {
127
+ const filePath =
128
+ (toolInput.file as string) ||
129
+ (toolInput.filePath as string) ||
130
+ (toolInput.file_path as string);
131
+ if (filePath && sessionId) {
132
+ const resolved = normalize(
133
+ isAbsolute(filePath) ? filePath : resolve(cwd, filePath),
134
+ );
135
+ trackOutlinedFile(sessionId, resolved);
136
+ debug(SOURCE, `Tracked outline for: ${filePath}`);
137
+ }
138
+ return { shouldAdvise: false, tracked: true };
139
+ }
140
+
141
+ // Only advise on Read tool calls
142
+ if (normalizedTool !== "read") {
143
+ return { shouldAdvise: false };
144
+ }
145
+
146
+ // Extract file path from tool input
147
+ const filePath =
148
+ (toolInput.filePath as string) ||
149
+ (toolInput.file_path as string) ||
150
+ (toolInput.path as string);
151
+
152
+ if (!filePath) {
153
+ return { shouldAdvise: false };
154
+ }
155
+
156
+ // Resolve to absolute path
157
+ const resolvedPath = normalize(
158
+ isAbsolute(filePath) ? filePath : resolve(cwd, filePath),
159
+ );
160
+
161
+ // Skip non-source-code files
162
+ const ext = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
163
+ if (SKIP_EXTENSIONS.has(ext)) {
164
+ return { shouldAdvise: false };
165
+ }
166
+
167
+ // Check if the agent is already using offset/limit (targeted read)
168
+ const offset = toolInput.offset as number | undefined;
169
+ const limit = toolInput.limit as number | undefined;
170
+ if (offset !== undefined && offset > 1) {
171
+ // Agent is doing a targeted read — no advisory needed
172
+ return { shouldAdvise: false };
173
+ }
174
+ if (limit !== undefined && limit < 100) {
175
+ // Agent is limiting the read — no advisory needed
176
+ return { shouldAdvise: false };
177
+ }
178
+
179
+ // Check file size
180
+ let fileSize: number;
181
+ try {
182
+ const stat = statSync(resolvedPath);
183
+ fileSize = stat.size;
184
+ } catch {
185
+ // Can't stat file — don't advise (file might not exist yet)
186
+ return { shouldAdvise: false };
187
+ }
188
+
189
+ // Skip small files
190
+ if (fileSize < DEFAULT_SIZE_THRESHOLD) {
191
+ return { shouldAdvise: false };
192
+ }
193
+
194
+ // Check if this file has already been outlined in this session
195
+ if (sessionId) {
196
+ const outlinedFiles = loadOutlinedFiles(sessionId);
197
+ if (outlinedFiles.has(resolvedPath)) {
198
+ debug(SOURCE, `File already outlined, skipping advisory: ${filePath}`);
199
+ return { shouldAdvise: false };
200
+ }
201
+ }
202
+
203
+ // Generate advisory
204
+ const estLines = estimateLines(fileSize);
205
+ const sizeKB = (fileSize / 1024).toFixed(1);
206
+
207
+ const advisory =
208
+ `[aide:context] This file is ~${estLines} lines (${sizeKB}KB). Consider using \`code_outline\` ` +
209
+ `first to see its structure, then \`Read\` with offset/limit for specific sections. ` +
210
+ `This preserves your context window for the full task.`;
211
+
212
+ debug(SOURCE, `Advisory for ${filePath}: ${estLines} lines, ${sizeKB}KB`);
213
+ return { shouldAdvise: true, advisory };
214
+ }
@@ -156,8 +156,8 @@ export const AidePlugin: Plugin = async (ctx: PluginInput): Promise<Hooks> => {
156
156
  // Plugin may be called before the client is fully ready
157
157
  }
158
158
 
159
- // Also log to stderr for direct observability
160
- console.error(rawLog);
159
+ // Also log to stderr when debugging
160
+ if (process.env.AIDE_DEBUG === "1") console.error(rawLog);
161
161
 
162
162
  const resolved = resolveProjectRoot(ctx);
163
163
 
@@ -170,7 +170,7 @@ export const AidePlugin: Plugin = async (ctx: PluginInput): Promise<Hooks> => {
170
170
  } catch {
171
171
  // non-fatal
172
172
  }
173
- console.error(resolvedLog);
173
+ if (process.env.AIDE_DEBUG === "1") console.error(resolvedLog);
174
174
 
175
175
  return createHooks(resolved.root, ctx.worktree, ctx.client, pluginRoot, {
176
176
  skipInit: !resolved.hasProjectRoot,