lupacode 1.0.6 → 1.0.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/dist/index.js CHANGED
@@ -62835,7 +62835,7 @@ class MarkdownRenderable extends Renderable {
62835
62835
  fg: this._fg,
62836
62836
  bg: this._bg,
62837
62837
  conceal: this._concealCode,
62838
- drawUnstyledText: !this._streaming,
62838
+ drawUnstyledText: true,
62839
62839
  streaming: this._streaming,
62840
62840
  treeSitterClient: this._treeSitterClient,
62841
62841
  width: "100%",
@@ -62878,7 +62878,7 @@ class MarkdownRenderable extends Renderable {
62878
62878
  renderable.fg = this._fg;
62879
62879
  renderable.bg = this._bg;
62880
62880
  renderable.conceal = this._concealCode;
62881
- renderable.drawUnstyledText = !this._streaming;
62881
+ renderable.drawUnstyledText = true;
62882
62882
  renderable.streaming = this._streaming;
62883
62883
  renderable.content = token.text;
62884
62884
  renderable.marginBottom = marginBottom;
@@ -96422,7 +96422,7 @@ var import_react35 = __toESM(require_react(), 1);
96422
96422
  // package.json
96423
96423
  var package_default2 = {
96424
96424
  name: "lupacode",
96425
- version: "1.0.6",
96425
+ version: "1.0.8",
96426
96426
  description: "AI-powered terminal coding assistant",
96427
96427
  type: "module",
96428
96428
  bin: {
@@ -96436,7 +96436,9 @@ var package_default2 = {
96436
96436
  ],
96437
96437
  scripts: {
96438
96438
  dev: "bun run --watch src/index.tsx",
96439
- build: 'bun build src/index.tsx --outdir dist --target bun --external "@opentui/core-*"',
96439
+ build: "bun run build:bundle && bun run build:copy-worker",
96440
+ "build:bundle": 'bun build src/index.tsx --outdir dist --target bun --external "@opentui/core-*"',
96441
+ "build:copy-worker": "bun run scripts/copy-worker.js",
96440
96442
  prepublishOnly: "bun run build",
96441
96443
  typecheck: "tsc -p tsconfig.json --noEmit"
96442
96444
  },
@@ -98164,7 +98166,7 @@ function InputBar({ onSubmit, disabled = false, sessionId, messages }) {
98164
98166
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(SettingsDialogContent, {}, undefined, false, undefined, this)
98165
98167
  });
98166
98168
  }
98167
- if (key.name === "?" && !key.ctrl) {
98169
+ if (key.name === "?" && !key.ctrl && !textareaRef.current?.plainText) {
98168
98170
  key.preventDefault();
98169
98171
  dialog.open({
98170
98172
  title: "Keyboard Shortcuts",
@@ -98560,43 +98562,43 @@ function prettyMilliseconds(milliseconds, options) {
98560
98562
 
98561
98563
  // src/components/messages/bot-message.tsx
98562
98564
  var globalSyntaxStyle = SyntaxStyle.fromStyles({
98563
- default: { fg: "#D4D4D4" },
98564
- keyword: { fg: "#569CD6" },
98565
- "keyword.control": { fg: "#C586C0" },
98566
- "keyword.import": { fg: "#C586C0" },
98567
- "keyword.function": { fg: "#DCDCAA" },
98568
- string: { fg: "#CE9178" },
98569
- "string.special": { fg: "#CE9178" },
98570
- number: { fg: "#B5CEA8" },
98571
- "number.float": { fg: "#B5CEA8" },
98572
- comment: { fg: "#6A9955", italic: true },
98573
- function: { fg: "#DCDCAA" },
98574
- "function.call": { fg: "#DCDCAA" },
98575
- "function.method": { fg: "#DCDCAA" },
98576
- type: { fg: "#4EC9B0" },
98577
- "type.builtin": { fg: "#4EC9B0" },
98578
- variable: { fg: "#9CDCFE" },
98579
- "variable.parameter": { fg: "#9CDCFE" },
98580
- "variable.builtin": { fg: "#9CDCFE" },
98581
- constant: { fg: "#4FC1FF" },
98582
- "constant.builtin": { fg: "#569CD6" },
98583
- property: { fg: "#9CDCFE" },
98584
- operator: { fg: "#D4D4D4" },
98585
- "punctuation.delimiter": { fg: "#D4D4D4" },
98586
- "punctuation.bracket": { fg: "#D4D4D4" },
98587
- boolean: { fg: "#569CD6" },
98588
- label: { fg: "#DCDCAA" },
98589
- "markup.heading": { fg: "#569CD6", bold: true },
98565
+ default: { fg: "#E4E4E7" },
98566
+ keyword: { fg: "#C792EA" },
98567
+ "keyword.control": { fg: "#C792EA" },
98568
+ "keyword.import": { fg: "#C792EA" },
98569
+ "keyword.function": { fg: "#F59E0B" },
98570
+ string: { fg: "#FBBF24" },
98571
+ "string.special": { fg: "#FBBF24" },
98572
+ number: { fg: "#A78BFA" },
98573
+ "number.float": { fg: "#A78BFA" },
98574
+ comment: { fg: "#78716C", italic: true },
98575
+ function: { fg: "#4ADE80" },
98576
+ "function.call": { fg: "#4ADE80" },
98577
+ "function.method": { fg: "#4ADE80" },
98578
+ type: { fg: "#22D3EE" },
98579
+ "type.builtin": { fg: "#22D3EE" },
98580
+ variable: { fg: "#F5F5F4" },
98581
+ "variable.parameter": { fg: "#FDBA74" },
98582
+ "variable.builtin": { fg: "#F5F5F4" },
98583
+ constant: { fg: "#A78BFA" },
98584
+ "constant.builtin": { fg: "#C792EA" },
98585
+ property: { fg: "#F5F5F4" },
98586
+ operator: { fg: "#F472B6" },
98587
+ "punctuation.delimiter": { fg: "#A1A1AA" },
98588
+ "punctuation.bracket": { fg: "#A1A1AA" },
98589
+ boolean: { fg: "#A78BFA" },
98590
+ label: { fg: "#FDBA74" },
98591
+ "markup.heading": { fg: "#C792EA", bold: true },
98590
98592
  "markup.italic": { italic: true },
98591
- "markup.strong": { fg: "#DCDCAA", bold: true },
98592
- "markup.strikethrough": { fg: "#888888", italic: true, dim: true },
98593
- "markup.raw": { fg: "#CE9178" },
98594
- "markup.link": { fg: "#569CD6", underline: true },
98595
- "markup.link.label": { fg: "#569CD6", underline: true },
98596
- "markup.link.url": { fg: "#4FC1FF" },
98597
- "markup.list": { fg: "#569CD6" },
98598
- "markup.quote": { fg: "#6A9955", italic: true },
98599
- conceal: { fg: "#555555" }
98593
+ "markup.strong": { fg: "#C792EA", bold: true },
98594
+ "markup.strikethrough": { fg: "#78716C", italic: true, dim: true },
98595
+ "markup.raw": { fg: "#FBBF24" },
98596
+ "markup.link": { fg: "#22D3EE", underline: true },
98597
+ "markup.link.label": { fg: "#22D3EE", underline: true },
98598
+ "markup.link.url": { fg: "#A78BFA" },
98599
+ "markup.list": { fg: "#F472B6" },
98600
+ "markup.quote": { fg: "#FBBF24", italic: true },
98601
+ conceal: { fg: "#3F3F46" }
98600
98602
  });
98601
98603
  function formatToolName(name23) {
98602
98604
  return name23.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
@@ -98615,6 +98617,29 @@ function isBashTool(tc) {
98615
98617
  const name23 = tc.type === "dynamic-tool" ? tc.toolName : tc.type.slice("tool-".length);
98616
98618
  return name23 === "bash";
98617
98619
  }
98620
+ function isEditFileTool(tc) {
98621
+ const name23 = tc.type === "dynamic-tool" ? tc.toolName : tc.type.slice("tool-".length);
98622
+ return name23 === "editFile";
98623
+ }
98624
+ function isWriteFileTool(tc) {
98625
+ const name23 = tc.type === "dynamic-tool" ? tc.toolName : tc.type.slice("tool-".length);
98626
+ return name23 === "writeFile";
98627
+ }
98628
+ function buildDiff(oldStr, newStr) {
98629
+ const oldLines = oldStr.split(`
98630
+ `);
98631
+ const newLines = newStr.split(`
98632
+ `);
98633
+ const lines = [];
98634
+ for (const line of oldLines) {
98635
+ lines.push(`- ${line}`);
98636
+ }
98637
+ for (const line of newLines) {
98638
+ lines.push(`+ ${line}`);
98639
+ }
98640
+ return lines.join(`
98641
+ `);
98642
+ }
98618
98643
  function isToolRunning(tc) {
98619
98644
  return tc.state !== "output-available" && tc.state !== "output-error";
98620
98645
  }
@@ -98636,7 +98661,6 @@ function renderToolCall(tc, colors, j2, renderKey) {
98636
98661
  }, undefined, false, undefined, this),
98637
98662
  " ",
98638
98663
  command,
98639
- running ? "" : "",
98640
98664
  tc.state === "output-error" ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
98641
98665
  fg: colors.error,
98642
98666
  children: [
@@ -98650,6 +98674,88 @@ function renderToolCall(tc, colors, j2, renderKey) {
98650
98674
  }, undefined, true, undefined, this)
98651
98675
  }, renderKey, false, undefined, this);
98652
98676
  }
98677
+ if (isEditFileTool(tc)) {
98678
+ const input = tc.input;
98679
+ const path5 = input?.path ?? "";
98680
+ const oldString = input?.oldString ?? "";
98681
+ const newString = input?.newString ?? "";
98682
+ const diff = buildDiff(oldString, newString);
98683
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
98684
+ width: "100%",
98685
+ flexDirection: "column",
98686
+ children: [
98687
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
98688
+ attributes: TextAttributes.DIM,
98689
+ children: [
98690
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
98691
+ fg: colors.info,
98692
+ children: "Edit:"
98693
+ }, undefined, false, undefined, this),
98694
+ " ",
98695
+ path5,
98696
+ running ? "..." : done ? " \u2713" : "",
98697
+ tc.state === "output-error" ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
98698
+ fg: colors.error,
98699
+ children: [
98700
+ " ",
98701
+ "\u2716",
98702
+ " ",
98703
+ tc.errorText
98704
+ ]
98705
+ }, undefined, true, undefined, this) : null
98706
+ ]
98707
+ }, undefined, true, undefined, this),
98708
+ done && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
98709
+ paddingX: 2,
98710
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("markdown", {
98711
+ content: "```diff\n" + diff + "\n```",
98712
+ syntaxStyle: globalSyntaxStyle,
98713
+ concealCode: true
98714
+ }, undefined, false, undefined, this)
98715
+ }, undefined, false, undefined, this)
98716
+ ]
98717
+ }, renderKey, true, undefined, this);
98718
+ }
98719
+ if (isWriteFileTool(tc)) {
98720
+ const input = tc.input;
98721
+ const path5 = input?.path ?? "";
98722
+ const content = input?.content ?? "";
98723
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
98724
+ width: "100%",
98725
+ flexDirection: "column",
98726
+ children: [
98727
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
98728
+ attributes: TextAttributes.DIM,
98729
+ children: [
98730
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
98731
+ fg: colors.info,
98732
+ children: "Write:"
98733
+ }, undefined, false, undefined, this),
98734
+ " ",
98735
+ path5,
98736
+ running ? "..." : done ? " \u2713" : "",
98737
+ tc.state === "output-error" ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
98738
+ fg: colors.error,
98739
+ children: [
98740
+ " ",
98741
+ "\u2716",
98742
+ " ",
98743
+ tc.errorText
98744
+ ]
98745
+ }, undefined, true, undefined, this) : null
98746
+ ]
98747
+ }, undefined, true, undefined, this),
98748
+ done && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
98749
+ paddingX: 2,
98750
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("markdown", {
98751
+ content: "```\n" + content + "\n```",
98752
+ syntaxStyle: globalSyntaxStyle,
98753
+ concealCode: true
98754
+ }, undefined, false, undefined, this)
98755
+ }, undefined, false, undefined, this)
98756
+ ]
98757
+ }, renderKey, true, undefined, this);
98758
+ }
98653
98759
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
98654
98760
  width: "100%",
