@pimzino/sgrep 1.3.40 → 1.3.44

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.
@@ -1,32 +1,20 @@
1
1
  {
2
- "description": "sgrep semantic search hooks - enhances prompts and manages index",
2
+ "description": "sgrep hooks - prompt hint, index watcher, and watcher cleanup",
3
3
  "hooks": {
4
- "PreToolUse": [
5
- {
6
- "matcher": "Grep|Glob",
7
- "hooks": [
8
- {
9
- "type": "command",
10
- "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/sgrep_tool_reminder.js",
11
- "timeout": 5
12
- }
13
- ]
14
- }
15
- ],
16
4
  "UserPromptSubmit": [
17
5
  {
18
6
  "hooks": [
19
7
  {
20
8
  "type": "command",
21
- "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/sgrep_enhance.js",
22
- "timeout": 60
9
+ "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/sgrep_prompt_hint.js",
10
+ "timeout": 5
23
11
  }
24
12
  ]
25
13
  }
26
14
  ],
27
15
  "SessionStart": [
28
16
  {
29
- "matcher": "startup|resume",
17
+ "matcher": "startup|resume|clear",
30
18
  "hooks": [
31
19
  {
32
20
  "type": "command",
@@ -34,37 +22,6 @@
34
22
  "timeout": 15
35
23
  }
36
24
  ]
37
- },
38
- {
39
- "matcher": "startup|compact",
40
- "hooks": [
41
- {
42
- "type": "command",
43
- "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/sgrep_project_summary.js",
44
- "timeout": 90
45
- }
46
- ]
47
- },
48
- {
49
- "matcher": "resume|clear",
50
- "hooks": [
51
- {
52
- "type": "command",
53
- "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/sgrep_context.js",
54
- "timeout": 5
55
- }
56
- ]
57
- }
58
- ],
59
- "SubagentStart": [
60
- {
61
- "hooks": [
62
- {
63
- "type": "command",
64
- "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/sgrep_context.js",
65
- "timeout": 5
66
- }
67
- ]
68
25
  }
69
26
  ],
70
27
  "SessionEnd": [
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * sgrep_prompt_hint.js - UserPromptSubmit hook
5
+ *
6
+ * Appends a short reminder to every prompt so the model knows
7
+ * sgrep is available for codebase search and understanding.
8
+ */
9
+
10
+ let data = "";
11
+ process.stdin.setEncoding("utf8");
12
+ process.stdin.on("data", (chunk) => (data += chunk));
13
+ process.stdin.on("end", () => {
14
+ console.log(
15
+ JSON.stringify({
16
+ hookSpecificOutput: {
17
+ hookEventName: "UserPromptSubmit",
18
+ additionalContext:
19
+ 'Before making changes, gather context: use sgrep "query" for codebase search/understanding.',
20
+ },
21
+ })
22
+ );
23
+ });
@@ -1,169 +1,169 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
- const os = require("os");
6
- const { execSync } = require("child_process");
7
-
8
- const DEBUG_ENABLED = process.env.SGREP_DEBUG === "1" || process.env.SGREP_DEBUG === "true";
9
- const DEBUG_LOG_FILE = process.env.SGREP_WATCH_KILL_LOG || path.join(os.tmpdir(), "sgrep-watch-kill.log");
10
-
11
- function debugLog(message) {
12
- if (!DEBUG_ENABLED) return;
13
- try {
14
- const dir = path.dirname(DEBUG_LOG_FILE);
15
- if (!fs.existsSync(dir)) {
16
- fs.mkdirSync(dir, { recursive: true });
17
- }
18
- const stamp = new Date().toISOString();
19
- fs.appendFileSync(DEBUG_LOG_FILE, `[${stamp}] ${message}\n`);
20
- } catch (e) {
21
- // Ignore errors
22
- }
23
- }
24
-
25
- function debugLogSection(title, content) {
26
- debugLog(`\n========== ${title} ==========`);
27
- debugLog(content);
28
- debugLog(`========== END ${title} ==========\n`);
29
- }
30
-
31
- /**
32
- * Kill a process by PID, with platform-specific handling
33
- */
34
- function killProcess(pid) {
35
- debugLog(`Attempting to kill process with PID: ${pid}`);
36
-
37
- // First try Node.js process.kill
38
- try {
39
- process.kill(pid, "SIGTERM");
40
- debugLog(`SUCCESS: Sent SIGTERM to process ${pid}`);
41
- return true;
42
- } catch (e) {
43
- if (e.code === "ESRCH") {
44
- debugLog(`INFO: Process ${pid} already exited`);
45
- return true; // Consider success if already gone
46
- }
47
- debugLog(`process.kill failed: ${e.message} (code: ${e.code})`);
48
- }
49
-
50
- // On Windows, try taskkill as fallback
51
- if (process.platform === "win32") {
52
- try {
53
- execSync(`taskkill /PID ${pid} /F`, {
54
- encoding: "utf8",
55
- timeout: 5000,
56
- stdio: ["pipe", "pipe", "pipe"],
57
- });
58
- debugLog(`SUCCESS: Killed process ${pid} using taskkill`);
59
- return true;
60
- } catch (e) {
61
- debugLog(`taskkill failed: ${e.message}`);
62
- }
63
- }
64
-
65
- return false;
66
- }
67
-
68
- function readHookInput() {
69
- return new Promise((resolve) => {
70
- let data = "";
71
- process.stdin.setEncoding("utf8");
72
- process.stdin.on("data", (chunk) => {
73
- data += chunk;
74
- });
75
- process.stdin.on("end", () => {
76
- if (!data.trim()) {
77
- debugLog("No input data received from stdin");
78
- resolve(null);
79
- return;
80
- }
81
- try {
82
- const parsed = JSON.parse(data);
83
- debugLogSection("RAW HOOK INPUT", JSON.stringify(parsed, null, 2));
84
- resolve(parsed);
85
- } catch (e) {
86
- debugLog(`Failed to decode JSON: ${e.message}`);
87
- debugLog(`Raw data: ${data}`);
88
- resolve(null);
89
- }
90
- });
91
- });
92
- }
93
-
94
- async function main() {
95
- debugLog("\n\n====================================================");
96
- debugLog("SGREP WATCH KILL HOOK TRIGGERED - SessionEnd");
97
- debugLog("====================================================");
98
-
99
- const payload = await readHookInput();
100
- if (!payload) {
101
- debugLog("ERROR: No payload received - exiting with error");
102
- process.exit(1);
103
- }
104
-
105
- // Log all payload fields for debugging
106
- debugLog(`Hook Event: ${payload.hook_event_name || 'unknown'}`);
107
- debugLog(`Session ID: ${payload.session_id || 'unknown'}`);
108
- debugLog(`Reason: ${payload.reason || 'unknown'} (clear/logout/prompt_input_exit/other)`);
109
- debugLog(`CWD: ${payload.cwd || 'unknown'}`);
110
- debugLog(`Permission Mode: ${payload.permission_mode || 'unknown'}`);
111
- debugLog(`Transcript Path: ${payload.transcript_path || 'unknown'}`);
112
-
113
- const sessionId = payload.session_id || "default";
114
- const pidFile = path.join(os.tmpdir(), `sgrep-watch-pid-${sessionId}.txt`);
115
-
116
- debugLog(`Looking for PID file: ${pidFile}`);
117
-
118
- if (!fs.existsSync(pidFile)) {
119
- debugLog(`SKIP: PID file not found - sgrep watch may not have been started`);
120
- process.exit(0); // Not an error - process may not have been started
121
- }
122
-
123
- let killed = false;
124
-
125
- try {
126
- const pidContent = fs.readFileSync(pidFile, "utf8").trim();
127
- debugLog(`PID file content: "${pidContent}"`);
128
-
129
- const pid = parseInt(pidContent, 10);
130
- debugLog(`Parsed PID: ${pid}`);
131
-
132
- if (!isNaN(pid) && pid > 0) {
133
- killed = killProcess(pid);
134
- } else {
135
- debugLog(`WARNING: Invalid PID (${pid}), cannot kill process`);
136
- }
137
- } catch (e) {
138
- debugLog(`ERROR reading PID file: ${e.message}`);
139
- }
140
-
141
- // Clean up PID file (sgrep watch should also clean it up on exit, but be safe)
142
- try {
143
- if (fs.existsSync(pidFile)) {
144
- fs.unlinkSync(pidFile);
145
- debugLog(`SUCCESS: Removed PID file: ${pidFile}`);
146
- }
147
- } catch (cleanupErr) {
148
- debugLog(`Failed to clean up PID file: ${cleanupErr.message}`);
149
- }
150
-
151
- // Clean up ready marker file
152
- const readyFile = path.join(os.tmpdir(), `sgrep-watch-ready-${sessionId}.txt`);
153
- try {
154
- if (fs.existsSync(readyFile)) {
155
- fs.unlinkSync(readyFile);
156
- debugLog(`SUCCESS: Removed ready file: ${readyFile}`);
157
- }
158
- } catch (cleanupErr) {
159
- debugLog(`Failed to clean up ready file: ${cleanupErr.message}`);
160
- }
161
-
162
- debugLog(`Kill operation completed. Success: ${killed}`);
163
-
164
-
165
- debugLog("====================================================\n");
166
- process.exit(0);
167
- }
168
-
169
- main();
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const { execSync } = require("child_process");
7
+
8
+ const DEBUG_ENABLED = process.env.SGREP_DEBUG === "1" || process.env.SGREP_DEBUG === "true";
9
+ const DEBUG_LOG_FILE = process.env.SGREP_WATCH_KILL_LOG || path.join(os.tmpdir(), "sgrep-watch-kill.log");
10
+
11
+ function debugLog(message) {
12
+ if (!DEBUG_ENABLED) return;
13
+ try {
14
+ const dir = path.dirname(DEBUG_LOG_FILE);
15
+ if (!fs.existsSync(dir)) {
16
+ fs.mkdirSync(dir, { recursive: true });
17
+ }
18
+ const stamp = new Date().toISOString();
19
+ fs.appendFileSync(DEBUG_LOG_FILE, `[${stamp}] ${message}\n`);
20
+ } catch (e) {
21
+ // Ignore errors
22
+ }
23
+ }
24
+
25
+ function debugLogSection(title, content) {
26
+ debugLog(`\n========== ${title} ==========`);
27
+ debugLog(content);
28
+ debugLog(`========== END ${title} ==========\n`);
29
+ }
30
+
31
+ /**
32
+ * Kill a process by PID, with platform-specific handling
33
+ */
34
+ function killProcess(pid) {
35
+ debugLog(`Attempting to kill process with PID: ${pid}`);
36
+
37
+ // First try Node.js process.kill
38
+ try {
39
+ process.kill(pid, "SIGTERM");
40
+ debugLog(`SUCCESS: Sent SIGTERM to process ${pid}`);
41
+ return true;
42
+ } catch (e) {
43
+ if (e.code === "ESRCH") {
44
+ debugLog(`INFO: Process ${pid} already exited`);
45
+ return true; // Consider success if already gone
46
+ }
47
+ debugLog(`process.kill failed: ${e.message} (code: ${e.code})`);
48
+ }
49
+
50
+ // On Windows, try taskkill as fallback
51
+ if (process.platform === "win32") {
52
+ try {
53
+ execSync(`taskkill /PID ${pid} /F`, {
54
+ encoding: "utf8",
55
+ timeout: 5000,
56
+ stdio: ["pipe", "pipe", "pipe"],
57
+ });
58
+ debugLog(`SUCCESS: Killed process ${pid} using taskkill`);
59
+ return true;
60
+ } catch (e) {
61
+ debugLog(`taskkill failed: ${e.message}`);
62
+ }
63
+ }
64
+
65
+ return false;
66
+ }
67
+
68
+ function readHookInput() {
69
+ return new Promise((resolve) => {
70
+ let data = "";
71
+ process.stdin.setEncoding("utf8");
72
+ process.stdin.on("data", (chunk) => {
73
+ data += chunk;
74
+ });
75
+ process.stdin.on("end", () => {
76
+ if (!data.trim()) {
77
+ debugLog("No input data received from stdin");
78
+ resolve(null);
79
+ return;
80
+ }
81
+ try {
82
+ const parsed = JSON.parse(data);
83
+ debugLogSection("RAW HOOK INPUT", JSON.stringify(parsed, null, 2));
84
+ resolve(parsed);
85
+ } catch (e) {
86
+ debugLog(`Failed to decode JSON: ${e.message}`);
87
+ debugLog(`Raw data: ${data}`);
88
+ resolve(null);
89
+ }
90
+ });
91
+ });
92
+ }
93
+
94
+ async function main() {
95
+ debugLog("\n\n====================================================");
96
+ debugLog("SGREP WATCH KILL HOOK TRIGGERED - SessionEnd");
97
+ debugLog("====================================================");
98
+
99
+ const payload = await readHookInput();
100
+ if (!payload) {
101
+ debugLog("ERROR: No payload received - exiting with error");
102
+ process.exit(1);
103
+ }
104
+
105
+ // Log all payload fields for debugging
106
+ debugLog(`Hook Event: ${payload.hook_event_name || 'unknown'}`);
107
+ debugLog(`Session ID: ${payload.session_id || 'unknown'}`);
108
+ debugLog(`Reason: ${payload.reason || 'unknown'} (clear/logout/prompt_input_exit/other)`);
109
+ debugLog(`CWD: ${payload.cwd || 'unknown'}`);
110
+ debugLog(`Permission Mode: ${payload.permission_mode || 'unknown'}`);
111
+ debugLog(`Transcript Path: ${payload.transcript_path || 'unknown'}`);
112
+
113
+ const sessionId = payload.session_id || "default";
114
+ const pidFile = path.join(os.tmpdir(), `sgrep-watch-pid-${sessionId}.txt`);
115
+
116
+ debugLog(`Looking for PID file: ${pidFile}`);
117
+
118
+ if (!fs.existsSync(pidFile)) {
119
+ debugLog(`SKIP: PID file not found - sgrep watch may not have been started`);
120
+ process.exit(0); // Not an error - process may not have been started
121
+ }
122
+
123
+ let killed = false;
124
+
125
+ try {
126
+ const pidContent = fs.readFileSync(pidFile, "utf8").trim();
127
+ debugLog(`PID file content: "${pidContent}"`);
128
+
129
+ const pid = parseInt(pidContent, 10);
130
+ debugLog(`Parsed PID: ${pid}`);
131
+
132
+ if (!isNaN(pid) && pid > 0) {
133
+ killed = killProcess(pid);
134
+ } else {
135
+ debugLog(`WARNING: Invalid PID (${pid}), cannot kill process`);
136
+ }
137
+ } catch (e) {
138
+ debugLog(`ERROR reading PID file: ${e.message}`);
139
+ }
140
+
141
+ // Clean up PID file (sgrep watch should also clean it up on exit, but be safe)
142
+ try {
143
+ if (fs.existsSync(pidFile)) {
144
+ fs.unlinkSync(pidFile);
145
+ debugLog(`SUCCESS: Removed PID file: ${pidFile}`);
146
+ }
147
+ } catch (cleanupErr) {
148
+ debugLog(`Failed to clean up PID file: ${cleanupErr.message}`);
149
+ }
150
+
151
+ // Clean up ready marker file
152
+ const readyFile = path.join(os.tmpdir(), `sgrep-watch-ready-${sessionId}.txt`);
153
+ try {
154
+ if (fs.existsSync(readyFile)) {
155
+ fs.unlinkSync(readyFile);
156
+ debugLog(`SUCCESS: Removed ready file: ${readyFile}`);
157
+ }
158
+ } catch (cleanupErr) {
159
+ debugLog(`Failed to clean up ready file: ${cleanupErr.message}`);
160
+ }
161
+
162
+ debugLog(`Kill operation completed. Success: ${killed}`);
163
+
164
+
165
+ debugLog("====================================================\n");
166
+ process.exit(0);
167
+ }
168
+
169
+ main();
@@ -1,90 +1,32 @@
1
1
  ---
2
2
  name: sgrep
3
- description: "Semantic grep - search code by meaning, not just text. 1 sgrep call replaces 5-10 grep/glob calls. Ask natural language questions about architecture, find implementations by functionality, and get AI-explained code with file references. Use as your FIRST tool for codebase exploration, understanding, and navigation. This skill must be invoked at the start of every session."
3
+ description: "Semantic codebase search and understanding. Use when exploring code, finding where something is implemented, understanding architecture or patterns, locating how a feature works, or answering any question about this repository. Invoke BEFORE reading or editing files to gather context. Replaces multiple grep/glob calls with a single semantic query."
4
4
  ---
5
5
 
6
- ## Tool Definition
6
+ ## How to Use
7
7
 
8
- sgrep (semantic grep) searches and explains code in the LOCAL repository using AI. It understands code semantics, not just text patterns.
9
-
10
- ## Execution Method
11
-
12
- Execute sgrep commands via Bash tool. Always run from project root directory.
8
+ Run via Bash from the project root:
13
9
 
14
10
  ```bash
15
- # Ask questions about this codebase (DEFAULT)
16
- sgrep "how does authentication work in this project?"
17
-
18
- # Search for code by meaning
19
- sgrep search "error handling logic"
11
+ # Ask about the codebase (default - returns explanations with file references)
12
+ sgrep "how does authentication work?"
13
+ sgrep "where are API routes defined?"
14
+ sgrep "what does the build pipeline do?"
15
+
16
+ # Search for code snippets by meaning
17
+ sgrep search "error handling middleware"
18
+ sgrep search "database connection setup"
20
19
  ```
21
20
 
22
- ## Decision Logic
23
-
24
- <use-sgrep>
25
- - Question targets code that EXISTS in this repository
26
- - Need to understand this project's architecture or patterns
27
- - Exploring this codebase before making changes
28
- - Finding implementations within this repository
29
- </use-sgrep>
30
-
31
- <do-not-use-sgrep>
32
- - External API documentation (Microsoft Graph, AWS SDK, etc.)
33
- - Library/framework docs (React hooks, Express middleware, etc.)
34
- - General programming concepts (dependency injection, OAuth, etc.)
35
- - Third-party CLI usage (kubectl, az, gh, etc.)
36
- - Best practices not specific to this codebase
37
- - Any knowledge that exists outside this repository
38
- </do-not-use-sgrep>
39
-
40
- <decision-rule>
41
- IF answer requires knowledge from outside this repository THEN use WebSearch/WebFetch
42
- IF answer is in the code files of this project THEN use sgrep
43
- </decision-rule>
44
-
45
- ## Commands
21
+ ## When to Use
46
22
 
47
- ### Default: Ask (explanations with code references)
48
-
49
- ```bash
50
- sgrep "how does the caching layer work?"
51
- sgrep "what patterns are used for API endpoints?"
52
- sgrep "where is user validation handled?"
53
- ```
54
-
55
- ### Search (raw code snippets only)
56
-
57
- ```bash
58
- sgrep search "authentication middleware"
59
- sgrep search "database connection handling"
60
- ```
23
+ - Before editing code, to understand what exists and where
24
+ - When asked to find, locate, or explain any code in this repo
25
+ - To understand architecture, patterns, or how features connect
26
+ - When exploring unfamiliar parts of the codebase
61
27
 
62
28
  ## Constraints
63
29
 
64
- - ALWAYS execute from project root directory
65
- - NEVER cd into subdirectories before running sgrep
66
- - For exact text matching, use Grep tool instead
67
-
68
- ## Examples
69
-
70
- ### Correct Usage
71
-
72
- ```bash
73
- sgrep "how does this project handle routing?" # Local codebase question
74
- sgrep "where is the config loaded?" # Local implementation
75
- sgrep search "HashRouter configuration" # Local code search
76
- ```
77
-
78
- ### Incorrect Usage (use WebSearch instead)
79
-
80
- ```bash
81
- # WRONG - these require external knowledge
82
- sgrep "How do Microsoft Graph cmdlets work?" # External API
83
- sgrep "What are React best practices?" # General knowledge
84
- sgrep "How to use kubectl?" # External CLI docs
85
- sgrep "What is OAuth 2.0?" # General concept
86
- ```
87
-
88
- ## Keywords
89
-
90
- codebase questions, local code, repository code, project architecture, code understanding, semantic search, find implementations
30
+ - Run from project root (never cd into subdirectories first)
31
+ - For exact text/symbol matching, use Grep instead
32
+ - For external docs or general knowledge, use WebSearch instead
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pimzino/sgrep",
3
- "version": "1.3.40",
3
+ "version": "1.3.44",
4
4
  "description": "Semantic grep - search codebases by meaning using the Augment SDK",
5
5
  "type": "module",
6
6
  "main": "build/index.js",
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * sgrep_context.js - Injects sgrep awareness into Claude Code sessions and subagents
5
- *
6
- * This hook runs on:
7
- * - SessionStart (startup, resume, clear, compact) - main session context
8
- * - SubagentStart - subagent (Task tool) context
9
- *
10
- * Ensures Claude is always aware of the sgrep semantic search tool.
11
- */
12
-
13
- const fs = require("fs");
14
- const path = require("path");
15
- const os = require("os");
16
-
17
- const DEBUG_ENABLED = process.env.SGREP_DEBUG === "1" || process.env.SGREP_DEBUG === "true";
18
- const DEBUG_LOG_FILE = process.env.SGREP_CONTEXT_LOG || path.join(os.tmpdir(), "sgrep-context.log");
19
-
20
- function debugLog(message) {
21
- if (!DEBUG_ENABLED) return;
22
- try {
23
- const dir = path.dirname(DEBUG_LOG_FILE);
24
- if (!fs.existsSync(dir)) {
25
- fs.mkdirSync(dir, { recursive: true });
26
- }
27
- const stamp = new Date().toISOString();
28
- fs.appendFileSync(DEBUG_LOG_FILE, `[${stamp}] ${message}\n`);
29
- } catch (e) {
30
- // Ignore errors
31
- }
32
- }
33
-
34
- function readHookInput() {
35
- return new Promise((resolve) => {
36
- let data = "";
37
- process.stdin.setEncoding("utf8");
38
- process.stdin.on("data", (chunk) => {
39
- data += chunk;
40
- });
41
- process.stdin.on("end", () => {
42
- if (!data.trim()) {
43
- debugLog("No input data received from stdin");
44
- resolve(null);
45
- return;
46
- }
47
- try {
48
- const parsed = JSON.parse(data);
49
- debugLog(`Received hook input: ${JSON.stringify(parsed, null, 2)}`);
50
- resolve(parsed);
51
- } catch (e) {
52
- debugLog(`Failed to decode JSON: ${e.message}`);
53
- resolve(null);
54
- }
55
- });
56
- });
57
- }
58
-
59
- async function main() {
60
- debugLog("\n====================================================");
61
- debugLog("SGREP CONTEXT HOOK TRIGGERED");
62
- debugLog("====================================================");
63
-
64
- const payload = await readHookInput();
65
- if (!payload) {
66
- debugLog("ERROR: No payload received - exiting with error");
67
- process.exit(1);
68
- }
69
-
70
- const eventName = payload.hook_event_name || "unknown";
71
- debugLog(`Hook event: ${eventName}`);
72
-
73
- // Log event-specific info
74
- if (eventName === "SessionStart") {
75
- debugLog(`Session source: ${payload.source || "unknown"}`);
76
- } else if (eventName === "SubagentStart") {
77
- debugLog(`Subagent ID: ${payload.agent_id || "unknown"}`);
78
- debugLog(`Subagent type: ${payload.agent_type || "unknown"}`);
79
- }
80
-
81
- // Same context message for both session and subagents
82
- // Make it directive - tell Claude to USE sgrep, not just that it exists
83
- const sgrepInstruction = `CODEBASE EXPLORATION: Before using Grep, Glob, or Read to explore code, run \`sgrep "your query"\` first via Bash. sgrep uses semantic search to find code by meaning (e.g., \`sgrep "authentication logic"\`, \`sgrep "database queries"\`). For questions about the codebase, use \`sgrep ask "how does X work?"\`. This is faster and more accurate than pattern matching.`;
84
-
85
- debugLog(`Outputting context: ${sgrepInstruction}`);
86
- console.log(sgrepInstruction);
87
- debugLog("====================================================\n");
88
- process.exit(0);
89
- }
90
-
91
- main();