@sdsrs/code-graph 0.163.0 → 0.165.0
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/README.md +5 -6
- package/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/claude-plugin/agents/code-explorer.md +15 -12
- package/claude-plugin/hooks/hooks.json +91 -1
- package/claude-plugin/scripts/adopt.js +62 -37
- package/claude-plugin/scripts/cg-answer.js +7 -0
- package/claude-plugin/scripts/covering-tests.js +1 -2
- package/claude-plugin/scripts/doctor.js +40 -1
- package/claude-plugin/scripts/incremental-index.js +4 -1
- package/claude-plugin/scripts/lifecycle.js +49 -13
- package/claude-plugin/scripts/post-grep-inject.js +58 -3
- package/claude-plugin/scripts/pre-edit-guide.js +122 -83
- package/claude-plugin/scripts/pre-grep-guide.js +243 -11
- package/claude-plugin/scripts/pre-read-guide.js +42 -28
- package/claude-plugin/scripts/project-root.js +23 -1
- package/claude-plugin/scripts/recommendation-log.js +11 -9
- package/claude-plugin/scripts/session-edits.js +58 -3
- package/claude-plugin/scripts/session-init.js +142 -349
- package/claude-plugin/scripts/stop-impact.js +171 -10
- package/claude-plugin/scripts/user-prompt-context.js +48 -16
- package/claude-plugin/skills/explore/SKILL.md +10 -7
- package/claude-plugin/templates/code-graph-snapshot.yml +1 -1
- package/claude-plugin/templates/plugin_code_graph_mcp.md +58 -169
- package/package.json +6 -6
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
|
-
// Per-session edit log shared by the PreToolUse
|
|
4
|
-
//
|
|
3
|
+
// Per-session edit log shared by the PreToolUse hooks (writers: pre-edit-guide
|
|
4
|
+
// for Edit/Write, pre-grep-guide for `sed -i`/`perl -pi`) and the
|
|
5
|
+
// Stop hook (reader) — P1 #3, Q1.
|
|
5
6
|
//
|
|
6
7
|
// Two files per (project, session), both in the shared cgTmpDir() so the
|
|
7
8
|
// SessionStart prune (24 h, mtime) and `uninstall`'s wholesale removal of that
|
|
@@ -84,6 +85,59 @@ function recordEdit(root, sessionId, { file, symbol = null }, now = Date.now())
|
|
|
84
85
|
} catch { return false; }
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
// Q1: an edit that names no definition (Write over an existing file, `sed -i`,
|
|
89
|
+
// `perl -pi`) baselines the file's definitions at once. Bounded so the hook
|
|
90
|
+
// stays inside its budget: a larger file is logged as a file only, and at
|
|
91
|
+
// most this many definitions — the first in the file — get a record.
|
|
92
|
+
const MAX_FILE_SCAN_BYTES = 256 * 1024;
|
|
93
|
+
const MAX_FILE_DEFINITIONS = 64;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Log an edit that names no definition: one file record, then one baselined
|
|
97
|
+
* record per definition of the file as it is now (before the edit). With
|
|
98
|
+
* `newText` (a Write's content) only definitions whose header the new text
|
|
99
|
+
* changes are recorded — the Stop hook would find the rest unchanged. Without
|
|
100
|
+
* it (`sed -i`: the result is unknown until the command runs) every
|
|
101
|
+
* definition is, and the Stop hook sorts them out. One append, best-effort.
|
|
102
|
+
* @param {string} root project root
|
|
103
|
+
* @param {string} sessionId
|
|
104
|
+
* @param {string} file root-relative
|
|
105
|
+
* @param {{newText?: string|null}} [opts]
|
|
106
|
+
* @returns {number} records written
|
|
107
|
+
*/
|
|
108
|
+
function recordFileEdit(root, sessionId, file, { newText = null } = {}, now = Date.now()) {
|
|
109
|
+
const p = editsPath(root, sessionId);
|
|
110
|
+
if (!p || !file) return 0;
|
|
111
|
+
const recs = [{ ts: now, file, symbol: null }];
|
|
112
|
+
for (const [symbol, sigs] of fileBaselines(root, file, newText)) recs.push({ ts: now, file, symbol, sigs });
|
|
113
|
+
try {
|
|
114
|
+
fs.appendFileSync(p, recs.map((r) => JSON.stringify(r) + '\n').join(''));
|
|
115
|
+
return recs.length;
|
|
116
|
+
} catch { return 0; }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function fileBaselines(root, file, newText) {
|
|
120
|
+
try {
|
|
121
|
+
const abs = path.join(root, file);
|
|
122
|
+
if (fs.statSync(abs).size > MAX_FILE_SCAN_BYTES) return [];
|
|
123
|
+
const { allSignatures, extractSignatures, signatureChanged } = require('./stop-impact');
|
|
124
|
+
const ext = path.extname(file).toLowerCase();
|
|
125
|
+
const all = allSignatures(fs.readFileSync(abs, 'utf8'), ext);
|
|
126
|
+
if (!all) return [];
|
|
127
|
+
const out = [];
|
|
128
|
+
for (const [symbol, sigs] of all) {
|
|
129
|
+
if (out.length === MAX_FILE_DEFINITIONS) break;
|
|
130
|
+
if (sigs.length > MAX_BASELINE_SIGS) continue;
|
|
131
|
+
if (typeof newText === 'string') {
|
|
132
|
+
const after = extractSignatures(newText, symbol, ext);
|
|
133
|
+
if (!after || after.length === 0 || !signatureChanged(sigs, after, symbol)) continue;
|
|
134
|
+
}
|
|
135
|
+
out.push([symbol, sigs]);
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
} catch { return []; }
|
|
139
|
+
}
|
|
140
|
+
|
|
87
141
|
/** Every well-formed record in the session log; a torn or foreign line is skipped. */
|
|
88
142
|
function readEdits(root, sessionId) {
|
|
89
143
|
const p = editsPath(root, sessionId);
|
|
@@ -137,5 +191,6 @@ function writeStopState(root, sessionId, state) {
|
|
|
137
191
|
}
|
|
138
192
|
|
|
139
193
|
module.exports = {
|
|
140
|
-
sessionKey, editsPath, stopStatePath, recordEdit, readEdits, readStopState, writeStopState,
|
|
194
|
+
sessionKey, editsPath, stopStatePath, recordEdit, recordFileEdit, readEdits, readStopState, writeStopState,
|
|
195
|
+
MAX_FILE_DEFINITIONS,
|
|
141
196
|
};
|