98655
98761
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
@@ -98799,6 +98905,7 @@ function BotMessage({
98799
98905
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("markdown", {
98800
98906
  content: part.text,
98801
98907
  syntaxStyle: globalSyntaxStyle,
98908
+ concealCode: true,
98802
98909
  streaming,
98803
98910
  tableOptions: {
98804
98911
  style: "grid",
@@ -106492,7 +106599,7 @@ function App() {
106492
106599
  }, undefined, false, undefined, this);
106493
106600
  }
106494
106601
  setCurrentVersion(package_default2.version);
106495
- checkForUpdate(package_default2.version);
106602
+ await checkForUpdate(package_default2.version);
106496
106603
  var renderer = await createCliRenderer({
106497
106604
  targetFps: 60,
106498
106605
  exitOnCtrlC: false
@@ -0,0 +1,1025 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // src/lib/tree-sitter/parser.worker.ts
5
+ import { Parser, Query, Language } from "web-tree-sitter";
6
+ import { mkdir as mkdir3 } from "fs/promises";
7
+ import * as path2 from "path";
8
+
9
+ // src/lib/tree-sitter/download-utils.ts
10
+ import { mkdir, readFile, writeFile } from "fs/promises";
11
+ import * as path from "path";
12
+
13
+ class DownloadUtils {
14
+ static hashUrl(url) {
15
+ let hash = 0;
16
+ for (let i = 0;i < url.length; i++) {
17
+ const char = url.charCodeAt(i);
18
+ hash = (hash << 5) - hash + char;
19
+ hash = hash & hash;
20
+ }
21
+ return Math.abs(hash).toString(16);
22
+ }
23
+ static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) {
24
+ const isUrl = source.startsWith("http://") || source.startsWith("https://");
25
+ if (isUrl) {
26
+ let cacheFileName;
27
+ if (useHashForCache) {
28
+ const hash = this.hashUrl(source);
29
+ cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`;
30
+ } else {
31
+ cacheFileName = path.basename(source);
32
+ }
33
+ const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName);
34
+ await mkdir(path.dirname(cacheFile), { recursive: true });
35
+ try {
36
+ const cachedContent = await readFile(cacheFile);
37
+ if (cachedContent.byteLength > 0) {
38
+ console.log(`Loaded from cache: ${cacheFile} (${source})`);
39
+ return { content: cachedContent, filePath: cacheFile };
40
+ }
41
+ } catch (error) {}
42
+ try {
43
+ console.log(`Downloading from URL: ${source}`);
44
+ const response = await fetch(source);
45
+ if (!response.ok) {
46
+ return { error: `Failed to fetch from ${source}: ${response.statusText}` };
47
+ }
48
+ const content = Buffer.from(await response.arrayBuffer());
49
+ try {
50
+ await writeFile(cacheFile, Buffer.from(content));
51
+ console.log(`Cached: ${source}`);
52
+ } catch (cacheError) {
53
+ console.warn(`Failed to cache: ${cacheError}`);
54
+ }
55
+ return { content, filePath: cacheFile };
56
+ } catch (error) {
57
+ return { error: `Error downloading from ${source}: ${error}` };
58
+ }
59
+ } else {
60
+ try {
61
+ console.log(`Loading from local path: ${source}`);
62
+ const content = await readFile(source);
63
+ return { content, filePath: source };
64
+ } catch (error) {
65
+ return { error: `Error loading from local path ${source}: ${error}` };
66
+ }
67
+ }
68
+ }
69
+ static async downloadToPath(source, targetPath) {
70
+ const isUrl = source.startsWith("http://") || source.startsWith("https://");
71
+ await mkdir(path.dirname(targetPath), { recursive: true });
72
+ if (isUrl) {
73
+ try {
74
+ console.log(`Downloading from URL: ${source}`);
75
+ const response = await fetch(source);
76
+ if (!response.ok) {
77
+ return { error: `Failed to fetch from ${source}: ${response.statusText}` };
78
+ }
79
+ const content = Buffer.from(await response.arrayBuffer());
80
+ await writeFile(targetPath, Buffer.from(content));
81
+ console.log(`Downloaded: ${source} -> ${targetPath}`);
82
+ return { content, filePath: targetPath };
83
+ } catch (error) {
84
+ return { error: `Error downloading from ${source}: ${error}` };
85
+ }
86
+ } else {
87
+ try {
88
+ console.log(`Copying from local path: ${source}`);
89
+ const content = await readFile(source);
90
+ await writeFile(targetPath, Buffer.from(content));
91
+ return { content, filePath: targetPath };
92
+ } catch (error) {
93
+ return { error: `Error copying from local path ${source}: ${error}` };
94
+ }
95
+ }
96
+ }
97
+ static async fetchHighlightQueries(sources, cacheDir, filetype) {
98
+ const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype));
99
+ const queryResults = await Promise.all(queryPromises);
100
+ const validQueries = queryResults.filter((query) => query.trim().length > 0);
101
+ return validQueries.join(`
102
+ `);
103
+ }
104
+ static async fetchHighlightQuery(source, cacheDir, filetype) {
105
+ const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype);
106
+ if (result.error) {
107
+ console.error(`Error fetching highlight query from ${source}:`, result.error);
108
+ return "";
109
+ }
110
+ if (result.content) {
111
+ return new TextDecoder().decode(result.content);
112
+ }
113
+ return "";
114
+ }
115
+ }
116
+
117
+ // src/lib/tree-sitter/parser.worker.ts
118
+ import { isMainThread } from "worker_threads";
119
+
120
+ // src/lib/bunfs.ts
121
+ import { basename as basename2, join as join2 } from "path";
122
+ function isBunfsPath(path2) {
123
+ return path2.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path2);
124
+ }
125
+ function getBunfsRootPath() {
126
+ return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
127
+ }
128
+ function normalizeBunfsPath(fileName) {
129
+ return join2(getBunfsRootPath(), basename2(fileName));
130
+ }
131
+
132
+ // src/platform/runtime.ts
133
+ import { mkdir as mkdir2, writeFile as writeFileNode } from "fs/promises";
134
+ import { dirname as dirname2, isAbsolute, resolve } from "path";
135
+ import { fileURLToPath } from "url";
136
+
137
+ // ../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
138
+ function ansiRegex({ onlyFirst = false } = {}) {
139
+ const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
140
+ const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
141
+ const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
142
+ const pattern = `${osc}|${csi}`;
143
+ return new RegExp(pattern, onlyFirst ? undefined : "g");
144
+ }
145
+
146
+ // ../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js
147
+ var regex = ansiRegex();
148
+ function stripAnsi(string) {
149
+ if (typeof string !== "string") {
150
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
151
+ }
152
+ return string.replace(regex, "");
153
+ }
154
+
155
+ // ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js
156
+ function isAmbiguous(x) {
157
+ return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
158
+ }
159
+ function isFullWidth(x) {
160
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
161
+ }
162
+ function isWide(x) {
163
+ return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
164
+ }
165
+
166
+ // ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js
167
+ function validate(codePoint) {
168
+ if (!Number.isSafeInteger(codePoint)) {
169
+ throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
170
+ }
171
+ }
172
+ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
173
+ validate(codePoint);
174
+ if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
175
+ return 2;
176
+ }
177
+ return 1;
178
+ }
179
+
180
+ // ../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.mjs
181
+ var emoji_regex_default = () => {
182
+ return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
183
+ };
184
+
185
+ // ../../node_modules/.bun/string-width@7.2.0/node_modules/string-width/index.js
186
+ var segmenter = new Intl.Segmenter;
187
+ var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
188
+ function stringWidth(string, options = {}) {
189
+ if (typeof string !== "string" || string.length === 0) {
190
+ return 0;
191
+ }
192
+ const {
193
+ ambiguousIsNarrow = true,
194
+ countAnsiEscapeCodes = false
195
+ } = options;
196
+ if (!countAnsiEscapeCodes) {
197
+ string = stripAnsi(string);
198
+ }
199
+ if (string.length === 0) {
200
+ return 0;
201
+ }
202
+ let width = 0;
203
+ const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
204
+ for (const { segment: character } of segmenter.segment(string)) {
205
+ const codePoint = character.codePointAt(0);
206
+ if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
207
+ continue;
208
+ }
209
+ if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
210
+ continue;
211
+ }
212
+ if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
213
+ continue;
214
+ }
215
+ if (codePoint >= 55296 && codePoint <= 57343) {
216
+ continue;
217
+ }
218
+ if (codePoint >= 65024 && codePoint <= 65039) {
219
+ continue;
220
+ }
221
+ if (defaultIgnorableCodePointRegex.test(character)) {
222
+ continue;
223
+ }
224
+ if (emoji_regex_default().test(character)) {
225
+ width += 2;
226
+ continue;
227
+ }
228
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
229
+ }
230
+ return width;
231
+ }
232
+
233
+ // src/platform/runtime.ts
234
+ var TEXT_ENCODER = new TextEncoder;
235
+ var bun = globalThis.Bun;
236
+ var sleep = bun?.sleep ?? standardSleep;
237
+ var stringWidth2 = bun?.stringWidth ?? stringWidth;
238
+ var stripANSI = bun?.stripANSI ?? stripAnsi;
239
+ var writeFile2 = bun?.write ?? writeFilePortable;
240
+ async function resolveBundledFilePath(loadBundledFile, fallbackPath, metaUrl) {
241
+ if (!bun) {
242
+ const path2 = typeof fallbackPath === "function" ? fallbackPath() : fallbackPath;
243
+ return fileURLToPath(path2 instanceof URL ? path2 : new URL(path2, metaUrl));
244
+ }
245
+ const loadedPath = (await loadBundledFile()).default;
246
+ if (loadedPath.startsWith("file:")) {
247
+ return fileURLToPath(loadedPath);
248
+ }
249
+ if (isAbsolute(loadedPath)) {
250
+ return loadedPath;
251
+ }
252
+ return resolve(dirname2(fileURLToPath(metaUrl)), loadedPath);
253
+ }
254
+ function standardSleep(msOrDate) {
255
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() - Date.now() : msOrDate;
256
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
257
+ }
258
+ async function writeFilePortable(destination, data, options) {
259
+ const destinationPath = destination instanceof URL ? fileURLToPath(destination) : destination;
260
+ if (options?.createPath) {
261
+ await mkdir2(dirname2(destinationPath), { recursive: true });
262
+ }
263
+ const bytes = typeof data === "string" ? TEXT_ENCODER.encode(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
264
+ await writeFileNode(destinationPath, bytes, { mode: options?.mode });
265
+ return bytes.byteLength;
266
+ }
267
+
268
+ // src/lib/tree-sitter/parser.worker.ts
269
+ var self = globalThis;
270
+
271
+ class ParserWorker {
272
+ bufferParsers = new Map;
273
+ filetypeParserOptions = new Map;
274
+ filetypeAliases = new Map;
275
+ filetypeParsers = new Map;
276
+ filetypeParserPromises = new Map;
277
+ reusableParsers = new Map;
278
+ reusableParserPromises = new Map;
279
+ initializePromise;
280
+ performance;
281
+ dataPath;
282
+ tsDataPath;
283
+ initialized = false;
284
+ constructor() {
285
+ this.performance = {
286
+ averageParseTime: 0,
287
+ parseTimes: [],
288
+ averageQueryTime: 0,
289
+ queryTimes: []
290
+ };
291
+ }
292
+ async fetchQueries(sources, filetype) {
293
+ if (!this.tsDataPath) {
294
+ return "";
295
+ }
296
+ return DownloadUtils.fetchHighlightQueries(sources, this.tsDataPath, filetype);
297
+ }
298
+ async initialize({ dataPath }) {
299
+ if (this.initializePromise) {
300
+ return this.initializePromise;
301
+ }
302
+ this.initializePromise = (async () => {
303
+ this.dataPath = dataPath;
304
+ this.tsDataPath = path2.join(dataPath, "tree-sitter");
305
+ await mkdir3(path2.join(this.tsDataPath, "languages"), { recursive: true });
306
+ await mkdir3(path2.join(this.tsDataPath, "queries"), { recursive: true });
307
+ let treeWasm = await resolveBundledFilePath(() => import("web-tree-sitter/tree-sitter.wasm", { with: { type: "wasm" } }), () => import.meta.resolve("web-tree-sitter/tree-sitter.wasm"), import.meta.url);
308
+ if (isBunfsPath(treeWasm)) {
309
+ treeWasm = normalizeBunfsPath(path2.parse(treeWasm).base);
310
+ }
311
+ await Parser.init({
312
+ locateFile() {
313
+ return treeWasm;
314
+ }
315
+ });
316
+ this.initialized = true;
317
+ })();
318
+ return this.initializePromise;
319
+ }
320
+ addFiletypeParser(filetypeParser) {
321
+ const previousAliases = this.filetypeParserOptions.get(filetypeParser.filetype)?.aliases ?? [];
322
+ for (const alias of previousAliases) {
323
+ if (this.filetypeAliases.get(alias) === filetypeParser.filetype) {
324
+ this.filetypeAliases.delete(alias);
325
+ }
326
+ }
327
+ const aliases = [...new Set((filetypeParser.aliases ?? []).filter((alias) => alias !== filetypeParser.filetype))];
328
+ this.filetypeAliases.delete(filetypeParser.filetype);
329
+ this.filetypeParserOptions.set(filetypeParser.filetype, {
330
+ ...filetypeParser,
331
+ aliases
332
+ });
333
+ for (const alias of aliases) {
334
+ this.filetypeAliases.set(alias, filetypeParser.filetype);
335
+ }
336
+ this.invalidateParserCaches(filetypeParser.filetype);
337
+ }
338
+ resolveCanonicalFiletype(filetype) {
339
+ if (this.filetypeParserOptions.has(filetype)) {
340
+ return filetype;
341
+ }
342
+ return this.filetypeAliases.get(filetype) ?? filetype;
343
+ }
344
+ invalidateParserCaches(filetype) {
345
+ this.filetypeParsers.delete(filetype);
346
+ this.filetypeParserPromises.delete(filetype);
347
+ const reusableParser = this.reusableParsers.get(filetype);
348
+ if (reusableParser) {
349
+ reusableParser.parser.delete();
350
+ this.reusableParsers.delete(filetype);
351
+ }
352
+ this.reusableParserPromises.delete(filetype);
353
+ }
354
+ async createQueries(filetypeParser, language) {
355
+ try {
356
+ const highlightQueryContent = await this.fetchQueries(filetypeParser.queries.highlights, filetypeParser.filetype);
357
+ if (!highlightQueryContent) {
358
+ console.error("Failed to fetch highlight queries for:", filetypeParser.filetype);
359
+ return;
360
+ }
361
+ const highlightsQuery = new Query(language, highlightQueryContent);
362
+ const result = {
363
+ highlights: highlightsQuery
364
+ };
365
+ if (filetypeParser.queries.injections && filetypeParser.queries.injections.length > 0) {
366
+ const injectionQueryContent = await this.fetchQueries(filetypeParser.queries.injections, filetypeParser.filetype);
367
+ if (injectionQueryContent) {
368
+ result.injections = new Query(language, injectionQueryContent);
369
+ }
370
+ }
371
+ return result;
372
+ } catch (error) {
373
+ console.error("Error creating queries for", filetypeParser.filetype, filetypeParser.queries);
374
+ console.error(error);
375
+ return;
376
+ }
377
+ }
378
+ async loadLanguage(languageSource) {
379
+ if (!this.initialized || !this.tsDataPath) {
380
+ return;
381
+ }
382
+ const result = await DownloadUtils.downloadOrLoad(languageSource, this.tsDataPath, "languages", ".wasm", false);
383
+ if (result.error) {
384
+ console.error(`Error loading language ${languageSource}:`, result.error);
385
+ return;
386
+ }
387
+ if (!result.filePath) {
388
+ return;
389
+ }
390
+ const normalizedPath = result.filePath.replaceAll("\\", "/");
391
+ try {
392
+ const language = await Language.load(normalizedPath);
393
+ return language;
394
+ } catch (error) {
395
+ console.error(`Error loading language from ${normalizedPath}:`, error);
396
+ return;
397
+ }
398
+ }
399
+ async resolveFiletypeParser(filetype) {
400
+ const canonicalFiletype = this.resolveCanonicalFiletype(filetype);
401
+ if (this.filetypeParsers.has(canonicalFiletype)) {
402
+ return this.filetypeParsers.get(canonicalFiletype);
403
+ }
404
+ if (this.filetypeParserPromises.has(canonicalFiletype)) {
405
+ return this.filetypeParserPromises.get(canonicalFiletype);
406
+ }
407
+ const loadingPromise = this.loadFiletypeParser(canonicalFiletype);
408
+ this.filetypeParserPromises.set(canonicalFiletype, loadingPromise);
409
+ try {
410
+ const result = await loadingPromise;
411
+ if (result) {
412
+ this.filetypeParsers.set(canonicalFiletype, result);
413
+ }
414
+ return result;
415
+ } finally {
416
+ this.filetypeParserPromises.delete(canonicalFiletype);
417
+ }
418
+ }
419
+ async loadFiletypeParser(filetype) {
420
+ const filetypeParserOptions = this.filetypeParserOptions.get(filetype);
421
+ if (!filetypeParserOptions) {
422
+ return;
423
+ }
424
+ const language = await this.loadLanguage(filetypeParserOptions.wasm);
425
+ if (!language) {
426
+ return;
427
+ }
428
+ const queries = await this.createQueries(filetypeParserOptions, language);
429
+ if (!queries) {
430
+ console.error("Failed to create queries for:", filetype);
431
+ return;
432
+ }
433
+ const filetypeParser = {
434
+ ...filetypeParserOptions,
435
+ queries,
436
+ language
437
+ };
438
+ return filetypeParser;
439
+ }
440
+ async preloadParser(filetype) {
441
+ return this.resolveFiletypeParser(filetype);
442
+ }
443
+ async getReusableParser(filetype) {
444
+ const canonicalFiletype = this.resolveCanonicalFiletype(filetype);
445
+ if (this.reusableParsers.has(canonicalFiletype)) {
446
+ return this.reusableParsers.get(canonicalFiletype);
447
+ }
448
+ if (this.reusableParserPromises.has(canonicalFiletype)) {
449
+ return this.reusableParserPromises.get(canonicalFiletype);
450
+ }
451
+ const creationPromise = this.createReusableParser(canonicalFiletype);
452
+ this.reusableParserPromises.set(canonicalFiletype, creationPromise);
453
+ try {
454
+ const result = await creationPromise;
455
+ if (result) {
456
+ this.reusableParsers.set(canonicalFiletype, result);
457
+ }
458
+ return result;
459
+ } finally {
460
+ this.reusableParserPromises.delete(canonicalFiletype);
461
+ }
462
+ }
463
+ async createReusableParser(filetype) {
464
+ const filetypeParser = await this.resolveFiletypeParser(filetype);
465
+ if (!filetypeParser) {
466
+ return;
467
+ }
468
+ const parser = new Parser;
469
+ parser.setLanguage(filetypeParser.language);
470
+ const reusableState = {
471
+ parser,
472
+ filetypeParser,
473
+ queries: filetypeParser.queries
474
+ };
475
+ return reusableState;
476
+ }
477
+ async handleInitializeParser(bufferId, version, content, filetype, messageId) {
478
+ const filetypeParser = await this.resolveFiletypeParser(filetype);
479
+ if (!filetypeParser) {
480
+ self.postMessage({
481
+ type: "PARSER_INIT_RESPONSE",
482
+ bufferId,
483
+ messageId,
484
+ hasParser: false,
485
+ warning: `No parser available for filetype ${filetype}`
486
+ });
487
+ return;
488
+ }
489
+ const parser = new Parser;
490
+ parser.setLanguage(filetypeParser.language);
491
+ const tree = parser.parse(content);
492
+ if (!tree) {
493
+ self.postMessage({
494
+ type: "PARSER_INIT_RESPONSE",
495
+ bufferId,
496
+ messageId,
497
+ hasParser: false,
498
+ error: "Failed to parse buffer"
499
+ });
500
+ return;
501
+ }
502
+ const parserState = {
503
+ parser,
504
+ tree,
505
+ queries: filetypeParser.queries,
506
+ filetype,
507
+ content,
508
+ injectionMapping: filetypeParser.injectionMapping
509
+ };
510
+ this.bufferParsers.set(bufferId, parserState);
511
+ self.postMessage({
512
+ type: "PARSER_INIT_RESPONSE",
513
+ bufferId,
514
+ messageId,
515
+ hasParser: true
516
+ });
517
+ const highlights = await this.initialQuery(parserState);
518
+ self.postMessage({
519
+ type: "HIGHLIGHT_RESPONSE",
520
+ bufferId,
521
+ version,
522
+ ...highlights
523
+ });
524
+ }
525
+ async initialQuery(parserState) {
526
+ const query = parserState.queries.highlights;
527
+ const matches = query.captures(parserState.tree.rootNode);
528
+ let injectionRanges = new Map;
529
+ if (parserState.queries.injections) {
530
+ const injectionResult = await this.processInjections(parserState);
531
+ matches.push(...injectionResult.captures);
532
+ injectionRanges = injectionResult.injectionRanges;
533
+ }
534
+ return this.getHighlights(parserState, matches, injectionRanges);
535
+ }
536
+ getNodeText(node, content) {
537
+ return content.substring(node.startIndex, node.endIndex);
538
+ }
539
+ async processInjections(parserState) {
540
+ const injectionMatches = [];
541
+ const injectionRanges = new Map;
542
+ if (!parserState.queries.injections) {
543
+ return { captures: injectionMatches, injectionRanges };
544
+ }
545
+ const content = parserState.content;
546
+ const injectionCaptures = parserState.queries.injections.captures(parserState.tree.rootNode);
547
+ const languageGroups = new Map;
548
+ const injectionMapping = parserState.injectionMapping;
549
+ for (const capture of injectionCaptures) {
550
+ const captureName = capture.name;
551
+ if (captureName === "injection.content" || captureName.includes("injection")) {
552
+ const nodeType = capture.node.type;
553
+ let targetLanguage;
554
+ if (injectionMapping?.nodeTypes && injectionMapping.nodeTypes[nodeType]) {
555
+ targetLanguage = injectionMapping.nodeTypes[nodeType];
556
+ } else if (nodeType === "code_fence_content") {
557
+ const parent = capture.node.parent;
558
+ if (parent) {
559
+ const infoString = parent.children.find((child) => child.type === "info_string");
560
+ if (infoString) {
561
+ const languageNode = infoString.children.find((child) => child.type === "language");
562
+ if (languageNode) {
563
+ const languageName = this.getNodeText(languageNode, content);
564
+ if (injectionMapping?.infoStringMap && injectionMapping.infoStringMap[languageName]) {
565
+ targetLanguage = injectionMapping.infoStringMap[languageName];
566
+ } else {
567
+ targetLanguage = languageName;
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ if (targetLanguage) {
574
+ if (!languageGroups.has(targetLanguage)) {
575
+ languageGroups.set(targetLanguage, []);
576
+ }
577
+ languageGroups.get(targetLanguage).push({ node: capture.node, name: capture.name });
578
+ }
579
+ }
580
+ }
581
+ for (const [language, captures] of languageGroups.entries()) {
582
+ const injectedParser = await this.getReusableParser(language);
583
+ if (!injectedParser) {
584
+ console.warn(`No parser found for injection language: ${language}`);
585
+ continue;
586
+ }
587
+ if (!injectionRanges.has(language)) {
588
+ injectionRanges.set(language, []);
589
+ }
590
+ const parser = injectedParser.parser;
591
+ for (const { node: injectionNode } of captures) {
592
+ try {
593
+ injectionRanges.get(language).push({
594
+ start: injectionNode.startIndex,
595
+ end: injectionNode.endIndex
596
+ });
597
+ const injectionContent = this.getNodeText(injectionNode, content);
598
+ const tree = parser.parse(injectionContent);
599
+ if (tree) {
600
+ const matches = injectedParser.queries.highlights.captures(tree.rootNode);
601
+ for (const match of matches) {
602
+ const offsetCapture = {
603
+ name: match.name,
604
+ patternIndex: match.patternIndex,
605
+ _injectedQuery: injectedParser.queries.highlights,
606
+ node: {
607
+ ...match.node,
608
+ startPosition: {
609
+ row: match.node.startPosition.row + injectionNode.startPosition.row,
610
+ column: match.node.startPosition.row === 0 ? match.node.startPosition.column + injectionNode.startPosition.column : match.node.startPosition.column
611
+ },
612
+ endPosition: {
613
+ row: match.node.endPosition.row + injectionNode.startPosition.row,
614
+ column: match.node.endPosition.row === 0 ? match.node.endPosition.column + injectionNode.startPosition.column : match.node.endPosition.column
615
+ },
616
+ startIndex: match.node.startIndex + injectionNode.startIndex,
617
+ endIndex: match.node.endIndex + injectionNode.startIndex
618
+ }
619
+ };
620
+ injectionMatches.push(offsetCapture);
621
+ }
622
+ tree.delete();
623
+ }
624
+ } catch (error) {
625
+ console.error(`Error processing injection for language ${language}:`, error);
626
+ }
627
+ }
628
+ }
629
+ return { captures: injectionMatches, injectionRanges };
630
+ }
631
+ editToRange(edit) {
632
+ return {
633
+ startPosition: {
634
+ column: edit.startPosition.column,
635
+ row: edit.startPosition.row
636
+ },
637
+ endPosition: {
638
+ column: edit.newEndPosition.column,
639
+ row: edit.newEndPosition.row
640
+ },
641
+ startIndex: edit.startIndex,
642
+ endIndex: edit.newEndIndex
643
+ };
644
+ }
645
+ async handleEdits(bufferId, content, edits) {
646
+ const parserState = this.bufferParsers.get(bufferId);
647
+ if (!parserState) {
648
+ return { warning: "No parser state found for buffer" };
649
+ }
650
+ parserState.content = content;
651
+ for (const edit of edits) {
652
+ parserState.tree.edit(edit);
653
+ }
654
+ const startParse = performance.now();
655
+ const newTree = parserState.parser.parse(content, parserState.tree);
656
+ const endParse = performance.now();
657
+ const parseTime = endParse - startParse;
658
+ this.performance.parseTimes.push(parseTime);
659
+ if (this.performance.parseTimes.length > 10) {
660
+ this.performance.parseTimes.shift();
661
+ }
662
+ this.performance.averageParseTime = this.performance.parseTimes.reduce((acc, time) => acc + time, 0) / this.performance.parseTimes.length;
663
+ if (!newTree) {
664
+ return { error: "Failed to parse buffer" };
665
+ }
666
+ const changedRanges = parserState.tree.getChangedRanges(newTree);
667
+ parserState.tree = newTree;
668
+ const startQuery = performance.now();
669
+ const matches = [];
670
+ if (changedRanges.length === 0) {
671
+ edits.forEach((edit) => {
672
+ const range = this.editToRange(edit);
673
+ changedRanges.push(range);
674
+ });
675
+ }
676
+ for (const range of changedRanges) {
677
+ let node = parserState.tree.rootNode.descendantForPosition(range.startPosition, range.endPosition);
678
+ if (!node) {
679
+ continue;
680
+ }
681
+ if (node.equals(parserState.tree.rootNode)) {
682
+ const rangeCaptures = parserState.queries.highlights.captures(node, {
683
+ startIndex: range.startIndex - 100,
684
+ endIndex: range.endIndex + 1000
685
+ });
686
+ matches.push(...rangeCaptures);
687
+ continue;
688
+ }
689
+ while (node && !this.nodeContainsRange(node, range)) {
690
+ node = node.parent;
691
+ }
692
+ if (!node) {
693
+ node = parserState.tree.rootNode;
694
+ }
695
+ const nodeCaptures = parserState.queries.highlights.captures(node);
696
+ matches.push(...nodeCaptures);
697
+ }
698
+ let injectionRanges = new Map;
699
+ if (parserState.queries.injections) {
700
+ const injectionResult = await this.processInjections(parserState);
701
+ matches.push(...injectionResult.captures);
702
+ injectionRanges = injectionResult.injectionRanges;
703
+ }
704
+ const endQuery = performance.now();
705
+ const queryTime = endQuery - startQuery;
706
+ this.performance.queryTimes.push(queryTime);
707
+ if (this.performance.queryTimes.length > 10) {
708
+ this.performance.queryTimes.shift();
709
+ }
710
+ this.performance.averageQueryTime = this.performance.queryTimes.reduce((acc, time) => acc + time, 0) / this.performance.queryTimes.length;
711
+ return this.getHighlights(parserState, matches, injectionRanges);
712
+ }
713
+ nodeContainsRange(node, range) {
714
+ return node.startPosition.row <= range.startPosition.row && node.endPosition.row >= range.endPosition.row && (node.startPosition.row < range.startPosition.row || node.startPosition.column <= range.startPosition.column) && (node.endPosition.row > range.endPosition.row || node.endPosition.column >= range.endPosition.column);
715
+ }
716
+ getHighlights(parserState, matches, injectionRanges) {
717
+ const lineHighlights = new Map;
718
+ const droppedHighlights = new Map;
719
+ for (const match of matches) {
720
+ const node = match.node;
721
+ const startLine = node.startPosition.row;
722
+ const endLine = node.endPosition.row;
723
+ const highlight = {
724
+ startCol: node.startPosition.column,
725
+ endCol: node.endPosition.column,
726
+ group: match.name
727
+ };
728
+ if (!lineHighlights.has(startLine)) {
729
+ lineHighlights.set(startLine, new Map);
730
+ droppedHighlights.set(startLine, new Map);
731
+ }
732
+ if (lineHighlights.get(startLine)?.has(node.id)) {
733
+ droppedHighlights.get(startLine)?.set(node.id, lineHighlights.get(startLine)?.get(node.id));
734
+ }
735
+ lineHighlights.get(startLine)?.set(node.id, highlight);
736
+ if (startLine !== endLine) {
737
+ for (let line = startLine + 1;line <= endLine; line++) {
738
+ if (!lineHighlights.has(line)) {
739
+ lineHighlights.set(line, new Map);
740
+ }
741
+ const hl = {
742
+ startCol: 0,
743
+ endCol: node.endPosition.column,
744
+ group: match.name
745
+ };
746
+ lineHighlights.get(line)?.set(node.id, hl);
747
+ }
748
+ }
749
+ }
750
+ return {
751
+ highlights: Array.from(lineHighlights.entries()).map(([line, lineHighlights2]) => ({
752
+ line,
753
+ highlights: Array.from(lineHighlights2.values()),
754
+ droppedHighlights: droppedHighlights.get(line) ? Array.from(droppedHighlights.get(line).values()) : []
755
+ }))
756
+ };
757
+ }
758
+ getSimpleHighlights(matches, injectionRanges) {
759
+ const highlights = [];
760
+ const flatInjectionRanges = [];
761
+ for (const [lang, ranges] of injectionRanges.entries()) {
762
+ for (const range of ranges) {
763
+ flatInjectionRanges.push({ ...range, lang });
764
+ }
765
+ }
766
+ for (const match of matches) {
767
+ const node = match.node;
768
+ let isInjection = false;
769
+ let injectionLang;
770
+ let containsInjection = false;
771
+ for (const injRange of flatInjectionRanges) {
772
+ if (node.startIndex >= injRange.start && node.endIndex <= injRange.end) {
773
+ isInjection = true;
774
+ injectionLang = injRange.lang;
775
+ break;
776
+ } else if (node.startIndex <= injRange.start && node.endIndex >= injRange.end) {
777
+ containsInjection = true;
778
+ break;
779
+ }
780
+ }
781
+ const matchQuery = match._injectedQuery;
782
+ const patternProperties = matchQuery?.setProperties?.[match.patternIndex];
783
+ const concealValue = patternProperties?.conceal ?? match.setProperties?.conceal;
784
+ const concealLines = patternProperties?.conceal_lines ?? match.setProperties?.conceal_lines;
785
+ const meta = {};
786
+ if (isInjection && injectionLang) {
787
+ meta.isInjection = true;
788
+ meta.injectionLang = injectionLang;
789
+ }
790
+ if (containsInjection) {
791
+ meta.containsInjection = true;
792
+ }
793
+ if (concealValue !== undefined) {
794
+ meta.conceal = concealValue;
795
+ }
796
+ if (concealLines !== undefined) {
797
+ meta.concealLines = concealLines;
798
+ }
799
+ if (Object.keys(meta).length > 0) {
800
+ highlights.push([node.startIndex, node.endIndex, match.name, meta]);
801
+ } else {
802
+ highlights.push([node.startIndex, node.endIndex, match.name]);
803
+ }
804
+ }
805
+ highlights.sort((a, b) => a[0] - b[0]);
806
+ return highlights;
807
+ }
808
+ async handleResetBuffer(bufferId, version, content) {
809
+ const parserState = this.bufferParsers.get(bufferId);
810
+ if (!parserState) {
811
+ return { warning: "No parser state found for buffer" };
812
+ }
813
+ parserState.content = content;
814
+ const newTree = parserState.parser.parse(content);
815
+ if (!newTree) {
816
+ return { error: "Failed to parse buffer during reset" };
817
+ }
818
+ parserState.tree = newTree;
819
+ const matches = parserState.queries.highlights.captures(parserState.tree.rootNode);
820
+ let injectionRanges = new Map;
821
+ if (parserState.queries.injections) {
822
+ const injectionResult = await this.processInjections(parserState);
823
+ matches.push(...injectionResult.captures);
824
+ injectionRanges = injectionResult.injectionRanges;
825
+ }
826
+ return this.getHighlights(parserState, matches, injectionRanges);
827
+ }
828
+ disposeBuffer(bufferId) {
829
+ const parserState = this.bufferParsers.get(bufferId);
830
+ if (!parserState) {
831
+ return;
832
+ }
833
+ parserState.tree.delete();
834
+ parserState.parser.delete();
835
+ this.bufferParsers.delete(bufferId);
836
+ }
837
+ async handleOneShotHighlight(content, filetype, messageId) {
838
+ const reusableState = await this.getReusableParser(filetype);
839
+ if (!reusableState) {
840
+ self.postMessage({
841
+ type: "ONESHOT_HIGHLIGHT_RESPONSE",
842
+ messageId,
843
+ hasParser: false,
844
+ warning: `No parser available for filetype ${filetype}`
845
+ });
846
+ return;
847
+ }
848
+ const parseContent = filetype === "markdown" && content.endsWith("```") ? content + `
849
+ ` : content;
850
+ const tree = reusableState.parser.parse(parseContent);
851
+ if (!tree) {
852
+ self.postMessage({
853
+ type: "ONESHOT_HIGHLIGHT_RESPONSE",
854
+ messageId,
855
+ hasParser: false,
856
+ error: "Failed to parse content"
857
+ });
858
+ return;
859
+ }
860
+ try {
861
+ const matches = reusableState.filetypeParser.queries.highlights.captures(tree.rootNode);
862
+ let injectionRanges = new Map;
863
+ if (reusableState.filetypeParser.queries.injections) {
864
+ const parserState = {
865
+ parser: reusableState.parser,
866
+ tree,
867
+ queries: reusableState.filetypeParser.queries,
868
+ filetype,
869
+ content,
870
+ injectionMapping: reusableState.filetypeParser.injectionMapping
871
+ };
872
+ const injectionResult = await this.processInjections(parserState);
873
+ matches.push(...injectionResult.captures);
874
+ injectionRanges = injectionResult.injectionRanges;
875
+ }
876
+ const highlights = this.getSimpleHighlights(matches, injectionRanges);
877
+ self.postMessage({
878
+ type: "ONESHOT_HIGHLIGHT_RESPONSE",
879
+ messageId,
880
+ hasParser: true,
881
+ highlights
882
+ });
883
+ } finally {
884
+ tree.delete();
885
+ }
886
+ }
887
+ async updateDataPath(dataPath) {
888
+ this.dataPath = dataPath;
889
+ this.tsDataPath = path2.join(dataPath, "tree-sitter");
890
+ try {
891
+ await mkdir3(path2.join(this.tsDataPath, "languages"), { recursive: true });
892
+ await mkdir3(path2.join(this.tsDataPath, "queries"), { recursive: true });
893
+ } catch (error) {
894
+ throw new Error(`Failed to update data path: ${error}`);
895
+ }
896
+ }
897
+ async clearCache() {
898
+ if (!this.dataPath || !this.tsDataPath) {
899
+ throw new Error("No data path configured");
900
+ }
901
+ const { rm } = await import("fs/promises");
902
+ try {
903
+ const treeSitterPath = path2.join(this.dataPath, "tree-sitter");
904
+ await rm(treeSitterPath, { recursive: true, force: true });
905
+ await mkdir3(path2.join(treeSitterPath, "languages"), { recursive: true });
906
+ await mkdir3(path2.join(treeSitterPath, "queries"), { recursive: true });
907
+ this.filetypeParsers.clear();
908
+ this.filetypeParserPromises.clear();
909
+ this.reusableParsers.clear();
910
+ this.reusableParserPromises.clear();
911
+ } catch (error) {
912
+ throw new Error(`Failed to clear cache: ${error}`);
913
+ }
914
+ }
915
+ }
916
+ if (!isMainThread) {
917
+ let logMessage = function(type, ...args) {
918
+ self.postMessage({
919
+ type: "WORKER_LOG",
920
+ logType: type,
921
+ data: args
922
+ });
923
+ };
924
+ const worker = new ParserWorker;
925
+ console.log = (...args) => logMessage("log", ...args);
926
+ console.error = (...args) => logMessage("error", ...args);
927
+ console.warn = (...args) => logMessage("warn", ...args);
928
+ self.onmessage = async (e) => {
929
+ const { type, bufferId, version, content, filetype, edits, filetypeParser, messageId, dataPath } = e.data;
930
+ try {
931
+ switch (type) {
932
+ case "INIT":
933
+ try {
934
+ await worker.initialize({ dataPath });
935
+ self.postMessage({ type: "INIT_RESPONSE" });
936
+ } catch (error) {
937
+ self.postMessage({
938
+ type: "INIT_RESPONSE",
939
+ error: error instanceof Error ? error.stack || error.message : String(error)
940
+ });
941
+ }
942
+ break;
943
+ case "ADD_FILETYPE_PARSER":
944
+ worker.addFiletypeParser(filetypeParser);
945
+ break;
946
+ case "PRELOAD_PARSER":
947
+ const maybeParser = await worker.preloadParser(filetype);
948
+ self.postMessage({ type: "PRELOAD_PARSER_RESPONSE", messageId, hasParser: !!maybeParser });
949
+ break;
950
+ case "INITIALIZE_PARSER":
951
+ await worker.handleInitializeParser(bufferId, version, content, filetype, messageId);
952
+ break;
953
+ case "HANDLE_EDITS":
954
+ const response = await worker.handleEdits(bufferId, content, edits);
955
+ if (response.highlights && response.highlights.length > 0) {
956
+ self.postMessage({ type: "HIGHLIGHT_RESPONSE", bufferId, version, ...response });
957
+ } else if (response.warning) {
958
+ self.postMessage({ type: "WARNING", bufferId, warning: response.warning });
959
+ } else if (response.error) {
960
+ self.postMessage({ type: "ERROR", bufferId, error: response.error });
961
+ }
962
+ break;
963
+ case "GET_PERFORMANCE":
964
+ self.postMessage({ type: "PERFORMANCE_RESPONSE", performance: worker.performance, messageId });
965
+ break;
966
+ case "RESET_BUFFER":
967
+ const resetResponse = await worker.handleResetBuffer(bufferId, version, content);
968
+ if (resetResponse.highlights && resetResponse.highlights.length > 0) {
969
+ self.postMessage({ type: "HIGHLIGHT_RESPONSE", bufferId, version, ...resetResponse });
970
+ } else if (resetResponse.warning) {
971
+ self.postMessage({ type: "WARNING", bufferId, warning: resetResponse.warning });
972
+ } else if (resetResponse.error) {
973
+ self.postMessage({ type: "ERROR", bufferId, error: resetResponse.error });
974
+ }
975
+ break;
976
+ case "DISPOSE_BUFFER":
977
+ worker.disposeBuffer(bufferId);
978
+ self.postMessage({ type: "BUFFER_DISPOSED", bufferId });
979
+ break;
980
+ case "ONESHOT_HIGHLIGHT":
981
+ await worker.handleOneShotHighlight(content, filetype, messageId);
982
+ break;
983
+ case "UPDATE_DATA_PATH":
984
+ try {
985
+ await worker.updateDataPath(dataPath);
986
+ self.postMessage({ type: "UPDATE_DATA_PATH_RESPONSE", messageId });
987
+ } catch (error) {
988
+ self.postMessage({
989
+ type: "UPDATE_DATA_PATH_RESPONSE",
990
+ messageId,
991
+ error: error instanceof Error ? error.message : String(error)
992
+ });
993
+ }
994
+ break;
995
+ case "CLEAR_CACHE":
996
+ try {
997
+ await worker.clearCache();
998
+ self.postMessage({ type: "CLEAR_CACHE_RESPONSE", messageId });
999
+ } catch (error) {
1000
+ self.postMessage({
1001
+ type: "CLEAR_CACHE_RESPONSE",
1002
+ messageId,
1003
+ error: error instanceof Error ? error.message : String(error)
1004
+ });
1005
+ }
1006
+ break;
1007
+ default:
1008
+ self.postMessage({
1009
+ type: "ERROR",
1010
+ bufferId,
1011
+ error: `Unknown message type: ${type}`
1012
+ });
1013
+ }
1014
+ } catch (error) {
1015
+ self.postMessage({
1016
+ type: "ERROR",
1017
+ bufferId,
1018
+ error: error instanceof Error ? error.stack || error.message : String(error)
1019
+ });
1020
+ }
1021
+ };
1022
+ }
1023
+
1024
+ //# debugId=025A5402888E132264756E2164756E21
1025
+ //# sourceMappingURL=parser.worker.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lupacode",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "AI-powered terminal coding assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,9 @@
14
14
  ],
15
15
  "scripts": {
16
16
  "dev": "bun run --watch src/index.tsx",
17
- "build": "bun build src/index.tsx --outdir dist --target bun --external \"@opentui/core-*\"",
17
+ "build": "bun run build:bundle && bun run build:copy-worker",
18
+ "build:bundle": "bun build src/index.tsx --outdir dist --target bun --external \"@opentui/core-*\"",
19
+ "build:copy-worker": "bun run scripts/copy-worker.js",
18
20
  "prepublishOnly": "bun run build",
19
21
  "typecheck": "tsc -p tsconfig.json --noEmit"
20
22
  },