pi-ghost-autocomplete 0.3.1 → 0.3.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.
- package/README.md +101 -6
- package/dist/bench-cli.js +81 -5
- package/dist/bench-cli.js.map +1 -1
- package/dist/bench.d.ts +130 -2
- package/dist/bench.d.ts.map +1 -1
- package/dist/bench.js +285 -4
- package/dist/bench.js.map +1 -1
- package/dist/cache.d.ts +124 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +173 -0
- package/dist/cache.js.map +1 -0
- package/dist/candidate-rerank.d.ts +57 -0
- package/dist/candidate-rerank.d.ts.map +1 -0
- package/dist/candidate-rerank.js +78 -0
- package/dist/candidate-rerank.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +148 -18
- package/dist/config.js.map +1 -1
- package/dist/context-aggregator.d.ts +14 -5
- package/dist/context-aggregator.d.ts.map +1 -1
- package/dist/context-aggregator.js +38 -9
- package/dist/context-aggregator.js.map +1 -1
- package/dist/context-selector.d.ts +128 -0
- package/dist/context-selector.d.ts.map +1 -0
- package/dist/context-selector.js +300 -0
- package/dist/context-selector.js.map +1 -0
- package/dist/cycle-manager.d.ts +102 -0
- package/dist/cycle-manager.d.ts.map +1 -0
- package/dist/cycle-manager.js +168 -0
- package/dist/cycle-manager.js.map +1 -0
- package/dist/edit-history-ring.d.ts +148 -0
- package/dist/edit-history-ring.d.ts.map +1 -0
- package/dist/edit-history-ring.js +262 -0
- package/dist/edit-history-ring.js.map +1 -0
- package/dist/entropy-stop.d.ts +102 -0
- package/dist/entropy-stop.d.ts.map +1 -0
- package/dist/entropy-stop.js +141 -0
- package/dist/entropy-stop.js.map +1 -0
- package/dist/eval-dataset.d.ts +66 -0
- package/dist/eval-dataset.d.ts.map +1 -0
- package/dist/eval-dataset.js +127 -0
- package/dist/eval-dataset.js.map +1 -0
- package/dist/fast-path-engine.d.ts +286 -0
- package/dist/fast-path-engine.d.ts.map +1 -0
- package/dist/fast-path-engine.js +341 -0
- package/dist/fast-path-engine.js.map +1 -0
- package/dist/fuzzy-matcher.d.ts +8 -0
- package/dist/fuzzy-matcher.d.ts.map +1 -1
- package/dist/fuzzy-matcher.js +5 -3
- package/dist/fuzzy-matcher.js.map +1 -1
- package/dist/ghost-editor.d.ts +321 -4
- package/dist/ghost-editor.d.ts.map +1 -1
- package/dist/ghost-editor.js +1190 -144
- package/dist/ghost-editor.js.map +1 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -2
- package/dist/index.js.map +1 -1
- package/dist/keystroke-timer.d.ts +59 -0
- package/dist/keystroke-timer.d.ts.map +1 -0
- package/dist/keystroke-timer.js +94 -0
- package/dist/keystroke-timer.js.map +1 -0
- package/dist/metrics-builder.d.ts +71 -0
- package/dist/metrics-builder.d.ts.map +1 -0
- package/dist/metrics-builder.js +71 -0
- package/dist/metrics-builder.js.map +1 -0
- package/dist/metrics.d.ts +99 -2
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +131 -17
- package/dist/metrics.js.map +1 -1
- package/dist/path-matcher.d.ts +9 -0
- package/dist/path-matcher.d.ts.map +1 -1
- package/dist/path-matcher.js +5 -2
- package/dist/path-matcher.js.map +1 -1
- package/dist/profile-store.d.ts +82 -0
- package/dist/profile-store.d.ts.map +1 -0
- package/dist/profile-store.js +199 -0
- package/dist/profile-store.js.map +1 -0
- package/dist/profile.d.ts +185 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +434 -0
- package/dist/profile.js.map +1 -0
- package/dist/providers/cloud-provider.d.ts +10 -1
- package/dist/providers/cloud-provider.d.ts.map +1 -1
- package/dist/providers/cloud-provider.js +71 -14
- package/dist/providers/cloud-provider.js.map +1 -1
- package/dist/providers/local-provider.d.ts +8 -1
- package/dist/providers/local-provider.d.ts.map +1 -1
- package/dist/providers/local-provider.js +15 -3
- package/dist/providers/local-provider.js.map +1 -1
- package/dist/providers/openai-compat-provider.d.ts +11 -1
- package/dist/providers/openai-compat-provider.d.ts.map +1 -1
- package/dist/providers/openai-compat-provider.js +93 -6
- package/dist/providers/openai-compat-provider.js.map +1 -1
- package/dist/providers/openai-completions-runner.d.ts +25 -1
- package/dist/providers/openai-completions-runner.d.ts.map +1 -1
- package/dist/providers/openai-completions-runner.js +109 -14
- package/dist/providers/openai-completions-runner.js.map +1 -1
- package/dist/providers/race.d.ts +58 -1
- package/dist/providers/race.d.ts.map +1 -1
- package/dist/providers/race.js +317 -4
- package/dist/providers/race.js.map +1 -1
- package/dist/providers/truncate.d.ts.map +1 -1
- package/dist/providers/truncate.js +20 -2
- package/dist/providers/truncate.js.map +1 -1
- package/dist/providers/types.d.ts +96 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +59 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/provisional-manager.d.ts +93 -0
- package/dist/provisional-manager.d.ts.map +1 -0
- package/dist/provisional-manager.js +98 -0
- package/dist/provisional-manager.js.map +1 -0
- package/dist/provisional.d.ts +150 -0
- package/dist/provisional.d.ts.map +1 -0
- package/dist/provisional.js +238 -0
- package/dist/provisional.js.map +1 -0
- package/dist/regret-tracker.d.ts +84 -0
- package/dist/regret-tracker.d.ts.map +1 -0
- package/dist/regret-tracker.js +145 -0
- package/dist/regret-tracker.js.map +1 -0
- package/dist/replay-cli.d.ts +13 -0
- package/dist/replay-cli.d.ts.map +1 -0
- package/dist/replay-cli.js +167 -0
- package/dist/replay-cli.js.map +1 -0
- package/dist/replay.d.ts +107 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +225 -0
- package/dist/replay.js.map +1 -0
- package/dist/reranker.d.ts +181 -0
- package/dist/reranker.d.ts.map +1 -0
- package/dist/reranker.js +324 -0
- package/dist/reranker.js.map +1 -0
- package/dist/session-trie.d.ts +103 -0
- package/dist/session-trie.d.ts.map +1 -0
- package/dist/session-trie.js +280 -0
- package/dist/session-trie.js.map +1 -0
- package/dist/speculative.d.ts +74 -0
- package/dist/speculative.d.ts.map +1 -0
- package/dist/speculative.js +107 -0
- package/dist/speculative.js.map +1 -0
- package/dist/tool-summarize.d.ts +40 -0
- package/dist/tool-summarize.d.ts.map +1 -0
- package/dist/tool-summarize.js +245 -0
- package/dist/tool-summarize.js.map +1 -0
- package/dist/trie-sanitize.d.ts +22 -0
- package/dist/trie-sanitize.d.ts.map +1 -0
- package/dist/trie-sanitize.js +142 -0
- package/dist/trie-sanitize.js.map +1 -0
- package/dist/versions.d.ts +23 -0
- package/dist/versions.d.ts.map +1 -0
- package/dist/versions.js +31 -0
- package/dist/versions.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast-path engine: owns the three sync ghost sources (session trie,
|
|
3
|
+
* completion cache, speculative-warm ring) and exposes a single lookup
|
|
4
|
+
* that returns the winning hit or null. PRD §M1 + §M2.
|
|
5
|
+
*
|
|
6
|
+
* Also exposes `decideDeterministic` — a pure function that resolves
|
|
7
|
+
* the path-prefix / fuzzy-filename decision used by the editor's
|
|
8
|
+
* deterministic ghost path (PRD §M4 deterministic matchers).
|
|
9
|
+
*
|
|
10
|
+
* Refactor #57 slices 1 + 2. Extracted from `ghost-editor.ts` to reduce
|
|
11
|
+
* the editor's responsibility surface. The engine is state-only — it
|
|
12
|
+
* does not touch the editor's render or metric pipeline; callers feed
|
|
13
|
+
* it fingerprints and read the result.
|
|
14
|
+
*
|
|
15
|
+
* Mutation methods (set/delete/insertFromAccept/penalize/...) are left
|
|
16
|
+
* on the inner instances (`engine.cache`, `engine.trie`,
|
|
17
|
+
* `engine.lastGhosts`) and accessed by the editor directly. Migrating
|
|
18
|
+
* those into named methods is a follow-up slice; the win here is
|
|
19
|
+
* consolidating the lookup ordering in one place so it can be unit
|
|
20
|
+
* tested without spinning up the editor.
|
|
21
|
+
*
|
|
22
|
+
* Remaining #57 slices: extract `applyDeterministic` mutation,
|
|
23
|
+
* ProvisionalManager, CycleManager, MetricsBuilder. ghost-editor.ts
|
|
24
|
+
* target: <800 LOC.
|
|
25
|
+
*/
|
|
26
|
+
import { createHash } from "node:crypto";
|
|
27
|
+
import { CompletionCache, decideWarmPath } from "./cache.js";
|
|
28
|
+
import { SessionTrie } from "./session-trie.js";
|
|
29
|
+
import { LastGhostsRing } from "./speculative.js";
|
|
30
|
+
import { extractPathPrefixToken, findPathPrefix } from "./path-matcher.js";
|
|
31
|
+
import { extractFuzzyToken, findFuzzyFilename } from "./fuzzy-matcher.js";
|
|
32
|
+
import { EditHistoryRing, PreEditTextCache, readEditHistoryEnv, } from "./edit-history-ring.js";
|
|
33
|
+
import { pickProvisional, provisionalDelayMs, ProvisionalManager, } from "./provisional-manager.js";
|
|
34
|
+
import { parseProvisionalEnv } from "./provisional.js";
|
|
35
|
+
/**
|
|
36
|
+
* Build the bundled config snapshot. Reads each knob once. Exported so
|
|
37
|
+
* tests + diag can compute the same fingerprint deterministically.
|
|
38
|
+
*/
|
|
39
|
+
export function buildFastPathEngineConfig(env = process.env) {
|
|
40
|
+
const editHistory = readEditHistoryEnv(env);
|
|
41
|
+
return {
|
|
42
|
+
rerankWeightsRaw: env.PI_GHOST_RERANK_WEIGHTS,
|
|
43
|
+
minConfidenceRaw: env.PI_GHOST_MIN_CONFIDENCE,
|
|
44
|
+
provisionalRaw: env.PI_GHOST_PROVISIONAL,
|
|
45
|
+
provisionalPreferRaw: env.PI_GHOST_PROVISIONAL_PREFER,
|
|
46
|
+
contextBm25WeightRaw: env.PI_GHOST_CONTEXT_BM25_WEIGHT,
|
|
47
|
+
contextEditLocalityWeightRaw: env.PI_GHOST_CONTEXT_EDIT_LOCALITY_WEIGHT,
|
|
48
|
+
contextToolMaxRaw: env.PI_GHOST_CONTEXT_TOOL_MAX,
|
|
49
|
+
shortHoverMsRaw: env.PI_GHOST_SHORT_HOVER_MS,
|
|
50
|
+
regretWindowMsRaw: env.PI_GHOST_REGRET_WINDOW_MS,
|
|
51
|
+
evalCaptureRaw: env.PI_GHOST_EVAL_CAPTURE,
|
|
52
|
+
editHistory: {
|
|
53
|
+
enabled: editHistory.enabled,
|
|
54
|
+
capacity: editHistory.capacity,
|
|
55
|
+
maxAgeMs: editHistory.maxAgeMs,
|
|
56
|
+
halfLifeMs: editHistory.halfLifeMs,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Stable fingerprint over the bundled config. Suitable for folding into
|
|
62
|
+
* cache keys so a knob change (e.g. swapping rerank weights mid-session)
|
|
63
|
+
* invalidates affected entries. Field ordering is the JSON ordering
|
|
64
|
+
* above; do not reorder without bumping the fingerprint version.
|
|
65
|
+
*/
|
|
66
|
+
export function fingerprintFastPathEngineConfig(cfg) {
|
|
67
|
+
const h = createHash("sha1");
|
|
68
|
+
h.update(JSON.stringify([
|
|
69
|
+
"fpe-cfg-v1",
|
|
70
|
+
cfg.rerankWeightsRaw ?? "",
|
|
71
|
+
cfg.minConfidenceRaw ?? "",
|
|
72
|
+
cfg.provisionalRaw ?? "",
|
|
73
|
+
cfg.provisionalPreferRaw ?? "",
|
|
74
|
+
cfg.contextBm25WeightRaw ?? "",
|
|
75
|
+
cfg.contextEditLocalityWeightRaw ?? "",
|
|
76
|
+
cfg.contextToolMaxRaw ?? "",
|
|
77
|
+
cfg.shortHoverMsRaw ?? "",
|
|
78
|
+
cfg.regretWindowMsRaw ?? "",
|
|
79
|
+
cfg.evalCaptureRaw ?? "",
|
|
80
|
+
cfg.editHistory.enabled,
|
|
81
|
+
cfg.editHistory.capacity,
|
|
82
|
+
cfg.editHistory.maxAgeMs,
|
|
83
|
+
cfg.editHistory.halfLifeMs,
|
|
84
|
+
]));
|
|
85
|
+
return h.digest("hex").slice(0, 16);
|
|
86
|
+
}
|
|
87
|
+
export class FastPathEngine {
|
|
88
|
+
cache = new CompletionCache();
|
|
89
|
+
trie = new SessionTrie();
|
|
90
|
+
lastGhosts = new LastGhostsRing();
|
|
91
|
+
/**
|
|
92
|
+
* Enhancement #1 — edit-history ring + pre-edit text cache. Capacity /
|
|
93
|
+
* decay parameters read once at construction from
|
|
94
|
+
* `PI_GHOST_EDIT_HISTORY*` env. The `enabled` flag is the master
|
|
95
|
+
* switch: when false the editor skips `record()` (zero overhead) and
|
|
96
|
+
* skips injecting an `editProximityScorer` into the reranker.
|
|
97
|
+
*/
|
|
98
|
+
editHistory;
|
|
99
|
+
preEditCache = new PreEditTextCache();
|
|
100
|
+
editHistoryEnabled;
|
|
101
|
+
/**
|
|
102
|
+
* PRD §M4 — workspace path index used by the deterministic matchers
|
|
103
|
+
* (`decideDeterministic`). `null` until the editor's async indexer
|
|
104
|
+
* resolves; the deterministic step is skipped in that window.
|
|
105
|
+
*/
|
|
106
|
+
pathIndex = null;
|
|
107
|
+
/** Phase 2 — bundled env snapshot. Consumers migrate to read from here
|
|
108
|
+
* instead of `process.env` over time. Immutable for an engine's lifetime. */
|
|
109
|
+
config;
|
|
110
|
+
configFingerprintCached;
|
|
111
|
+
/**
|
|
112
|
+
* PRD §M3.5b — provisional ghost manager. Owned by the engine so the
|
|
113
|
+
* `picker` closure can be built from the engine's own trie + lastGhosts
|
|
114
|
+
* without the editor having to reach in. The editor still supplies the
|
|
115
|
+
* `canRender` predicate (editor-state) and `onShow` callback (UI mutator).
|
|
116
|
+
*/
|
|
117
|
+
provisional = new ProvisionalManager();
|
|
118
|
+
constructor(env = process.env) {
|
|
119
|
+
this.config = buildFastPathEngineConfig(env);
|
|
120
|
+
this.editHistoryEnabled = this.config.editHistory.enabled;
|
|
121
|
+
this.editHistory = new EditHistoryRing({
|
|
122
|
+
capacity: this.config.editHistory.capacity,
|
|
123
|
+
maxAgeMs: this.config.editHistory.maxAgeMs,
|
|
124
|
+
halfLifeMs: this.config.editHistory.halfLifeMs,
|
|
125
|
+
});
|
|
126
|
+
this.configFingerprintCached = fingerprintFastPathEngineConfig(this.config);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Stable fingerprint over the bundled env config. Suitable for folding
|
|
130
|
+
* into cache keys so a knob change invalidates affected entries. See
|
|
131
|
+
* `fingerprintFastPathEngineConfig` for the field-ordering contract.
|
|
132
|
+
*/
|
|
133
|
+
getConfigFingerprint() {
|
|
134
|
+
return this.configFingerprintCached;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Install or replace the workspace path index. Called once at editor
|
|
138
|
+
* startup after the async indexer resolves; may be re-called with
|
|
139
|
+
* `null` to disable deterministic matching (test / shutdown path).
|
|
140
|
+
*/
|
|
141
|
+
setPathIndex(pi) {
|
|
142
|
+
this.pathIndex = pi;
|
|
143
|
+
}
|
|
144
|
+
getPathIndex() {
|
|
145
|
+
return this.pathIndex;
|
|
146
|
+
}
|
|
147
|
+
// === Mutation wrappers (refactor #57 slice A) =========================
|
|
148
|
+
// Editor goes through these instead of reaching into trie/cache/lastGhosts
|
|
149
|
+
// directly. Each method maps 1:1 to a single inner-instance call — no
|
|
150
|
+
// new logic, just a stable surface so future refactors (e.g. swapping
|
|
151
|
+
// the trie implementation) don't ripple through `ghost-editor.ts`.
|
|
152
|
+
/** PRD §M2 — seed (prefix, ghost) into the session trie after an accept. */
|
|
153
|
+
recordAccept(prefix, ghost, weight) {
|
|
154
|
+
this.trie.insertFromAccept(prefix, ghost, weight);
|
|
155
|
+
}
|
|
156
|
+
/** PRD §M2 / #5 — apply a negative-signal penalty to a (prefix, ghost) pair. */
|
|
157
|
+
penalize(prefix, ghost, magnitude) {
|
|
158
|
+
this.trie.penalize(prefix, ghost, magnitude);
|
|
159
|
+
}
|
|
160
|
+
/** PRD §M1a — write a completed ghost into the cache keyed on `cacheKey`. */
|
|
161
|
+
setCacheEntry(cacheKey, value) {
|
|
162
|
+
this.cache.set(cacheKey, value);
|
|
163
|
+
}
|
|
164
|
+
/** PRD §M1a — evict a single cache entry on a non-accept outcome. */
|
|
165
|
+
deleteCacheEntry(cacheKey) {
|
|
166
|
+
this.cache.delete(cacheKey);
|
|
167
|
+
}
|
|
168
|
+
/** PRD §M1b — record a shown ghost into the speculative-warm ring. */
|
|
169
|
+
recordRecentGhost(entry) {
|
|
170
|
+
this.lastGhosts.push(entry);
|
|
171
|
+
}
|
|
172
|
+
// === Provisional surface (refactor #57 phase 3) =======================
|
|
173
|
+
/**
|
|
174
|
+
* PRD §M3.5b — arm a provisional ghost. Engine reads
|
|
175
|
+
* `PI_GHOST_PROVISIONAL` from the bundled config; no-op when disabled.
|
|
176
|
+
* The engine builds the `picker` from its own `trie` + `lastGhosts` +
|
|
177
|
+
* caller's profile. Editor supplies the `canRender` predicate
|
|
178
|
+
* (editor-state) and `onShow` callback (UI mutator).
|
|
179
|
+
*/
|
|
180
|
+
armProvisional(input) {
|
|
181
|
+
if (!parseProvisionalEnv(this.config.provisionalRaw))
|
|
182
|
+
return;
|
|
183
|
+
this.provisional.arm({
|
|
184
|
+
prefix: input.prefix,
|
|
185
|
+
delayMs: provisionalDelayMs(input.debounceMs),
|
|
186
|
+
canRender: input.canRender,
|
|
187
|
+
picker: () => pickProvisional({
|
|
188
|
+
prefix: input.prefix,
|
|
189
|
+
trie: this.trie,
|
|
190
|
+
profile: input.profile,
|
|
191
|
+
lastGhosts: this.lastGhosts,
|
|
192
|
+
}),
|
|
193
|
+
onShow: input.onShow,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* PRD §M3.5b — reconcile an LLM result against any displayed
|
|
198
|
+
* provisional. Engine reads `PI_GHOST_PROVISIONAL_PREFER` from the
|
|
199
|
+
* bundled config.
|
|
200
|
+
*/
|
|
201
|
+
reconcileProvisional(input) {
|
|
202
|
+
return this.provisional.reconcile({
|
|
203
|
+
llm: input.llm,
|
|
204
|
+
swapMarginEnvRaw: this.config.provisionalPreferRaw,
|
|
205
|
+
now: input.now,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/** True iff a provisional pick is currently displayed. */
|
|
209
|
+
isProvisionalShown() {
|
|
210
|
+
return this.provisional.isShown;
|
|
211
|
+
}
|
|
212
|
+
/** Cancel a pending provisional timer without touching the displayed pick. */
|
|
213
|
+
cancelProvisionalTimer() {
|
|
214
|
+
this.provisional.cancelTimer();
|
|
215
|
+
}
|
|
216
|
+
/** Reset provisional state (timer + displayed pick). */
|
|
217
|
+
clearProvisional() {
|
|
218
|
+
this.provisional.clear();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Try, in order: session trie → completion cache → speculative warm.
|
|
222
|
+
* Returns null when nothing matches. Lookup is sync and allocation-light;
|
|
223
|
+
* fits inside a keystroke handler.
|
|
224
|
+
*
|
|
225
|
+
* `prefix` is the full pre-cursor text (multiline). The trie consults
|
|
226
|
+
* only the last line (committed messages + accepts are seeded against
|
|
227
|
+
* single-line prefixes). The cache/warm path consults the full prefix.
|
|
228
|
+
*/
|
|
229
|
+
lookup(prefix, ctx) {
|
|
230
|
+
const lastLine = prefix.split("\n").pop() ?? "";
|
|
231
|
+
const trieHit = this.trie.lookup(lastLine);
|
|
232
|
+
if (trieHit) {
|
|
233
|
+
return {
|
|
234
|
+
ghost: trieHit.ghost,
|
|
235
|
+
mode: "trie",
|
|
236
|
+
providerName: "session-trie",
|
|
237
|
+
cacheKey: undefined,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
// Default the config fingerprint to the engine's own snapshot —
|
|
241
|
+
// callers get knob-change cache invalidation automatically. An
|
|
242
|
+
// explicit `ctx.configFingerprint` (e.g. tests) overrides.
|
|
243
|
+
const configFingerprint = ctx.configFingerprint ?? this.configFingerprintCached;
|
|
244
|
+
const warm = decideWarmPath({
|
|
245
|
+
cache: this.cache,
|
|
246
|
+
ring: this.lastGhosts,
|
|
247
|
+
prefix,
|
|
248
|
+
contextFingerprint: ctx.contextFingerprint,
|
|
249
|
+
providerFingerprint: ctx.providerFingerprint,
|
|
250
|
+
versionFingerprint: ctx.versionFingerprint,
|
|
251
|
+
configFingerprint,
|
|
252
|
+
cooldownActive: ctx.cooldownActive,
|
|
253
|
+
...(ctx.now !== undefined ? { now: ctx.now } : {}),
|
|
254
|
+
});
|
|
255
|
+
return warm ?? null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Deterministic-aware lookup. Runs `decideDeterministic` first (when
|
|
259
|
+
* a `deterministic` input is supplied) and falls back to the standard
|
|
260
|
+
* trie/cache/warm lookup. Returns a discriminated union so the caller
|
|
261
|
+
* can route deterministic decisions through its `applyDeterministic`
|
|
262
|
+
* mutator (different metrics path) while still using a single entry
|
|
263
|
+
* point. Pass `deterministic: null` to skip the path-prefix/fuzzy
|
|
264
|
+
* matchers (e.g., when an autocomplete popup is open).
|
|
265
|
+
*
|
|
266
|
+
* No editor state inside the engine — `deterministic` is supplied as a
|
|
267
|
+
* fully-formed `DeterministicInput`, and the editor owns the eventual
|
|
268
|
+
* mutation (`applyServedGhost` / `applyDeterministic`).
|
|
269
|
+
*/
|
|
270
|
+
lookupWithDeterministic(prefix, ctx, deterministic) {
|
|
271
|
+
if (deterministic) {
|
|
272
|
+
const decision = decideDeterministic(deterministic);
|
|
273
|
+
if (decision)
|
|
274
|
+
return { kind: "deterministic", decision };
|
|
275
|
+
}
|
|
276
|
+
const hit = this.lookup(prefix, ctx);
|
|
277
|
+
if (hit)
|
|
278
|
+
return { kind: "fast-path", hit };
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Resolve a deterministic ghost candidate from the active path index.
|
|
284
|
+
* Tries path-prefix first (e.g. `src/co|` → `src/config.ts`), then
|
|
285
|
+
* fuzzy-filename (e.g. `cfg|` → `config.ts` with replace).
|
|
286
|
+
*
|
|
287
|
+
* Pure function — does not consult `this`, autocomplete state, or
|
|
288
|
+
* cursor mutation. The editor's `tryDeterministic` wraps this with the
|
|
289
|
+
* `isShowingAutocomplete()` guard and the `applyDeterministic` mutation.
|
|
290
|
+
*
|
|
291
|
+
* Returns null when no candidate clears the score gates (≥70 fuzzy
|
|
292
|
+
* baseline; ≥85 for non-action-trigger contexts).
|
|
293
|
+
*/
|
|
294
|
+
export function decideDeterministic(input) {
|
|
295
|
+
const partial = input.lineText.slice(0, input.cursorCol);
|
|
296
|
+
const pathTok = extractPathPrefixToken(partial);
|
|
297
|
+
if (pathTok) {
|
|
298
|
+
const m = findPathPrefix(input.pathIndex, pathTok.token, {
|
|
299
|
+
recentPaths: input.recentPaths,
|
|
300
|
+
profileBoost: input.profileBoost,
|
|
301
|
+
});
|
|
302
|
+
if (m) {
|
|
303
|
+
return {
|
|
304
|
+
ghost: m.suffix,
|
|
305
|
+
replaceFrom: null,
|
|
306
|
+
providerName: "path-prefix",
|
|
307
|
+
matchedPath: m.match,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const fuzTok = extractFuzzyToken(input.lineText, input.cursorCol);
|
|
312
|
+
if (!fuzTok)
|
|
313
|
+
return null;
|
|
314
|
+
const fm = findFuzzyFilename(input.pathIndex, fuzTok.token, {
|
|
315
|
+
recentPaths: input.recentPaths,
|
|
316
|
+
profileBoost: input.profileBoost,
|
|
317
|
+
});
|
|
318
|
+
if (!fm)
|
|
319
|
+
return null;
|
|
320
|
+
if (fm.score < 70)
|
|
321
|
+
return null;
|
|
322
|
+
if (fm.score < 85 && !fuzTok.hasActionTrigger)
|
|
323
|
+
return null;
|
|
324
|
+
return {
|
|
325
|
+
ghost: fm.ghost,
|
|
326
|
+
replaceFrom: fm.replace ? { line: input.cursorLine, col: fuzTok.startCol } : null,
|
|
327
|
+
providerName: bandToProvider(fm.band),
|
|
328
|
+
matchedPath: fm.match,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
export function bandToProvider(band) {
|
|
332
|
+
switch (band) {
|
|
333
|
+
case "basename-prefix":
|
|
334
|
+
return "basename-prefix";
|
|
335
|
+
case "fuzzy-basename":
|
|
336
|
+
return "fuzzy-basename";
|
|
337
|
+
case "fuzzy-path":
|
|
338
|
+
return "fuzzy-path";
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=fast-path-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fast-path-engine.js","sourceRoot":"","sources":["../src/fast-path-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAkB,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAkB,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GAGlB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAuFvD;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAuB,OAAO,CAAC,GAAG;IAC3E,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO;QACN,gBAAgB,EAAE,GAAG,CAAC,uBAAuB;QAC7C,gBAAgB,EAAE,GAAG,CAAC,uBAAuB;QAC7C,cAAc,EAAE,GAAG,CAAC,oBAAoB;QACxC,oBAAoB,EAAE,GAAG,CAAC,2BAA2B;QACrD,oBAAoB,EAAE,GAAG,CAAC,4BAA4B;QACtD,4BAA4B,EAAE,GAAG,CAAC,qCAAqC;QACvE,iBAAiB,EAAE,GAAG,CAAC,yBAAyB;QAChD,eAAe,EAAE,GAAG,CAAC,uBAAuB;QAC5C,iBAAiB,EAAE,GAAG,CAAC,yBAAyB;QAChD,cAAc,EAAE,GAAG,CAAC,qBAAqB;QACzC,WAAW,EAAE;YACZ,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,UAAU,EAAE,WAAW,CAAC,UAAU;SAClC;KACD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAAC,GAAyB;IACxE,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,MAAM,CACP,IAAI,CAAC,SAAS,CAAC;QACd,YAAY;QACZ,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAC1B,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAC1B,GAAG,CAAC,cAAc,IAAI,EAAE;QACxB,GAAG,CAAC,oBAAoB,IAAI,EAAE;QAC9B,GAAG,CAAC,oBAAoB,IAAI,EAAE;QAC9B,GAAG,CAAC,4BAA4B,IAAI,EAAE;QACtC,GAAG,CAAC,iBAAiB,IAAI,EAAE;QAC3B,GAAG,CAAC,eAAe,IAAI,EAAE;QACzB,GAAG,CAAC,iBAAiB,IAAI,EAAE;QAC3B,GAAG,CAAC,cAAc,IAAI,EAAE;QACxB,GAAG,CAAC,WAAW,CAAC,OAAO;QACvB,GAAG,CAAC,WAAW,CAAC,QAAQ;QACxB,GAAG,CAAC,WAAW,CAAC,QAAQ;QACxB,GAAG,CAAC,WAAW,CAAC,UAAU;KAC1B,CAAC,CACF,CAAC;IACF,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,OAAO,cAAc;IACjB,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9B,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;IACzB,UAAU,GAAG,IAAI,cAAc,EAAE,CAAC;IAC3C;;;;;;OAMG;IACM,WAAW,CAAkB;IAC7B,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACtC,kBAAkB,CAAU;IACrC;;;;OAIG;IACK,SAAS,GAAqB,IAAI,CAAC;IAC3C;kFAC8E;IACrE,MAAM,CAAuB;IACrB,uBAAuB,CAAS;IACjD;;;;;OAKG;IACc,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAExD,YAAY,MAAuB,OAAO,CAAC,GAAG;QAC7C,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;QAC1D,IAAI,CAAC,WAAW,GAAG,IAAI,eAAe,CAAC;YACtC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ;YAC1C,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ;YAC1C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU;SAC9C,CAAC,CAAC;QACH,IAAI,CAAC,uBAAuB,GAAG,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7E,CAAC;IAED;;;;OAIG;IACH,oBAAoB;QACnB,OAAO,IAAI,CAAC,uBAAuB,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,EAAoB;QAChC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,YAAY;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED,yEAAyE;IACzE,2EAA2E;IAC3E,sEAAsE;IACtE,sEAAsE;IACtE,mEAAmE;IAEnE,4EAA4E;IAC5E,YAAY,CAAC,MAAc,EAAE,KAAa,EAAE,MAAc;QACzD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,gFAAgF;IAChF,QAAQ,CAAC,MAAc,EAAE,KAAa,EAAE,SAAiB;QACxD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC;IAED,6EAA6E;IAC7E,aAAa,CAAC,QAAgB,EAAE,KAAiB;QAChD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,qEAAqE;IACrE,gBAAgB,CAAC,QAAgB;QAChC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,sEAAsE;IACtE,iBAAiB,CAAC,KAAgB;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,yEAAyE;IAEzE;;;;;;OAMG;IACH,cAAc,CAAC,KAMd;QACA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;YAAE,OAAO;QAC7D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC;YAC7C,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,GAAG,EAAE,CACZ,eAAe,CAAC;gBACf,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU,EAAE,IAAI,CAAC,UAAU;aAC3B,CAAC;YACH,MAAM,EAAE,KAAK,CAAC,MAAM;SACpB,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,oBAAoB,CAAC,KAGpB;QACA,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YACjC,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,oBAAoB;YAClD,GAAG,EAAE,KAAK,CAAC,GAAG;SACd,CAAC,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,kBAAkB;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;IACjC,CAAC;IAED,8EAA8E;IAC9E,sBAAsB;QACrB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;IAChC,CAAC;IAED,wDAAwD;IACxD,gBAAgB;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,MAAc,EAAE,GAA0B;QAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,OAAO,EAAE,CAAC;YACb,OAAO;gBACN,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,MAAM;gBACZ,YAAY,EAAE,cAAc;gBAC5B,QAAQ,EAAE,SAAS;aACnB,CAAC;QACH,CAAC;QACD,gEAAgE;QAChE,+DAA+D;QAC/D,2DAA2D;QAC3D,MAAM,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,uBAAuB,CAAC;QAChF,MAAM,IAAI,GAAG,cAAc,CAAC;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,MAAM;YACN,kBAAkB,EAAE,GAAG,CAAC,kBAAkB;YAC1C,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,kBAAkB,EAAE,GAAG,CAAC,kBAAkB;YAC1C,iBAAiB;YACjB,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;QACH,OAAO,IAAI,IAAI,IAAI,CAAC;IACrB,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,uBAAuB,CACtB,MAAc,EACd,GAA0B,EAC1B,aAAwC;QAKxC,IAAI,aAAa,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;YACpD,IAAI,QAAQ;gBAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;QAC1D,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,GAAG;YAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AA4BD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAEzD,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE;YACxD,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC;YACP,OAAO;gBACN,KAAK,EAAE,CAAC,CAAC,MAAM;gBACf,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,aAAa;gBAC3B,WAAW,EAAE,CAAC,CAAC,KAAK;aACpB,CAAC;QACH,CAAC;IACF,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE;QAC3D,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;KAChC,CAAC,CAAC;IACH,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,IAAI,EAAE,CAAC,KAAK,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,EAAE,CAAC,KAAK,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAE3D,OAAO;QACN,KAAK,EAAE,EAAE,CAAC,KAAK;QACf,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;QACjF,YAAY,EAAE,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC;QACrC,WAAW,EAAE,EAAE,CAAC,KAAK;KACrB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAe;IAC7C,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,iBAAiB;YACrB,OAAO,iBAAiB,CAAC;QAC1B,KAAK,gBAAgB;YACpB,OAAO,gBAAgB,CAAC;QACzB,KAAK,YAAY;YAChB,OAAO,YAAY,CAAC;IACtB,CAAC;AACF,CAAC"}
|
package/dist/fuzzy-matcher.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { PathIndex } from "./path-index.js";
|
|
2
2
|
export interface FindFuzzyOptions {
|
|
3
3
|
recentPaths?: Set<string> | null;
|
|
4
|
+
/**
|
|
5
|
+
* PRD §M4 — bounded persistent-path boost. Caller wires
|
|
6
|
+
* `(path) => profileStore.profilePathBoost(path)` which returns
|
|
7
|
+
* `[0, 0.2]`. Multiplied by 10 to give it integer-scale weight (max
|
|
8
|
+
* +2) that nudges fuzzy tie-breakers without overriding subtree (+5)
|
|
9
|
+
* or short-path (+5) bonuses.
|
|
10
|
+
*/
|
|
11
|
+
profileBoost?: ((path: string) => number) | null;
|
|
4
12
|
}
|
|
5
13
|
export type FuzzyBand = "basename-prefix" | "fuzzy-basename" | "fuzzy-path";
|
|
6
14
|
export interface FuzzyToken {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fuzzy-matcher.d.ts","sourceRoot":"","sources":["../src/fuzzy-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,gBAAgB;IAChC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"fuzzy-matcher.d.ts","sourceRoot":"","sources":["../src/fuzzy-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,gBAAgB;IAChC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACjC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,CAAC;CACjD;AAsBD,MAAM,MAAM,SAAS,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,YAAY,CAAC;AAE5E,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAqB9E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAIxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,gBAAqB,GACzB,UAAU,GAAG,IAAI,CAyDnB"}
|
package/dist/fuzzy-matcher.js
CHANGED
|
@@ -80,6 +80,7 @@ export function findFuzzyFilename(index, token, opts = {}) {
|
|
|
80
80
|
const lowerToken = token.toLowerCase();
|
|
81
81
|
const cwdRel = relSubtree(index.root, index.cwd);
|
|
82
82
|
const recent = opts.recentPaths ?? null;
|
|
83
|
+
const profileBoost = opts.profileBoost ?? null;
|
|
83
84
|
let best = null;
|
|
84
85
|
for (const f of index.files) {
|
|
85
86
|
const bn = basename(f);
|
|
@@ -88,9 +89,10 @@ export function findFuzzyFilename(index, token, opts = {}) {
|
|
|
88
89
|
const subBoost = inSub ? 5 : 0;
|
|
89
90
|
const shortBoost = Math.max(0, 5 - Math.floor(f.length / 30));
|
|
90
91
|
const recentBoostV = recentBoost(f, recent);
|
|
92
|
+
const pb = profileBoost ? profileBoost(f) * 10 : 0;
|
|
91
93
|
let candidate = null;
|
|
92
94
|
if (lowerBn.startsWith(lowerToken)) {
|
|
93
|
-
const score = 85 + subBoost + shortBoost + recentBoostV;
|
|
95
|
+
const score = 85 + subBoost + shortBoost + recentBoostV + pb;
|
|
94
96
|
const suffix = bn.slice(token.length);
|
|
95
97
|
if (suffix) {
|
|
96
98
|
candidate = {
|
|
@@ -105,7 +107,7 @@ export function findFuzzyFilename(index, token, opts = {}) {
|
|
|
105
107
|
}
|
|
106
108
|
else if (isSubsequence(lowerToken, lowerBn)) {
|
|
107
109
|
const ratio = token.length / bn.length;
|
|
108
|
-
const score = 60 + Math.floor(ratio * 20) + subBoost + shortBoost + recentBoostV;
|
|
110
|
+
const score = 60 + Math.floor(ratio * 20) + subBoost + shortBoost + recentBoostV + pb;
|
|
109
111
|
candidate = {
|
|
110
112
|
match: f,
|
|
111
113
|
score,
|
|
@@ -117,7 +119,7 @@ export function findFuzzyFilename(index, token, opts = {}) {
|
|
|
117
119
|
}
|
|
118
120
|
else if (isSubsequence(lowerToken, f.toLowerCase())) {
|
|
119
121
|
const ratio = token.length / f.length;
|
|
120
|
-
const score = 45 + Math.floor(ratio * 25) + subBoost + shortBoost + recentBoostV;
|
|
122
|
+
const score = 45 + Math.floor(ratio * 25) + subBoost + shortBoost + recentBoostV + pb;
|
|
121
123
|
candidate = {
|
|
122
124
|
match: f,
|
|
123
125
|
score,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fuzzy-matcher.js","sourceRoot":"","sources":["../src/fuzzy-matcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"fuzzy-matcher.js","sourceRoot":"","sources":["../src/fuzzy-matcher.ts"],"names":[],"mappings":"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"}
|