@kili-ai/dev-install 0.2.64

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.
@@ -0,0 +1,1660 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/core/client.ts
5
+ var import_node_crypto = require("crypto");
6
+
7
+ // src/core/constants.ts
8
+ var NPM_ORG = "kili-ai";
9
+ var NPM_PACKAGE = "ide";
10
+ var PACKAGE_NAME = `@${NPM_ORG}/${NPM_PACKAGE}`;
11
+ var DEFAULT_API_URL = true ? "https://app-dev.trykili.ai" : "https://api.trykili.ai";
12
+ var DEFAULT_WEB_URL = true ? "https://kili-ui.vercel.app/" : "https://app.trykili.ai";
13
+ var AUTH_TIMEOUT_MS = 5 * 60 * 1e3;
14
+ var PLACEMENT = {
15
+ TERMINAL_SPINNER: "claude_code_terminal_spinner",
16
+ TERMINAL_STATUSLINE: "claude_code_terminal_statusline",
17
+ EXTENSION_SPINNER: "claude_code_extension_spinner",
18
+ EXTENSION_STATUSBAR: "claude_code_extension_statusbar"
19
+ };
20
+ var DWELL_THRESHOLD_MS = 0;
21
+ var ERRORS = {
22
+ REQUIRED_API_KEY: 'Kili API key is required. Run "Kili: Sign In".',
23
+ REQUEST_FAILED: "Kili request failed.",
24
+ TIMEOUT: "Kili request timed out.",
25
+ NETWORK: "Kili network error."
26
+ };
27
+
28
+ // src/core/debug.ts
29
+ var import_node_fs = require("fs");
30
+ var import_node_path2 = require("path");
31
+
32
+ // src/core/paths.ts
33
+ var import_node_os = require("os");
34
+ var import_node_path = require("path");
35
+ function kiliHome() {
36
+ return (0, import_node_path.join)((0, import_node_os.homedir)(), ".kili");
37
+ }
38
+ function adCachePath() {
39
+ return (0, import_node_path.join)(kiliHome(), "ad-cache.json");
40
+ }
41
+ function logoCachePath() {
42
+ return (0, import_node_path.join)(kiliHome(), "logo-cache.json");
43
+ }
44
+ function pendingTurnPath() {
45
+ return (0, import_node_path.join)(kiliHome(), "pending-turn.json");
46
+ }
47
+ function terminalHeartbeatPath() {
48
+ return (0, import_node_path.join)(kiliHome(), "terminal-heartbeat.json");
49
+ }
50
+ function runtimeConfigPath() {
51
+ return (0, import_node_path.join)(kiliHome(), "config.json");
52
+ }
53
+ function debugLogPath() {
54
+ return (0, import_node_path.join)(kiliHome(), "debug.log");
55
+ }
56
+ function claudeSettingsPath() {
57
+ return (0, import_node_path.join)((0, import_node_os.homedir)(), ".claude", "settings.json");
58
+ }
59
+
60
+ // src/core/debug.ts
61
+ var _MAX_BYTES = 256e3;
62
+ function _processTag() {
63
+ const entry = process.argv[1];
64
+ if (!entry) return "?";
65
+ const name = (0, import_node_path2.basename)(entry).replace(/\.[cm]?js$/, "");
66
+ return name || "?";
67
+ }
68
+ function _rotateIfLarge(path) {
69
+ try {
70
+ if ((0, import_node_fs.statSync)(path).size < _MAX_BYTES) return;
71
+ (0, import_node_fs.renameSync)(path, `${path}.1`);
72
+ } catch {
73
+ }
74
+ }
75
+ function _format(args) {
76
+ return args.map((arg) => {
77
+ if (typeof arg === "string") return arg;
78
+ if (arg instanceof Error) return `${arg.name}: ${arg.message}`;
79
+ try {
80
+ return JSON.stringify(arg);
81
+ } catch {
82
+ return String(arg);
83
+ }
84
+ }).join(" ");
85
+ }
86
+ function debugLog(...args) {
87
+ if (process.env.KILI_DEBUG === "1") {
88
+ console.error("[kili]", ...args);
89
+ }
90
+ try {
91
+ const path = debugLogPath();
92
+ (0, import_node_fs.mkdirSync)((0, import_node_path2.dirname)(path), { recursive: true });
93
+ _rotateIfLarge(path);
94
+ const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${_processTag()}] ${_format(args)}
95
+ `;
96
+ (0, import_node_fs.appendFileSync)(path, line, "utf8");
97
+ } catch {
98
+ }
99
+ }
100
+
101
+ // src/core/errors.ts
102
+ var KiliError = class extends Error {
103
+ constructor(message, statusCode) {
104
+ super(message);
105
+ this.name = "KiliError";
106
+ this.statusCode = statusCode;
107
+ }
108
+ };
109
+
110
+ // src/core/client.ts
111
+ var _defaultTimeoutMs = 5e3;
112
+ var KiliClient = class {
113
+ /** Keyed by placement id, value is every ad api.kili served for that
114
+ * placement, in the order the server returned them -- how many that is
115
+ * per call depends entirely on which `IAdServeStrategy` is configured
116
+ * server-side (currently `RandomAdServeStrategy`, one ad; `ads.service.ts`
117
+ * can also serve a whole shuffled candidate list under `AllAdServeStrategy`).
118
+ * Either way this is grouped into an array per placement, never a single
119
+ * value, so the client never has to know or care which strategy is live.
120
+ * A placement api.kili had nothing to serve for (e.g. no active campaign)
121
+ * simply has no entry -- callers should treat a missing key exactly like
122
+ * "no ad", the same as an empty `ads[]` today. Grouping, not the old
123
+ * `new Map(...)` overwrite: a `Map` built from `[placementId, ad]` pairs
124
+ * silently keeps only the *last* entry for a repeated key, which is
125
+ * exactly what used to throw away every ad but one under
126
+ * `AllAdServeStrategy` -- confirmed live as the root cause of "same ad
127
+ * every time". */
128
+ async fetchAds(input) {
129
+ if (!input.apiKey) {
130
+ throw new KiliError(ERRORS.REQUIRED_API_KEY, 401);
131
+ }
132
+ const baseUrl = input.apiUrl ?? DEFAULT_API_URL;
133
+ const result = await this._request(baseUrl, input);
134
+ debugLog(
135
+ "fetchAds",
136
+ result.ads.map((ad) => ({
137
+ placementId: ad.placementId,
138
+ adId: ad.adId,
139
+ hasFavicon: Boolean(ad.favicon),
140
+ favicon: ad.favicon
141
+ }))
142
+ );
143
+ const grouped = /* @__PURE__ */ new Map();
144
+ for (const ad of result.ads) {
145
+ const list = grouped.get(ad.placementId);
146
+ if (list) list.push(ad);
147
+ else grouped.set(ad.placementId, [ad]);
148
+ }
149
+ return grouped;
150
+ }
151
+ async _request(baseUrl, input) {
152
+ const controller = new AbortController();
153
+ const timer = setTimeout(() => controller.abort(), _defaultTimeoutMs);
154
+ try {
155
+ const res = await fetch(`${baseUrl}/ads`, {
156
+ method: "POST",
157
+ headers: {
158
+ "content-type": "application/json",
159
+ "x-kili-api-key": input.apiKey
160
+ },
161
+ body: JSON.stringify(this._body(input)),
162
+ signal: controller.signal
163
+ });
164
+ if (!res.ok) {
165
+ throw new KiliError(ERRORS.REQUEST_FAILED, res.status);
166
+ }
167
+ return await res.json();
168
+ } catch (error) {
169
+ throw this._toKiliError(error);
170
+ } finally {
171
+ clearTimeout(timer);
172
+ }
173
+ }
174
+ _body(input) {
175
+ return {
176
+ // No `messages` field -- api.kili's ad selection (`RandomAdServeStrategy`
177
+ // / `AllAdServeStrategy`, and the `IAdServeStrategy` interface itself)
178
+ // never reads conversation content at all, so sending it here was pure
179
+ // dead weight: payload size and server-side parsing for a field nothing
180
+ // picks on. The wire schema still accepts it (optional, defaults to
181
+ // `[]` server-side) for any other caller and for a future relevancy
182
+ // strategy -- we just stopped being the one paying for it.
183
+ // `placement` carries our own distinguishing value directly (see
184
+ // PLACEMENT in constants.ts) rather than a shared generic slot type
185
+ // -- that's the only field that lands in `ad_events`, so it has to be
186
+ // the one that tells our four surfaces apart. `placementId` is still
187
+ // a required wire field; sending the same value keeps the two in
188
+ // sync without adding a second meaning to track.
189
+ placements: input.placementIds.map((placementId) => ({
190
+ placement: placementId,
191
+ placementId
192
+ })),
193
+ kiliContext: {
194
+ sessionId: this._sessionId(input.sessionId),
195
+ user: { userId: input.installId },
196
+ device: {
197
+ ua: "@kili-ai/ide",
198
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
199
+ locale: Intl.DateTimeFormat().resolvedOptions().locale
200
+ }
201
+ }
202
+ };
203
+ }
204
+ /** api.kili requires a UUID; fall back to a fresh one when Claude's own
205
+ * `session_id` doesn't parse as one. */
206
+ _sessionId(raw) {
207
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
208
+ return uuidPattern.test(raw) ? raw : (0, import_node_crypto.randomUUID)();
209
+ }
210
+ _toKiliError(error) {
211
+ if (error instanceof KiliError) return error;
212
+ if (error instanceof Error && error.name === "AbortError") {
213
+ return new KiliError(ERRORS.TIMEOUT, 408);
214
+ }
215
+ return new KiliError(ERRORS.NETWORK, 503);
216
+ }
217
+ };
218
+ async function beacon(url) {
219
+ if (!url) return;
220
+ try {
221
+ const res = await fetch(url, { method: "GET" });
222
+ debugLog("beacon", { url, status: res.status, ok: res.ok });
223
+ } catch (error) {
224
+ debugLog(
225
+ "beacon: threw",
226
+ { url },
227
+ error instanceof Error ? error.message : error
228
+ );
229
+ }
230
+ }
231
+
232
+ // src/core/store.ts
233
+ var import_node_fs2 = require("fs");
234
+ var import_node_path3 = require("path");
235
+
236
+ // node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
237
+ function createScanner(text, ignoreTrivia = false) {
238
+ const len = text.length;
239
+ let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
240
+ function scanHexDigits(count, exact) {
241
+ let digits = 0;
242
+ let value2 = 0;
243
+ while (digits < count || !exact) {
244
+ let ch = text.charCodeAt(pos);
245
+ if (ch >= 48 && ch <= 57) {
246
+ value2 = value2 * 16 + ch - 48;
247
+ } else if (ch >= 65 && ch <= 70) {
248
+ value2 = value2 * 16 + ch - 65 + 10;
249
+ } else if (ch >= 97 && ch <= 102) {
250
+ value2 = value2 * 16 + ch - 97 + 10;
251
+ } else {
252
+ break;
253
+ }
254
+ pos++;
255
+ digits++;
256
+ }
257
+ if (digits < count) {
258
+ value2 = -1;
259
+ }
260
+ return value2;
261
+ }
262
+ function setPosition(newPosition) {
263
+ pos = newPosition;
264
+ value = "";
265
+ tokenOffset = 0;
266
+ token = 16;
267
+ scanError = 0;
268
+ }
269
+ function scanNumber() {
270
+ let start = pos;
271
+ if (text.charCodeAt(pos) === 48) {
272
+ pos++;
273
+ } else {
274
+ pos++;
275
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
276
+ pos++;
277
+ }
278
+ }
279
+ if (pos < text.length && text.charCodeAt(pos) === 46) {
280
+ pos++;
281
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
282
+ pos++;
283
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
284
+ pos++;
285
+ }
286
+ } else {
287
+ scanError = 3;
288
+ return text.substring(start, pos);
289
+ }
290
+ }
291
+ let end = pos;
292
+ if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
293
+ pos++;
294
+ if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
295
+ pos++;
296
+ }
297
+ if (pos < text.length && isDigit(text.charCodeAt(pos))) {
298
+ pos++;
299
+ while (pos < text.length && isDigit(text.charCodeAt(pos))) {
300
+ pos++;
301
+ }
302
+ end = pos;
303
+ } else {
304
+ scanError = 3;
305
+ }
306
+ }
307
+ return text.substring(start, end);
308
+ }
309
+ function scanString() {
310
+ let result = "", start = pos;
311
+ while (true) {
312
+ if (pos >= len) {
313
+ result += text.substring(start, pos);
314
+ scanError = 2;
315
+ break;
316
+ }
317
+ const ch = text.charCodeAt(pos);
318
+ if (ch === 34) {
319
+ result += text.substring(start, pos);
320
+ pos++;
321
+ break;
322
+ }
323
+ if (ch === 92) {
324
+ result += text.substring(start, pos);
325
+ pos++;
326
+ if (pos >= len) {
327
+ scanError = 2;
328
+ break;
329
+ }
330
+ const ch2 = text.charCodeAt(pos++);
331
+ switch (ch2) {
332
+ case 34:
333
+ result += '"';
334
+ break;
335
+ case 92:
336
+ result += "\\";
337
+ break;
338
+ case 47:
339
+ result += "/";
340
+ break;
341
+ case 98:
342
+ result += "\b";
343
+ break;
344
+ case 102:
345
+ result += "\f";
346
+ break;
347
+ case 110:
348
+ result += "\n";
349
+ break;
350
+ case 114:
351
+ result += "\r";
352
+ break;
353
+ case 116:
354
+ result += " ";
355
+ break;
356
+ case 117:
357
+ const ch3 = scanHexDigits(4, true);
358
+ if (ch3 >= 0) {
359
+ result += String.fromCharCode(ch3);
360
+ } else {
361
+ scanError = 4;
362
+ }
363
+ break;
364
+ default:
365
+ scanError = 5;
366
+ }
367
+ start = pos;
368
+ continue;
369
+ }
370
+ if (ch >= 0 && ch <= 31) {
371
+ if (isLineBreak(ch)) {
372
+ result += text.substring(start, pos);
373
+ scanError = 2;
374
+ break;
375
+ } else {
376
+ scanError = 6;
377
+ }
378
+ }
379
+ pos++;
380
+ }
381
+ return result;
382
+ }
383
+ function scanNext() {
384
+ value = "";
385
+ scanError = 0;
386
+ tokenOffset = pos;
387
+ lineStartOffset = lineNumber;
388
+ prevTokenLineStartOffset = tokenLineStartOffset;
389
+ if (pos >= len) {
390
+ tokenOffset = len;
391
+ return token = 17;
392
+ }
393
+ let code = text.charCodeAt(pos);
394
+ if (isWhiteSpace(code)) {
395
+ do {
396
+ pos++;
397
+ value += String.fromCharCode(code);
398
+ code = text.charCodeAt(pos);
399
+ } while (isWhiteSpace(code));
400
+ return token = 15;
401
+ }
402
+ if (isLineBreak(code)) {
403
+ pos++;
404
+ value += String.fromCharCode(code);
405
+ if (code === 13 && text.charCodeAt(pos) === 10) {
406
+ pos++;
407
+ value += "\n";
408
+ }
409
+ lineNumber++;
410
+ tokenLineStartOffset = pos;
411
+ return token = 14;
412
+ }
413
+ switch (code) {
414
+ // tokens: []{}:,
415
+ case 123:
416
+ pos++;
417
+ return token = 1;
418
+ case 125:
419
+ pos++;
420
+ return token = 2;
421
+ case 91:
422
+ pos++;
423
+ return token = 3;
424
+ case 93:
425
+ pos++;
426
+ return token = 4;
427
+ case 58:
428
+ pos++;
429
+ return token = 6;
430
+ case 44:
431
+ pos++;
432
+ return token = 5;
433
+ // strings
434
+ case 34:
435
+ pos++;
436
+ value = scanString();
437
+ return token = 10;
438
+ // comments
439
+ case 47:
440
+ const start = pos - 1;
441
+ if (text.charCodeAt(pos + 1) === 47) {
442
+ pos += 2;
443
+ while (pos < len) {
444
+ if (isLineBreak(text.charCodeAt(pos))) {
445
+ break;
446
+ }
447
+ pos++;
448
+ }
449
+ value = text.substring(start, pos);
450
+ return token = 12;
451
+ }
452
+ if (text.charCodeAt(pos + 1) === 42) {
453
+ pos += 2;
454
+ const safeLength = len - 1;
455
+ let commentClosed = false;
456
+ while (pos < safeLength) {
457
+ const ch = text.charCodeAt(pos);
458
+ if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
459
+ pos += 2;
460
+ commentClosed = true;
461
+ break;
462
+ }
463
+ pos++;
464
+ if (isLineBreak(ch)) {
465
+ if (ch === 13 && text.charCodeAt(pos) === 10) {
466
+ pos++;
467
+ }
468
+ lineNumber++;
469
+ tokenLineStartOffset = pos;
470
+ }
471
+ }
472
+ if (!commentClosed) {
473
+ pos++;
474
+ scanError = 1;
475
+ }
476
+ value = text.substring(start, pos);
477
+ return token = 13;
478
+ }
479
+ value += String.fromCharCode(code);
480
+ pos++;
481
+ return token = 16;
482
+ // numbers
483
+ case 45:
484
+ value += String.fromCharCode(code);
485
+ pos++;
486
+ if (pos === len || !isDigit(text.charCodeAt(pos))) {
487
+ return token = 16;
488
+ }
489
+ // found a minus, followed by a number so
490
+ // we fall through to proceed with scanning
491
+ // numbers
492
+ case 48:
493
+ case 49:
494
+ case 50:
495
+ case 51:
496
+ case 52:
497
+ case 53:
498
+ case 54:
499
+ case 55:
500
+ case 56:
501
+ case 57:
502
+ value += scanNumber();
503
+ return token = 11;
504
+ // literals and unknown symbols
505
+ default:
506
+ while (pos < len && isUnknownContentCharacter(code)) {
507
+ pos++;
508
+ code = text.charCodeAt(pos);
509
+ }
510
+ if (tokenOffset !== pos) {
511
+ value = text.substring(tokenOffset, pos);
512
+ switch (value) {
513
+ case "true":
514
+ return token = 8;
515
+ case "false":
516
+ return token = 9;
517
+ case "null":
518
+ return token = 7;
519
+ }
520
+ return token = 16;
521
+ }
522
+ value += String.fromCharCode(code);
523
+ pos++;
524
+ return token = 16;
525
+ }
526
+ }
527
+ function isUnknownContentCharacter(code) {
528
+ if (isWhiteSpace(code) || isLineBreak(code)) {
529
+ return false;
530
+ }
531
+ switch (code) {
532
+ case 125:
533
+ case 93:
534
+ case 123:
535
+ case 91:
536
+ case 34:
537
+ case 58:
538
+ case 44:
539
+ case 47:
540
+ return false;
541
+ }
542
+ return true;
543
+ }
544
+ function scanNextNonTrivia() {
545
+ let result;
546
+ do {
547
+ result = scanNext();
548
+ } while (result >= 12 && result <= 15);
549
+ return result;
550
+ }
551
+ return {
552
+ setPosition,
553
+ getPosition: () => pos,
554
+ scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
555
+ getToken: () => token,
556
+ getTokenValue: () => value,
557
+ getTokenOffset: () => tokenOffset,
558
+ getTokenLength: () => pos - tokenOffset,
559
+ getTokenStartLine: () => lineStartOffset,
560
+ getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
561
+ getTokenError: () => scanError
562
+ };
563
+ }
564
+ function isWhiteSpace(ch) {
565
+ return ch === 32 || ch === 9;
566
+ }
567
+ function isLineBreak(ch) {
568
+ return ch === 10 || ch === 13;
569
+ }
570
+ function isDigit(ch) {
571
+ return ch >= 48 && ch <= 57;
572
+ }
573
+ var CharacterCodes;
574
+ (function(CharacterCodes2) {
575
+ CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
576
+ CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
577
+ CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
578
+ CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
579
+ CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
580
+ CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
581
+ CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
582
+ CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
583
+ CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
584
+ CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
585
+ CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
586
+ CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
587
+ CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
588
+ CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
589
+ CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
590
+ CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
591
+ CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
592
+ CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
593
+ CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
594
+ CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
595
+ CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
596
+ CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
597
+ CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
598
+ CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
599
+ CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
600
+ CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
601
+ CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
602
+ CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
603
+ CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
604
+ CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
605
+ CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
606
+ CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
607
+ CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
608
+ CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
609
+ CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
610
+ CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
611
+ CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
612
+ CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
613
+ CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
614
+ CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
615
+ CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
616
+ CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
617
+ CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
618
+ CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
619
+ CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
620
+ CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
621
+ CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
622
+ CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
623
+ CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
624
+ CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
625
+ CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
626
+ CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
627
+ CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
628
+ CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
629
+ CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
630
+ CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
631
+ CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
632
+ CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
633
+ CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
634
+ CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
635
+ CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
636
+ CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
637
+ CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
638
+ CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
639
+ CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
640
+ CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
641
+ CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
642
+ CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
643
+ CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
644
+ CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
645
+ CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
646
+ CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
647
+ CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
648
+ CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
649
+ CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
650
+ CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
651
+ CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
652
+ CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
653
+ CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
654
+ CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
655
+ })(CharacterCodes || (CharacterCodes = {}));
656
+
657
+ // node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/string-intern.js
658
+ var cachedSpaces = new Array(20).fill(0).map((_, index) => {
659
+ return " ".repeat(index);
660
+ });
661
+ var maxCachedValues = 200;
662
+ var cachedBreakLinesWithSpaces = {
663
+ " ": {
664
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
665
+ return "\n" + " ".repeat(index);
666
+ }),
667
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
668
+ return "\r" + " ".repeat(index);
669
+ }),
670
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
671
+ return "\r\n" + " ".repeat(index);
672
+ })
673
+ },
674
+ " ": {
675
+ "\n": new Array(maxCachedValues).fill(0).map((_, index) => {
676
+ return "\n" + " ".repeat(index);
677
+ }),
678
+ "\r": new Array(maxCachedValues).fill(0).map((_, index) => {
679
+ return "\r" + " ".repeat(index);
680
+ }),
681
+ "\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
682
+ return "\r\n" + " ".repeat(index);
683
+ })
684
+ }
685
+ };
686
+
687
+ // node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
688
+ var ParseOptions;
689
+ (function(ParseOptions2) {
690
+ ParseOptions2.DEFAULT = {
691
+ allowTrailingComma: false
692
+ };
693
+ })(ParseOptions || (ParseOptions = {}));
694
+ function parse(text, errors = [], options = ParseOptions.DEFAULT) {
695
+ let currentProperty = null;
696
+ let currentParent = [];
697
+ const previousParents = [];
698
+ function onValue(value) {
699
+ if (Array.isArray(currentParent)) {
700
+ currentParent.push(value);
701
+ } else if (currentProperty !== null) {
702
+ currentParent[currentProperty] = value;
703
+ }
704
+ }
705
+ const visitor = {
706
+ onObjectBegin: () => {
707
+ const object = {};
708
+ onValue(object);
709
+ previousParents.push(currentParent);
710
+ currentParent = object;
711
+ currentProperty = null;
712
+ },
713
+ onObjectProperty: (name) => {
714
+ currentProperty = name;
715
+ },
716
+ onObjectEnd: () => {
717
+ currentParent = previousParents.pop();
718
+ },
719
+ onArrayBegin: () => {
720
+ const array = [];
721
+ onValue(array);
722
+ previousParents.push(currentParent);
723
+ currentParent = array;
724
+ currentProperty = null;
725
+ },
726
+ onArrayEnd: () => {
727
+ currentParent = previousParents.pop();
728
+ },
729
+ onLiteralValue: onValue,
730
+ onError: (error, offset, length) => {
731
+ errors.push({ error, offset, length });
732
+ }
733
+ };
734
+ visit(text, visitor, options);
735
+ return currentParent[0];
736
+ }
737
+ function visit(text, visitor, options = ParseOptions.DEFAULT) {
738
+ const _scanner = createScanner(text, false);
739
+ const _jsonPath = [];
740
+ let suppressedCallbacks = 0;
741
+ function toNoArgVisit(visitFunction) {
742
+ return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
743
+ }
744
+ function toOneArgVisit(visitFunction) {
745
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
746
+ }
747
+ function toOneArgVisitWithPath(visitFunction) {
748
+ return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
749
+ }
750
+ function toBeginVisit(visitFunction) {
751
+ return visitFunction ? () => {
752
+ if (suppressedCallbacks > 0) {
753
+ suppressedCallbacks++;
754
+ } else {
755
+ let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
756
+ if (cbReturn === false) {
757
+ suppressedCallbacks = 1;
758
+ }
759
+ }
760
+ } : () => true;
761
+ }
762
+ function toEndVisit(visitFunction) {
763
+ return visitFunction ? () => {
764
+ if (suppressedCallbacks > 0) {
765
+ suppressedCallbacks--;
766
+ }
767
+ if (suppressedCallbacks === 0) {
768
+ visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
769
+ }
770
+ } : () => true;
771
+ }
772
+ const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
773
+ const disallowComments = options && options.disallowComments;
774
+ const allowTrailingComma = options && options.allowTrailingComma;
775
+ function scanNext() {
776
+ while (true) {
777
+ const token = _scanner.scan();
778
+ switch (_scanner.getTokenError()) {
779
+ case 4:
780
+ handleError(
781
+ 14
782
+ /* ParseErrorCode.InvalidUnicode */
783
+ );
784
+ break;
785
+ case 5:
786
+ handleError(
787
+ 15
788
+ /* ParseErrorCode.InvalidEscapeCharacter */
789
+ );
790
+ break;
791
+ case 3:
792
+ handleError(
793
+ 13
794
+ /* ParseErrorCode.UnexpectedEndOfNumber */
795
+ );
796
+ break;
797
+ case 1:
798
+ if (!disallowComments) {
799
+ handleError(
800
+ 11
801
+ /* ParseErrorCode.UnexpectedEndOfComment */
802
+ );
803
+ }
804
+ break;
805
+ case 2:
806
+ handleError(
807
+ 12
808
+ /* ParseErrorCode.UnexpectedEndOfString */
809
+ );
810
+ break;
811
+ case 6:
812
+ handleError(
813
+ 16
814
+ /* ParseErrorCode.InvalidCharacter */
815
+ );
816
+ break;
817
+ }
818
+ switch (token) {
819
+ case 12:
820
+ case 13:
821
+ if (disallowComments) {
822
+ handleError(
823
+ 10
824
+ /* ParseErrorCode.InvalidCommentToken */
825
+ );
826
+ } else {
827
+ onComment();
828
+ }
829
+ break;
830
+ case 16:
831
+ handleError(
832
+ 1
833
+ /* ParseErrorCode.InvalidSymbol */
834
+ );
835
+ break;
836
+ case 15:
837
+ case 14:
838
+ break;
839
+ default:
840
+ return token;
841
+ }
842
+ }
843
+ }
844
+ function handleError(error, skipUntilAfter = [], skipUntil = []) {
845
+ onError(error);
846
+ if (skipUntilAfter.length + skipUntil.length > 0) {
847
+ let token = _scanner.getToken();
848
+ while (token !== 17) {
849
+ if (skipUntilAfter.indexOf(token) !== -1) {
850
+ scanNext();
851
+ break;
852
+ } else if (skipUntil.indexOf(token) !== -1) {
853
+ break;
854
+ }
855
+ token = scanNext();
856
+ }
857
+ }
858
+ }
859
+ function parseString(isValue) {
860
+ const value = _scanner.getTokenValue();
861
+ if (isValue) {
862
+ onLiteralValue(value);
863
+ } else {
864
+ onObjectProperty(value);
865
+ _jsonPath.push(value);
866
+ }
867
+ scanNext();
868
+ return true;
869
+ }
870
+ function parseLiteral() {
871
+ switch (_scanner.getToken()) {
872
+ case 11:
873
+ const tokenValue = _scanner.getTokenValue();
874
+ let value = Number(tokenValue);
875
+ if (isNaN(value)) {
876
+ handleError(
877
+ 2
878
+ /* ParseErrorCode.InvalidNumberFormat */
879
+ );
880
+ value = 0;
881
+ }
882
+ onLiteralValue(value);
883
+ break;
884
+ case 7:
885
+ onLiteralValue(null);
886
+ break;
887
+ case 8:
888
+ onLiteralValue(true);
889
+ break;
890
+ case 9:
891
+ onLiteralValue(false);
892
+ break;
893
+ default:
894
+ return false;
895
+ }
896
+ scanNext();
897
+ return true;
898
+ }
899
+ function parseProperty() {
900
+ if (_scanner.getToken() !== 10) {
901
+ handleError(3, [], [
902
+ 2,
903
+ 5
904
+ /* SyntaxKind.CommaToken */
905
+ ]);
906
+ return false;
907
+ }
908
+ parseString(false);
909
+ if (_scanner.getToken() === 6) {
910
+ onSeparator(":");
911
+ scanNext();
912
+ if (!parseValue()) {
913
+ handleError(4, [], [
914
+ 2,
915
+ 5
916
+ /* SyntaxKind.CommaToken */
917
+ ]);
918
+ }
919
+ } else {
920
+ handleError(5, [], [
921
+ 2,
922
+ 5
923
+ /* SyntaxKind.CommaToken */
924
+ ]);
925
+ }
926
+ _jsonPath.pop();
927
+ return true;
928
+ }
929
+ function parseObject() {
930
+ onObjectBegin();
931
+ scanNext();
932
+ let needsComma = false;
933
+ while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
934
+ if (_scanner.getToken() === 5) {
935
+ if (!needsComma) {
936
+ handleError(4, [], []);
937
+ }
938
+ onSeparator(",");
939
+ scanNext();
940
+ if (_scanner.getToken() === 2 && allowTrailingComma) {
941
+ break;
942
+ }
943
+ } else if (needsComma) {
944
+ handleError(6, [], []);
945
+ }
946
+ if (!parseProperty()) {
947
+ handleError(4, [], [
948
+ 2,
949
+ 5
950
+ /* SyntaxKind.CommaToken */
951
+ ]);
952
+ }
953
+ needsComma = true;
954
+ }
955
+ onObjectEnd();
956
+ if (_scanner.getToken() !== 2) {
957
+ handleError(7, [
958
+ 2
959
+ /* SyntaxKind.CloseBraceToken */
960
+ ], []);
961
+ } else {
962
+ scanNext();
963
+ }
964
+ return true;
965
+ }
966
+ function parseArray() {
967
+ onArrayBegin();
968
+ scanNext();
969
+ let isFirstElement = true;
970
+ let needsComma = false;
971
+ while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
972
+ if (_scanner.getToken() === 5) {
973
+ if (!needsComma) {
974
+ handleError(4, [], []);
975
+ }
976
+ onSeparator(",");
977
+ scanNext();
978
+ if (_scanner.getToken() === 4 && allowTrailingComma) {
979
+ break;
980
+ }
981
+ } else if (needsComma) {
982
+ handleError(6, [], []);
983
+ }
984
+ if (isFirstElement) {
985
+ _jsonPath.push(0);
986
+ isFirstElement = false;
987
+ } else {
988
+ _jsonPath[_jsonPath.length - 1]++;
989
+ }
990
+ if (!parseValue()) {
991
+ handleError(4, [], [
992
+ 4,
993
+ 5
994
+ /* SyntaxKind.CommaToken */
995
+ ]);
996
+ }
997
+ needsComma = true;
998
+ }
999
+ onArrayEnd();
1000
+ if (!isFirstElement) {
1001
+ _jsonPath.pop();
1002
+ }
1003
+ if (_scanner.getToken() !== 4) {
1004
+ handleError(8, [
1005
+ 4
1006
+ /* SyntaxKind.CloseBracketToken */
1007
+ ], []);
1008
+ } else {
1009
+ scanNext();
1010
+ }
1011
+ return true;
1012
+ }
1013
+ function parseValue() {
1014
+ switch (_scanner.getToken()) {
1015
+ case 3:
1016
+ return parseArray();
1017
+ case 1:
1018
+ return parseObject();
1019
+ case 10:
1020
+ return parseString(true);
1021
+ default:
1022
+ return parseLiteral();
1023
+ }
1024
+ }
1025
+ scanNext();
1026
+ if (_scanner.getToken() === 17) {
1027
+ if (options.allowEmptyContent) {
1028
+ return true;
1029
+ }
1030
+ handleError(4, [], []);
1031
+ return false;
1032
+ }
1033
+ if (!parseValue()) {
1034
+ handleError(4, [], []);
1035
+ return false;
1036
+ }
1037
+ if (_scanner.getToken() !== 17) {
1038
+ handleError(9, [], []);
1039
+ }
1040
+ return true;
1041
+ }
1042
+
1043
+ // node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
1044
+ var ScanError;
1045
+ (function(ScanError2) {
1046
+ ScanError2[ScanError2["None"] = 0] = "None";
1047
+ ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
1048
+ ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
1049
+ ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
1050
+ ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
1051
+ ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
1052
+ ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
1053
+ })(ScanError || (ScanError = {}));
1054
+ var SyntaxKind;
1055
+ (function(SyntaxKind2) {
1056
+ SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
1057
+ SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
1058
+ SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
1059
+ SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
1060
+ SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
1061
+ SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
1062
+ SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
1063
+ SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
1064
+ SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
1065
+ SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
1066
+ SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
1067
+ SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
1068
+ SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
1069
+ SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
1070
+ SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
1071
+ SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
1072
+ SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
1073
+ })(SyntaxKind || (SyntaxKind = {}));
1074
+ var parse2 = parse;
1075
+ var ParseErrorCode;
1076
+ (function(ParseErrorCode2) {
1077
+ ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
1078
+ ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
1079
+ ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
1080
+ ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
1081
+ ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
1082
+ ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
1083
+ ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
1084
+ ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
1085
+ ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
1086
+ ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
1087
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
1088
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
1089
+ ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
1090
+ ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
1091
+ ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
1092
+ ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
1093
+ })(ParseErrorCode || (ParseErrorCode = {}));
1094
+ function printParseErrorCode(code) {
1095
+ switch (code) {
1096
+ case 1:
1097
+ return "InvalidSymbol";
1098
+ case 2:
1099
+ return "InvalidNumberFormat";
1100
+ case 3:
1101
+ return "PropertyNameExpected";
1102
+ case 4:
1103
+ return "ValueExpected";
1104
+ case 5:
1105
+ return "ColonExpected";
1106
+ case 6:
1107
+ return "CommaExpected";
1108
+ case 7:
1109
+ return "CloseBraceExpected";
1110
+ case 8:
1111
+ return "CloseBracketExpected";
1112
+ case 9:
1113
+ return "EndOfFileExpected";
1114
+ case 10:
1115
+ return "InvalidCommentToken";
1116
+ case 11:
1117
+ return "UnexpectedEndOfComment";
1118
+ case 12:
1119
+ return "UnexpectedEndOfString";
1120
+ case 13:
1121
+ return "UnexpectedEndOfNumber";
1122
+ case 14:
1123
+ return "InvalidUnicode";
1124
+ case 15:
1125
+ return "InvalidEscapeCharacter";
1126
+ case 16:
1127
+ return "InvalidCharacter";
1128
+ }
1129
+ return "<unknown ParseErrorCode>";
1130
+ }
1131
+
1132
+ // src/core/store.ts
1133
+ function readJson(path, fallback) {
1134
+ if (!(0, import_node_fs2.existsSync)(path)) return fallback;
1135
+ try {
1136
+ return JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
1137
+ } catch {
1138
+ return fallback;
1139
+ }
1140
+ }
1141
+ var SettingsParseError = class extends Error {
1142
+ };
1143
+ function readJsonOwnedByUser(path, fallback) {
1144
+ if (!(0, import_node_fs2.existsSync)(path)) return fallback;
1145
+ const text = (0, import_node_fs2.readFileSync)(path, "utf8");
1146
+ const errors = [];
1147
+ const parsed = parse2(text, errors, { allowTrailingComma: true });
1148
+ if (errors.length > 0) {
1149
+ const first = errors[0];
1150
+ throw new SettingsParseError(
1151
+ `${path} exists but could not be parsed as JSON, even allowing for JSONC comments/trailing commas -- refusing to overwrite it. (${printParseErrorCode(first.error)} at offset ${first.offset})`
1152
+ );
1153
+ }
1154
+ return parsed;
1155
+ }
1156
+ function writeJsonAtomic(path, value) {
1157
+ (0, import_node_fs2.mkdirSync)((0, import_node_path3.dirname)(path), { recursive: true });
1158
+ const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
1159
+ (0, import_node_fs2.writeFileSync)(tmp, JSON.stringify(value), "utf8");
1160
+ try {
1161
+ (0, import_node_fs2.renameSync)(tmp, path);
1162
+ } catch {
1163
+ (0, import_node_fs2.writeFileSync)(path, JSON.stringify(value), "utf8");
1164
+ try {
1165
+ (0, import_node_fs2.unlinkSync)(tmp);
1166
+ } catch {
1167
+ }
1168
+ }
1169
+ }
1170
+
1171
+ // src/core/cache.ts
1172
+ var _TERMINAL_HEARTBEAT_STALE_MS = 5e3;
1173
+ function _isValidEntry(entry) {
1174
+ return typeof entry === "object" && entry !== null && Array.isArray(entry.ads) && Array.isArray(entry.perAd) && typeof entry.currentIndex === "number";
1175
+ }
1176
+ function isTerminalActive() {
1177
+ const heartbeat = readJson(
1178
+ terminalHeartbeatPath(),
1179
+ null
1180
+ );
1181
+ if (!heartbeat) return false;
1182
+ return Date.now() - heartbeat.ts < _TERMINAL_HEARTBEAT_STALE_MS;
1183
+ }
1184
+ function putAd(placementId, ads) {
1185
+ const cache = readJson(adCachePath(), {});
1186
+ const entry = {
1187
+ ads,
1188
+ currentIndex: 0,
1189
+ rotationStartedAt: Date.now(),
1190
+ perAd: ads.map(() => ({ firstSeenAt: null, impressionFiredAt: null }))
1191
+ };
1192
+ cache[placementId] = entry;
1193
+ writeJsonAtomic(adCachePath(), cache);
1194
+ debugLog("putAd", { placementId, adCount: ads.length });
1195
+ return entry;
1196
+ }
1197
+ function startPendingTurn(pending) {
1198
+ writeJsonAtomic(pendingTurnPath(), pending);
1199
+ }
1200
+ function takePendingTurn() {
1201
+ const pending = readJson(pendingTurnPath(), null);
1202
+ if (pending) writeJsonAtomic(pendingTurnPath(), null);
1203
+ return pending;
1204
+ }
1205
+ async function settlePendingTurn() {
1206
+ const pending = takePendingTurn();
1207
+ if (!pending) {
1208
+ debugLog("settlePendingTurn: nothing pending");
1209
+ return;
1210
+ }
1211
+ const dwellMs = Date.now() - pending.startedAt;
1212
+ if (dwellMs < DWELL_THRESHOLD_MS) {
1213
+ debugLog("settlePendingTurn: turn too short", {
1214
+ dwellMs,
1215
+ threshold: DWELL_THRESHOLD_MS
1216
+ });
1217
+ return;
1218
+ }
1219
+ const cache = readJson(adCachePath(), {});
1220
+ let changed = false;
1221
+ const toBeacon = [];
1222
+ const decisions = {};
1223
+ for (const placementId of pending.placementIds) {
1224
+ const entry = cache[placementId];
1225
+ if (!_isValidEntry(entry) || entry.ads.length === 0) {
1226
+ decisions[placementId] = "no cached rotation set";
1227
+ continue;
1228
+ }
1229
+ const dwell = entry.perAd[entry.currentIndex];
1230
+ if (!dwell || dwell.impressionFiredAt) {
1231
+ decisions[placementId] = "already fired";
1232
+ continue;
1233
+ }
1234
+ dwell.impressionFiredAt = Date.now();
1235
+ changed = true;
1236
+ const impUrl = entry.ads[entry.currentIndex].impUrl;
1237
+ if (impUrl) toBeacon.push(impUrl);
1238
+ decisions[placementId] = "fired";
1239
+ }
1240
+ debugLog("settlePendingTurn", {
1241
+ placementIds: pending.placementIds,
1242
+ dwellMs,
1243
+ decisions
1244
+ });
1245
+ if (changed) writeJsonAtomic(adCachePath(), cache);
1246
+ await Promise.all(toBeacon.map((url) => beacon(url)));
1247
+ }
1248
+
1249
+ // src/core/config.ts
1250
+ var import_node_crypto2 = require("crypto");
1251
+ function _read() {
1252
+ return readJson(runtimeConfigPath(), {});
1253
+ }
1254
+ function toSessionId(claudeSessionId) {
1255
+ return claudeSessionId ?? (0, import_node_crypto2.randomUUID)();
1256
+ }
1257
+ function readRuntimeConfig() {
1258
+ const stored = _read();
1259
+ if (!stored.apiKey || !stored.apiUrl || !stored.installId) return null;
1260
+ return {
1261
+ apiKey: stored.apiKey,
1262
+ apiUrl: stored.apiUrl,
1263
+ webUrl: stored.webUrl ?? DEFAULT_WEB_URL,
1264
+ enabled: stored.enabled ?? true,
1265
+ installId: stored.installId,
1266
+ webviewPatchedEditors: stored.webviewPatchedEditors ?? []
1267
+ };
1268
+ }
1269
+
1270
+ // src/core/webviewPatch.ts
1271
+ var import_node_fs3 = require("fs");
1272
+ var import_node_os2 = require("os");
1273
+ var import_node_path4 = require("path");
1274
+ var _MARKER = "__kiliSpinnerLinkPatch";
1275
+ var _ANCHORS = [
1276
+ {
1277
+ version: "2.1.258",
1278
+ find: 'function od0($){if(!$)return KH1;if($.mode==="replace")return $.verbs.length>0?$.verbs:KH1;return[...KH1,...$.verbs]}function s$0({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=C2(()=>od0(X),[X]),Z=C2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=J1(0),[z,U]=J1(()=>mi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%a$0.length)},120);return()=>clearInterval(W)},[]),Vy(()=>{U(mi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(Y==="compacting")H="Compacting";let B=td0(H+"...",Z+3);return E("div",{className:gi.container,"data-permission-mode":J,children:[D("span",{"aria-hidden":"true",className:gi.icon,style:{fontSize:`${$}px`},children:a$0[G]}),D("span",{"aria-hidden":"true",className:gi.text,children:B}),D("span",{className:YN.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}',
1279
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function od0($){if(!$)return KH1;if($.mode==="replace")return $.verbs.length>0?$.verbs:KH1;return[...KH1,...$.verbs]}function s$0({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=C2(()=>{${_MARKER}.clear();return od0(X).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[X]),Z=C2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=J1(0),[z,U]=J1(()=>mi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%a$0.length)},120);return()=>clearInterval(W)},[]),Vy(()=>{U(mi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(!Q.includes(H))H=Q[0];if(Y==="compacting")H="Compacting";let B=H+"...",K=${_MARKER}.get(H);_kiliLog({labels:Q,width:Z,drawn:H,wasStale:!Q.includes(z),linked:!!K,hasLogo:!!(K&&K.logo)});return E("div",{className:gi.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":J,children:[D("span",{"aria-hidden":"true",className:gi.icon,style:{fontSize:\`\${$}px\`},children:a$0[G]}),K?D("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},"aria-hidden":"true",className:gi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?D("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,B]}):D("span",{"aria-hidden":"true",className:gi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:B}),D("span",{className:YN.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}`
1280
+ },
1281
+ {
1282
+ version: "2.1.251",
1283
+ find: 'function ac0($){if(!$)return TV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:TV1;return[...TV1,...$.verbs]}function L30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=t2(()=>ac0(X),[X]),Z=t2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Ki(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%R30.length)},120);return()=>clearInterval(W)},[]),sk(()=>{U(Ki(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(Y==="compacting")H="Compacting";let B=rc0(H+"...",Z+3);return E("div",{className:Fi.container,"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Fi.icon,style:{fontSize:`${$}px`},children:R30[G]}),j("span",{"aria-hidden":"true",className:Fi.text,children:B}),j("span",{className:aO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}',
1284
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function ac0($){if(!$)return TV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:TV1;return[...TV1,...$.verbs]}function L30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=t2(()=>{${_MARKER}.clear();return ac0(X).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[X]),Z=t2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Ki(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%R30.length)},120);return()=>clearInterval(W)},[]),sk(()=>{U(Ki(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(!Q.includes(H))H=Q[0];if(Y==="compacting")H="Compacting";let B=H+"...",K=${_MARKER}.get(H);_kiliLog({labels:Q,width:Z,drawn:H,wasStale:!Q.includes(z),linked:!!K,hasLogo:!!(K&&K.logo)});return E("div",{className:Fi.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Fi.icon,style:{fontSize:\`\${$}px\`},children:R30[G]}),K?j("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},"aria-hidden":"true",className:Fi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?j("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,B]}):j("span",{"aria-hidden":"true",className:Fi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:B}),j("span",{className:aO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}`
1285
+ },
1286
+ {
1287
+ version: "2.1.250",
1288
+ find: 'function cc0($){if(!$)return NV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:NV1;return[...NV1,...$.verbs]}function R30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=o2(()=>cc0(X),[X]),Z=o2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Ki(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%w30.length)},120);return()=>clearInterval(W)},[]),rk(()=>{U(Ki(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(Y==="compacting")H="Compacting";let B=lc0(H+"...",Z+3);return E("div",{className:Fi.container,"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Fi.icon,style:{fontSize:`${$}px`},children:w30[G]}),j("span",{"aria-hidden":"true",className:Fi.text,children:B}),j("span",{className:dO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}',
1289
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function cc0($){if(!$)return NV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:NV1;return[...NV1,...$.verbs]}function R30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=o2(()=>{${_MARKER}.clear();return cc0(X).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[X]),Z=o2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Ki(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%w30.length)},120);return()=>clearInterval(W)},[]),rk(()=>{U(Ki(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(!Q.includes(H))H=Q[0];if(Y==="compacting")H="Compacting";let B=H+"...",K=${_MARKER}.get(H);_kiliLog({labels:Q,width:Z,drawn:H,wasStale:!Q.includes(z),linked:!!K,hasLogo:!!(K&&K.logo)});return E("div",{className:Fi.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Fi.icon,style:{fontSize:\`\${$}px\`},children:w30[G]}),K?j("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},"aria-hidden":"true",className:Fi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?j("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,B]}):j("span",{"aria-hidden":"true",className:Fi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:B}),j("span",{className:dO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}`
1290
+ },
1291
+ {
1292
+ version: "2.1.247",
1293
+ find: 'function Ec0($){if(!$)return RV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:RV1;return[...RV1,...$.verbs]}function w30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=o2(()=>Ec0(X),[X]),Z=o2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Fi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%M30.length)},120);return()=>clearInterval(W)},[]),rk(()=>{U(Fi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(Y==="compacting")H="Compacting";let B=Ic0(H+"...",Z+3);return E("div",{className:Wi.container,"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Wi.icon,style:{fontSize:`${$}px`},children:M30[G]}),j("span",{"aria-hidden":"true",className:Wi.text,children:B}),j("span",{className:dO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}',
1294
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function Ec0($){if(!$)return RV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:RV1;return[...RV1,...$.verbs]}function w30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=o2(()=>{${_MARKER}.clear();return Ec0(X).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[X]),Z=o2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Fi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%M30.length)},120);return()=>clearInterval(W)},[]),rk(()=>{U(Fi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(!Q.includes(H))H=Q[0];if(Y==="compacting")H="Compacting";let B=H+"...",K=${_MARKER}.get(H);_kiliLog({labels:Q,width:Z,drawn:H,wasStale:!Q.includes(z),linked:!!K,hasLogo:!!(K&&K.logo)});return E("div",{className:Wi.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Wi.icon,style:{fontSize:\`\${$}px\`},children:M30[G]}),K?j("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},"aria-hidden":"true",className:Wi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?j("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,B]}):j("span",{"aria-hidden":"true",className:Wi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:B}),j("span",{className:dO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}`
1295
+ },
1296
+ {
1297
+ version: "2.1.246",
1298
+ find: 'function Tc0($){if(!$)return RV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:RV1;return[...RV1,...$.verbs]}function _30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=i2(()=>Tc0(X),[X]),Z=i2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Fi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%P30.length)},120);return()=>clearInterval(W)},[]),rk(()=>{U(Fi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(Y==="compacting")H="Compacting";let B=Ec0(H+"...",Z+3);return E("div",{className:Wi.container,"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Wi.icon,style:{fontSize:`${$}px`},children:P30[G]}),j("span",{"aria-hidden":"true",className:Wi.text,children:B}),j("span",{className:dO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}',
1299
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function Tc0($){if(!$)return RV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:RV1;return[...RV1,...$.verbs]}function _30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=i2(()=>{${_MARKER}.clear();return Tc0(X).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[X]),Z=i2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Fi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%P30.length)},120);return()=>clearInterval(W)},[]),rk(()=>{U(Fi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(!Q.includes(H))H=Q[0];if(Y==="compacting")H="Compacting";let B=H+"...",K=${_MARKER}.get(H);_kiliLog({labels:Q,width:Z,drawn:H,wasStale:!Q.includes(z),linked:!!K,hasLogo:!!(K&&K.logo)});return E("div",{className:Wi.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Wi.icon,style:{fontSize:\`\${$}px\`},children:P30[G]}),K?j("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},"aria-hidden":"true",className:Wi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?j("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,B]}):j("span",{"aria-hidden":"true",className:Wi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:B}),j("span",{className:dO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}`
1300
+ },
1301
+ {
1302
+ version: "2.1.245",
1303
+ find: 'function Lc0($){if(!$)return wV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:wV1;return[...wV1,...$.verbs]}function M30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=i2(()=>Lc0(X),[X]),Z=i2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Bi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%j30.length)},120);return()=>clearInterval(W)},[]),dk(()=>{U(Bi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(Y==="compacting")H="Compacting";let B=Tc0(H+"...",Z+3);return E("div",{className:Hi.container,"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Hi.icon,style:{fontSize:`${$}px`},children:j30[G]}),j("span",{"aria-hidden":"true",className:Hi.text,children:B}),j("span",{className:lO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}',
1304
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function Lc0($){if(!$)return wV1;if($.mode==="replace")return $.verbs.length>0?$.verbs:wV1;return[...wV1,...$.verbs]}function M30({size:$=16,permissionMode:J,status:Y,spinnerVerbsConfig:X}){let Q=i2(()=>{${_MARKER}.clear();return Lc0(X).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[X]),Z=i2(()=>Math.max(...Q.map((W)=>W.length)),[Q]),[G,q]=Y1(0),[z,U]=Y1(()=>Bi(Q));Z1(()=>{let W=setInterval(()=>{q((F)=>(F+1)%j30.length)},120);return()=>clearInterval(W)},[]),dk(()=>{U(Bi(Q))},(W)=>{let F=[2000,3000,5000];return W<F.length?F[W]:5000});let H=z;if(!Q.includes(H))H=Q[0];if(Y==="compacting")H="Compacting";let B=H+"...",K=${_MARKER}.get(H);_kiliLog({labels:Q,width:Z,drawn:H,wasStale:!Q.includes(z),linked:!!K,hasLogo:!!(K&&K.logo)});return E("div",{className:Hi.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":J,children:[j("span",{"aria-hidden":"true",className:Hi.icon,style:{fontSize:\`\${$}px\`},children:j30[G]}),K?j("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},"aria-hidden":"true",className:Hi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?j("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,B]}):j("span",{"aria-hidden":"true",className:Hi.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:B}),j("span",{className:lO.visuallyHidden,children:Y==="compacting"?"Compacting conversation":"Claude is working"})]})}`
1305
+ },
1306
+ {
1307
+ version: "2.1.232",
1308
+ find: 'function cBt(e){if(!e)return r0e;if(e.mode==="replace")return e.verbs.length>0?e.verbs:r0e;return[...r0e,...e.verbs]}function Mot({size:e=16,permissionMode:t,status:i,spinnerVerbsConfig:n}){let o=Jn(()=>cBt(n),[n]),r=Jn(()=>Math.max(...o.map((p)=>p.length)),[o]),[s,a]=ne(0),[l,c]=ne(()=>LG(o));se(()=>{let p=setInterval(()=>{a((f)=>(f+1)%Rot.length)},120);return()=>clearInterval(p)},[]),o0e(()=>{c(LG(o))},(p)=>{let f=[2000,3000,5000];return p<f.length?f[p]:5000});let u=l;if(i==="compacting")u="Compacting";let h=dBt(u+"...",r+3);return I("div",{className:kG.container,"data-permission-mode":t,children:[b("span",{className:kG.icon,style:{fontSize:`${e}px`},children:Rot[s]}),b("span",{className:kG.text,children:h})]})}',
1309
+ replace: `var ${_MARKER}=new Map();var __kiliLastLog="";var __kiliLastGeom="";function _kiliLog(o){try{var s=JSON.stringify(o);if(s===__kiliLastLog)return;__kiliLastLog=s;console.log("[kili]",o)}catch(e){}}function _kiliParseLink(raw){let i=raw.indexOf("\\u0001");if(i<0)return null;let rest=raw.slice(i+1);let j2=rest.indexOf("\\u0001");return j2<0?{label:raw.slice(0,i),url:rest,logo:null}:{label:raw.slice(0,i),url:rest.slice(0,j2),logo:rest.slice(j2+1)}}function cBt(e){if(!e)return r0e;if(e.mode==="replace")return e.verbs.length>0?e.verbs:r0e;return[...r0e,...e.verbs]}function Mot({size:e=16,permissionMode:t,status:i,spinnerVerbsConfig:n}){let o=Jn(()=>{${_MARKER}.clear();return cBt(n).map((raw)=>{let p=_kiliParseLink(raw);if(p){${_MARKER}.set(p.label,{url:p.url,logo:p.logo});return p.label}return raw})},[n]),r=Jn(()=>Math.max(...o.map((p)=>p.length)),[o]),[s,a]=ne(0),[l,c]=ne(()=>LG(o));se(()=>{let p=setInterval(()=>{a((f)=>(f+1)%Rot.length)},120);return()=>clearInterval(p)},[]),o0e(()=>{c(LG(o))},(p)=>{let f=[2000,3000,5000];return p<f.length?f[p]:5000});let u=l;if(!o.includes(u))u=o[0];if(i==="compacting")u="Compacting";let h=u+"...",K=${_MARKER}.get(u);_kiliLog({labels:o,width:r,drawn:u,wasStale:!o.includes(l),linked:!!K,hasLogo:!!(K&&K.logo)});return I("div",{className:kG.container,style:{overflow:"visible",maxWidth:"none",width:"auto",flexWrap:"nowrap"},"data-permission-mode":t,children:[b("span",{className:kG.icon,style:{fontSize:\`\${e}px\`},children:Rot[s]}),K?b("a",{ref:(el)=>{if(!el)return;try{var sel=[],q=el.parentElement;for(var i=0;i<8&&q;i++){var qr=q.getBoundingClientRect();if(qr.height>80)break;var cn=(typeof q.className==="string"?q.className:"").trim();if(cn)sel.push("."+cn.split(/\\s+/).join("."));q=q.parentElement}if(sel.length){var id="__kiliUnclip",st=document.getElementById(id);if(!st){st=document.createElement("style");st.id=id;document.head.appendChild(st)}var css=sel.join(",")+"{overflow:visible!important;max-width:none!important;min-width:0!important;flex-shrink:0!important;text-overflow:clip!important;white-space:nowrap!important;animation:none!important;transition:none!important}";if(st.textContent!==css)st.textContent=css}setTimeout(function(){try{var o=[],n=el;for(var k=0;k<8&&n;k++){var c=getComputedStyle(n),r=n.getBoundingClientRect();o.push(k+":"+n.tagName+" w="+Math.round(r.width)+" h="+Math.round(r.height)+" sw="+n.scrollWidth+" tlen="+((n.textContent||"").length)+" anim="+c.animationName+" ovf="+c.overflow);n=n.parentElement}var g=o.join(" | ");if(g!==__kiliLastGeom){__kiliLastGeom=g;console.log("[kili-geom]",g)}}catch(e){}},50)}catch(e){}},className:kG.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},href:K.url,target:"_blank",rel:"noopener noreferrer",children:[K.logo?b("img",{src:K.logo,alt:"",style:{width:"14px",height:"14px",borderRadius:"3px",objectFit:"cover",verticalAlign:"middle",marginRight:"4px"}}):null,h]}):b("span",{className:kG.text,style:{color:"#22c55e",whiteSpace:"nowrap",overflow:"visible",textOverflow:"clip",maxWidth:"none",flexShrink:0,width:"auto",animation:"none",transition:"none"},children:h})]})}`
1310
+ }
1311
+ ];
1312
+ var _LINK_SEP = String.fromCharCode(1);
1313
+ function encodeLinkedVerb(label, url, logoUrl) {
1314
+ return logoUrl ? `${label}${_LINK_SEP}${url}${_LINK_SEP}${logoUrl}` : `${label}${_LINK_SEP}${url}`;
1315
+ }
1316
+ var _PATCH_VERSION = "9";
1317
+ var _VERSION_TAG = `${_MARKER}_v${_PATCH_VERSION}`;
1318
+ function _parseVersion(folderName) {
1319
+ const m = folderName.match(/^anthropic\.claude-code-(\d+)\.(\d+)\.(\d+)/);
1320
+ if (!m) return null;
1321
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
1322
+ }
1323
+ function findClaudeCodeWebviewFiles() {
1324
+ const home = (0, import_node_os2.homedir)();
1325
+ const extensionRoots = [
1326
+ { editorFolder: "Cursor", root: (0, import_node_path4.join)(home, ".cursor", "extensions") },
1327
+ { editorFolder: "Code", root: (0, import_node_path4.join)(home, ".vscode", "extensions") },
1328
+ {
1329
+ editorFolder: "VSCodium",
1330
+ root: (0, import_node_path4.join)(home, ".vscode-oss", "extensions")
1331
+ }
1332
+ ];
1333
+ const found = [];
1334
+ for (const { editorFolder, root } of extensionRoots) {
1335
+ if (!(0, import_node_fs3.existsSync)(root)) continue;
1336
+ let entries = [];
1337
+ try {
1338
+ entries = (0, import_node_fs3.readdirSync)(root);
1339
+ } catch {
1340
+ continue;
1341
+ }
1342
+ const candidates = [];
1343
+ for (const entry of entries) {
1344
+ if (!entry.startsWith("anthropic.claude-code-")) continue;
1345
+ const filePath = (0, import_node_path4.join)(root, entry, "webview", "index.js");
1346
+ if (!(0, import_node_fs3.existsSync)(filePath)) continue;
1347
+ let mtimeMs = 0;
1348
+ try {
1349
+ mtimeMs = (0, import_node_fs3.statSync)(filePath).mtimeMs;
1350
+ } catch {
1351
+ }
1352
+ candidates.push({ filePath, version: _parseVersion(entry), mtimeMs });
1353
+ }
1354
+ if (candidates.length === 0) continue;
1355
+ const newest = candidates.reduce((best, c) => {
1356
+ if (c.version && best.version) {
1357
+ for (let i = 0; i < 3; i++) {
1358
+ if (c.version[i] !== best.version[i]) {
1359
+ return c.version[i] > best.version[i] ? c : best;
1360
+ }
1361
+ }
1362
+ return c.mtimeMs > best.mtimeMs ? c : best;
1363
+ }
1364
+ if (c.version && !best.version) return c;
1365
+ if (!c.version && best.version) return best;
1366
+ return c.mtimeMs > best.mtimeMs ? c : best;
1367
+ });
1368
+ found.push({ editorFolder, filePath: newest.filePath });
1369
+ }
1370
+ return found;
1371
+ }
1372
+ function isCurrentlyPatched(editorFolder) {
1373
+ return findClaudeCodeWebviewFiles().filter((f) => f.editorFolder === editorFolder).some((f) => {
1374
+ try {
1375
+ return (0, import_node_fs3.readFileSync)(f.filePath, "utf8").includes(_VERSION_TAG);
1376
+ } catch {
1377
+ return false;
1378
+ }
1379
+ });
1380
+ }
1381
+
1382
+ // src/core/copy.ts
1383
+ var _ESC = String.fromCharCode(27);
1384
+ var _DIM = `${_ESC}[2m`;
1385
+ var _RESET = `${_ESC}[0m`;
1386
+ function adNameLine(ad) {
1387
+ const name = ad.title?.trim();
1388
+ const body = ad.adText.trim();
1389
+ return name ? `${name}: ${body}` : body;
1390
+ }
1391
+ function truncate(text, maxLength) {
1392
+ if (text.length <= maxLength) return text;
1393
+ const hardCut = text.slice(0, maxLength - 1);
1394
+ const lastSpace = hardCut.lastIndexOf(" ");
1395
+ const wastedByBackingOff = hardCut.length - lastSpace;
1396
+ const cut = lastSpace > 0 && wastedByBackingOff <= 6 ? hardCut.slice(0, lastSpace) : hardCut;
1397
+ return `${cut.trimEnd()}\u2026`;
1398
+ }
1399
+ var _SPINNER_MAX = 60;
1400
+ var _SPINNER_PREFIX = "[";
1401
+ var _SPINNER_SUFFIX = "]";
1402
+ var RESET_VERBS = ["Thinking\u2026"];
1403
+ function spinnerVerb(ad) {
1404
+ const budget = _SPINNER_MAX - _SPINNER_PREFIX.length - _SPINNER_SUFFIX.length;
1405
+ const body = truncate(adNameLine(ad), Math.max(10, budget));
1406
+ return `${_SPINNER_PREFIX}${body}${_SPINNER_SUFFIX}`;
1407
+ }
1408
+ function spinnerVerbLink(ad, logoDataUri) {
1409
+ const verb = spinnerVerb(ad);
1410
+ const logo = logoDataUri === void 0 ? ad.favicon : logoDataUri ?? void 0;
1411
+ return ad.clickUrl ? encodeLinkedVerb(verb, ad.clickUrl, logo) : verb;
1412
+ }
1413
+
1414
+ // src/core/editorSettings.ts
1415
+ var import_node_fs4 = require("fs");
1416
+ var import_node_os3 = require("os");
1417
+ var import_node_path5 = require("path");
1418
+ var _KNOWN_APP_NAMES = ["Cursor", "Visual Studio Code", "VSCodium"];
1419
+ function _userSettingsFolder(appName) {
1420
+ const lower = appName.toLowerCase();
1421
+ if (lower.includes("cursor")) return "Cursor";
1422
+ if (lower.includes("vscodium")) return "VSCodium";
1423
+ if (lower.includes("visual studio code") || lower.includes("code"))
1424
+ return "Code";
1425
+ return null;
1426
+ }
1427
+ function editorSettingsPath(appName) {
1428
+ const folder = _userSettingsFolder(appName);
1429
+ if (!folder) return null;
1430
+ const home = (0, import_node_os3.homedir)();
1431
+ switch (process.platform) {
1432
+ case "win32": {
1433
+ const appData = process.env.APPDATA ?? (0, import_node_path5.join)(home, "AppData", "Roaming");
1434
+ return (0, import_node_path5.join)(appData, folder, "User", "settings.json");
1435
+ }
1436
+ case "darwin":
1437
+ return (0, import_node_path5.join)(
1438
+ home,
1439
+ "Library",
1440
+ "Application Support",
1441
+ folder,
1442
+ "User",
1443
+ "settings.json"
1444
+ );
1445
+ default:
1446
+ return (0, import_node_path5.join)(
1447
+ process.env.XDG_CONFIG_HOME ?? (0, import_node_path5.join)(home, ".config"),
1448
+ folder,
1449
+ "User",
1450
+ "settings.json"
1451
+ );
1452
+ }
1453
+ }
1454
+ function writeClaudeCodeSpinnerVerbs(appName, verbs) {
1455
+ const path = editorSettingsPath(appName);
1456
+ if (!path) return false;
1457
+ const current = readJsonOwnedByUser(path, {});
1458
+ const next = {
1459
+ ...current,
1460
+ "claudeCode.spinnerVerbs": verbs === void 0 ? void 0 : { mode: "replace", verbs }
1461
+ };
1462
+ writeJsonAtomic(path, next);
1463
+ return true;
1464
+ }
1465
+ function writeClaudeCodeSpinnerVerbsEverywhereInstalled(plainVerbs, linkVerbs) {
1466
+ for (const appName of _KNOWN_APP_NAMES) {
1467
+ const path = editorSettingsPath(appName);
1468
+ if (!path || !(0, import_node_fs4.existsSync)(path)) continue;
1469
+ const folder = _userSettingsFolder(appName);
1470
+ const isPatched = folder !== null && isCurrentlyPatched(folder);
1471
+ try {
1472
+ writeClaudeCodeSpinnerVerbs(appName, isPatched ? linkVerbs : plainVerbs);
1473
+ } catch {
1474
+ }
1475
+ }
1476
+ }
1477
+
1478
+ // src/claude/settings.ts
1479
+ var import_node_fs5 = require("fs");
1480
+ var import_node_path6 = require("path");
1481
+ function updateSpinnerVerb(verb) {
1482
+ const settings = readJsonOwnedByUser(
1483
+ claudeSettingsPath(),
1484
+ {}
1485
+ );
1486
+ settings.spinnerVerbs = { mode: "replace", verbs: [verb] };
1487
+ writeJsonAtomic(claudeSettingsPath(), settings);
1488
+ }
1489
+
1490
+ // src/core/logoCache.ts
1491
+ var _FETCH_TIMEOUT_MS = 3e3;
1492
+ var _MAX_BYTES2 = 1e5;
1493
+ var KILI_FALLBACK_LOGO_DATA_URI = `data:image/svg+xml,${encodeURIComponent(
1494
+ '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><rect width="14" height="14" rx="3" fill="#000"/><rect x="2" y="2" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="6" y="2" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="10" y="2" width="3" height="3" rx="0.6" fill="#22C55E"/><rect x="2" y="6" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="6" y="6" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="10" y="6" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="2" y="10" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="6" y="10" width="3" height="3" rx="0.6" fill="#D1D5DB"/><rect x="10" y="10" width="3" height="3" rx="0.6" fill="#D1D5DB"/></svg>'
1495
+ )}`;
1496
+ function getCachedLogoDataUri(url) {
1497
+ const cache = readJson(logoCachePath(), {});
1498
+ return cache[url] ?? null;
1499
+ }
1500
+ function resolveLogoDataUri(favicon) {
1501
+ if (!favicon) return KILI_FALLBACK_LOGO_DATA_URI;
1502
+ return getCachedLogoDataUri(favicon) ?? KILI_FALLBACK_LOGO_DATA_URI;
1503
+ }
1504
+ async function fetchAndCacheLogoDataUri(url) {
1505
+ const cached = getCachedLogoDataUri(url);
1506
+ if (cached) return cached;
1507
+ const controller = new AbortController();
1508
+ const timer = setTimeout(() => controller.abort(), _FETCH_TIMEOUT_MS);
1509
+ try {
1510
+ const res = await fetch(url, { signal: controller.signal });
1511
+ if (!res.ok) {
1512
+ debugLog("logoCache: fetch not ok", url, res.status);
1513
+ return null;
1514
+ }
1515
+ const contentType = res.headers.get("content-type") ?? "image/png";
1516
+ if (!contentType.startsWith("image/")) {
1517
+ debugLog("logoCache: non-image content-type", url, contentType);
1518
+ return null;
1519
+ }
1520
+ const buf = await res.arrayBuffer();
1521
+ if (buf.byteLength > _MAX_BYTES2) {
1522
+ debugLog("logoCache: oversized", url, buf.byteLength, "> ", _MAX_BYTES2);
1523
+ return null;
1524
+ }
1525
+ const dataUri = `data:${contentType};base64,${Buffer.from(buf).toString("base64")}`;
1526
+ const cache = readJson(logoCachePath(), {});
1527
+ cache[url] = dataUri;
1528
+ writeJsonAtomic(logoCachePath(), cache);
1529
+ debugLog("logoCache: cached", url, buf.byteLength, "bytes");
1530
+ return dataUri;
1531
+ } catch (e) {
1532
+ debugLog("logoCache: fetch threw", url, e instanceof Error ? e.message : e);
1533
+ return null;
1534
+ } finally {
1535
+ clearTimeout(timer);
1536
+ }
1537
+ }
1538
+
1539
+ // src/core/refresh.ts
1540
+ var _ALL_PLACEMENTS = [
1541
+ PLACEMENT.TERMINAL_SPINNER,
1542
+ PLACEMENT.EXTENSION_SPINNER,
1543
+ PLACEMENT.EXTENSION_STATUSBAR
1544
+ ];
1545
+ var TERMINAL_PLACEMENTS = [PLACEMENT.TERMINAL_SPINNER];
1546
+ var EXTENSION_PLACEMENTS = [
1547
+ PLACEMENT.EXTENSION_SPINNER,
1548
+ PLACEMENT.EXTENSION_STATUSBAR
1549
+ ];
1550
+ async function refreshAllPlacements(config, sessionId, placementIds = _ALL_PLACEMENTS) {
1551
+ const client = new KiliClient();
1552
+ const adSets = await client.fetchAds({
1553
+ apiKey: config.apiKey,
1554
+ apiUrl: config.apiUrl,
1555
+ installId: config.installId,
1556
+ sessionId,
1557
+ placementIds
1558
+ });
1559
+ debugLog("refreshAllPlacements", {
1560
+ requested: placementIds,
1561
+ got: [...adSets].map(([id, ads]) => `${id}:${ads.length}`),
1562
+ sessionId
1563
+ });
1564
+ for (const [placementId, ads] of adSets) putAd(placementId, ads);
1565
+ const terminalAds = adSets.get(PLACEMENT.TERMINAL_SPINNER);
1566
+ if (terminalAds?.[0]) updateSpinnerVerb(spinnerVerb(terminalAds[0]));
1567
+ const extensionAds = adSets.get(PLACEMENT.EXTENSION_SPINNER);
1568
+ if (extensionAds?.[0]) applyExtensionSpinnerAd(extensionAds[0], config);
1569
+ return adSets;
1570
+ }
1571
+ function applyExtensionSpinnerAd(ad, config) {
1572
+ const logo = resolveLogoDataUri(ad.favicon);
1573
+ if (ad.favicon) void fetchAndCacheLogoDataUri(ad.favicon);
1574
+ const link = spinnerVerbLink(ad, logo);
1575
+ debugLog("applyExtensionSpinnerAd", {
1576
+ adId: ad.adId,
1577
+ hasFavicon: Boolean(ad.favicon),
1578
+ favicon: ad.favicon,
1579
+ usingFallbackBadge: logo.startsWith("data:image/svg+xml"),
1580
+ encodedHasLogoSeparator: [...link].filter((c) => c.codePointAt(0) === 1).length,
1581
+ patchedEditors: config.webviewPatchedEditors
1582
+ });
1583
+ writeClaudeCodeSpinnerVerbsEverywhereInstalled([spinnerVerb(ad)], [link]);
1584
+ }
1585
+
1586
+ // src/hook.ts
1587
+ async function main() {
1588
+ const event = process.argv[2];
1589
+ try {
1590
+ const stdin = await _readStdin();
1591
+ const payload = _parsePayload(stdin);
1592
+ if (event === "UserPromptSubmit") {
1593
+ await _onUserPromptSubmit(payload);
1594
+ } else if (event === "Stop") {
1595
+ await settlePendingTurn();
1596
+ _clearSpinnerAfterTurn();
1597
+ }
1598
+ } catch (error) {
1599
+ debugLog("hook error", event, error);
1600
+ }
1601
+ process.exit(0);
1602
+ }
1603
+ function _clearSpinnerAfterTurn() {
1604
+ const config = readRuntimeConfig();
1605
+ if (!config || !config.enabled) return;
1606
+ if (isTerminalActive()) return;
1607
+ writeClaudeCodeSpinnerVerbsEverywhereInstalled(RESET_VERBS, RESET_VERBS);
1608
+ debugLog("clearSpinnerAfterTurn: reset panel verb");
1609
+ }
1610
+ async function _onUserPromptSubmit(payload) {
1611
+ const config = readRuntimeConfig();
1612
+ if (!config || !config.enabled) return;
1613
+ const sessionId = toSessionId(payload.sessionId);
1614
+ const terminalActive = isTerminalActive();
1615
+ if (!terminalActive) {
1616
+ writeClaudeCodeSpinnerVerbsEverywhereInstalled(RESET_VERBS, RESET_VERBS);
1617
+ }
1618
+ const ads = await refreshAllPlacements(
1619
+ config,
1620
+ sessionId,
1621
+ TERMINAL_PLACEMENTS
1622
+ );
1623
+ const settledPlacements = terminalActive ? ads.has(PLACEMENT.TERMINAL_SPINNER) ? [PLACEMENT.TERMINAL_SPINNER] : [] : [PLACEMENT.EXTENSION_SPINNER];
1624
+ debugLog("onUserPromptSubmit", {
1625
+ terminalActive,
1626
+ settledPlacements
1627
+ });
1628
+ if (settledPlacements.length > 0) {
1629
+ startPendingTurn({
1630
+ sessionId,
1631
+ placementIds: settledPlacements,
1632
+ startedAt: Date.now()
1633
+ });
1634
+ }
1635
+ }
1636
+ function _readStdin() {
1637
+ return new Promise((resolve) => {
1638
+ let data = "";
1639
+ process.stdin.setEncoding("utf8");
1640
+ process.stdin.on("data", (chunk) => {
1641
+ data += chunk;
1642
+ });
1643
+ process.stdin.on("end", () => resolve(data));
1644
+ process.stdin.on("error", () => resolve(data));
1645
+ setTimeout(() => resolve(data), 2e3);
1646
+ });
1647
+ }
1648
+ function _parsePayload(raw) {
1649
+ try {
1650
+ const json = JSON.parse(raw);
1651
+ return {
1652
+ sessionId: typeof json.session_id === "string" ? json.session_id : void 0,
1653
+ userInput: typeof json.user_input === "string" ? json.user_input : typeof json.prompt === "string" ? json.prompt : void 0
1654
+ };
1655
+ } catch {
1656
+ return { sessionId: void 0, userInput: void 0 };
1657
+ }
1658
+ }
1659
+ void main();
1660
+ //# sourceMappingURL=hook.js.map