@bastiangx/opencode-unmoji 0.1.0 → 0.3.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.
Files changed (76) hide show
  1. package/README.md +24 -5
  2. package/dist/core/emoji-data-generated.d.ts.map +1 -1
  3. package/dist/core/emoji-data-generated.js +7645 -5370
  4. package/dist/core/emoji-data-generated.js.map +1 -1
  5. package/dist/core/emoji-data.d.ts +3 -0
  6. package/dist/core/emoji-data.d.ts.map +1 -1
  7. package/dist/core/emoji-data.js +46 -2
  8. package/dist/core/emoji-data.js.map +1 -1
  9. package/dist/core/processor.d.ts +12 -1
  10. package/dist/core/processor.d.ts.map +1 -1
  11. package/dist/core/processor.js +67 -12
  12. package/dist/core/processor.js.map +1 -1
  13. package/dist/data/emoji-data-gen.d.ts +6 -0
  14. package/dist/data/emoji-data-gen.d.ts.map +1 -0
  15. package/dist/data/emoji-data-gen.js +30638 -0
  16. package/dist/data/emoji-data-gen.js.map +1 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +135 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/plugin.bundled.js +7949 -5445
  22. package/dist/src/core/config.d.ts +22 -0
  23. package/dist/src/core/config.d.ts.map +1 -0
  24. package/dist/src/core/config.js +82 -0
  25. package/dist/src/core/config.js.map +1 -0
  26. package/dist/src/core/emoji-data.d.ts +11 -0
  27. package/dist/src/core/emoji-data.d.ts.map +1 -0
  28. package/dist/src/core/emoji-data.js +105 -0
  29. package/dist/src/core/emoji-data.js.map +1 -0
  30. package/dist/src/core/processor.d.ts +16 -0
  31. package/dist/src/core/processor.d.ts.map +1 -0
  32. package/dist/src/core/processor.js +115 -0
  33. package/dist/src/core/processor.js.map +1 -0
  34. package/dist/src/index.d.ts +4 -0
  35. package/dist/src/index.d.ts.map +1 -0
  36. package/dist/src/index.js +153 -0
  37. package/dist/src/index.js.map +1 -0
  38. package/dist/src/types/config.d.ts +55 -0
  39. package/dist/src/types/config.d.ts.map +1 -0
  40. package/dist/src/types/config.js +36 -0
  41. package/dist/src/types/config.js.map +1 -0
  42. package/dist/src/types/errors.d.ts +59 -0
  43. package/dist/src/types/errors.d.ts.map +1 -0
  44. package/dist/src/types/errors.js +6 -0
  45. package/dist/src/types/errors.js.map +1 -0
  46. package/dist/src/utils/code-detector.d.ts +17 -0
  47. package/dist/src/utils/code-detector.d.ts.map +1 -0
  48. package/dist/src/utils/code-detector.js +288 -0
  49. package/dist/src/utils/code-detector.js.map +1 -0
  50. package/dist/src/utils/grapheme.d.ts +20 -0
  51. package/dist/src/utils/grapheme.d.ts.map +1 -0
  52. package/dist/src/utils/grapheme.js +82 -0
  53. package/dist/src/utils/grapheme.js.map +1 -0
  54. package/dist/streaming/hooks.d.ts +12 -0
  55. package/dist/streaming/hooks.d.ts.map +1 -0
  56. package/dist/streaming/hooks.js +8 -0
  57. package/dist/streaming/hooks.js.map +1 -0
  58. package/dist/streaming/sanitizer.d.ts +66 -0
  59. package/dist/streaming/sanitizer.d.ts.map +1 -0
  60. package/dist/streaming/sanitizer.js +118 -0
  61. package/dist/streaming/sanitizer.js.map +1 -0
  62. package/dist/streaming/state.d.ts +10 -0
  63. package/dist/streaming/state.d.ts.map +1 -0
  64. package/dist/streaming/state.js +33 -0
  65. package/dist/streaming/state.js.map +1 -0
  66. package/dist/types/config.d.ts +21 -0
  67. package/dist/types/config.d.ts.map +1 -1
  68. package/dist/types/config.js +14 -0
  69. package/dist/types/config.js.map +1 -1
  70. package/dist/utils/code-detector.d.ts.map +1 -1
  71. package/dist/utils/code-detector.js +46 -10
  72. package/dist/utils/code-detector.js.map +1 -1
  73. package/dist/utils/grapheme.d.ts.map +1 -1
  74. package/dist/utils/grapheme.js +20 -2
  75. package/dist/utils/grapheme.js.map +1 -1
  76. package/package.json +19 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4BxB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACnD,gBAAgB,EAAE,CAAC;SACjB,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;SACnE,OAAO,CAAC,QAAQ,CAAC;IACnB,iBAAiB,EAAE,CAAC;SAClB,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;SACtC,OAAO,CAAC,UAAU,CAAC;IACrB,kBAAkB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7C,kBAAkB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7C,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACtC,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1C,kBAAkB,EAAE,CAAC;SACnB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;SACnD,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;IAClB,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3C,iBAAiB,EAAE,CAAC;SAClB,IAAI,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;SAC3C,OAAO,CAAC,QAAQ,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC3C,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,OAAO;IACb,gBAAgB,EAAE,QAAQ;IAC1B,iBAAiB,EAAE,UAAU;IAC7B,kBAAkB,EAAE,IAAI;IACxB,kBAAkB,EAAE,IAAI;IACxB,UAAU,EAAE,KAAK;IACjB,eAAe,EAAE,IAAI;IACrB,kBAAkB,EAAE,CAAC,KAAK,CAAC;IAC3B,gBAAgB,EAAE,IAAI;IACtB,iBAAiB,EAAE,QAAQ;CAC3B,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Domain error types for unmoji plugin
