greprag 5.73.1 → 5.73.2

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.
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ /** Client-side project document mirror helpers.
3
+ *
4
+ * One rule set feeds:
5
+ * - `greprag doc mirror sync` / `greprag doc update`
6
+ * - Stop-hook touched-doc upserts
7
+ * - `greprag load` / `greprag status` freshness warnings
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.MAX_DOC_CHARS = void 0;
44
+ exports.normalizeDocRel = normalizeDocRel;
45
+ exports.isDocMirrorEligible = isDocMirrorEligible;
46
+ exports.titleFromMarkdown = titleFromMarkdown;
47
+ exports.tagsFromPath = tagsFromPath;
48
+ exports.docContentHash = docContentHash;
49
+ exports.collectDocMirrorInventory = collectDocMirrorInventory;
50
+ exports.collectTouchedDocMirrorDocs = collectTouchedDocMirrorDocs;
51
+ exports.computeDocMirrorFreshness = computeDocMirrorFreshness;
52
+ exports.fetchDocMirrorSummaries = fetchDocMirrorSummaries;
53
+ exports.formatDocMirrorFreshness = formatDocMirrorFreshness;
54
+ const crypto = __importStar(require("node:crypto"));
55
+ const fs = __importStar(require("node:fs"));
56
+ const path = __importStar(require("node:path"));
57
+ const docptr_refs_1 = require("./docptr-refs");
58
+ const proc_1 = require("./proc");
59
+ exports.MAX_DOC_CHARS = 600_000;
60
+ const MAX_FILESYSTEM_DOCS = 2_000;
61
+ const REF_SCAN_CHARS = 4_000;
62
+ function normalizeDocRel(input) {
63
+ return (input || '')
64
+ .replace(/\\/g, '/')
65
+ .replace(/^\.\//, '')
66
+ .replace(/^\/+/, '')
67
+ .replace(/\/+/g, '/')
68
+ .trim();
69
+ }
70
+ function isDocMirrorEligible(relPath) {
71
+ const p = normalizeDocRel(relPath);
72
+ if (!p.toLowerCase().endsWith('.md'))
73
+ return false;
74
+ const segments = p.split('/');
75
+ const base = segments[segments.length - 1] || '';
76
+ const lowerBase = base.toLowerCase();
77
+ if (lowerBase === 'claude.md' || lowerBase === 'memory.md')
78
+ return false;
79
+ for (const seg of segments.slice(0, -1)) {
80
+ if (!seg)
81
+ return false;
82
+ if (seg.startsWith('.'))
83
+ return false;
84
+ if (seg === 'node_modules' || seg === 'dist' || seg === 'build' || seg === 'vendor')
85
+ return false;
86
+ }
87
+ return true;
88
+ }
89
+ function titleFromMarkdown(markdown, relPath) {
90
+ const heading = (markdown || '').split(/\r?\n/).find((line) => /^#{1,3}\s+\S/.test(line));
91
+ if (heading)
92
+ return heading.replace(/^#{1,3}\s+/, '').trim().slice(0, 140);
93
+ const base = normalizeDocRel(relPath).split('/').pop() || relPath;
94
+ return base.replace(/\.md$/i, '').replace(/[-_]+/g, ' ').trim() || relPath;
95
+ }
96
+ function tagsFromPath(relPath) {
97
+ const stop = new Set(['docs', 'doc', 'adr', 'readme', 'md', 'index']);
98
+ const tokens = normalizeDocRel(relPath)
99
+ .replace(/\.md$/i, '')
100
+ .split(/[\/._\s-]+/)
101
+ .map((t) => t.toLowerCase().trim())
102
+ .filter((t) => t.length >= 3 && !stop.has(t));
103
+ return Array.from(new Set(tokens)).slice(0, 12);
104
+ }
105
+ function docContentHash(content) {
106
+ return crypto.createHash('sha256').update(content).digest('hex');
107
+ }
108
+ function gitLsFiles(cwd) {
109
+ try {
110
+ const out = (0, proc_1.safeExecFileSync)('git', ['ls-files'], {
111
+ cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'],
112
+ });
113
+ return out.split(/\r?\n/).map(normalizeDocRel).filter(Boolean);
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ function walkMarkdownFiles(cwd, maxDocs = MAX_FILESYSTEM_DOCS) {
120
+ const files = [];
121
+ let truncated = false;
122
+ const visit = (dir) => {
123
+ if (truncated)
124
+ return;
125
+ let entries;
126
+ try {
127
+ entries = fs.readdirSync(dir, { withFileTypes: true });
128
+ }
129
+ catch {
130
+ return;
131
+ }
132
+ for (const entry of entries) {
133
+ if (truncated)
134
+ return;
135
+ const abs = path.join(dir, entry.name);
136
+ const rel = normalizeDocRel(path.relative(cwd, abs));
137
+ if (entry.isDirectory()) {
138
+ if (entry.name.startsWith('.'))
139
+ continue;
140
+ if (entry.name === 'node_modules' || entry.name === 'dist'
141
+ || entry.name === 'build' || entry.name === 'vendor')
142
+ continue;
143
+ visit(abs);
144
+ }
145
+ else if (entry.isFile() && isDocMirrorEligible(rel)) {
146
+ files.push(rel);
147
+ if (files.length >= maxDocs)
148
+ truncated = true;
149
+ }
150
+ }
151
+ };
152
+ visit(cwd);
153
+ return { files, truncated };
154
+ }
155
+ function touchedToRel(cwd, filePath) {
156
+ const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
157
+ const rel = normalizeDocRel(path.relative(cwd, abs));
158
+ if (!rel || rel.startsWith('../') || path.isAbsolute(rel))
159
+ return null;
160
+ return rel;
161
+ }
162
+ function buildCollection(cwd, relPaths, source, presentForRefs, gitAvailable, truncated = false) {
163
+ const docs = [];
164
+ const skipped = [];
165
+ const seen = new Set();
166
+ for (const raw of relPaths) {
167
+ const rel = normalizeDocRel(raw);
168
+ if (!isDocMirrorEligible(rel) || seen.has(rel))
169
+ continue;
170
+ seen.add(rel);
171
+ try {
172
+ const content = fs.readFileSync(path.join(cwd, rel), 'utf-8');
173
+ if (!content.trim()) {
174
+ skipped.push({ path: rel, reason: 'empty' });
175
+ continue;
176
+ }
177
+ if (content.length > exports.MAX_DOC_CHARS) {
178
+ skipped.push({ path: rel, reason: 'too large' });
179
+ continue;
180
+ }
181
+ docs.push({
182
+ path: rel,
183
+ content,
184
+ title: titleFromMarkdown(content, rel),
185
+ tags: tagsFromPath(rel),
186
+ refs: presentForRefs.size ? (0, docptr_refs_1.extractDocRefs)(content.slice(0, REF_SCAN_CHARS), rel, cwd, presentForRefs) : [],
187
+ contentHash: docContentHash(content),
188
+ });
189
+ }
190
+ catch {
191
+ skipped.push({ path: rel, reason: 'unreadable' });
192
+ }
193
+ }
194
+ return {
195
+ source,
196
+ docs: docs.sort((a, b) => a.path.localeCompare(b.path)),
197
+ presentPaths: Array.from(seen).sort(),
198
+ skipped,
199
+ gitAvailable,
200
+ truncated,
201
+ };
202
+ }
203
+ function collectDocMirrorInventory(cwd) {
204
+ const tracked = gitLsFiles(cwd);
205
+ if (tracked) {
206
+ return buildCollection(cwd, tracked.filter(isDocMirrorEligible), 'git', new Set(tracked), true);
207
+ }
208
+ const walked = walkMarkdownFiles(cwd);
209
+ return buildCollection(cwd, walked.files, 'filesystem', new Set(), false, walked.truncated);
210
+ }
211
+ function collectTouchedDocMirrorDocs(filesTouched, cwd) {
212
+ const tracked = gitLsFiles(cwd);
213
+ const presentForRefs = tracked ? new Set(tracked) : new Set();
214
+ const rels = filesTouched
215
+ .map((f) => touchedToRel(cwd, f))
216
+ .filter((f) => !!f && isDocMirrorEligible(f));
217
+ return buildCollection(cwd, rels, tracked ? 'git' : 'filesystem', presentForRefs, !!tracked);
218
+ }
219
+ function computeDocMirrorFreshness(local, remoteDocs) {
220
+ const remote = new Map();
221
+ for (const doc of remoteDocs) {
222
+ const rel = normalizeDocRel(doc.path);
223
+ if (rel)
224
+ remote.set(rel, doc.contentHash || '');
225
+ }
226
+ const localMap = new Map(local.docs.map((doc) => [doc.path, doc.contentHash]));
227
+ const changed = [];
228
+ const missing = [];
229
+ for (const doc of local.docs) {
230
+ if (!remote.has(doc.path))
231
+ missing.push(doc.path);
232
+ else if (remote.get(doc.path) && remote.get(doc.path) !== doc.contentHash)
233
+ changed.push(doc.path);
234
+ }
235
+ const removed = Array.from(remote.keys()).filter((rel) => !localMap.has(rel)).sort();
236
+ const stale = changed.length + missing.length + removed.length;
237
+ return {
238
+ status: remote.size === 0 && local.docs.length > 0 ? 'empty' : stale > 0 ? 'stale' : 'fresh',
239
+ source: local.source,
240
+ localCount: local.docs.length,
241
+ remoteCount: remote.size,
242
+ changed,
243
+ missing,
244
+ removed,
245
+ skipped: local.skipped,
246
+ truncated: local.truncated,
247
+ ...(!local.gitAvailable ? { note: 'using filesystem fallback; git is unavailable' } : {}),
248
+ };
249
+ }
250
+ async function fetchDocMirrorSummaries(apiUrl, apiKey, projectId, timeoutMs = 4_000) {
251
+ try {
252
+ const ctrl = new AbortController();
253
+ const timer = setTimeout(() => ctrl.abort(), timeoutMs);
254
+ const res = await fetch(`${apiUrl}/v1/doc/${projectId}/list`, {
255
+ headers: { 'Authorization': `Bearer ${apiKey}` },
256
+ signal: ctrl.signal,
257
+ });
258
+ clearTimeout(timer);
259
+ if (!res.ok)
260
+ return null;
261
+ const data = await res.json();
262
+ return Array.isArray(data.docs) ? data.docs : [];
263
+ }
264
+ catch {
265
+ return null;
266
+ }
267
+ }
268
+ function formatDocMirrorFreshness(report) {
269
+ const source = report.source === 'filesystem' ? 'filesystem fallback' : report.source;
270
+ if (report.status === 'unknown')
271
+ return 'Doc mirror: unknown — could not check the remote mirror.';
272
+ if (report.status === 'empty') {
273
+ return `Doc mirror: empty — ${report.localCount} local doc(s) found via ${source}. Run: greprag doc update`;
274
+ }
275
+ if (report.status === 'fresh') {
276
+ return `Doc mirror: fresh — ${report.localCount} doc(s) mirrored via ${source}.`;
277
+ }
278
+ const parts = [
279
+ report.changed.length ? `${report.changed.length} changed` : '',
280
+ report.missing.length ? `${report.missing.length} new` : '',
281
+ report.removed.length ? `${report.removed.length} removed` : '',
282
+ ].filter(Boolean).join(', ');
283
+ return `Doc mirror: stale — ${parts || 'local and remote differ'}. Run: greprag doc update`;
284
+ }
285
+ //# sourceMappingURL=doc-mirror-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-mirror-client.js","sourceRoot":"","sources":["../src/doc-mirror-client.ts"],"names":[],"mappings":"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"}
package/dist/hook.js CHANGED
@@ -132,6 +132,7 @@ const procedure_watch_1 = require("./procedure-watch");
132
132
  const inline_atom_hook_1 = require("./inline-atom-hook");
133
133
  const skill_landing_1 = require("./skill-landing");
134
134
  const skill_mirror_client_1 = require("./skill-mirror-client");
135
+ const doc_mirror_client_1 = require("./doc-mirror-client");
135
136
  const equipped_loadouts_cache_1 = require("./equipped-loadouts-cache");
136
137
  const codex_chip_hooks_1 = require("./codex-chip-hooks");
137
138
  const API_URL_DEFAULT = 'https://api.greprag.com';
@@ -1215,6 +1216,20 @@ async function store(input, source = 'claude-code') {
1215
1216
  }
1216
1217
  catch { /* best-effort — a docptr outage never fails the Stop hook */ }
1217
1218
  }
1219
+ // Doc Mirror sibling: exact touched Markdown bodies shadow into the project
1220
+ // docs store. Uses API upsert mode so one touched doc cannot prune the rest
1221
+ // of the mirror. Full deletion/reconciliation remains `greprag doc update`.
1222
+ try {
1223
+ const mirror = (0, doc_mirror_client_1.collectTouchedDocMirrorDocs)(turn.filesTouched, cwd);
1224
+ if (mirror.docs.length > 0) {
1225
+ await apiCall(`${cfg.apiUrl}/v1/doc/${anchor.projectId}/mirror`, cfg.apiKey, {
1226
+ projectName: anchor.projectName,
1227
+ docs: mirror.docs.map(({ contentHash: _contentHash, ...doc }) => doc),
1228
+ mode: 'upsert',
1229
+ });
1230
+ }
1231
+ }
1232
+ catch { /* best-effort — a doc mirror miss never fails the Stop hook */ }
1218
1233
  // Procedure System episode observer (docs/procedure-system.md V1 LEARN leg):
1219
1234
  // gated on "a watch file exists" — zero cost when no watch is open. One
1220
1235
  // synchronous flash-lite continuity call per observed turn; close/watchdog