@sayknow-cli/tui 0.5.6 → 0.5.8

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/CHANGELOG.md CHANGED
@@ -2,7 +2,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [0.5.6] - 2026-08-28
5
+ ## [0.5.8] - 2026-09-10
6
+
7
+ ## [0.5.7] - 2026-09-10
8
+
9
+ ### Added
10
+
11
+ - `@` file search accepts Hangul chosung (초성): a bare consonant matches any syllable carrying it as its initial, so `@ㅎㄱ` finds `한글.txt`. Literal and full-syllable matches keep ranking above chosung matches, and a chosung query never matches a name with no Hangul in it.
12
+
13
+ ### Fixed
14
+
15
+ - `@` file search and path autocomplete now match canonically decomposed (NFD) file names against composed (NFC) input. macOS reports Korean directory entries as conjoining jamo while composer keystrokes are precomposed, so `@한` found nothing even though `한글.txt` existed. Both the directory-listing prefix match and the native fuzzy matcher now compare composed forms while completion values keep the on-disk name.
16
+ - `@` fuzzy discovery no longer re-filters native matches through a plain ASCII subsequence check. The native matcher already returns only scored entries and is the authority on what matched, so the second pass could only discard valid Hangul results; it now filters by path (`.git` exclusion) alone.
6
17
 
7
18
  ## [0.7.8] - 2026-06-30
8
19
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sayknow-cli/tui",
4
- "version": "0.5.6",
4
+ "version": "0.5.8",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://sayknow-cli.com",
7
7
  "author": "jaybeyond",
@@ -38,8 +38,8 @@
38
38
  "fmt": "biome format --write ."
39
39
  },
40
40
  "dependencies": {
41
- "@sayknow-cli/natives": "0.5.6",
42
- "@sayknow-cli/utils": "0.5.6",
41
+ "@sayknow-cli/natives": "0.5.8",
42
+ "@sayknow-cli/utils": "0.5.8",
43
43
  "lru-cache": "11.3.6",
44
44
  "marked": "^18.0.3"
45
45
  },
@@ -743,8 +743,13 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
743
743
  const entries = await this.#getCachedDirEntries(searchDir);
744
744
  const suggestions: AutocompleteItem[] = [];
745
745
 
746
+ // Compare in NFC: macOS returns Korean directory entries as decomposed
747
+ // jamo while composer input is precomposed, so the same visible name
748
+ // would otherwise never prefix-match. Completion values keep the
749
+ // on-disk name.
750
+ const lowerSearchPrefix = searchPrefix.normalize("NFC").toLowerCase();
746
751
  for (const entry of entries) {
747
- if (!entry.name.toLowerCase().startsWith(searchPrefix.toLowerCase())) {
752
+ if (!entry.name.normalize("NFC").toLowerCase().startsWith(lowerSearchPrefix)) {
748
753
  continue;
749
754
  }
750
755
  // Skip .git directory
@@ -835,14 +840,14 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
835
840
  const searchPath = scopedQuery?.baseDir ?? this.#basePath;
836
841
  const fuzzyQuery = scopedQuery?.query ?? query;
837
842
  const result = await fuzzyFind(buildAutocompleteFuzzyDiscoveryProfile(fuzzyQuery, searchPath));
838
- const lowerQuery = fuzzyQuery.toLowerCase();
843
+ // The native matcher is the authority for what matched: it returns only
844
+ // scored entries and understands Hangul composition and chosung queries.
845
+ // Re-running the plain ASCII subsequence check here can only discard
846
+ // valid matches, so this pass filters by path alone.
839
847
  const filteredMatches = result.matches.filter(entry => {
840
848
  const p = entry.path.endsWith("/") ? entry.path.slice(0, -1) : entry.path;
841
849
  const normalized = p.replaceAll("\\", "/");
842
- if (/(^|\/)\.git(\/|$)/.test(normalized)) {
843
- return false;
844
- }
845
- return lowerQuery.length === 0 || fuzzyMatch(lowerQuery, normalized.toLowerCase());
850
+ return !/(^|\/)\.git(\/|$)/.test(normalized);
846
851
  });
847
852
  const topEntries = filteredMatches.slice(0, 20);
848
853
  const suggestions: AutocompleteItem[] = [];