3
+ * Following neverthrow Result pattern - errors as discriminated unions
4
+ */
5
+ export type ConfigError = {
6
+ domain: "config";
7
+ code: "FILE_NOT_FOUND";
8
+ path: string;
9
+ } | {
10
+ domain: "config";
11
+ code: "READ_FAILED";
12
+ path: string;
13
+ reason: string;
14
+ } | {
15
+ domain: "config";
16
+ code: "INVALID_JSON";
17
+ path: string;
18
+ raw: string;
19
+ } | {
20
+ domain: "config";
21
+ code: "INVALID_SCHEMA";
22
+ details: string;
23
+ };
24
+ export type EmojiDataError = {
25
+ domain: "emoji-data";
26
+ code: "FETCH_FAILED";
27
+ reason: string;
28
+ } | {
29
+ domain: "emoji-data";
30
+ code: "INVALID_DATA";
31
+ details: string;
32
+ } | {
33
+ domain: "emoji-data";
34
+ code: "EMPTY_DATASET";
35
+ };
36
+ export type ProcessingError = {
37
+ domain: "processing";
38
+ code: "EMOJI_DATA_UNAVAILABLE";
39
+ cause: EmojiDataError;
40
+ } | {
41
+ domain: "processing";
42
+ code: "REPLACEMENT_FAILED";
43
+ emoji: string;
44
+ reason: string;
45
+ };
46
+ export type PluginError = {
47
+ domain: "plugin";
48
+ code: "CONFIG_LOAD_FAILED";
49
+ cause: ConfigError;
50
+ } | {
51
+ domain: "plugin";
52
+ code: "PROCESSING_FAILED";
53
+ cause: ProcessingError;
54
+ } | {
55
+ domain: "plugin";
56
+ code: "INIT_FAILED";
57
+ reason: string;
58
+ };
59
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/types/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,WAAW,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,MAAM,MAAM,cAAc,GACvB;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC;AAEnD,MAAM,MAAM,eAAe,GACxB;IACA,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,wBAAwB,CAAC;IAC/B,KAAK,EAAE,cAAc,CAAC;CACrB,GACD;IACA,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACd,CAAC;AAEL,MAAM,MAAM,WAAW,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACpE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GACvE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Domain error types for unmoji plugin
3
+ * Following neverthrow Result pattern - errors as discriminated unions
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/types/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,17 @@
1
+ export interface TextRange {
2
+ start: number;
3
+ end: number;
4
+ }
5
+ export interface DetectCodeBlockOptions {
6
+ preserveCodeBlocks: boolean;
7
+ preserveInlineCode: boolean;
8
+ }
9
+ export interface DetectQuoteOptions {
10
+ preserveBlockquotes: boolean;
11
+ preserveInlineQuotes: boolean;
12
+ }
13
+ export declare function detectCodeBlocks(text: string, options: DetectCodeBlockOptions): TextRange[];
14
+ export declare function isInPreservedRange(index: number, ranges: TextRange[]): boolean;
15
+ export declare function detectQuotes(text: string, options: DetectQuoteOptions): TextRange[];
16
+ export declare function mergeRanges(rangesGroups: TextRange[][]): TextRange[];
17
+ //# sourceMappingURL=code-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-detector.d.ts","sourceRoot":"","sources":["../../../src/utils/code-detector.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,sBAAsB;IACtC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IAClC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;CAC9B;AAuKD,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC7B,SAAS,EAAE,CAkCb;AAED,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,EAAE,GACjB,OAAO,CAOT;AAED,wBAAgB,YAAY,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,GACzB,SAAS,EAAE,CAmGb;AAED,wBAAgB,WAAW,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,CAuCpE"}
@@ -0,0 +1,288 @@
1
+ function detectFencedCodeBlocks(text) {
2
+ const ranges = [];
3
+ const length = text.length;
4
+ let pos = 0;
5
+ let inBlock = false;
6
+ let blockStart = 0;
7
+ let fenceLen = 0;
8
+ while (pos <= length) {
9
+ const lineBreakIndex = text.indexOf("\n", pos);
10
+ const lineEnd = lineBreakIndex === -1 ? length : lineBreakIndex;
11
+ const lineStart = pos;
12
+ const line = text.slice(lineStart, lineEnd);
13
+ let firstNonWs = 0;
14
+ while (firstNonWs < line.length) {
15
+ const ch = line.charAt(firstNonWs);
16
+ if (ch !== " " && ch !== "\t") {
17
+ break;
18
+ }
19
+ firstNonWs += 1;
20
+ }
21
+ const trimmed = line.slice(firstNonWs);
22
+ if (!inBlock) {
23
+ if (trimmed.startsWith("```")) {
24
+ let btCount = 0;
25
+ while (btCount < trimmed.length && trimmed.charAt(btCount) === "`") {
26
+ btCount += 1;
27
+ }
28
+ if (btCount >= 3) {
29
+ inBlock = true;
30
+ fenceLen = btCount;
31
+ blockStart = lineStart + firstNonWs;
32
+ }
33
+ }
34
+ }
35
+ else {
36
+ if (trimmed.startsWith("`")) {
37
+ let btCount = 0;
38
+ while (btCount < trimmed.length && trimmed.charAt(btCount) === "`") {
39
+ btCount += 1;
40
+ }
41
+ if (btCount >= fenceLen) {
42
+ let onlyTicksAndWs = true;
43
+ for (let i = btCount; i < trimmed.length; i += 1) {
44
+ const ch = trimmed.charAt(i);
45
+ if (ch !== " " && ch !== "\t" && ch !== "`") {
46
+ onlyTicksAndWs = false;
47
+ break;
48
+ }
49
+ }
50
+ if (onlyTicksAndWs) {
51
+ ranges.push({ start: blockStart, end: lineEnd });
52
+ inBlock = false;
53
+ fenceLen = 0;
54
+ }
55
+ }
56
+ }
57
+ }
58
+ if (lineBreakIndex === -1) {
59
+ break;
60
+ }
61
+ pos = lineEnd + 1;
62
+ }
63
+ if (inBlock) {
64
+ // Unterminated fenced block: bound the preserved range so we do
65
+ // not treat the entire remaining buffer as code. This is
66
+ // important when processing streaming chunks where the closing
67
+ // fence may not have arrived yet.
68
+ const MAX_UNCLOSED_BLOCK_LENGTH = 8192;
69
+ const maxEnd = Math.min(length, blockStart + MAX_UNCLOSED_BLOCK_LENGTH);
70
+ let end = maxEnd;
71
+ let scanPos = blockStart;
72
+ let prevLineEnd = blockStart;
73
+ while (scanPos < maxEnd) {
74
+ const lineBreakIndex = text.indexOf("\n", scanPos);
75
+ if (lineBreakIndex === -1 || lineBreakIndex >= maxEnd) {
76
+ break;
77
+ }
78
+ const lineEnd = lineBreakIndex;
79
+ const line = text.slice(scanPos, lineEnd);
80
+ // Stop the block at the first blank line after some content.
81
+ if (line.trim() === "") {
82
+ end = prevLineEnd > blockStart ? prevLineEnd : lineEnd;
83
+ break;
84
+ }
85
+ prevLineEnd = lineEnd;
86
+ scanPos = lineEnd + 1;
87
+ }
88
+ if (end > blockStart) {
89
+ ranges.push({ start: blockStart, end });
90
+ }
91
+ }
92
+ return ranges;
93
+ }
94
+ function detectInlineCodeOutsideBlocks(text, blockRanges) {
95
+ const ranges = [];
96
+ const length = text.length;
97
+ let i = 0;
98
+ while (i < length) {
99
+ const ch = text.charAt(i);
100
+ if (ch === "`" && isInPreservedRange(i, blockRanges)) {
101
+ i += 1;
102
+ continue;
103
+ }
104
+ if (ch === "`") {
105
+ const start = i;
106
+ i += 1;
107
+ while (i < length) {
108
+ const cur = text.charAt(i);
109
+ if (cur === "\n") {
110
+ break;
111
+ }
112
+ if (cur === "\\") {
113
+ if (i + 1 < length && text.charAt(i + 1) === "`") {
114
+ i += 2;
115
+ continue;
116
+ }
117
+ }
118
+ if (cur === "`") {
119
+ const end = i + 1;
120
+ ranges.push({ start, end });
121
+ i = end;
122
+ break;
123
+ }
124
+ i += 1;
125
+ }
126
+ if (i >= length || text.charAt(i) === "\n") {
127
+ i = start + 1;
128
+ }
129
+ continue;
130
+ }
131
+ i += 1;
132
+ }
133
+ return ranges;
134
+ }
135
+ export function detectCodeBlocks(text, options) {
136
+ if (text.length === 0) {
137
+ return [];
138
+ }
139
+ const ranges = [];
140
+ let blockRanges = [];
141
+ // Always detect fenced blocks when we need inline code detection,
142
+ // even if we're not preserving them. This ensures inline code
143
+ // detection knows where fenced blocks are to exclude them.
144
+ if (options.preserveCodeBlocks || options.preserveInlineCode) {
145
+ blockRanges = detectFencedCodeBlocks(text);
146
+ }
147
+ if (options.preserveCodeBlocks) {
148
+ for (const r of blockRanges) {
149
+ ranges.push(r);
150
+ }
151
+ }
152
+ if (options.preserveInlineCode) {
153
+ // Use blockRanges to exclude inline code detection from fenced blocks
154
+ const inlineRanges = detectInlineCodeOutsideBlocks(text, blockRanges);
155
+ for (const r of inlineRanges) {
156
+ ranges.push(r);
157
+ }
158
+ }
159
+ if (ranges.length === 0) {
160
+ return [];
161
+ }
162
+ ranges.sort((a, b) => a.start - b.start);
163
+ return ranges;
164
+ }
165
+ export function isInPreservedRange(index, ranges) {
166
+ for (const range of ranges) {
167
+ if (index >= range.start && index < range.end) {
168
+ return true;
169
+ }
170
+ }
171
+ return false;
172
+ }
173
+ export function detectQuotes(text, options) {
174
+ if (text.length === 0) {
175
+ return [];
176
+ }
177
+ const ranges = [];
178
+ if (options.preserveBlockquotes) {
179
+ let currentPos = 0;
180
+ const length = text.length;
181
+ while (currentPos <= length) {
182
+ const lineBreakIndex = text.indexOf("\n", currentPos);
183
+ const lineEnd = lineBreakIndex === -1 ? length : lineBreakIndex;
184
+ const lineStart = currentPos;
185
+ const line = text.slice(lineStart, lineEnd);
186
+ let firstNonWs = 0;
187
+ while (firstNonWs < line.length) {
188
+ const ch = line.charAt(firstNonWs);
189
+ if (ch !== " " && ch !== "\t") {
190
+ break;
191
+ }
192
+ firstNonWs += 1;
193
+ }
194
+ const trimmed = line.slice(firstNonWs);
195
+ if (trimmed.startsWith(">")) {
196
+ const start = lineStart + firstNonWs;
197
+ const end = lineBreakIndex === -1 ? lineEnd : lineEnd;
198
+ ranges.push({ start, end });
199
+ }
200
+ if (lineBreakIndex === -1) {
201
+ break;
202
+ }
203
+ currentPos = lineEnd + 1;
204
+ }
205
+ }
206
+ if (options.preserveInlineQuotes) {
207
+ const doubleQuoteRegex = /"([^"\\]|\\.)*"/g;
208
+ let doubleMatch = doubleQuoteRegex.exec(text);
209
+ while (doubleMatch !== null) {
210
+ const matchIndex = doubleMatch.index;
211
+ const matchLength = doubleMatch[0].length;
212
+ let inExisting = false;
213
+ for (const range of ranges) {
214
+ if (matchIndex >= range.start && matchIndex < range.end) {
215
+ inExisting = true;
216
+ break;
217
+ }
218
+ }
219
+ if (!inExisting) {
220
+ ranges.push({
221
+ start: matchIndex,
222
+ end: matchIndex + matchLength,
223
+ });
224
+ }
225
+ doubleMatch = doubleQuoteRegex.exec(text);
226
+ }
227
+ const singleQuoteRegex = /'([^'\\]|\\.)*'/g;
228
+ let singleMatch = singleQuoteRegex.exec(text);
229
+ while (singleMatch !== null) {
230
+ const matchIndex = singleMatch.index;
231
+ const matchLength = singleMatch[0].length;
232
+ let inExisting = false;
233
+ for (const range of ranges) {
234
+ if (matchIndex >= range.start && matchIndex < range.end) {
235
+ inExisting = true;
236
+ break;
237
+ }
238
+ }
239
+ if (!inExisting) {
240
+ ranges.push({
241
+ start: matchIndex,
242
+ end: matchIndex + matchLength,
243
+ });
244
+ }
245
+ singleMatch = singleQuoteRegex.exec(text);
246
+ }
247
+ }
248
+ if (ranges.length === 0) {
249
+ return [];
250
+ }
251
+ ranges.sort((a, b) => a.start - b.start);
252
+ return ranges;
253
+ }
254
+ export function mergeRanges(rangesGroups) {
255
+ const flat = [];
256
+ for (const group of rangesGroups) {
257
+ for (const r of group) {
258
+ flat.push(r);
259
+ }
260
+ }
261
+ if (flat.length === 0) {
262
+ return [];
263
+ }
264
+ flat.sort((a, b) => a.start - b.start);
265
+ const merged = [];
266
+ let current = {
267
+ start: flat[0].start,
268
+ end: flat[0].end,
269
+ };
270
+ for (let i = 1; i < flat.length; i += 1) {
271
+ const r = flat[i];
272
+ if (r.start <= current.end) {
273
+ if (r.end > current.end) {
274
+ current = {
275
+ start: current.start,
276
+ end: r.end,
277
+ };
278
+ }
279
+ }
280
+ else {
281
+ merged.push(current);
282
+ current = { start: r.start, end: r.end };
283
+ }
284
+ }
285
+ merged.push(current);
286
+ return merged;
287
+ }
288
+ //# sourceMappingURL=code-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-detector.js","sourceRoot":"","sources":["../../../src/utils/code-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * grapheme.ts - Unicode-aware string segmentation
3
+ *
4
+ * Handles splitting strings into proper Unicode grapheme clusters instead of
5
+ * simple characters or codepoints. Essential for complex emoji detection.
6
+ *
7
+ * Key concepts:
8
+ * - Native Intl.Segmenter usage with fallback to Graphemer library
9
+ * - Support for Zero Width Joiners (ZWJ) and skin tone modifiers
10
+ * - Fast-path emoji detection using Extended_Pictographic regex
11
+ *
12
+ * Main exports:
13
+ * - graphemes: (text: string) => Generator<string>
14
+ * - mightContainEmoji: (text: string) => boolean
15
+ *
16
+ * @see src/core/processor.ts
17
+ */
18
+ export declare function graphemes(text: string): Generator<string>;
19
+ export declare function mightContainEmoji(text: string): boolean;
20
+ //# sourceMappingURL=grapheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grapheme.d.ts","sourceRoot":"","sources":["../../../src/utils/grapheme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAwDH,wBAAiB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAgB1D;AAQD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgBvD"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * grapheme.ts - Unicode-aware string segmentation
3
+ *
4
+ * Handles splitting strings into proper Unicode grapheme clusters instead of
5
+ * simple characters or codepoints. Essential for complex emoji detection.
6
+ *
7
+ * Key concepts:
8
+ * - Native Intl.Segmenter usage with fallback to Graphemer library
9
+ * - Support for Zero Width Joiners (ZWJ) and skin tone modifiers
10
+ * - Fast-path emoji detection using Extended_Pictographic regex
11
+ *
12
+ * Main exports:
13
+ * - graphemes: (text: string) => Generator<string>
14
+ * - mightContainEmoji: (text: string) => boolean
15
+ *
16
+ * @see src/core/processor.ts
17
+ */
18
+ import Graphemer from "graphemer";
19
+ import { EXTRA_STRIPPABLE } from "../core/emoji-data.js";
20
+ let intlSegmenter = null;
21
+ let graphemer = null;
22
+ function hasIntlSegmenter() {
23
+ const globalIntl = Intl;
24
+ return typeof globalIntl.Segmenter === "function";
25
+ }
26
+ function getIntlSegmenter() {
27
+ if (intlSegmenter) {
28
+ return intlSegmenter;
29
+ }
30
+ const globalIntl = Intl;
31
+ intlSegmenter = new globalIntl.Segmenter("en", {
32
+ granularity: "grapheme",
33
+ });
34
+ return intlSegmenter;
35
+ }
36
+ function getGraphemer() {
37
+ if (!graphemer) {
38
+ graphemer = new Graphemer();
39
+ }
40
+ return graphemer;
41
+ }
42
+ function getSegmenter() {
43
+ if (hasIntlSegmenter()) {
44
+ return getIntlSegmenter();
45
+ }
46
+ return getGraphemer();
47
+ }
48
+ export function* graphemes(text) {
49
+ const segmenter = getSegmenter();
50
+ if ("segment" in segmenter) {
51
+ for (const { segment } of segmenter.segment(text)) {
52
+ yield segment;
53
+ }
54
+ return;
55
+ }
56
+ const segments = segmenter.splitGraphemes(text);
57
+ for (const segment of segments) {
58
+ yield segment;
59
+ }
60
+ }
61
+ // Fast path: Extended_Pictographic and Regional Indicators
62
+ const _PICTOGRAPHIC_RI_REGEX = /[\p{Extended_Pictographic}\p{RI}]/u;
63
+ // Keycap emoji pattern: digit/hash/asterisk + optional variation selector + keycap
64
+ const _KEYCAP_REGEX = /[0-9#*]\uFE0F?\u20E3/u;
65
+ export function mightContainEmoji(text) {
66
+ // Fast path: check Extended_Pictographic and Regional Indicators first
67
+ if (_PICTOGRAPHIC_RI_REGEX.test(text)) {
68
+ return true;
69
+ }
70
+ // Slow path: check for keycap sequences (rare in practice)
71
+ if (_KEYCAP_REGEX.test(text)) {
72
+ return true;
73
+ }
74
+ // Check for extra strippables (non-emoji glyphs we want to remove)
75
+ for (const extra of EXTRA_STRIPPABLE) {
76
+ if (text.includes(extra)) {
77
+ return true;
78
+ }
79
+ }
80
+ return false;
81
+ }
82
+ //# sourceMappingURL=grapheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grapheme.js","sourceRoot":"","sources":["../../../src/utils/grapheme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAUzD,IAAI,aAAa,GAAyB,IAAI,CAAC;AAC/C,IAAI,SAAS,GAAqB,IAAI,CAAC;AAEvC,SAAS,gBAAgB;IACxB,MAAM,UAAU,GAAG,IAElB,CAAC;IAEF,OAAO,OAAO,UAAU,CAAC,SAAS,KAAK,UAAU,CAAC;AACnD,CAAC;AAED,SAAS,gBAAgB;IACxB,IAAI,aAAa,EAAE,CAAC;QACnB,OAAO,aAAa,CAAC;IACtB,CAAC;IAED,MAAM,UAAU,GAAG,IAElB,CAAC;IAEF,aAAa,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE;QAC9C,WAAW,EAAE,UAAU;KACvB,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,SAAS,YAAY;IACpB,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,YAAY;IACpB,IAAI,gBAAgB,EAAE,EAAE,CAAC;QACxB,OAAO,gBAAgB,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,YAAY,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,CAAC,CAAC,SAAS,CAAC,IAAY;IACtC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IAEjC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;QAC5B,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,OAAO,CAAC;QACf,CAAC;QAED,OAAO;IACR,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAEhD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,OAAO,CAAC;IACf,CAAC;AACF,CAAC;AAED,2DAA2D;AAC3D,MAAM,sBAAsB,GAAG,oCAAoC,CAAC;AAEpE,mFAAmF;AACnF,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAE9C,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,uEAAuE;IACvE,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,2DAA2D;IAC3D,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,mEAAmE;IACnE,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { UnmojiConfig } from "../types/config.js";
2
+ type TextCompleteInput = {
3
+ sessionID: string;
4
+ messageID: string;
5
+ partID: string;
6
+ };
7
+ type TextCompleteOutput = {
8
+ text: string;
9
+ };
10
+ export declare function onTextComplete(input: TextCompleteInput, output: TextCompleteOutput, config: UnmojiConfig): Promise<void>;
11
+ export {};
12
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/streaming/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,KAAK,iBAAiB,GAAG;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,wBAAgB,cAAc,CAC7B,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -0,0 +1,8 @@
1
+ import { processText } from "../core/processor.js";
2
+ export function onTextComplete(input, output, config) {
3
+ processText(output.text, config).match((sanitized) => {
4
+ output.text = sanitized;
5
+ }, () => { });
6
+ return Promise.resolve();
7
+ }
8
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/streaming/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYnD,MAAM,UAAU,cAAc,CAC7B,KAAwB,EACxB,MAA0B,EAC1B,MAAoB;IAEpB,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CACrC,CAAC,SAAS,EAAE,EAAE;QACb,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC;IACzB,CAAC,EACD,GAAG,EAAE,GAAE,CAAC,CACR,CAAC;IACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,66 @@
1
+ import type { UnmojiConfig } from "../types/config.js";
2
+ import type { StreamingError } from "../types/errors.js";
3
+ import type { StreamingState } from "./state.js";
4
+ import { type ResultAsync } from "neverthrow";
5
+ type MessagePart = {
6
+ id: string;
7
+ sessionID: string;
8
+ messageID: string;
9
+ type: string;
10
+ text?: string;
11
+ role?: string;
12
+ };
13
+ type MessagePartUpdatedEvent = {
14
+ type: "message.part.updated";
15
+ properties: {
16
+ part: MessagePart;
17
+ };
18
+ };
19
+ type SessionIdleEvent = {
20
+ type: "session.idle";
21
+ properties: {
22
+ sessionID: string;
23
+ };
24
+ };
25
+ type OpencodeEvent = MessagePartUpdatedEvent | SessionIdleEvent;
26
+ type OpencodeClient = {
27
+ event: {
28
+ subscribe: () => Promise<{
29
+ stream: AsyncIterable<OpencodeEvent>;
30
+ }>;
31
+ };
32
+ session: {
33
+ updatePart: (args: {
34
+ sessionID: string;
35
+ messageID: string;
36
+ partID: string;
37
+ text: string;
38
+ }) => Promise<void>;
39
+ };
40
+ message: {
41
+ list: (args: {
42
+ sessionID: string;
43
+ }) => Promise<Message[]>;
44
+ };
45
+ };
46
+ type Message = {
47
+ id: string;
48
+ sessionID: string;
49
+ role: string;
50
+ parts: MessagePart[];
51
+ };
52
+ type SanitizeDeps = {
53
+ client: OpencodeClient;
54
+ config: UnmojiConfig;
55
+ };
56
+ type DebounceArgs = {
57
+ deps: SanitizeDeps;
58
+ state: StreamingState;
59
+ part: MessagePart;
60
+ };
61
+ export declare function scheduleDebouncedSanitize(args: DebounceArgs): void;
62
+ export declare function sanitizeAndUpdatePart(args: DebounceArgs): ResultAsync<void, StreamingError>;
63
+ export declare function startStreamingSanitizer(deps: SanitizeDeps, state: StreamingState): ResultAsync<void, StreamingError>;
64
+ export declare function sanitizeLastAssistantMessage(client: OpencodeClient, config: UnmojiConfig, sessionID: string): ResultAsync<void, StreamingError>;
65
+ export {};
66
+ //# sourceMappingURL=sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/streaming/sanitizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,YAAY,CAAC;AAG3E,KAAK,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC9B,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE;QACX,IAAI,EAAE,WAAW,CAAC;KAClB,CAAC;CACF,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACvB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;CACF,CAAC;AAEF,KAAK,aAAa,GAAG,uBAAuB,GAAG,gBAAgB,CAAC;AAEhE,KAAK,cAAc,GAAG;IACrB,KAAK,EAAE;QACN,SAAS,EAAE,MAAM,OAAO,CAAC;YAAE,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;SAAE,CAAC,CAAC;KACnE,CAAC;IACF,OAAO,EAAE;QACR,UAAU,EAAE,CAAC,IAAI,EAAE;YAClB,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC;YAClB,MAAM,EAAE,MAAM,CAAC;YACf,IAAI,EAAE,MAAM,CAAC;SACb,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACpB,CAAC;IACF,OAAO,EAAE;QACR,IAAI,EAAE,CAAC,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;KAC1D,CAAC;CACF,CAAC;AAEF,KAAK,OAAO,GAAG;IACd,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,EAAE,CAAC;CACrB,CAAC;AAEF,KAAK,YAAY,GAAG;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,KAAK,YAAY,GAAG;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,WAAW,CAAC;CAClB,CAAC;AAmBF,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAgBlE;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,YAAY,GAChB,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,CAqCnC;AAED,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,cAAc,GACnB,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,CAyBnC;AAED,wBAAgB,4BAA4B,CAC3C,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,GACf,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,CAgDnC"}