pi-ghost-autocomplete 0.3.2 → 0.5.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/LICENSE +561 -0
- package/README.md +186 -4
- package/dist/bench-cli.js +1 -123
- package/dist/bench.d.ts +7 -3
- package/dist/bench.js +1 -522
- package/dist/config.d.ts +46 -3
- package/dist/context-aggregator.d.ts +4 -1
- package/dist/cycle-manager.d.ts +2 -21
- package/dist/entropy-stop.d.ts +4 -1
- package/dist/eval-dataset.d.ts +2 -13
- package/dist/fuzzy-matcher.d.ts +4 -1
- package/dist/ghost-editor.d.ts +11 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +1 -289
- package/dist/intent.d.ts +179 -0
- package/dist/metrics.d.ts +4 -1
- package/dist/path-index.d.ts +4 -1
- package/dist/path-matcher.d.ts +4 -1
- package/dist/profile-store.d.ts +4 -1
- package/dist/profile.d.ts +2 -20
- package/dist/providers/cloud-provider.d.ts +4 -1
- package/dist/providers/local-provider.d.ts +4 -1
- package/dist/providers/openai-compat-chat-provider.d.ts +31 -0
- package/dist/providers/openai-compat-provider.d.ts +24 -1
- package/dist/providers/race.d.ts +4 -1
- package/dist/providers/router.d.ts +59 -0
- package/dist/providers/types.d.ts +13 -1
- package/dist/recent-paths.d.ts +4 -1
- package/dist/replay-cli.js +1 -166
- package/dist/replay.d.ts +2 -7
- package/package.json +10 -6
- package/dist/bench-cli.d.ts +0 -3
- package/dist/bench-cli.d.ts.map +0 -1
- package/dist/bench-cli.js.map +0 -1
- package/dist/bench.d.ts.map +0 -1
- package/dist/bench.js.map +0 -1
- package/dist/cache.d.ts +0 -124
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js +0 -173
- package/dist/cache.js.map +0 -1
- package/dist/candidate-rerank.d.ts +0 -57
- package/dist/candidate-rerank.d.ts.map +0 -1
- package/dist/candidate-rerank.js +0 -78
- package/dist/candidate-rerank.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -317
- package/dist/config.js.map +0 -1
- package/dist/context-aggregator.d.ts.map +0 -1
- package/dist/context-aggregator.js +0 -87
- package/dist/context-aggregator.js.map +0 -1
- package/dist/context-selector.d.ts +0 -128
- package/dist/context-selector.d.ts.map +0 -1
- package/dist/context-selector.js +0 -300
- package/dist/context-selector.js.map +0 -1
- package/dist/cycle-manager.d.ts.map +0 -1
- package/dist/cycle-manager.js +0 -168
- package/dist/cycle-manager.js.map +0 -1
- package/dist/edit-history-ring.d.ts +0 -148
- package/dist/edit-history-ring.d.ts.map +0 -1
- package/dist/edit-history-ring.js +0 -262
- package/dist/edit-history-ring.js.map +0 -1
- package/dist/entropy-stop.d.ts.map +0 -1
- package/dist/entropy-stop.js +0 -141
- package/dist/entropy-stop.js.map +0 -1
- package/dist/eval-dataset.d.ts.map +0 -1
- package/dist/eval-dataset.js +0 -127
- package/dist/eval-dataset.js.map +0 -1
- package/dist/fast-path-engine.d.ts +0 -286
- package/dist/fast-path-engine.d.ts.map +0 -1
- package/dist/fast-path-engine.js +0 -341
- package/dist/fast-path-engine.js.map +0 -1
- package/dist/fuzzy-matcher.d.ts.map +0 -1
- package/dist/fuzzy-matcher.js +0 -162
- package/dist/fuzzy-matcher.js.map +0 -1
- package/dist/ghost-editor.d.ts.map +0 -1
- package/dist/ghost-editor.js +0 -1491
- package/dist/ghost-editor.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/keystroke-timer.d.ts +0 -59
- package/dist/keystroke-timer.d.ts.map +0 -1
- package/dist/keystroke-timer.js +0 -94
- package/dist/keystroke-timer.js.map +0 -1
- package/dist/metrics-builder.d.ts +0 -71
- package/dist/metrics-builder.d.ts.map +0 -1
- package/dist/metrics-builder.js +0 -71
- package/dist/metrics-builder.js.map +0 -1
- package/dist/metrics.d.ts.map +0 -1
- package/dist/metrics.js +0 -212
- package/dist/metrics.js.map +0 -1
- package/dist/path-index.d.ts.map +0 -1
- package/dist/path-index.js +0 -148
- package/dist/path-index.js.map +0 -1
- package/dist/path-matcher.d.ts.map +0 -1
- package/dist/path-matcher.js +0 -88
- package/dist/path-matcher.js.map +0 -1
- package/dist/profile-store.d.ts.map +0 -1
- package/dist/profile-store.js +0 -199
- package/dist/profile-store.js.map +0 -1
- package/dist/profile.d.ts.map +0 -1
- package/dist/profile.js +0 -434
- package/dist/profile.js.map +0 -1
- package/dist/providers/cloud-provider.d.ts.map +0 -1
- package/dist/providers/cloud-provider.js +0 -109
- package/dist/providers/cloud-provider.js.map +0 -1
- package/dist/providers/local-provider.d.ts.map +0 -1
- package/dist/providers/local-provider.js +0 -48
- package/dist/providers/local-provider.js.map +0 -1
- package/dist/providers/openai-compat-provider.d.ts.map +0 -1
- package/dist/providers/openai-compat-provider.js +0 -215
- package/dist/providers/openai-compat-provider.js.map +0 -1
- package/dist/providers/openai-completions-runner.d.ts +0 -52
- package/dist/providers/openai-completions-runner.d.ts.map +0 -1
- package/dist/providers/openai-completions-runner.js +0 -141
- package/dist/providers/openai-completions-runner.js.map +0 -1
- package/dist/providers/race.d.ts.map +0 -1
- package/dist/providers/race.js +0 -441
- package/dist/providers/race.js.map +0 -1
- package/dist/providers/truncate.d.ts +0 -7
- package/dist/providers/truncate.d.ts.map +0 -1
- package/dist/providers/truncate.js +0 -57
- package/dist/providers/truncate.js.map +0 -1
- package/dist/providers/types.d.ts.map +0 -1
- package/dist/providers/types.js +0 -60
- package/dist/providers/types.js.map +0 -1
- package/dist/provisional-manager.d.ts +0 -93
- package/dist/provisional-manager.d.ts.map +0 -1
- package/dist/provisional-manager.js +0 -98
- package/dist/provisional-manager.js.map +0 -1
- package/dist/provisional.d.ts +0 -150
- package/dist/provisional.d.ts.map +0 -1
- package/dist/provisional.js +0 -238
- package/dist/provisional.js.map +0 -1
- package/dist/recent-paths.d.ts.map +0 -1
- package/dist/recent-paths.js +0 -114
- package/dist/recent-paths.js.map +0 -1
- package/dist/regret-tracker.d.ts +0 -84
- package/dist/regret-tracker.d.ts.map +0 -1
- package/dist/regret-tracker.js +0 -145
- package/dist/regret-tracker.js.map +0 -1
- package/dist/replay-cli.d.ts +0 -13
- package/dist/replay-cli.d.ts.map +0 -1
- package/dist/replay-cli.js.map +0 -1
- package/dist/replay.d.ts.map +0 -1
- package/dist/replay.js +0 -225
- package/dist/replay.js.map +0 -1
- package/dist/reranker.d.ts +0 -181
- package/dist/reranker.d.ts.map +0 -1
- package/dist/reranker.js +0 -324
- package/dist/reranker.js.map +0 -1
- package/dist/session-trie.d.ts +0 -103
- package/dist/session-trie.d.ts.map +0 -1
- package/dist/session-trie.js +0 -280
- package/dist/session-trie.js.map +0 -1
- package/dist/speculative.d.ts +0 -74
- package/dist/speculative.d.ts.map +0 -1
- package/dist/speculative.js +0 -107
- package/dist/speculative.js.map +0 -1
- package/dist/tool-summarize.d.ts +0 -40
- package/dist/tool-summarize.d.ts.map +0 -1
- package/dist/tool-summarize.js +0 -245
- package/dist/tool-summarize.js.map +0 -1
- package/dist/trie-sanitize.d.ts +0 -22
- package/dist/trie-sanitize.d.ts.map +0 -1
- package/dist/trie-sanitize.js +0 -142
- package/dist/trie-sanitize.js.map +0 -1
- package/dist/versions.d.ts +0 -23
- package/dist/versions.d.ts.map +0 -1
- package/dist/versions.js +0 -31
- package/dist/versions.js.map +0 -1
package/dist/context-selector.js
DELETED
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Relevance-pruned context selection. See PRD §M6b.
|
|
3
|
-
*
|
|
4
|
-
* Replaces the "last N messages" recency window with a scan-then-select
|
|
5
|
-
* design motivated by ChaI-TeA (RESEARCH §2): models can exploit distant
|
|
6
|
-
* conversation history; a pure recency window blinds the selector to
|
|
7
|
-
* high-IDF distant turns.
|
|
8
|
-
*
|
|
9
|
-
* Pipeline:
|
|
10
|
-
* 1. Scan up to `maxScan` candidates from the branch (newest first).
|
|
11
|
-
* 2. Tokenize each candidate's text (lower-case, drop stopwords).
|
|
12
|
-
* 3. Score each candidate as `0.7 * recencyWeight + 0.3 * bm25Score`,
|
|
13
|
-
* both normalized to [0, 1].
|
|
14
|
-
* 4. Sort by score, take top `maxSelected`, enforce `maxChars` budget by
|
|
15
|
-
* truncating the lowest-recency tail.
|
|
16
|
-
*
|
|
17
|
-
* Pure module: no I/O, no editor state.
|
|
18
|
-
*/
|
|
19
|
-
export const DEFAULT_MAX_SCAN = 200;
|
|
20
|
-
export const DEFAULT_MAX_SELECTED = 8;
|
|
21
|
-
export const DEFAULT_MAX_CHARS = 4000;
|
|
22
|
-
export const DEFAULT_BM25_WEIGHT = 0.3;
|
|
23
|
-
/**
|
|
24
|
-
* Enhancement #1: weight on the edit-history token-overlap locality
|
|
25
|
-
* signal. Default 0 (opt-in). When > 0, the score formula becomes:
|
|
26
|
-
* `score = (1 - bm25Weight - editLocalityWeight) * recency
|
|
27
|
-
* + bm25Weight * bm25
|
|
28
|
-
* + editLocalityWeight * editLocality`
|
|
29
|
-
* where `editLocality` is 1 if the candidate text shares any token with
|
|
30
|
-
* `editTokens`, else 0. `bm25Weight + editLocalityWeight` is clamped to
|
|
31
|
-
* 1; recency coefficient gets whatever remains.
|
|
32
|
-
*/
|
|
33
|
-
export const DEFAULT_EDIT_LOCALITY_WEIGHT = 0;
|
|
34
|
-
export const RECENCY_HALF_LIFE = 4;
|
|
35
|
-
const BM25_K1 = 1.5;
|
|
36
|
-
const BM25_B = 0.75;
|
|
37
|
-
/**
|
|
38
|
-
* Small fixed English stopword list. No language detection — when ghost
|
|
39
|
-
* autocomplete moves to non-English prompts, this set may need expansion
|
|
40
|
-
* or a per-language switch. Until then, the cost of leaving these in is
|
|
41
|
-
* higher than the cost of an English-only set.
|
|
42
|
-
*/
|
|
43
|
-
export const STOPWORDS = new Set([
|
|
44
|
-
"the",
|
|
45
|
-
"a",
|
|
46
|
-
"an",
|
|
47
|
-
"of",
|
|
48
|
-
"and",
|
|
49
|
-
"or",
|
|
50
|
-
"to",
|
|
51
|
-
"in",
|
|
52
|
-
"on",
|
|
53
|
-
"for",
|
|
54
|
-
"is",
|
|
55
|
-
"are",
|
|
56
|
-
"this",
|
|
57
|
-
"that",
|
|
58
|
-
]);
|
|
59
|
-
/**
|
|
60
|
-
* Tokenize text into lower-case alphanumeric words, dropping stopwords and
|
|
61
|
-
* single-character noise. Kept intentionally simple — proper tokenization
|
|
62
|
-
* (subword, punctuation handling, code identifiers) would over-fit the
|
|
63
|
-
* v0.5 prompt corpus.
|
|
64
|
-
*
|
|
65
|
-
* Caveat: camelCase identifiers do NOT split. `getRecentMessages` becomes a
|
|
66
|
-
* single token `getrecentmessages`. File paths and snake_case split on the
|
|
67
|
-
* separator characters and tokenize as expected.
|
|
68
|
-
*/
|
|
69
|
-
export function tokenize(text) {
|
|
70
|
-
const out = [];
|
|
71
|
-
for (const m of text.toLowerCase().matchAll(/[a-z0-9]+/g)) {
|
|
72
|
-
const t = m[0];
|
|
73
|
-
if (t.length < 2)
|
|
74
|
-
continue;
|
|
75
|
-
if (STOPWORDS.has(t))
|
|
76
|
-
continue;
|
|
77
|
-
out.push(t);
|
|
78
|
-
}
|
|
79
|
-
return out;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Compute document frequencies over a candidate pool. Used as the corpus
|
|
83
|
-
* for BM25's IDF term.
|
|
84
|
-
*/
|
|
85
|
-
export function computeDocFreqs(candidates) {
|
|
86
|
-
const docFreqs = new Map();
|
|
87
|
-
const docLens = [];
|
|
88
|
-
let totalLen = 0;
|
|
89
|
-
for (const c of candidates) {
|
|
90
|
-
const tokens = tokenize(c.text);
|
|
91
|
-
docLens.push(tokens.length);
|
|
92
|
-
totalLen += tokens.length;
|
|
93
|
-
const seen = new Set();
|
|
94
|
-
for (const t of tokens) {
|
|
95
|
-
if (seen.has(t))
|
|
96
|
-
continue;
|
|
97
|
-
seen.add(t);
|
|
98
|
-
docFreqs.set(t, (docFreqs.get(t) ?? 0) + 1);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
const avgDocLen = candidates.length > 0 ? totalLen / candidates.length : 0;
|
|
102
|
-
return { docFreqs, avgDocLen, docLens };
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* BM25 score for `queryTokens` against a document. Uses an IDF floor
|
|
106
|
-
* `log(1 + 1/N)` so terms appearing in every candidate still contribute a
|
|
107
|
-
* small positive score instead of zero — PRD §M6b "BM25-on-small-corpus
|
|
108
|
-
* caveat".
|
|
109
|
-
*/
|
|
110
|
-
export function bm25Score(queryTokens, docTokens, docFreqs, N, avgDocLen) {
|
|
111
|
-
if (queryTokens.length === 0 || docTokens.length === 0 || N === 0)
|
|
112
|
-
return 0;
|
|
113
|
-
const docLen = docTokens.length;
|
|
114
|
-
const idfFloor = Math.log(1 + 1 / Math.max(1, N));
|
|
115
|
-
// Term-frequency in the document.
|
|
116
|
-
const tf = new Map();
|
|
117
|
-
for (const t of docTokens)
|
|
118
|
-
tf.set(t, (tf.get(t) ?? 0) + 1);
|
|
119
|
-
let score = 0;
|
|
120
|
-
const seenInQuery = new Set();
|
|
121
|
-
for (const q of queryTokens) {
|
|
122
|
-
if (seenInQuery.has(q))
|
|
123
|
-
continue;
|
|
124
|
-
seenInQuery.add(q);
|
|
125
|
-
const f = tf.get(q);
|
|
126
|
-
if (!f)
|
|
127
|
-
continue;
|
|
128
|
-
const df = docFreqs.get(q) ?? 0;
|
|
129
|
-
// Standard Okapi IDF; clamp at the floor so universal terms still count.
|
|
130
|
-
const idfRaw = Math.log((N - df + 0.5) / (df + 0.5) + 1);
|
|
131
|
-
const idf = Math.max(idfFloor, idfRaw);
|
|
132
|
-
const lenNorm = 1 - BM25_B + BM25_B * (docLen / Math.max(1, avgDocLen));
|
|
133
|
-
const tfNorm = (f * (BM25_K1 + 1)) / (f + BM25_K1 * lenNorm);
|
|
134
|
-
score += idf * tfNorm;
|
|
135
|
-
}
|
|
136
|
-
return score;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Exponential recency weight: 1.0 at the newest position, decays e-fold
|
|
140
|
-
* every `RECENCY_HALF_LIFE` positions. `distance` is positions from the
|
|
141
|
-
* newest end of the candidate pool (0 = newest).
|
|
142
|
-
*/
|
|
143
|
-
export function recencyWeight(distance) {
|
|
144
|
-
return Math.exp(-distance / RECENCY_HALF_LIFE);
|
|
145
|
-
}
|
|
146
|
-
function minMaxNormalize(xs) {
|
|
147
|
-
if (xs.length === 0)
|
|
148
|
-
return [];
|
|
149
|
-
let min = Infinity;
|
|
150
|
-
let max = -Infinity;
|
|
151
|
-
for (const x of xs) {
|
|
152
|
-
if (x < min)
|
|
153
|
-
min = x;
|
|
154
|
-
if (x > max)
|
|
155
|
-
max = x;
|
|
156
|
-
}
|
|
157
|
-
const spread = max - min;
|
|
158
|
-
if (spread < 1e-9)
|
|
159
|
-
return xs.map(() => 0.5);
|
|
160
|
-
return xs.map((x) => (x - min) / spread);
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Select the most relevant subset of `candidates` for the current prefix.
|
|
164
|
-
* `candidates` should be newest-first (index 0 = newest). Returns selected
|
|
165
|
-
* entries in their original branch order (oldest-first of those selected)
|
|
166
|
-
* for natural prompt rendering.
|
|
167
|
-
*/
|
|
168
|
-
export function selectContext(candidates, prefix, opts = {}) {
|
|
169
|
-
const maxScan = Math.max(0, opts.maxScan ?? DEFAULT_MAX_SCAN);
|
|
170
|
-
const maxSelected = Math.max(0, opts.maxSelected ?? DEFAULT_MAX_SELECTED);
|
|
171
|
-
const maxChars = Math.max(0, opts.maxChars ?? DEFAULT_MAX_CHARS);
|
|
172
|
-
const bm25WeightRaw = Math.min(1, Math.max(0, opts.bm25Weight ?? DEFAULT_BM25_WEIGHT));
|
|
173
|
-
const editLocalityWeightRaw = Math.min(1, Math.max(0, opts.editLocalityWeight ?? DEFAULT_EDIT_LOCALITY_WEIGHT));
|
|
174
|
-
// Clamp the sum at 1 so recency coefficient never goes negative. If the
|
|
175
|
-
// caller asks for bm25=0.7 + editLocality=0.5, scale both proportionally.
|
|
176
|
-
const sum = bm25WeightRaw + editLocalityWeightRaw;
|
|
177
|
-
const scale = sum > 1 ? 1 / sum : 1;
|
|
178
|
-
const bm25Weight = bm25WeightRaw * scale;
|
|
179
|
-
const editLocalityWeight = editLocalityWeightRaw * scale;
|
|
180
|
-
const recencyWeightCoef = 1 - bm25Weight - editLocalityWeight;
|
|
181
|
-
// Normalize editTokens to lowercase to align with the selector's tokenize.
|
|
182
|
-
// Edit-history tokens preserve identifier case (code identifiers are
|
|
183
|
-
// case-sensitive); context-selector lowercases (prose tokens). Compare
|
|
184
|
-
// post-normalization so the two spaces meet.
|
|
185
|
-
const editTokens = opts.editTokens
|
|
186
|
-
? new Set(Array.from(opts.editTokens, (t) => t.toLowerCase()))
|
|
187
|
-
: undefined;
|
|
188
|
-
const editLocalityActive = editLocalityWeight > 0 && editTokens && editTokens.size > 0;
|
|
189
|
-
const scanned = candidates.slice(0, maxScan);
|
|
190
|
-
if (scanned.length === 0 || maxSelected === 0) {
|
|
191
|
-
return { candidates: [], scannedCount: 0, selectedCount: 0, totalChars: 0 };
|
|
192
|
-
}
|
|
193
|
-
const queryTokens = tokenize(prefix);
|
|
194
|
-
const { docFreqs, avgDocLen } = computeDocFreqs(scanned);
|
|
195
|
-
// Per-candidate raw scores.
|
|
196
|
-
const recencyRaw = scanned.map((_, i) => recencyWeight(i));
|
|
197
|
-
const docTokens = scanned.map((c) => tokenize(c.text));
|
|
198
|
-
const bm25Raw = docTokens.map((toks) => bm25Score(queryTokens, toks, docFreqs, scanned.length, avgDocLen));
|
|
199
|
-
const editLocalityRaw = editLocalityActive
|
|
200
|
-
? docTokens.map((toks) => (toks.some((t) => editTokens.has(t)) ? 1 : 0))
|
|
201
|
-
: scanned.map(() => 0);
|
|
202
|
-
const recencyNorm = minMaxNormalize(recencyRaw);
|
|
203
|
-
const bm25Norm = minMaxNormalize(bm25Raw);
|
|
204
|
-
// editLocality is already in {0, 1} — skip normalization.
|
|
205
|
-
const combined = scanned.map((c, i) => ({
|
|
206
|
-
candidate: c,
|
|
207
|
-
score: recencyWeightCoef * recencyNorm[i] +
|
|
208
|
-
bm25Weight * bm25Norm[i] +
|
|
209
|
-
editLocalityWeight * editLocalityRaw[i],
|
|
210
|
-
// Carry the newest-first index for ordering selected entries back into
|
|
211
|
-
// chronological order at the end.
|
|
212
|
-
index: i,
|
|
213
|
-
}));
|
|
214
|
-
// Top-N by score; ties broken by recency (lower index = newer).
|
|
215
|
-
combined.sort((a, b) => {
|
|
216
|
-
const ds = b.score - a.score;
|
|
217
|
-
if (Math.abs(ds) > 1e-9)
|
|
218
|
-
return ds;
|
|
219
|
-
return a.index - b.index;
|
|
220
|
-
});
|
|
221
|
-
const topN = combined.slice(0, maxSelected);
|
|
222
|
-
// Char-budget enforcement (PRD §M6b: "drop lowest-recency tail").
|
|
223
|
-
// Sort newest-first then greedily fill — once the budget would be
|
|
224
|
-
// exceeded, stop. This gives priority to newer entries, which matches
|
|
225
|
-
// PRD's "drop lowest-recency tail" intent.
|
|
226
|
-
//
|
|
227
|
-
// Edge case: the very first (newest) entry's `len` may exceed `maxChars`
|
|
228
|
-
// on its own. We still keep it (the alternative is no context at all),
|
|
229
|
-
// even though `totalChars` then exceeds the budget. This is a documented
|
|
230
|
-
// best-effort policy — a future revision could truncate such entries
|
|
231
|
-
// mid-text, but that risks splitting mid-token.
|
|
232
|
-
topN.sort((a, b) => a.index - b.index);
|
|
233
|
-
let totalChars = 0;
|
|
234
|
-
const kept = [];
|
|
235
|
-
for (const c of topN) {
|
|
236
|
-
const len = c.candidate.text.length;
|
|
237
|
-
if (totalChars + len > maxChars && kept.length > 0) {
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
totalChars += len;
|
|
241
|
-
kept.push(c);
|
|
242
|
-
}
|
|
243
|
-
// Render oldest-first for natural prompt rendering (newest at the end).
|
|
244
|
-
kept.sort((a, b) => b.index - a.index);
|
|
245
|
-
return {
|
|
246
|
-
candidates: kept.map((k) => k.candidate),
|
|
247
|
-
scannedCount: scanned.length,
|
|
248
|
-
selectedCount: kept.length,
|
|
249
|
-
totalChars,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Parse `PI_GHOST_CONTEXT_BM25_WEIGHT`. Returns fallback on bad input or
|
|
254
|
-
* outside [0, 1].
|
|
255
|
-
*/
|
|
256
|
-
export function parseBm25WeightEnv(raw) {
|
|
257
|
-
if (raw === undefined)
|
|
258
|
-
return DEFAULT_BM25_WEIGHT;
|
|
259
|
-
const v = Number(raw);
|
|
260
|
-
if (!Number.isFinite(v) || v < 0 || v > 1)
|
|
261
|
-
return DEFAULT_BM25_WEIGHT;
|
|
262
|
-
return v;
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Parse `PI_GHOST_CONTEXT_EDIT_LOCALITY_WEIGHT`. Returns 0 (no-op) on bad
|
|
266
|
-
* input or outside [0, 1]. Enhancement #1.
|
|
267
|
-
*/
|
|
268
|
-
export function parseEditLocalityWeightEnv(raw) {
|
|
269
|
-
if (raw === undefined)
|
|
270
|
-
return DEFAULT_EDIT_LOCALITY_WEIGHT;
|
|
271
|
-
const v = Number(raw);
|
|
272
|
-
if (!Number.isFinite(v) || v < 0 || v > 1)
|
|
273
|
-
return DEFAULT_EDIT_LOCALITY_WEIGHT;
|
|
274
|
-
return v;
|
|
275
|
-
}
|
|
276
|
-
function numEnv(name, fallback, min = 0, max = Number.POSITIVE_INFINITY) {
|
|
277
|
-
const raw = process.env[name];
|
|
278
|
-
if (!raw)
|
|
279
|
-
return fallback;
|
|
280
|
-
const v = Number(raw);
|
|
281
|
-
if (!Number.isFinite(v) || v < min || v > max)
|
|
282
|
-
return fallback;
|
|
283
|
-
return Math.floor(v);
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Build a `ContextSelectorOpts` from the documented env knobs (PRD §M6d).
|
|
287
|
-
* Returns a defaulted opts object. `editTokens` is omitted — the caller
|
|
288
|
-
* must inject the live edit-history token set on each call (env can only
|
|
289
|
-
* configure the weight, not the dynamic data).
|
|
290
|
-
*/
|
|
291
|
-
export function readContextEnv() {
|
|
292
|
-
return {
|
|
293
|
-
maxScan: numEnv("PI_GHOST_CONTEXT_MAX_SCAN", DEFAULT_MAX_SCAN, 0),
|
|
294
|
-
maxSelected: numEnv("PI_GHOST_CONTEXT_MAX_SELECTED", DEFAULT_MAX_SELECTED, 0),
|
|
295
|
-
maxChars: numEnv("PI_GHOST_CONTEXT_MAX_CHARS", DEFAULT_MAX_CHARS, 0),
|
|
296
|
-
bm25Weight: parseBm25WeightEnv(process.env.PI_GHOST_CONTEXT_BM25_WEIGHT),
|
|
297
|
-
editLocalityWeight: parseEditLocalityWeightEnv(process.env.PI_GHOST_CONTEXT_EDIT_LOCALITY_WEIGHT),
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
//# sourceMappingURL=context-selector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-selector.js","sourceRoot":"","sources":["../src/context-selector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cycle-manager.d.ts","sourceRoot":"","sources":["../src/cycle-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA4BH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,CAK7F;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAInD;AAED;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,KAAK,CAA4B;IAEzC,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAWpC;;;OAGG;IACH,IAAI,UAAU,IAAI,SAAS,MAAM,EAAE,CAElC;IAED;;;;;OAKG;IACH,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAI3B;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO;IAc3B;;;;;;;;;;;;OAYG;IACH,uBAAuB,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;IAgBtE;;OAEG;IACH,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAQ5E"}
|
package/dist/cycle-manager.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CycleManager — owns multi-candidate state and word-level partial-accept
|
|
3
|
-
* gestures for the GREAT Ghost autocomplete.
|
|
4
|
-
*
|
|
5
|
-
* PRD §M3e (Alt+]/Alt+[ cycling with clamp-at-edges, no wrap) +
|
|
6
|
-
* PRD §M3f (Ctrl+Right word-by-word acceptance in append mode).
|
|
7
|
-
*
|
|
8
|
-
* Design notes:
|
|
9
|
-
*
|
|
10
|
-
* - Candidate list is stored read-only (frozen) so that future refactors
|
|
11
|
-
* don't accidentally mutate ranked text. Per-candidate consumption from
|
|
12
|
-
* word-level accepts is tracked separately in `consumed[idx]`.
|
|
13
|
-
* - `current` returns `string | null` — `null` distinguishes "no candidates
|
|
14
|
-
* installed" from "current candidate is empty after full consumption".
|
|
15
|
-
* - `acceptPartialWordAppend()` is named to make the append-mode invariant
|
|
16
|
-
* impossible to forget at call sites. Replace-mode ghosts (fuzzy/path)
|
|
17
|
-
* accept atomically; word-by-word doesn't apply.
|
|
18
|
-
* - No hidden auto-reset: caller is responsible for `reset()` after the
|
|
19
|
-
* final-chunk accept so the lifecycle is explicit.
|
|
20
|
-
*
|
|
21
|
-
* Extracted as part of refactor #57 so `GhostEditor` stays thin.
|
|
22
|
-
*/
|
|
23
|
-
function emptyState() {
|
|
24
|
-
return {
|
|
25
|
-
originals: Object.freeze([]),
|
|
26
|
-
consumed: [],
|
|
27
|
-
candidateIdx: 0,
|
|
28
|
-
cycledCount: 0,
|
|
29
|
-
partialAccepts: 0,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Pure helper: compute the next index for Alt+]/Alt[+ cycle.
|
|
34
|
-
* Returns null when the move would go past an edge (no wrap, per PRD).
|
|
35
|
-
*/
|
|
36
|
-
export function cycleCandidateIdx(currentIdx, len, dir) {
|
|
37
|
-
if (len <= 1)
|
|
38
|
-
return null;
|
|
39
|
-
const next = currentIdx + dir;
|
|
40
|
-
if (next < 0 || next >= len)
|
|
41
|
-
return null;
|
|
42
|
-
return next;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Extract the next lexical "word" chunk from the start of a ghost string.
|
|
46
|
-
* Skips leading whitespace, then either consumes an identifier run (`\w+`)
|
|
47
|
-
* OR a single non-word non-space char so code like `foo("bar")` accepts as
|
|
48
|
-
* `foo`, `(`, `"`, `bar`, `"`, `)` rather than gulping the whole
|
|
49
|
-
* expression. Used by Ctrl+Right partial accept.
|
|
50
|
-
*
|
|
51
|
-
* Returns the empty string when the ghost is empty or contains only
|
|
52
|
-
* whitespace — caller treats that as a no-op.
|
|
53
|
-
*/
|
|
54
|
-
export function nextWordChunk(ghost) {
|
|
55
|
-
if (!ghost)
|
|
56
|
-
return "";
|
|
57
|
-
const m = /^\s*(\w+|[^\s\w])/.exec(ghost);
|
|
58
|
-
return m ? m[0] : "";
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* CycleManager — small mutable facade over CycleState.
|
|
62
|
-
* All mutation goes through the manager so editor code stays declarative.
|
|
63
|
-
*/
|
|
64
|
-
export class CycleManager {
|
|
65
|
-
state = emptyState();
|
|
66
|
-
reset() {
|
|
67
|
-
this.state = emptyState();
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Install a fresh ranked candidate list for a newly shown ghost.
|
|
71
|
-
* Always resets indices, cycledCount, partialAccepts, and consumed
|
|
72
|
-
* offsets. The stored list is frozen — partial-accepts shrink the
|
|
73
|
-
* per-candidate `consumed` offset, never the underlying text.
|
|
74
|
-
*/
|
|
75
|
-
setCandidates(texts) {
|
|
76
|
-
const originals = Object.freeze(texts.length > 0 ? [...texts] : []);
|
|
77
|
-
this.state = {
|
|
78
|
-
originals,
|
|
79
|
-
consumed: new Array(originals.length).fill(0),
|
|
80
|
-
candidateIdx: 0,
|
|
81
|
-
cycledCount: 0,
|
|
82
|
-
partialAccepts: 0,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Read-only view of the ranked candidate list as installed. Stable across
|
|
87
|
-
* partial accepts (consumption is tracked separately via `current`).
|
|
88
|
-
*/
|
|
89
|
-
get candidates() {
|
|
90
|
-
return this.state.originals;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Currently displayed ghost text — the un-consumed remainder of the
|
|
94
|
-
* candidate at `candidateIdx`. Returns `null` when no candidates are
|
|
95
|
-
* installed; returns `""` when the current candidate has been fully
|
|
96
|
-
* consumed by partial accepts (caller must then `reset()`).
|
|
97
|
-
*/
|
|
98
|
-
get current() {
|
|
99
|
-
const o = this.state.originals[this.state.candidateIdx];
|
|
100
|
-
if (o === undefined)
|
|
101
|
-
return null;
|
|
102
|
-
return o.slice(this.state.consumed[this.state.candidateIdx] ?? 0);
|
|
103
|
-
}
|
|
104
|
-
get cycledCount() {
|
|
105
|
-
return this.state.cycledCount;
|
|
106
|
-
}
|
|
107
|
-
get partialAccepts() {
|
|
108
|
-
return this.state.partialAccepts;
|
|
109
|
-
}
|
|
110
|
-
get candidateIdx() {
|
|
111
|
-
return this.state.candidateIdx;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Attempt a cycle in the given direction. Returns true if the ghost text
|
|
115
|
-
* actually changed (i.e., a legal non-edge move occurred). Each
|
|
116
|
-
* candidate retains its own `consumed` offset across cycles so the user
|
|
117
|
-
* can partial-accept on A, cycle to B, cycle back to A and resume.
|
|
118
|
-
*/
|
|
119
|
-
cycle(dir) {
|
|
120
|
-
const nextIdx = cycleCandidateIdx(this.state.candidateIdx, this.state.originals.length, dir);
|
|
121
|
-
if (nextIdx === null) {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
this.state.candidateIdx = nextIdx;
|
|
125
|
-
this.state.cycledCount++;
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Perform a word-level partial accept on the currently displayed
|
|
130
|
-
* candidate. APPEND MODE ONLY — callers must check
|
|
131
|
-
* `!ghostReplaceFrom && cursorAtEnd()` before invoking. Naming
|
|
132
|
-
* deliberately includes `Append` so the invariant is impossible to
|
|
133
|
-
* forget at the call site.
|
|
134
|
-
*
|
|
135
|
-
* Returns the chunk that should be inserted now, plus the remaining
|
|
136
|
-
* ghost suffix (or `null` if this was the final chunk). When `remaining`
|
|
137
|
-
* is `null` the caller is responsible for finalizing and calling
|
|
138
|
-
* `reset()` — the manager does NOT auto-reset so lifecycle stays
|
|
139
|
-
* explicit.
|
|
140
|
-
*/
|
|
141
|
-
acceptPartialWordAppend() {
|
|
142
|
-
const cur = this.current;
|
|
143
|
-
if (cur === null || cur.length === 0) {
|
|
144
|
-
return { chunk: "", remaining: null };
|
|
145
|
-
}
|
|
146
|
-
const chunk = nextWordChunk(cur);
|
|
147
|
-
if (!chunk) {
|
|
148
|
-
return { chunk: "", remaining: null };
|
|
149
|
-
}
|
|
150
|
-
const idx = this.state.candidateIdx;
|
|
151
|
-
this.state.consumed[idx] = (this.state.consumed[idx] ?? 0) + chunk.length;
|
|
152
|
-
this.state.partialAccepts++;
|
|
153
|
-
const tail = cur.slice(chunk.length);
|
|
154
|
-
return { chunk, remaining: tail.length === 0 ? null : tail };
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Snapshot for diagnostics / metrics (no raw candidate text leaked).
|
|
158
|
-
*/
|
|
159
|
-
snapshot() {
|
|
160
|
-
return {
|
|
161
|
-
count: this.state.originals.length,
|
|
162
|
-
idx: this.state.candidateIdx,
|
|
163
|
-
cycled: this.state.cycledCount,
|
|
164
|
-
partials: this.state.partialAccepts,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
//# sourceMappingURL=cycle-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cycle-manager.js","sourceRoot":"","sources":["../src/cycle-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edit-history ring + aggregated index. Enhancement #1
|
|
3
|
-
* (Next-Edit-Prediction motivated). See `docs/edit-history-signals-spec.md`.
|
|
4
|
-
*
|
|
5
|
-
* Records the most recent K edits (default 32) made in-session, then
|
|
6
|
-
* exposes:
|
|
7
|
-
* - a `snapshot()` of newest-first events with age filtering, and
|
|
8
|
-
* - an `index()` of decayed token frequencies + per-URI line proximity.
|
|
9
|
-
*
|
|
10
|
-
* The reranker reads `index()` to compute `editProximityBoost`; the M6
|
|
11
|
-
* context selector reads it (opt-in) for a token-overlap locality bit.
|
|
12
|
-
*
|
|
13
|
-
* Privacy: events are pre-sanitized at capture (`containsSensitive` on
|
|
14
|
-
* the raw added/removed text — caller is responsible for invoking it
|
|
15
|
-
* before calling `record`). Only tokens + scalars + URIs survive. No
|
|
16
|
-
* raw text is ever stored on the ring. The ring lives in-process only —
|
|
17
|
-
* no persistence in v0.5.
|
|
18
|
-
*/
|
|
19
|
-
export declare const TOKEN_CAP_PER_EVENT = 16;
|
|
20
|
-
export declare const DEFAULT_CAPACITY = 32;
|
|
21
|
-
export declare const DEFAULT_MAX_AGE_MS: number;
|
|
22
|
-
export declare const DEFAULT_HALF_LIFE_MS: number;
|
|
23
|
-
export interface EditEvent {
|
|
24
|
-
ts: number;
|
|
25
|
-
uri: string;
|
|
26
|
-
rangeStartLine: number;
|
|
27
|
-
addedTokens: string[];
|
|
28
|
-
removedTokens: string[];
|
|
29
|
-
netCharDelta: number;
|
|
30
|
-
}
|
|
31
|
-
export interface EditHistoryIndex {
|
|
32
|
-
addedFreq: Map<string, number>;
|
|
33
|
-
removedFreq: Map<string, number>;
|
|
34
|
-
recentUris: Set<string>;
|
|
35
|
-
lastEditLineByUri: Map<string, number>;
|
|
36
|
-
totalEvents: number;
|
|
37
|
-
}
|
|
38
|
-
export interface EditHistoryOpts {
|
|
39
|
-
capacity?: number;
|
|
40
|
-
maxAgeMs?: number;
|
|
41
|
-
halfLifeMs?: number;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Tokenize text using the same regex as `profile.ts` (`\b[\w][\w-]*\b`).
|
|
45
|
-
* Code identifiers are case-sensitive — we do NOT lowercase. Result is
|
|
46
|
-
* capped at `TOKEN_CAP_PER_EVENT` to bound memory per event.
|
|
47
|
-
*/
|
|
48
|
-
export declare function tokenize(text: string): string[];
|
|
49
|
-
/**
|
|
50
|
-
* Exponential time-decay weight: 1.0 at `ageMs=0`, halves every
|
|
51
|
-
* `halfLifeMs`. Pure helper for tests + index().
|
|
52
|
-
*/
|
|
53
|
-
export declare function timeDecayWeight(ageMs: number, halfLifeMs?: number): number;
|
|
54
|
-
export declare class EditHistoryRing {
|
|
55
|
-
private readonly events;
|
|
56
|
-
readonly capacity: number;
|
|
57
|
-
readonly maxAgeMs: number;
|
|
58
|
-
readonly halfLifeMs: number;
|
|
59
|
-
constructor(opts?: EditHistoryOpts);
|
|
60
|
-
/**
|
|
61
|
-
* Append an event. `ts` defaults to `Date.now()`. Caller is responsible
|
|
62
|
-
* for sanitization — the ring does not re-validate. Overflow drops the
|
|
63
|
-
* oldest event.
|
|
64
|
-
*/
|
|
65
|
-
record(ev: Omit<EditEvent, "ts"> & {
|
|
66
|
-
ts?: number;
|
|
67
|
-
}): void;
|
|
68
|
-
/**
|
|
69
|
-
* Newest-first list of events not older than `maxAgeMs`. Returns a
|
|
70
|
-
* copy — safe for the caller to retain.
|
|
71
|
-
*
|
|
72
|
-
* Scans without early-break: we cannot assume `record()` was called in
|
|
73
|
-
* ts-monotonic order (a backfill or test clock could insert older
|
|
74
|
-
* events after newer ones). At capacity=32 the scan cost is trivial.
|
|
75
|
-
*/
|
|
76
|
-
snapshot(now?: number): EditEvent[];
|
|
77
|
-
/**
|
|
78
|
-
* Aggregated index of recent edit signals, with exponential time-decay
|
|
79
|
-
* applied to token frequencies. URIs touched within `maxAgeMs` are
|
|
80
|
-
* collected; the *most recent* edit line per URI is kept (used by the
|
|
81
|
-
* reranker for line-proximity scoring).
|
|
82
|
-
*/
|
|
83
|
-
index(now?: number): EditHistoryIndex;
|
|
84
|
-
clear(): void;
|
|
85
|
-
get size(): number;
|
|
86
|
-
}
|
|
87
|
-
/** Default per-entry size cap. 1 MB — large enough for any realistic
|
|
88
|
-
* source file, small enough that 16 × 1MB = 16MB worst-case is bounded. */
|
|
89
|
-
export declare const DEFAULT_PRE_EDIT_MAX_BYTES: number;
|
|
90
|
-
/**
|
|
91
|
-
* Per-document pre-edit text cache. Holds the most recent `capacity`
|
|
92
|
-
* document texts so we can derive the *removed* slice of an edit before
|
|
93
|
-
* the on-disk text mutates. LRU-bounded to avoid pinning every project
|
|
94
|
-
* file in RAM. v0.5 stores transiently in process only — never persisted.
|
|
95
|
-
*
|
|
96
|
-
* Per-entry size is capped at `maxBytesPerEntry` (default 1 MB). Texts
|
|
97
|
-
* exceeding the cap are stored as empty string — the next edit on that
|
|
98
|
-
* document will derive empty `removedTokens`, which is the same
|
|
99
|
-
* degradation as a fresh LRU miss. This bounds worst-case memory at
|
|
100
|
-
* `capacity * maxBytesPerEntry` regardless of project file sizes.
|
|
101
|
-
*/
|
|
102
|
-
export declare class PreEditTextCache {
|
|
103
|
-
private readonly map;
|
|
104
|
-
readonly capacity: number;
|
|
105
|
-
readonly maxBytesPerEntry: number;
|
|
106
|
-
constructor(capacity?: number, maxBytesPerEntry?: number);
|
|
107
|
-
/** Returns the snapshot for `uri` (or `""` if absent) without touching LRU order. */
|
|
108
|
-
peek(uri: string): string;
|
|
109
|
-
/**
|
|
110
|
-
* Update the snapshot. Move-to-front semantics; oldest is evicted when
|
|
111
|
-
* capacity is exceeded. Texts exceeding `maxBytesPerEntry` are stored
|
|
112
|
-
* as empty string (the next edit on this URI gets no `removedTokens`,
|
|
113
|
-
* matching the LRU-miss degradation path).
|
|
114
|
-
*
|
|
115
|
-
* Byte length uses UTF-16 code units (`text.length`), not UTF-8 bytes —
|
|
116
|
-
* the cap is approximate but stable across machines.
|
|
117
|
-
*/
|
|
118
|
-
update(uri: string, text: string): void;
|
|
119
|
-
clear(): void;
|
|
120
|
-
get size(): number;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Spec §5.1 — compute the raw `editProximityScore` for a candidate. Pure
|
|
124
|
-
* function. Returns 0 when the ring is empty (zero events). Output is
|
|
125
|
-
* un-normalized: the reranker's min-max normalization re-maps the value
|
|
126
|
-
* across the candidate set so absolute scale doesn't matter — only the
|
|
127
|
-
* relative ordering does. The same un-normalized value is reported on
|
|
128
|
-
* the `MetricRecord` for observability.
|
|
129
|
-
*
|
|
130
|
-
* `currentUri` / `currentLine` describe the user's cursor at predict
|
|
131
|
-
* time. The prompt-buffer editor uses a static `"prompt"` URI sentinel
|
|
132
|
-
* and the current cursor line.
|
|
133
|
-
*/
|
|
134
|
-
export declare function editProximityScore(text: string, index: EditHistoryIndex, currentUri: string, currentLine: number): number;
|
|
135
|
-
/**
|
|
136
|
-
* Pure character-diff helper. Returns the minimal `{ added, removed }`
|
|
137
|
-
* slice between two strings by stripping the common prefix + suffix.
|
|
138
|
-
* Caller is responsible for `containsSensitive` checks before tokenizing
|
|
139
|
-
* the result. Returns empty strings for both sides when texts are equal.
|
|
140
|
-
*/
|
|
141
|
-
export declare function diffStrings(prev: string, next: string): {
|
|
142
|
-
added: string;
|
|
143
|
-
removed: string;
|
|
144
|
-
};
|
|
145
|
-
export declare function readEditHistoryEnv(env?: Record<string, string | undefined>): Required<EditHistoryOpts> & {
|
|
146
|
-
enabled: boolean;
|
|
147
|
-
};
|
|
148
|
-
//# sourceMappingURL=edit-history-ring.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edit-history-ring.d.ts","sourceRoot":"","sources":["../src/edit-history-ring.ts"],"names":[],"mappings":"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"}
|