@kyma-api/agent 0.1.1 → 0.1.3

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/main.js CHANGED
@@ -1,3081 +1,65 @@
1
1
  // src/sdk/main.ts
2
2
  import { readFileSync as readFileSync5 } from "fs";
3
- import { join as join9, dirname as dirname6 } from "path";
4
- import { fileURLToPath as fileURLToPath4 } from "url";
5
- import { execSync } from "child_process";
6
-
7
- // src/sdk/kyma-interactive-mode.ts
8
- import {
9
- InteractiveMode
10
- } from "@mariozechner/pi-coding-agent";
11
-
12
- // node_modules/@mariozechner/pi-tui/dist/autocomplete.js
13
- import { spawn } from "child_process";
14
- import { readdirSync, statSync } from "fs";
15
- import { homedir } from "os";
16
- import { basename, dirname, join } from "path";
17
-
18
- // node_modules/@mariozechner/pi-tui/dist/fuzzy.js
19
- function fuzzyMatch(query, text) {
20
- const queryLower = query.toLowerCase();
21
- const textLower = text.toLowerCase();
22
- const matchQuery = (normalizedQuery) => {
23
- if (normalizedQuery.length === 0) {
24
- return { matches: true, score: 0 };
25
- }
26
- if (normalizedQuery.length > textLower.length) {
27
- return { matches: false, score: 0 };
28
- }
29
- let queryIndex = 0;
30
- let score = 0;
31
- let lastMatchIndex = -1;
32
- let consecutiveMatches = 0;
33
- for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {
34
- if (textLower[i] === normalizedQuery[queryIndex]) {
35
- const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]);
36
- if (lastMatchIndex === i - 1) {
37
- consecutiveMatches++;
38
- score -= consecutiveMatches * 5;
39
- } else {
40
- consecutiveMatches = 0;
41
- if (lastMatchIndex >= 0) {
42
- score += (i - lastMatchIndex - 1) * 2;
43
- }
44
- }
45
- if (isWordBoundary) {
46
- score -= 10;
47
- }
48
- score += i * 0.1;
49
- lastMatchIndex = i;
50
- queryIndex++;
51
- }
52
- }
53
- if (queryIndex < normalizedQuery.length) {
54
- return { matches: false, score: 0 };
55
- }
56
- return { matches: true, score };
57
- };
58
- const primaryMatch = matchQuery(queryLower);
59
- if (primaryMatch.matches) {
60
- return primaryMatch;
61
- }
62
- const alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);
63
- const numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);
64
- const swappedQuery = alphaNumericMatch ? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}` : numericAlphaMatch ? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}` : "";
65
- if (!swappedQuery) {
66
- return primaryMatch;
67
- }
68
- const swappedMatch = matchQuery(swappedQuery);
69
- if (!swappedMatch.matches) {
70
- return primaryMatch;
71
- }
72
- return { matches: true, score: swappedMatch.score + 5 };
73
- }
74
- function fuzzyFilter(items, query, getText) {
75
- if (!query.trim()) {
76
- return items;
77
- }
78
- const tokens = query.trim().split(/\s+/).filter((t) => t.length > 0);
79
- if (tokens.length === 0) {
80
- return items;
81
- }
82
- const results = [];
83
- for (const item of items) {
84
- const text = getText(item);
85
- let totalScore = 0;
86
- let allMatch = true;
87
- for (const token of tokens) {
88
- const match = fuzzyMatch(token, text);
89
- if (match.matches) {
90
- totalScore += match.score;
91
- } else {
92
- allMatch = false;
93
- break;
94
- }
95
- }
96
- if (allMatch) {
97
- results.push({ item, totalScore });
98
- }
99
- }
100
- results.sort((a, b) => a.totalScore - b.totalScore);
101
- return results.map((r) => r.item);
102
- }
103
-
104
- // node_modules/@mariozechner/pi-tui/dist/autocomplete.js
105
- var PATH_DELIMITERS = /* @__PURE__ */ new Set([" ", " ", '"', "'", "="]);
106
- function toDisplayPath(value) {
107
- return value.replace(/\\/g, "/");
108
- }
109
- function escapeRegex(value) {
110
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
111
- }
112
- function buildFdPathQuery(query) {
113
- const normalized = toDisplayPath(query);
114
- if (!normalized.includes("/")) {
115
- return normalized;
116
- }
117
- const hasTrailingSeparator = normalized.endsWith("/");
118
- const trimmed = normalized.replace(/^\/+|\/+$/g, "");
119
- if (!trimmed) {
120
- return normalized;
121
- }
122
- const separatorPattern = "[\\\\/]";
123
- const segments = trimmed.split("/").filter(Boolean).map((segment) => escapeRegex(segment));
124
- if (segments.length === 0) {
125
- return normalized;
126
- }
127
- let pattern = segments.join(separatorPattern);
128
- if (hasTrailingSeparator) {
129
- pattern += separatorPattern;
130
- }
131
- return pattern;
132
- }
133
- function findLastDelimiter(text) {
134
- for (let i = text.length - 1; i >= 0; i -= 1) {
135
- if (PATH_DELIMITERS.has(text[i] ?? "")) {
136
- return i;
137
- }
138
- }
139
- return -1;
140
- }
141
- function findUnclosedQuoteStart(text) {
142
- let inQuotes = false;
143
- let quoteStart = -1;
144
- for (let i = 0; i < text.length; i += 1) {
145
- if (text[i] === '"') {
146
- inQuotes = !inQuotes;
147
- if (inQuotes) {
148
- quoteStart = i;
149
- }
150
- }
151
- }
152
- return inQuotes ? quoteStart : null;
153
- }
154
- function isTokenStart(text, index) {
155
- return index === 0 || PATH_DELIMITERS.has(text[index - 1] ?? "");
156
- }
157
- function extractQuotedPrefix(text) {
158
- const quoteStart = findUnclosedQuoteStart(text);
159
- if (quoteStart === null) {
160
- return null;
161
- }
162
- if (quoteStart > 0 && text[quoteStart - 1] === "@") {
163
- if (!isTokenStart(text, quoteStart - 1)) {
164
- return null;
165
- }
166
- return text.slice(quoteStart - 1);
167
- }
168
- if (!isTokenStart(text, quoteStart)) {
169
- return null;
170
- }
171
- return text.slice(quoteStart);
172
- }
173
- function parsePathPrefix(prefix) {
174
- if (prefix.startsWith('@"')) {
175
- return { rawPrefix: prefix.slice(2), isAtPrefix: true, isQuotedPrefix: true };
176
- }
177
- if (prefix.startsWith('"')) {
178
- return { rawPrefix: prefix.slice(1), isAtPrefix: false, isQuotedPrefix: true };
179
- }
180
- if (prefix.startsWith("@")) {
181
- return { rawPrefix: prefix.slice(1), isAtPrefix: true, isQuotedPrefix: false };
182
- }
183
- return { rawPrefix: prefix, isAtPrefix: false, isQuotedPrefix: false };
184
- }
185
- function buildCompletionValue(path3, options2) {
186
- const needsQuotes = options2.isQuotedPrefix || path3.includes(" ");
187
- const prefix = options2.isAtPrefix ? "@" : "";
188
- if (!needsQuotes) {
189
- return `${prefix}${path3}`;
190
- }
191
- const openQuote = `${prefix}"`;
192
- const closeQuote = '"';
193
- return `${openQuote}${path3}${closeQuote}`;
194
- }
195
- async function walkDirectoryWithFd(baseDir, fdPath, query, maxResults, signal) {
196
- const args = [
197
- "--base-directory",
198
- baseDir,
199
- "--max-results",
200
- String(maxResults),
201
- "--type",
202
- "f",
203
- "--type",
204
- "d",
205
- "--full-path",
206
- "--hidden",
207
- "--exclude",
208
- ".git",
209
- "--exclude",
210
- ".git/*",
211
- "--exclude",
212
- ".git/**"
213
- ];
214
- if (query) {
215
- args.push(buildFdPathQuery(query));
216
- }
217
- return await new Promise((resolve) => {
218
- if (signal.aborted) {
219
- resolve([]);
220
- return;
221
- }
222
- const child = spawn(fdPath, args, {
223
- stdio: ["ignore", "pipe", "pipe"]
224
- });
225
- let stdout = "";
226
- let resolved = false;
227
- const finish = (results) => {
228
- if (resolved)
229
- return;
230
- resolved = true;
231
- signal.removeEventListener("abort", onAbort);
232
- resolve(results);
233
- };
234
- const onAbort = () => {
235
- if (child.exitCode === null) {
236
- child.kill("SIGKILL");
237
- }
238
- };
239
- signal.addEventListener("abort", onAbort, { once: true });
240
- child.stdout.setEncoding("utf-8");
241
- child.stdout.on("data", (chunk) => {
242
- stdout += chunk;
243
- });
244
- child.on("error", () => {
245
- finish([]);
246
- });
247
- child.on("close", (code) => {
248
- if (signal.aborted || code !== 0 || !stdout) {
249
- finish([]);
250
- return;
251
- }
252
- const lines = stdout.trim().split("\n").filter(Boolean);
253
- const results = [];
254
- for (const line of lines) {
255
- const displayLine = toDisplayPath(line);
256
- const hasTrailingSeparator = displayLine.endsWith("/");
257
- const normalizedPath = hasTrailingSeparator ? displayLine.slice(0, -1) : displayLine;
258
- if (normalizedPath === ".git" || normalizedPath.startsWith(".git/") || normalizedPath.includes("/.git/")) {
259
- continue;
260
- }
261
- results.push({
262
- path: displayLine,
263
- isDirectory: hasTrailingSeparator
264
- });
265
- }
266
- finish(results);
267
- });
268
- });
269
- }
270
- var CombinedAutocompleteProvider = class {
271
- commands;
272
- basePath;
273
- fdPath;
274
- constructor(commands = [], basePath = process.cwd(), fdPath = null) {
275
- this.commands = commands;
276
- this.basePath = basePath;
277
- this.fdPath = fdPath;
278
- }
279
- async getSuggestions(lines, cursorLine, cursorCol, options2) {
280
- const currentLine = lines[cursorLine] || "";
281
- const textBeforeCursor = currentLine.slice(0, cursorCol);
282
- const atPrefix = this.extractAtPrefix(textBeforeCursor);
283
- if (atPrefix) {
284
- const { rawPrefix, isQuotedPrefix } = parsePathPrefix(atPrefix);
285
- const suggestions2 = await this.getFuzzyFileSuggestions(rawPrefix, {
286
- isQuotedPrefix,
287
- signal: options2.signal
288
- });
289
- if (suggestions2.length === 0)
290
- return null;
291
- return {
292
- items: suggestions2,
293
- prefix: atPrefix
294
- };
295
- }
296
- if (!options2.force && textBeforeCursor.startsWith("/")) {
297
- const spaceIndex = textBeforeCursor.indexOf(" ");
298
- if (spaceIndex === -1) {
299
- const prefix = textBeforeCursor.slice(1);
300
- const commandItems = this.commands.map((cmd) => ({
301
- name: "name" in cmd ? cmd.name : cmd.value,
302
- label: "name" in cmd ? cmd.name : cmd.label,
303
- description: cmd.description
304
- }));
305
- const filtered = fuzzyFilter(commandItems, prefix, (item) => item.name).map((item) => ({
306
- value: item.name,
307
- label: item.label,
308
- ...item.description && { description: item.description }
309
- }));
310
- if (filtered.length === 0)
311
- return null;
312
- return {
313
- items: filtered,
314
- prefix: textBeforeCursor
315
- };
316
- }
317
- const commandName = textBeforeCursor.slice(1, spaceIndex);
318
- const argumentText = textBeforeCursor.slice(spaceIndex + 1);
319
- const command = this.commands.find((cmd) => {
320
- const name = "name" in cmd ? cmd.name : cmd.value;
321
- return name === commandName;
322
- });
323
- if (!command || !("getArgumentCompletions" in command) || !command.getArgumentCompletions) {
324
- return null;
325
- }
326
- const argumentSuggestions = await command.getArgumentCompletions(argumentText);
327
- if (!Array.isArray(argumentSuggestions) || argumentSuggestions.length === 0) {
328
- return null;
329
- }
330
- return {
331
- items: argumentSuggestions,
332
- prefix: argumentText
333
- };
334
- }
335
- const pathMatch = this.extractPathPrefix(textBeforeCursor, options2.force ?? false);
336
- if (pathMatch === null) {
337
- return null;
338
- }
339
- const suggestions = this.getFileSuggestions(pathMatch);
340
- if (suggestions.length === 0)
341
- return null;
342
- return {
343
- items: suggestions,
344
- prefix: pathMatch
345
- };
346
- }
347
- applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
348
- const currentLine = lines[cursorLine] || "";
349
- const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
350
- const afterCursor = currentLine.slice(cursorCol);
351
- const isQuotedPrefix = prefix.startsWith('"') || prefix.startsWith('@"');
352
- const hasLeadingQuoteAfterCursor = afterCursor.startsWith('"');
353
- const hasTrailingQuoteInItem = item.value.endsWith('"');
354
- const adjustedAfterCursor = isQuotedPrefix && hasTrailingQuoteInItem && hasLeadingQuoteAfterCursor ? afterCursor.slice(1) : afterCursor;
355
- const isSlashCommand = prefix.startsWith("/") && beforePrefix.trim() === "" && !prefix.slice(1).includes("/");
356
- if (isSlashCommand) {
357
- const newLine2 = `${beforePrefix}/${item.value} ${adjustedAfterCursor}`;
358
- const newLines2 = [...lines];
359
- newLines2[cursorLine] = newLine2;
360
- return {
361
- lines: newLines2,
362
- cursorLine,
363
- cursorCol: beforePrefix.length + item.value.length + 2
364
- // +2 for "/" and space
365
- };
366
- }
367
- if (prefix.startsWith("@")) {
368
- const isDirectory2 = item.label.endsWith("/");
369
- const suffix = isDirectory2 ? "" : " ";
370
- const newLine2 = `${beforePrefix + item.value}${suffix}${adjustedAfterCursor}`;
371
- const newLines2 = [...lines];
372
- newLines2[cursorLine] = newLine2;
373
- const hasTrailingQuote2 = item.value.endsWith('"');
374
- const cursorOffset2 = isDirectory2 && hasTrailingQuote2 ? item.value.length - 1 : item.value.length;
375
- return {
376
- lines: newLines2,
377
- cursorLine,
378
- cursorCol: beforePrefix.length + cursorOffset2 + suffix.length
379
- };
380
- }
381
- const textBeforeCursor = currentLine.slice(0, cursorCol);
382
- if (textBeforeCursor.includes("/") && textBeforeCursor.includes(" ")) {
383
- const newLine2 = beforePrefix + item.value + adjustedAfterCursor;
384
- const newLines2 = [...lines];
385
- newLines2[cursorLine] = newLine2;
386
- const isDirectory2 = item.label.endsWith("/");
387
- const hasTrailingQuote2 = item.value.endsWith('"');
388
- const cursorOffset2 = isDirectory2 && hasTrailingQuote2 ? item.value.length - 1 : item.value.length;
389
- return {
390
- lines: newLines2,
391
- cursorLine,
392
- cursorCol: beforePrefix.length + cursorOffset2
393
- };
394
- }
395
- const newLine = beforePrefix + item.value + adjustedAfterCursor;
396
- const newLines = [...lines];
397
- newLines[cursorLine] = newLine;
398
- const isDirectory = item.label.endsWith("/");
399
- const hasTrailingQuote = item.value.endsWith('"');
400
- const cursorOffset = isDirectory && hasTrailingQuote ? item.value.length - 1 : item.value.length;
401
- return {
402
- lines: newLines,
403
- cursorLine,
404
- cursorCol: beforePrefix.length + cursorOffset
405
- };
406
- }
407
- // Extract @ prefix for fuzzy file suggestions
408
- extractAtPrefix(text) {
409
- const quotedPrefix = extractQuotedPrefix(text);
410
- if (quotedPrefix?.startsWith('@"')) {
411
- return quotedPrefix;
412
- }
413
- const lastDelimiterIndex = findLastDelimiter(text);
414
- const tokenStart = lastDelimiterIndex === -1 ? 0 : lastDelimiterIndex + 1;
415
- if (text[tokenStart] === "@") {
416
- return text.slice(tokenStart);
417
- }
418
- return null;
419
- }
420
- // Extract a path-like prefix from the text before cursor
421
- extractPathPrefix(text, forceExtract = false) {
422
- const quotedPrefix = extractQuotedPrefix(text);
423
- if (quotedPrefix) {
424
- return quotedPrefix;
425
- }
426
- const lastDelimiterIndex = findLastDelimiter(text);
427
- const pathPrefix = lastDelimiterIndex === -1 ? text : text.slice(lastDelimiterIndex + 1);
428
- if (forceExtract) {
429
- return pathPrefix;
430
- }
431
- if (pathPrefix.includes("/") || pathPrefix.startsWith(".") || pathPrefix.startsWith("~/")) {
432
- return pathPrefix;
433
- }
434
- if (pathPrefix === "" && text.endsWith(" ")) {
435
- return pathPrefix;
436
- }
437
- return null;
438
- }
439
- // Expand home directory (~/) to actual home path
440
- expandHomePath(path3) {
441
- if (path3.startsWith("~/")) {
442
- const expandedPath = join(homedir(), path3.slice(2));
443
- return path3.endsWith("/") && !expandedPath.endsWith("/") ? `${expandedPath}/` : expandedPath;
444
- } else if (path3 === "~") {
445
- return homedir();
446
- }
447
- return path3;
448
- }
449
- resolveScopedFuzzyQuery(rawQuery) {
450
- const normalizedQuery = toDisplayPath(rawQuery);
451
- const slashIndex = normalizedQuery.lastIndexOf("/");
452
- if (slashIndex === -1) {
453
- return null;
454
- }
455
- const displayBase = normalizedQuery.slice(0, slashIndex + 1);
456
- const query = normalizedQuery.slice(slashIndex + 1);
457
- let baseDir;
458
- if (displayBase.startsWith("~/")) {
459
- baseDir = this.expandHomePath(displayBase);
460
- } else if (displayBase.startsWith("/")) {
461
- baseDir = displayBase;
462
- } else {
463
- baseDir = join(this.basePath, displayBase);
464
- }
465
- try {
466
- if (!statSync(baseDir).isDirectory()) {
467
- return null;
468
- }
469
- } catch {
470
- return null;
471
- }
472
- return { baseDir, query, displayBase };
473
- }
474
- scopedPathForDisplay(displayBase, relativePath) {
475
- const normalizedRelativePath = toDisplayPath(relativePath);
476
- if (displayBase === "/") {
477
- return `/${normalizedRelativePath}`;
478
- }
479
- return `${toDisplayPath(displayBase)}${normalizedRelativePath}`;
480
- }
481
- // Get file/directory suggestions for a given path prefix
482
- getFileSuggestions(prefix) {
483
- try {
484
- let searchDir;
485
- let searchPrefix;
486
- const { rawPrefix, isAtPrefix, isQuotedPrefix } = parsePathPrefix(prefix);
487
- let expandedPrefix = rawPrefix;
488
- if (expandedPrefix.startsWith("~")) {
489
- expandedPrefix = this.expandHomePath(expandedPrefix);
490
- }
491
- const isRootPrefix = rawPrefix === "" || rawPrefix === "./" || rawPrefix === "../" || rawPrefix === "~" || rawPrefix === "~/" || rawPrefix === "/" || isAtPrefix && rawPrefix === "";
492
- if (isRootPrefix) {
493
- if (rawPrefix.startsWith("~") || expandedPrefix.startsWith("/")) {
494
- searchDir = expandedPrefix;
495
- } else {
496
- searchDir = join(this.basePath, expandedPrefix);
497
- }
498
- searchPrefix = "";
499
- } else if (rawPrefix.endsWith("/")) {
500
- if (rawPrefix.startsWith("~") || expandedPrefix.startsWith("/")) {
501
- searchDir = expandedPrefix;
502
- } else {
503
- searchDir = join(this.basePath, expandedPrefix);
504
- }
505
- searchPrefix = "";
506
- } else {
507
- const dir = dirname(expandedPrefix);
508
- const file = basename(expandedPrefix);
509
- if (rawPrefix.startsWith("~") || expandedPrefix.startsWith("/")) {
510
- searchDir = dir;
511
- } else {
512
- searchDir = join(this.basePath, dir);
513
- }
514
- searchPrefix = file;
515
- }
516
- const entries = readdirSync(searchDir, { withFileTypes: true });
517
- const suggestions = [];
518
- for (const entry of entries) {
519
- if (!entry.name.toLowerCase().startsWith(searchPrefix.toLowerCase())) {
520
- continue;
521
- }
522
- let isDirectory = entry.isDirectory();
523
- if (!isDirectory && entry.isSymbolicLink()) {
524
- try {
525
- const fullPath = join(searchDir, entry.name);
526
- isDirectory = statSync(fullPath).isDirectory();
527
- } catch {
528
- }
529
- }
530
- let relativePath;
531
- const name = entry.name;
532
- const displayPrefix = rawPrefix;
533
- if (displayPrefix.endsWith("/")) {
534
- relativePath = displayPrefix + name;
535
- } else if (displayPrefix.includes("/") || displayPrefix.includes("\\")) {
536
- if (displayPrefix.startsWith("~/")) {
537
- const homeRelativeDir = displayPrefix.slice(2);
538
- const dir = dirname(homeRelativeDir);
539
- relativePath = `~/${dir === "." ? name : join(dir, name)}`;
540
- } else if (displayPrefix.startsWith("/")) {
541
- const dir = dirname(displayPrefix);
542
- if (dir === "/") {
543
- relativePath = `/${name}`;
544
- } else {
545
- relativePath = `${dir}/${name}`;
546
- }
547
- } else {
548
- relativePath = join(dirname(displayPrefix), name);
549
- if (displayPrefix.startsWith("./") && !relativePath.startsWith("./")) {
550
- relativePath = `./${relativePath}`;
551
- }
552
- }
553
- } else {
554
- if (displayPrefix.startsWith("~")) {
555
- relativePath = `~/${name}`;
556
- } else {
557
- relativePath = name;
558
- }
559
- }
560
- relativePath = toDisplayPath(relativePath);
561
- const pathValue = isDirectory ? `${relativePath}/` : relativePath;
562
- const value = buildCompletionValue(pathValue, {
563
- isDirectory,
564
- isAtPrefix,
565
- isQuotedPrefix
566
- });
567
- suggestions.push({
568
- value,
569
- label: name + (isDirectory ? "/" : "")
570
- });
571
- }
572
- suggestions.sort((a, b) => {
573
- const aIsDir = a.value.endsWith("/");
574
- const bIsDir = b.value.endsWith("/");
575
- if (aIsDir && !bIsDir)
576
- return -1;
577
- if (!aIsDir && bIsDir)
578
- return 1;
579
- return a.label.localeCompare(b.label);
580
- });
581
- return suggestions;
582
- } catch (_e) {
583
- return [];
584
- }
585
- }
586
- // Score an entry against the query (higher = better match)
587
- // isDirectory adds bonus to prioritize folders
588
- scoreEntry(filePath, query, isDirectory) {
589
- const fileName = basename(filePath);
590
- const lowerFileName = fileName.toLowerCase();
591
- const lowerQuery = query.toLowerCase();
592
- let score = 0;
593
- if (lowerFileName === lowerQuery)
594
- score = 100;
595
- else if (lowerFileName.startsWith(lowerQuery))
596
- score = 80;
597
- else if (lowerFileName.includes(lowerQuery))
598
- score = 50;
599
- else if (filePath.toLowerCase().includes(lowerQuery))
600
- score = 30;
601
- if (isDirectory && score > 0)
602
- score += 10;
603
- return score;
604
- }
605
- // Fuzzy file search using fd (fast, respects .gitignore)
606
- async getFuzzyFileSuggestions(query, options2) {
607
- if (!this.fdPath || options2.signal.aborted) {
608
- return [];
609
- }
610
- try {
611
- const scopedQuery = this.resolveScopedFuzzyQuery(query);
612
- const fdBaseDir = scopedQuery?.baseDir ?? this.basePath;
613
- const fdQuery = scopedQuery?.query ?? query;
614
- const entries = await walkDirectoryWithFd(fdBaseDir, this.fdPath, fdQuery, 100, options2.signal);
615
- if (options2.signal.aborted) {
616
- return [];
617
- }
618
- const scoredEntries = entries.map((entry) => ({
619
- ...entry,
620
- score: fdQuery ? this.scoreEntry(entry.path, fdQuery, entry.isDirectory) : 1
621
- })).filter((entry) => entry.score > 0);
622
- scoredEntries.sort((a, b) => b.score - a.score);
623
- const topEntries = scoredEntries.slice(0, 20);
624
- const suggestions = [];
625
- for (const { path: entryPath, isDirectory } of topEntries) {
626
- const pathWithoutSlash = isDirectory ? entryPath.slice(0, -1) : entryPath;
627
- const displayPath = scopedQuery ? this.scopedPathForDisplay(scopedQuery.displayBase, pathWithoutSlash) : pathWithoutSlash;
628
- const entryName = basename(pathWithoutSlash);
629
- const completionPath = isDirectory ? `${displayPath}/` : displayPath;
630
- const value = buildCompletionValue(completionPath, {
631
- isDirectory,
632
- isAtPrefix: true,
633
- isQuotedPrefix: options2.isQuotedPrefix
634
- });
635
- suggestions.push({
636
- value,
637
- label: entryName + (isDirectory ? "/" : ""),
638
- description: displayPath
639
- });
640
- }
641
- return suggestions;
642
- } catch {
643
- return [];
644
- }
645
- }
646
- // Check if we should trigger file completion (called on Tab key)
647
- shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
648
- const currentLine = lines[cursorLine] || "";
649
- const textBeforeCursor = currentLine.slice(0, cursorCol);
650
- if (textBeforeCursor.trim().startsWith("/") && !textBeforeCursor.trim().includes(" ")) {
651
- return false;
652
- }
653
- return true;
654
- }
655
- };
656
-
657
- // node_modules/@mariozechner/pi-tui/dist/utils.js
658
- var segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
659
- function getSegmenter() {
660
- return segmenter;
661
- }
662
- var zeroWidthRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Mark}|\\p{Surrogate})+$", "v");
663
- var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Mark}\\p{Surrogate}]+", "v");
664
- var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
665
- var AnsiCodeTracker = class {
666
- // Track individual attributes separately so we can reset them specifically
667
- bold = false;
668
- dim = false;
669
- italic = false;
670
- underline = false;
671
- blink = false;
672
- inverse = false;
673
- hidden = false;
674
- strikethrough = false;
675
- fgColor = null;
676
- // Stores the full code like "31" or "38;5;240"
677
- bgColor = null;
678
- // Stores the full code like "41" or "48;5;240"
679
- process(ansiCode) {
680
- if (!ansiCode.endsWith("m")) {
681
- return;
682
- }
683
- const match = ansiCode.match(/\x1b\[([\d;]*)m/);
684
- if (!match)
685
- return;
686
- const params = match[1];
687
- if (params === "" || params === "0") {
688
- this.reset();
689
- return;
690
- }
691
- const parts = params.split(";");
692
- let i = 0;
693
- while (i < parts.length) {
694
- const code = Number.parseInt(parts[i], 10);
695
- if (code === 38 || code === 48) {
696
- if (parts[i + 1] === "5" && parts[i + 2] !== void 0) {
697
- const colorCode = `${parts[i]};${parts[i + 1]};${parts[i + 2]}`;
698
- if (code === 38) {
699
- this.fgColor = colorCode;
700
- } else {
701
- this.bgColor = colorCode;
702
- }
703
- i += 3;
704
- continue;
705
- } else if (parts[i + 1] === "2" && parts[i + 4] !== void 0) {
706
- const colorCode = `${parts[i]};${parts[i + 1]};${parts[i + 2]};${parts[i + 3]};${parts[i + 4]}`;
707
- if (code === 38) {
708
- this.fgColor = colorCode;
709
- } else {
710
- this.bgColor = colorCode;
711
- }
712
- i += 5;
713
- continue;
714
- }
715
- }
716
- switch (code) {
717
- case 0:
718
- this.reset();
719
- break;
720
- case 1:
721
- this.bold = true;
722
- break;
723
- case 2:
724
- this.dim = true;
725
- break;
726
- case 3:
727
- this.italic = true;
728
- break;
729
- case 4:
730
- this.underline = true;
731
- break;
732
- case 5:
733
- this.blink = true;
734
- break;
735
- case 7:
736
- this.inverse = true;
737
- break;
738
- case 8:
739
- this.hidden = true;
740
- break;
741
- case 9:
742
- this.strikethrough = true;
743
- break;
744
- case 21:
745
- this.bold = false;
746
- break;
747
- // Some terminals
748
- case 22:
749
- this.bold = false;
750
- this.dim = false;
751
- break;
752
- case 23:
753
- this.italic = false;
754
- break;
755
- case 24:
756
- this.underline = false;
757
- break;
758
- case 25:
759
- this.blink = false;
760
- break;
761
- case 27:
762
- this.inverse = false;
763
- break;
764
- case 28:
765
- this.hidden = false;
766
- break;
767
- case 29:
768
- this.strikethrough = false;
769
- break;
770
- case 39:
771
- this.fgColor = null;
772
- break;
773
- // Default fg
774
- case 49:
775
- this.bgColor = null;
776
- break;
777
- // Default bg
778
- default:
779
- if (code >= 30 && code <= 37 || code >= 90 && code <= 97) {
780
- this.fgColor = String(code);
781
- } else if (code >= 40 && code <= 47 || code >= 100 && code <= 107) {
782
- this.bgColor = String(code);
783
- }
784
- break;
785
- }
786
- i++;
787
- }
788
- }
789
- reset() {
790
- this.bold = false;
791
- this.dim = false;
792
- this.italic = false;
793
- this.underline = false;
794
- this.blink = false;
795
- this.inverse = false;
796
- this.hidden = false;
797
- this.strikethrough = false;
798
- this.fgColor = null;
799
- this.bgColor = null;
800
- }
801
- /** Clear all state for reuse. */
802
- clear() {
803
- this.reset();
804
- }
805
- getActiveCodes() {
806
- const codes = [];
807
- if (this.bold)
808
- codes.push("1");
809
- if (this.dim)
810
- codes.push("2");
811
- if (this.italic)
812
- codes.push("3");
813
- if (this.underline)
814
- codes.push("4");
815
- if (this.blink)
816
- codes.push("5");
817
- if (this.inverse)
818
- codes.push("7");
819
- if (this.hidden)
820
- codes.push("8");
821
- if (this.strikethrough)
822
- codes.push("9");
823
- if (this.fgColor)
824
- codes.push(this.fgColor);
825
- if (this.bgColor)
826
- codes.push(this.bgColor);
827
- if (codes.length === 0)
828
- return "";
829
- return `\x1B[${codes.join(";")}m`;
830
- }
831
- hasActiveCodes() {
832
- return this.bold || this.dim || this.italic || this.underline || this.blink || this.inverse || this.hidden || this.strikethrough || this.fgColor !== null || this.bgColor !== null;
833
- }
834
- /**
835
- * Get reset codes for attributes that need to be turned off at line end,
836
- * specifically underline which bleeds into padding.
837
- * Returns empty string if no problematic attributes are active.
838
- */
839
- getLineEndReset() {
840
- if (this.underline) {
841
- return "\x1B[24m";
842
- }
843
- return "";
844
- }
845
- };
846
- var pooledStyleTracker = new AnsiCodeTracker();
847
-
848
- // node_modules/@mariozechner/pi-tui/dist/keys.js
849
- var MODIFIERS = {
850
- shift: 1,
851
- alt: 2,
852
- ctrl: 4
853
- };
854
- var LOCK_MASK = 64 + 128;
855
- var ARROW_CODEPOINTS = {
856
- up: -1,
857
- down: -2,
858
- right: -3,
859
- left: -4
860
- };
861
- var FUNCTIONAL_CODEPOINTS = {
862
- delete: -10,
863
- insert: -11,
864
- pageUp: -12,
865
- pageDown: -13,
866
- home: -14,
867
- end: -15
868
- };
869
- var KITTY_FUNCTIONAL_KEY_EQUIVALENTS = /* @__PURE__ */ new Map([
870
- [57399, 48],
871
- // KP_0 -> 0
872
- [57400, 49],
873
- // KP_1 -> 1
874
- [57401, 50],
875
- // KP_2 -> 2
876
- [57402, 51],
877
- // KP_3 -> 3
878
- [57403, 52],
879
- // KP_4 -> 4
880
- [57404, 53],
881
- // KP_5 -> 5
882
- [57405, 54],
883
- // KP_6 -> 6
884
- [57406, 55],
885
- // KP_7 -> 7
886
- [57407, 56],
887
- // KP_8 -> 8
888
- [57408, 57],
889
- // KP_9 -> 9
890
- [57409, 46],
891
- // KP_DECIMAL -> .
892
- [57410, 47],
893
- // KP_DIVIDE -> /
894
- [57411, 42],
895
- // KP_MULTIPLY -> *
896
- [57412, 45],
897
- // KP_SUBTRACT -> -
898
- [57413, 43],
899
- // KP_ADD -> +
900
- [57415, 61],
901
- // KP_EQUAL -> =
902
- [57416, 44],
903
- // KP_SEPARATOR -> ,
904
- [57417, ARROW_CODEPOINTS.left],
905
- [57418, ARROW_CODEPOINTS.right],
906
- [57419, ARROW_CODEPOINTS.up],
907
- [57420, ARROW_CODEPOINTS.down],
908
- [57421, FUNCTIONAL_CODEPOINTS.pageUp],
909
- [57422, FUNCTIONAL_CODEPOINTS.pageDown],
910
- [57423, FUNCTIONAL_CODEPOINTS.home],
911
- [57424, FUNCTIONAL_CODEPOINTS.end],
912
- [57425, FUNCTIONAL_CODEPOINTS.insert],
913
- [57426, FUNCTIONAL_CODEPOINTS.delete]
914
- ]);
915
- var KITTY_PRINTABLE_ALLOWED_MODIFIERS = MODIFIERS.shift | LOCK_MASK;
916
-
917
- // node_modules/@mariozechner/pi-tui/dist/tui.js
918
- import * as fs from "fs";
919
- import * as os from "os";
920
- import * as path from "path";
921
- import { performance } from "perf_hooks";
922
-
923
- // node_modules/@mariozechner/pi-tui/dist/components/editor.js
924
- var baseSegmenter = getSegmenter();
925
-
926
- // node_modules/@mariozechner/pi-tui/dist/components/input.js
927
- var segmenter2 = getSegmenter();
928
-
929
- // node_modules/marked/lib/marked.esm.js
930
- function _getDefaults() {
931
- return {
932
- async: false,
933
- breaks: false,
934
- extensions: null,
935
- gfm: true,
936
- hooks: null,
937
- pedantic: false,
938
- renderer: null,
939
- silent: false,
940
- tokenizer: null,
941
- walkTokens: null
942
- };
943
- }
944
- var _defaults = _getDefaults();
945
- function changeDefaults(newDefaults) {
946
- _defaults = newDefaults;
947
- }
948
- var noopTest = { exec: () => null };
949
- function edit(regex, opt = "") {
950
- let source = typeof regex === "string" ? regex : regex.source;
951
- const obj = {
952
- replace: (name, val) => {
953
- let valSource = typeof val === "string" ? val : val.source;
954
- valSource = valSource.replace(other.caret, "$1");
955
- source = source.replace(name, valSource);
956
- return obj;
957
- },
958
- getRegex: () => {
959
- return new RegExp(source, opt);
960
- }
961
- };
962
- return obj;
963
- }
964
- var other = {
965
- codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm,
966
- outputLinkReplace: /\\([\[\]])/g,
967
- indentCodeCompensation: /^(\s+)(?:```)/,
968
- beginningSpace: /^\s+/,
969
- endingHash: /#$/,
970
- startingSpaceChar: /^ /,
971
- endingSpaceChar: / $/,
972
- nonSpaceChar: /[^ ]/,
973
- newLineCharGlobal: /\n/g,
974
- tabCharGlobal: /\t/g,
975
- multipleSpaceGlobal: /\s+/g,
976
- blankLine: /^[ \t]*$/,
977
- doubleBlankLine: /\n[ \t]*\n[ \t]*$/,
978
- blockquoteStart: /^ {0,3}>/,
979
- blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g,
980
- blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm,
981
- listReplaceTabs: /^\t+/,
982
- listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,
983
- listIsTask: /^\[[ xX]\] /,
984
- listReplaceTask: /^\[[ xX]\] +/,
985
- anyLine: /\n.*\n/,
986
- hrefBrackets: /^<(.*)>$/,
987
- tableDelimiter: /[:|]/,
988
- tableAlignChars: /^\||\| *$/g,
989
- tableRowBlankLine: /\n[ \t]*$/,
990
- tableAlignRight: /^ *-+: *$/,
991
- tableAlignCenter: /^ *:-+: *$/,
992
- tableAlignLeft: /^ *:-+ *$/,
993
- startATag: /^<a /i,
994
- endATag: /^<\/a>/i,
995
- startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i,
996
- endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i,
997
- startAngleBracket: /^</,
998
- endAngleBracket: />$/,
999
- pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/,
1000
- unicodeAlphaNumeric: /[\p{L}\p{N}]/u,
1001
- escapeTest: /[&<>"']/,
1002
- escapeReplace: /[&<>"']/g,
1003
- escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,
1004
- escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,
1005
- unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,
1006
- caret: /(^|[^\[])\^/g,
1007
- percentDecode: /%25/g,
1008
- findPipe: /\|/g,
1009
- splitPipe: / \|/,
1010
- slashPipe: /\\\|/g,
1011
- carriageReturn: /\r\n|\r/g,
1012
- spaceLine: /^ +$/gm,
1013
- notSpaceStart: /^\S*/,
1014
- endingNewline: /\n$/,
1015
- listItemRegex: (bull) => new RegExp(`^( {0,3}${bull})((?:[ ][^\\n]*)?(?:\\n|$))`),
1016
- nextBulletRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),
1017
- hrRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
1018
- fencesBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
1019
- headingBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
1020
- htmlBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, "i")
1021
- };
1022
- var newline = /^(?:[ \t]*(?:\n|$))+/;
1023
- var blockCode = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
1024
- var fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
1025
- var hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
1026
- var heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
1027
- var bullet = /(?:[*+-]|\d{1,9}[.)])/;
1028
- var lheadingCore = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
1029
- var lheading = edit(lheadingCore).replace(/bull/g, bullet).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
1030
- var lheadingGfm = edit(lheadingCore).replace(/bull/g, bullet).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
1031
- var _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
1032
- var blockText = /^[^\n]+/;
1033
- var _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
1034
- var def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", _blockLabel).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
1035
- var list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, bullet).getRegex();
1036
- var _tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
1037
- var _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
1038
- var html = edit(
1039
- "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))",
1040
- "i"
1041
- ).replace("comment", _comment).replace("tag", _tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
1042
- var paragraph = edit(_paragraph).replace("hr", hr).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", _tag).getRegex();
1043
- var blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", paragraph).getRegex();
1044
- var blockNormal = {
1045
- blockquote,
1046
- code: blockCode,
1047
- def,
1048
- fences,
1049
- heading,
1050
- hr,
1051
- html,
1052
- lheading,
1053
- list,
1054
- newline,
1055
- paragraph,
1056
- table: noopTest,
1057
- text: blockText
1058
- };
1059
- var gfmTable = edit(
1060
- "^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"
1061
- ).replace("hr", hr).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", _tag).getRegex();
1062
- var blockGfm = {
1063
- ...blockNormal,
1064
- lheading: lheadingGfm,
1065
- table: gfmTable,
1066
- paragraph: edit(_paragraph).replace("hr", hr).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", gfmTable).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", _tag).getRegex()
1067
- };
1068
- var blockPedantic = {
1069
- ...blockNormal,
1070
- html: edit(
1071
- `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`
1072
- ).replace("comment", _comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
1073
- def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
1074
- heading: /^(#{1,6})(.*)(?:\n+|$)/,
1075
- fences: noopTest,
1076
- // fences not supported
1077
- lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
1078
- paragraph: edit(_paragraph).replace("hr", hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", lheading).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex()
1079
- };
1080
- var escape = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
1081
- var inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
1082
- var br = /^( {2,}|\\)\n(?!\s*$)/;
1083
- var inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
1084
- var _punctuation = /[\p{P}\p{S}]/u;
1085
- var _punctuationOrSpace = /[\s\p{P}\p{S}]/u;
1086
- var _notPunctuationOrSpace = /[^\s\p{P}\p{S}]/u;
1087
- var punctuation = edit(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, _punctuationOrSpace).getRegex();
1088
- var _punctuationGfmStrongEm = /(?!~)[\p{P}\p{S}]/u;
1089
- var _punctuationOrSpaceGfmStrongEm = /(?!~)[\s\p{P}\p{S}]/u;
1090
- var _notPunctuationOrSpaceGfmStrongEm = /(?:[^\s\p{P}\p{S}]|~)/u;
1091
- var blockSkip = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
1092
- var emStrongLDelimCore = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
1093
- var emStrongLDelim = edit(emStrongLDelimCore, "u").replace(/punct/g, _punctuation).getRegex();
1094
- var emStrongLDelimGfm = edit(emStrongLDelimCore, "u").replace(/punct/g, _punctuationGfmStrongEm).getRegex();
1095
- var emStrongRDelimAstCore = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
1096
- var emStrongRDelimAst = edit(emStrongRDelimAstCore, "gu").replace(/notPunctSpace/g, _notPunctuationOrSpace).replace(/punctSpace/g, _punctuationOrSpace).replace(/punct/g, _punctuation).getRegex();
1097
- var emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, "gu").replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm).replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm).replace(/punct/g, _punctuationGfmStrongEm).getRegex();
1098
- var emStrongRDelimUnd = edit(
1099
- "^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)",
1100
- "gu"
1101
- ).replace(/notPunctSpace/g, _notPunctuationOrSpace).replace(/punctSpace/g, _punctuationOrSpace).replace(/punct/g, _punctuation).getRegex();
1102
- var anyPunctuation = edit(/\\(punct)/, "gu").replace(/punct/g, _punctuation).getRegex();
1103
- var autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
1104
- var _inlineComment = edit(_comment).replace("(?:-->|$)", "-->").getRegex();
1105
- var tag = edit(
1106
- "^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>"
1107
- ).replace("comment", _inlineComment).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
1108
- var _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
1109
- var link = edit(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", _inlineLabel).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
1110
- var reflink = edit(/^!?\[(label)\]\[(ref)\]/).replace("label", _inlineLabel).replace("ref", _blockLabel).getRegex();
1111
- var nolink = edit(/^!?\[(ref)\](?:\[\])?/).replace("ref", _blockLabel).getRegex();
1112
- var reflinkSearch = edit("reflink|nolink(?!\\()", "g").replace("reflink", reflink).replace("nolink", nolink).getRegex();
1113
- var inlineNormal = {
1114
- _backpedal: noopTest,
1115
- // only used for GFM url
1116
- anyPunctuation,
1117
- autolink,
1118
- blockSkip,
1119
- br,
1120
- code: inlineCode,
1121
- del: noopTest,
1122
- emStrongLDelim,
1123
- emStrongRDelimAst,
1124
- emStrongRDelimUnd,
1125
- escape,
1126
- link,
1127
- nolink,
1128
- punctuation,
1129
- reflink,
1130
- reflinkSearch,
1131
- tag,
1132
- text: inlineText,
1133
- url: noopTest
1134
- };
1135
- var inlinePedantic = {
1136
- ...inlineNormal,
1137
- link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", _inlineLabel).getRegex(),
1138
- reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", _inlineLabel).getRegex()
1139
- };
1140
- var inlineGfm = {
1141
- ...inlineNormal,
1142
- emStrongRDelimAst: emStrongRDelimAstGfm,
1143
- emStrongLDelim: emStrongLDelimGfm,
1144
- url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, "i").replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),
1145
- _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
1146
- del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,
1147
- text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
1148
- };
1149
- var inlineBreaks = {
1150
- ...inlineGfm,
1151
- br: edit(br).replace("{2,}", "*").getRegex(),
1152
- text: edit(inlineGfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
1153
- };
1154
- var block = {
1155
- normal: blockNormal,
1156
- gfm: blockGfm,
1157
- pedantic: blockPedantic
1158
- };
1159
- var inline = {
1160
- normal: inlineNormal,
1161
- gfm: inlineGfm,
1162
- breaks: inlineBreaks,
1163
- pedantic: inlinePedantic
1164
- };
1165
- var escapeReplacements = {
1166
- "&": "&amp;",
1167
- "<": "&lt;",
1168
- ">": "&gt;",
1169
- '"': "&quot;",
1170
- "'": "&#39;"
1171
- };
1172
- var getEscapeReplacement = (ch) => escapeReplacements[ch];
1173
- function escape2(html2, encode) {
1174
- if (encode) {
1175
- if (other.escapeTest.test(html2)) {
1176
- return html2.replace(other.escapeReplace, getEscapeReplacement);
1177
- }
1178
- } else {
1179
- if (other.escapeTestNoEncode.test(html2)) {
1180
- return html2.replace(other.escapeReplaceNoEncode, getEscapeReplacement);
1181
- }
1182
- }
1183
- return html2;
1184
- }
1185
- function cleanUrl(href) {
1186
- try {
1187
- href = encodeURI(href).replace(other.percentDecode, "%");
1188
- } catch {
1189
- return null;
1190
- }
1191
- return href;
1192
- }
1193
- function splitCells(tableRow, count) {
1194
- const row = tableRow.replace(other.findPipe, (match, offset, str) => {
1195
- let escaped = false;
1196
- let curr = offset;
1197
- while (--curr >= 0 && str[curr] === "\\") escaped = !escaped;
1198
- if (escaped) {
1199
- return "|";
1200
- } else {
1201
- return " |";
1202
- }
1203
- }), cells = row.split(other.splitPipe);
1204
- let i = 0;
1205
- if (!cells[0].trim()) {
1206
- cells.shift();
1207
- }
1208
- if (cells.length > 0 && !cells.at(-1)?.trim()) {
1209
- cells.pop();
1210
- }
1211
- if (count) {
1212
- if (cells.length > count) {
1213
- cells.splice(count);
1214
- } else {
1215
- while (cells.length < count) cells.push("");
1216
- }
1217
- }
1218
- for (; i < cells.length; i++) {
1219
- cells[i] = cells[i].trim().replace(other.slashPipe, "|");
1220
- }
1221
- return cells;
1222
- }
1223
- function rtrim(str, c, invert) {
1224
- const l = str.length;
1225
- if (l === 0) {
1226
- return "";
1227
- }
1228
- let suffLen = 0;
1229
- while (suffLen < l) {
1230
- const currChar = str.charAt(l - suffLen - 1);
1231
- if (currChar === c && !invert) {
1232
- suffLen++;
1233
- } else if (currChar !== c && invert) {
1234
- suffLen++;
1235
- } else {
1236
- break;
1237
- }
1238
- }
1239
- return str.slice(0, l - suffLen);
1240
- }
1241
- function findClosingBracket(str, b) {
1242
- if (str.indexOf(b[1]) === -1) {
1243
- return -1;
1244
- }
1245
- let level = 0;
1246
- for (let i = 0; i < str.length; i++) {
1247
- if (str[i] === "\\") {
1248
- i++;
1249
- } else if (str[i] === b[0]) {
1250
- level++;
1251
- } else if (str[i] === b[1]) {
1252
- level--;
1253
- if (level < 0) {
1254
- return i;
1255
- }
1256
- }
1257
- }
1258
- if (level > 0) {
1259
- return -2;
1260
- }
1261
- return -1;
1262
- }
1263
- function outputLink(cap, link2, raw, lexer2, rules) {
1264
- const href = link2.href;
1265
- const title = link2.title || null;
1266
- const text = cap[1].replace(rules.other.outputLinkReplace, "$1");
1267
- lexer2.state.inLink = true;
1268
- const token = {
1269
- type: cap[0].charAt(0) === "!" ? "image" : "link",
1270
- raw,
1271
- href,
1272
- title,
1273
- text,
1274
- tokens: lexer2.inlineTokens(text)
1275
- };
1276
- lexer2.state.inLink = false;
1277
- return token;
1278
- }
1279
- function indentCodeCompensation(raw, text, rules) {
1280
- const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);
1281
- if (matchIndentToCode === null) {
1282
- return text;
1283
- }
1284
- const indentToCode = matchIndentToCode[1];
1285
- return text.split("\n").map((node) => {
1286
- const matchIndentInNode = node.match(rules.other.beginningSpace);
1287
- if (matchIndentInNode === null) {
1288
- return node;
1289
- }
1290
- const [indentInNode] = matchIndentInNode;
1291
- if (indentInNode.length >= indentToCode.length) {
1292
- return node.slice(indentToCode.length);
1293
- }
1294
- return node;
1295
- }).join("\n");
1296
- }
1297
- var _Tokenizer = class {
1298
- options;
1299
- rules;
1300
- // set by the lexer
1301
- lexer;
1302
- // set by the lexer
1303
- constructor(options2) {
1304
- this.options = options2 || _defaults;
1305
- }
1306
- space(src) {
1307
- const cap = this.rules.block.newline.exec(src);
1308
- if (cap && cap[0].length > 0) {
1309
- return {
1310
- type: "space",
1311
- raw: cap[0]
1312
- };
1313
- }
1314
- }
1315
- code(src) {
1316
- const cap = this.rules.block.code.exec(src);
1317
- if (cap) {
1318
- const text = cap[0].replace(this.rules.other.codeRemoveIndent, "");
1319
- return {
1320
- type: "code",
1321
- raw: cap[0],
1322
- codeBlockStyle: "indented",
1323
- text: !this.options.pedantic ? rtrim(text, "\n") : text
1324
- };
1325
- }
1326
- }
1327
- fences(src) {
1328
- const cap = this.rules.block.fences.exec(src);
1329
- if (cap) {
1330
- const raw = cap[0];
1331
- const text = indentCodeCompensation(raw, cap[3] || "", this.rules);
1332
- return {
1333
- type: "code",
1334
- raw,
1335
- lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : cap[2],
1336
- text
1337
- };
1338
- }
1339
- }
1340
- heading(src) {
1341
- const cap = this.rules.block.heading.exec(src);
1342
- if (cap) {
1343
- let text = cap[2].trim();
1344
- if (this.rules.other.endingHash.test(text)) {
1345
- const trimmed = rtrim(text, "#");
1346
- if (this.options.pedantic) {
1347
- text = trimmed.trim();
1348
- } else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {
1349
- text = trimmed.trim();
1350
- }
1351
- }
1352
- return {
1353
- type: "heading",
1354
- raw: cap[0],
1355
- depth: cap[1].length,
1356
- text,
1357
- tokens: this.lexer.inline(text)
1358
- };
1359
- }
1360
- }
1361
- hr(src) {
1362
- const cap = this.rules.block.hr.exec(src);
1363
- if (cap) {
1364
- return {
1365
- type: "hr",
1366
- raw: rtrim(cap[0], "\n")
1367
- };
1368
- }
1369
- }
1370
- blockquote(src) {
1371
- const cap = this.rules.block.blockquote.exec(src);
1372
- if (cap) {
1373
- let lines = rtrim(cap[0], "\n").split("\n");
1374
- let raw = "";
1375
- let text = "";
1376
- const tokens = [];
1377
- while (lines.length > 0) {
1378
- let inBlockquote = false;
1379
- const currentLines = [];
1380
- let i;
1381
- for (i = 0; i < lines.length; i++) {
1382
- if (this.rules.other.blockquoteStart.test(lines[i])) {
1383
- currentLines.push(lines[i]);
1384
- inBlockquote = true;
1385
- } else if (!inBlockquote) {
1386
- currentLines.push(lines[i]);
1387
- } else {
1388
- break;
1389
- }
1390
- }
1391
- lines = lines.slice(i);
1392
- const currentRaw = currentLines.join("\n");
1393
- const currentText = currentRaw.replace(this.rules.other.blockquoteSetextReplace, "\n $1").replace(this.rules.other.blockquoteSetextReplace2, "");
1394
- raw = raw ? `${raw}
1395
- ${currentRaw}` : currentRaw;
1396
- text = text ? `${text}
1397
- ${currentText}` : currentText;
1398
- const top = this.lexer.state.top;
1399
- this.lexer.state.top = true;
1400
- this.lexer.blockTokens(currentText, tokens, true);
1401
- this.lexer.state.top = top;
1402
- if (lines.length === 0) {
1403
- break;
1404
- }
1405
- const lastToken = tokens.at(-1);
1406
- if (lastToken?.type === "code") {
1407
- break;
1408
- } else if (lastToken?.type === "blockquote") {
1409
- const oldToken = lastToken;
1410
- const newText = oldToken.raw + "\n" + lines.join("\n");
1411
- const newToken = this.blockquote(newText);
1412
- tokens[tokens.length - 1] = newToken;
1413
- raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;
1414
- text = text.substring(0, text.length - oldToken.text.length) + newToken.text;
1415
- break;
1416
- } else if (lastToken?.type === "list") {
1417
- const oldToken = lastToken;
1418
- const newText = oldToken.raw + "\n" + lines.join("\n");
1419
- const newToken = this.list(newText);
1420
- tokens[tokens.length - 1] = newToken;
1421
- raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
1422
- text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
1423
- lines = newText.substring(tokens.at(-1).raw.length).split("\n");
1424
- continue;
1425
- }
1426
- }
1427
- return {
1428
- type: "blockquote",
1429
- raw,
1430
- tokens,
1431
- text
1432
- };
1433
- }
1434
- }
1435
- list(src) {
1436
- let cap = this.rules.block.list.exec(src);
1437
- if (cap) {
1438
- let bull = cap[1].trim();
1439
- const isordered = bull.length > 1;
1440
- const list2 = {
1441
- type: "list",
1442
- raw: "",
1443
- ordered: isordered,
1444
- start: isordered ? +bull.slice(0, -1) : "",
1445
- loose: false,
1446
- items: []
1447
- };
1448
- bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
1449
- if (this.options.pedantic) {
1450
- bull = isordered ? bull : "[*+-]";
1451
- }
1452
- const itemRegex = this.rules.other.listItemRegex(bull);
1453
- let endsWithBlankLine = false;
1454
- while (src) {
1455
- let endEarly = false;
1456
- let raw = "";
1457
- let itemContents = "";
1458
- if (!(cap = itemRegex.exec(src))) {
1459
- break;
1460
- }
1461
- if (this.rules.block.hr.test(src)) {
1462
- break;
1463
- }
1464
- raw = cap[0];
1465
- src = src.substring(raw.length);
1466
- let line = cap[2].split("\n", 1)[0].replace(this.rules.other.listReplaceTabs, (t) => " ".repeat(3 * t.length));
1467
- let nextLine = src.split("\n", 1)[0];
1468
- let blankLine = !line.trim();
1469
- let indent = 0;
1470
- if (this.options.pedantic) {
1471
- indent = 2;
1472
- itemContents = line.trimStart();
1473
- } else if (blankLine) {
1474
- indent = cap[1].length + 1;
1475
- } else {
1476
- indent = cap[2].search(this.rules.other.nonSpaceChar);
1477
- indent = indent > 4 ? 1 : indent;
1478
- itemContents = line.slice(indent);
1479
- indent += cap[1].length;
1480
- }
1481
- if (blankLine && this.rules.other.blankLine.test(nextLine)) {
1482
- raw += nextLine + "\n";
1483
- src = src.substring(nextLine.length + 1);
1484
- endEarly = true;
1485
- }
1486
- if (!endEarly) {
1487
- const nextBulletRegex = this.rules.other.nextBulletRegex(indent);
1488
- const hrRegex = this.rules.other.hrRegex(indent);
1489
- const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);
1490
- const headingBeginRegex = this.rules.other.headingBeginRegex(indent);
1491
- const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);
1492
- while (src) {
1493
- const rawLine = src.split("\n", 1)[0];
1494
- let nextLineWithoutTabs;
1495
- nextLine = rawLine;
1496
- if (this.options.pedantic) {
1497
- nextLine = nextLine.replace(this.rules.other.listReplaceNesting, " ");
1498
- nextLineWithoutTabs = nextLine;
1499
- } else {
1500
- nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, " ");
1501
- }
1502
- if (fencesBeginRegex.test(nextLine)) {
1503
- break;
1504
- }
1505
- if (headingBeginRegex.test(nextLine)) {
1506
- break;
1507
- }
1508
- if (htmlBeginRegex.test(nextLine)) {
1509
- break;
1510
- }
1511
- if (nextBulletRegex.test(nextLine)) {
1512
- break;
1513
- }
1514
- if (hrRegex.test(nextLine)) {
1515
- break;
1516
- }
1517
- if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) {
1518
- itemContents += "\n" + nextLineWithoutTabs.slice(indent);
1519
- } else {
1520
- if (blankLine) {
1521
- break;
1522
- }
1523
- if (line.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4) {
1524
- break;
1525
- }
1526
- if (fencesBeginRegex.test(line)) {
1527
- break;
1528
- }
1529
- if (headingBeginRegex.test(line)) {
1530
- break;
1531
- }
1532
- if (hrRegex.test(line)) {
1533
- break;
1534
- }
1535
- itemContents += "\n" + nextLine;
1536
- }
1537
- if (!blankLine && !nextLine.trim()) {
1538
- blankLine = true;
1539
- }
1540
- raw += rawLine + "\n";
1541
- src = src.substring(rawLine.length + 1);
1542
- line = nextLineWithoutTabs.slice(indent);
1543
- }
1544
- }
1545
- if (!list2.loose) {
1546
- if (endsWithBlankLine) {
1547
- list2.loose = true;
1548
- } else if (this.rules.other.doubleBlankLine.test(raw)) {
1549
- endsWithBlankLine = true;
1550
- }
1551
- }
1552
- let istask = null;
1553
- let ischecked;
1554
- if (this.options.gfm) {
1555
- istask = this.rules.other.listIsTask.exec(itemContents);
1556
- if (istask) {
1557
- ischecked = istask[0] !== "[ ] ";
1558
- itemContents = itemContents.replace(this.rules.other.listReplaceTask, "");
1559
- }
1560
- }
1561
- list2.items.push({
1562
- type: "list_item",
1563
- raw,
1564
- task: !!istask,
1565
- checked: ischecked,
1566
- loose: false,
1567
- text: itemContents,
1568
- tokens: []
1569
- });
1570
- list2.raw += raw;
1571
- }
1572
- const lastItem = list2.items.at(-1);
1573
- if (lastItem) {
1574
- lastItem.raw = lastItem.raw.trimEnd();
1575
- lastItem.text = lastItem.text.trimEnd();
1576
- } else {
1577
- return;
1578
- }
1579
- list2.raw = list2.raw.trimEnd();
1580
- for (let i = 0; i < list2.items.length; i++) {
1581
- this.lexer.state.top = false;
1582
- list2.items[i].tokens = this.lexer.blockTokens(list2.items[i].text, []);
1583
- if (!list2.loose) {
1584
- const spacers = list2.items[i].tokens.filter((t) => t.type === "space");
1585
- const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((t) => this.rules.other.anyLine.test(t.raw));
1586
- list2.loose = hasMultipleLineBreaks;
1587
- }
1588
- }
1589
- if (list2.loose) {
1590
- for (let i = 0; i < list2.items.length; i++) {
1591
- list2.items[i].loose = true;
1592
- }
1593
- }
1594
- return list2;
1595
- }
1596
- }
1597
- html(src) {
1598
- const cap = this.rules.block.html.exec(src);
1599
- if (cap) {
1600
- const token = {
1601
- type: "html",
1602
- block: true,
1603
- raw: cap[0],
1604
- pre: cap[1] === "pre" || cap[1] === "script" || cap[1] === "style",
1605
- text: cap[0]
1606
- };
1607
- return token;
1608
- }
1609
- }
1610
- def(src) {
1611
- const cap = this.rules.block.def.exec(src);
1612
- if (cap) {
1613
- const tag2 = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " ");
1614
- const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "";
1615
- const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : cap[3];
1616
- return {
1617
- type: "def",
1618
- tag: tag2,
1619
- raw: cap[0],
1620
- href,
1621
- title
1622
- };
1623
- }
1624
- }
1625
- table(src) {
1626
- const cap = this.rules.block.table.exec(src);
1627
- if (!cap) {
1628
- return;
1629
- }
1630
- if (!this.rules.other.tableDelimiter.test(cap[2])) {
1631
- return;
1632
- }
1633
- const headers = splitCells(cap[1]);
1634
- const aligns = cap[2].replace(this.rules.other.tableAlignChars, "").split("|");
1635
- const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, "").split("\n") : [];
1636
- const item = {
1637
- type: "table",
1638
- raw: cap[0],
1639
- header: [],
1640
- align: [],
1641
- rows: []
1642
- };
1643
- if (headers.length !== aligns.length) {
1644
- return;
1645
- }
1646
- for (const align of aligns) {
1647
- if (this.rules.other.tableAlignRight.test(align)) {
1648
- item.align.push("right");
1649
- } else if (this.rules.other.tableAlignCenter.test(align)) {
1650
- item.align.push("center");
1651
- } else if (this.rules.other.tableAlignLeft.test(align)) {
1652
- item.align.push("left");
1653
- } else {
1654
- item.align.push(null);
1655
- }
1656
- }
1657
- for (let i = 0; i < headers.length; i++) {
1658
- item.header.push({
1659
- text: headers[i],
1660
- tokens: this.lexer.inline(headers[i]),
1661
- header: true,
1662
- align: item.align[i]
1663
- });
1664
- }
1665
- for (const row of rows) {
1666
- item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
1667
- return {
1668
- text: cell,
1669
- tokens: this.lexer.inline(cell),
1670
- header: false,
1671
- align: item.align[i]
1672
- };
1673
- }));
1674
- }
1675
- return item;
1676
- }
1677
- lheading(src) {
1678
- const cap = this.rules.block.lheading.exec(src);
1679
- if (cap) {
1680
- return {
1681
- type: "heading",
1682
- raw: cap[0],
1683
- depth: cap[2].charAt(0) === "=" ? 1 : 2,
1684
- text: cap[1],
1685
- tokens: this.lexer.inline(cap[1])
1686
- };
1687
- }
1688
- }
1689
- paragraph(src) {
1690
- const cap = this.rules.block.paragraph.exec(src);
1691
- if (cap) {
1692
- const text = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1];
1693
- return {
1694
- type: "paragraph",
1695
- raw: cap[0],
1696
- text,
1697
- tokens: this.lexer.inline(text)
1698
- };
1699
- }
1700
- }
1701
- text(src) {
1702
- const cap = this.rules.block.text.exec(src);
1703
- if (cap) {
1704
- return {
1705
- type: "text",
1706
- raw: cap[0],
1707
- text: cap[0],
1708
- tokens: this.lexer.inline(cap[0])
1709
- };
1710
- }
1711
- }
1712
- escape(src) {
1713
- const cap = this.rules.inline.escape.exec(src);
1714
- if (cap) {
1715
- return {
1716
- type: "escape",
1717
- raw: cap[0],
1718
- text: cap[1]
1719
- };
1720
- }
1721
- }
1722
- tag(src) {
1723
- const cap = this.rules.inline.tag.exec(src);
1724
- if (cap) {
1725
- if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {
1726
- this.lexer.state.inLink = true;
1727
- } else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {
1728
- this.lexer.state.inLink = false;
1729
- }
1730
- if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {
1731
- this.lexer.state.inRawBlock = true;
1732
- } else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {
1733
- this.lexer.state.inRawBlock = false;
1734
- }
1735
- return {
1736
- type: "html",
1737
- raw: cap[0],
1738
- inLink: this.lexer.state.inLink,
1739
- inRawBlock: this.lexer.state.inRawBlock,
1740
- block: false,
1741
- text: cap[0]
1742
- };
1743
- }
1744
- }
1745
- link(src) {
1746
- const cap = this.rules.inline.link.exec(src);
1747
- if (cap) {
1748
- const trimmedUrl = cap[2].trim();
1749
- if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {
1750
- if (!this.rules.other.endAngleBracket.test(trimmedUrl)) {
1751
- return;
1752
- }
1753
- const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\");
1754
- if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
1755
- return;
1756
- }
1757
- } else {
1758
- const lastParenIndex = findClosingBracket(cap[2], "()");
1759
- if (lastParenIndex === -2) {
1760
- return;
1761
- }
1762
- if (lastParenIndex > -1) {
1763
- const start = cap[0].indexOf("!") === 0 ? 5 : 4;
1764
- const linkLen = start + cap[1].length + lastParenIndex;
1765
- cap[2] = cap[2].substring(0, lastParenIndex);
1766
- cap[0] = cap[0].substring(0, linkLen).trim();
1767
- cap[3] = "";
1768
- }
1769
- }
1770
- let href = cap[2];
1771
- let title = "";
1772
- if (this.options.pedantic) {
1773
- const link2 = this.rules.other.pedanticHrefTitle.exec(href);
1774
- if (link2) {
1775
- href = link2[1];
1776
- title = link2[3];
1777
- }
1778
- } else {
1779
- title = cap[3] ? cap[3].slice(1, -1) : "";
1780
- }
1781
- href = href.trim();
1782
- if (this.rules.other.startAngleBracket.test(href)) {
1783
- if (this.options.pedantic && !this.rules.other.endAngleBracket.test(trimmedUrl)) {
1784
- href = href.slice(1);
1785
- } else {
1786
- href = href.slice(1, -1);
1787
- }
1788
- }
1789
- return outputLink(cap, {
1790
- href: href ? href.replace(this.rules.inline.anyPunctuation, "$1") : href,
1791
- title: title ? title.replace(this.rules.inline.anyPunctuation, "$1") : title
1792
- }, cap[0], this.lexer, this.rules);
1793
- }
1794
- }
1795
- reflink(src, links) {
1796
- let cap;
1797
- if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
1798
- const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, " ");
1799
- const link2 = links[linkString.toLowerCase()];
1800
- if (!link2) {
1801
- const text = cap[0].charAt(0);
1802
- return {
1803
- type: "text",
1804
- raw: text,
1805
- text
1806
- };
1807
- }
1808
- return outputLink(cap, link2, cap[0], this.lexer, this.rules);
1809
- }
1810
- }
1811
- emStrong(src, maskedSrc, prevChar = "") {
1812
- let match = this.rules.inline.emStrongLDelim.exec(src);
1813
- if (!match) return;
1814
- if (match[3] && prevChar.match(this.rules.other.unicodeAlphaNumeric)) return;
1815
- const nextChar = match[1] || match[2] || "";
1816
- if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
1817
- const lLength = [...match[0]].length - 1;
1818
- let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
1819
- const endReg = match[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
1820
- endReg.lastIndex = 0;
1821
- maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
1822
- while ((match = endReg.exec(maskedSrc)) != null) {
1823
- rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
1824
- if (!rDelim) continue;
1825
- rLength = [...rDelim].length;
1826
- if (match[3] || match[4]) {
1827
- delimTotal += rLength;
1828
- continue;
1829
- } else if (match[5] || match[6]) {
1830
- if (lLength % 3 && !((lLength + rLength) % 3)) {
1831
- midDelimTotal += rLength;
1832
- continue;
1833
- }
1834
- }
1835
- delimTotal -= rLength;
1836
- if (delimTotal > 0) continue;
1837
- rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
1838
- const lastCharLength = [...match[0]][0].length;
1839
- const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);
1840
- if (Math.min(lLength, rLength) % 2) {
1841
- const text2 = raw.slice(1, -1);
1842
- return {
1843
- type: "em",
1844
- raw,
1845
- text: text2,
1846
- tokens: this.lexer.inlineTokens(text2)
1847
- };
1848
- }
1849
- const text = raw.slice(2, -2);
1850
- return {
1851
- type: "strong",
1852
- raw,
1853
- text,
1854
- tokens: this.lexer.inlineTokens(text)
1855
- };
1856
- }
1857
- }
1858
- }
1859
- codespan(src) {
1860
- const cap = this.rules.inline.code.exec(src);
1861
- if (cap) {
1862
- let text = cap[2].replace(this.rules.other.newLineCharGlobal, " ");
1863
- const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);
1864
- const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);
1865
- if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
1866
- text = text.substring(1, text.length - 1);
1867
- }
1868
- return {
1869
- type: "codespan",
1870
- raw: cap[0],
1871
- text
1872
- };
1873
- }
1874
- }
1875
- br(src) {
1876
- const cap = this.rules.inline.br.exec(src);
1877
- if (cap) {
1878
- return {
1879
- type: "br",
1880
- raw: cap[0]
1881
- };
1882
- }
1883
- }
1884
- del(src) {
1885
- const cap = this.rules.inline.del.exec(src);
1886
- if (cap) {
1887
- return {
1888
- type: "del",
1889
- raw: cap[0],
1890
- text: cap[2],
1891
- tokens: this.lexer.inlineTokens(cap[2])
1892
- };
1893
- }
1894
- }
1895
- autolink(src) {
1896
- const cap = this.rules.inline.autolink.exec(src);
1897
- if (cap) {
1898
- let text, href;
1899
- if (cap[2] === "@") {
1900
- text = cap[1];
1901
- href = "mailto:" + text;
1902
- } else {
1903
- text = cap[1];
1904
- href = text;
1905
- }
1906
- return {
1907
- type: "link",
1908
- raw: cap[0],
1909
- text,
1910
- href,
1911
- tokens: [
1912
- {
1913
- type: "text",
1914
- raw: text,
1915
- text
1916
- }
1917
- ]
1918
- };
1919
- }
1920
- }
1921
- url(src) {
1922
- let cap;
1923
- if (cap = this.rules.inline.url.exec(src)) {
1924
- let text, href;
1925
- if (cap[2] === "@") {
1926
- text = cap[0];
1927
- href = "mailto:" + text;
1928
- } else {
1929
- let prevCapZero;
1930
- do {
1931
- prevCapZero = cap[0];
1932
- cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? "";
1933
- } while (prevCapZero !== cap[0]);
1934
- text = cap[0];
1935
- if (cap[1] === "www.") {
1936
- href = "http://" + cap[0];
1937
- } else {
1938
- href = cap[0];
1939
- }
1940
- }
1941
- return {
1942
- type: "link",
1943
- raw: cap[0],
1944
- text,
1945
- href,
1946
- tokens: [
1947
- {
1948
- type: "text",
1949
- raw: text,
1950
- text
1951
- }
1952
- ]
1953
- };
1954
- }
1955
- }
1956
- inlineText(src) {
1957
- const cap = this.rules.inline.text.exec(src);
1958
- if (cap) {
1959
- const escaped = this.lexer.state.inRawBlock;
1960
- return {
1961
- type: "text",
1962
- raw: cap[0],
1963
- text: cap[0],
1964
- escaped
1965
- };
1966
- }
1967
- }
1968
- };
1969
- var _Lexer = class __Lexer {
1970
- tokens;
1971
- options;
1972
- state;
1973
- tokenizer;
1974
- inlineQueue;
1975
- constructor(options2) {
1976
- this.tokens = [];
1977
- this.tokens.links = /* @__PURE__ */ Object.create(null);
1978
- this.options = options2 || _defaults;
1979
- this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
1980
- this.tokenizer = this.options.tokenizer;
1981
- this.tokenizer.options = this.options;
1982
- this.tokenizer.lexer = this;
1983
- this.inlineQueue = [];
1984
- this.state = {
1985
- inLink: false,
1986
- inRawBlock: false,
1987
- top: true
1988
- };
1989
- const rules = {
1990
- other,
1991
- block: block.normal,
1992
- inline: inline.normal
1993
- };
1994
- if (this.options.pedantic) {
1995
- rules.block = block.pedantic;
1996
- rules.inline = inline.pedantic;
1997
- } else if (this.options.gfm) {
1998
- rules.block = block.gfm;
1999
- if (this.options.breaks) {
2000
- rules.inline = inline.breaks;
2001
- } else {
2002
- rules.inline = inline.gfm;
2003
- }
2004
- }
2005
- this.tokenizer.rules = rules;
2006
- }
2007
- /**
2008
- * Expose Rules
2009
- */
2010
- static get rules() {
2011
- return {
2012
- block,
2013
- inline
2014
- };
2015
- }
2016
- /**
2017
- * Static Lex Method
2018
- */
2019
- static lex(src, options2) {
2020
- const lexer2 = new __Lexer(options2);
2021
- return lexer2.lex(src);
2022
- }
2023
- /**
2024
- * Static Lex Inline Method
2025
- */
2026
- static lexInline(src, options2) {
2027
- const lexer2 = new __Lexer(options2);
2028
- return lexer2.inlineTokens(src);
2029
- }
2030
- /**
2031
- * Preprocessing
2032
- */
2033
- lex(src) {
2034
- src = src.replace(other.carriageReturn, "\n");
2035
- this.blockTokens(src, this.tokens);
2036
- for (let i = 0; i < this.inlineQueue.length; i++) {
2037
- const next = this.inlineQueue[i];
2038
- this.inlineTokens(next.src, next.tokens);
2039
- }
2040
- this.inlineQueue = [];
2041
- return this.tokens;
2042
- }
2043
- blockTokens(src, tokens = [], lastParagraphClipped = false) {
2044
- if (this.options.pedantic) {
2045
- src = src.replace(other.tabCharGlobal, " ").replace(other.spaceLine, "");
2046
- }
2047
- while (src) {
2048
- let token;
2049
- if (this.options.extensions?.block?.some((extTokenizer) => {
2050
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
2051
- src = src.substring(token.raw.length);
2052
- tokens.push(token);
2053
- return true;
2054
- }
2055
- return false;
2056
- })) {
2057
- continue;
2058
- }
2059
- if (token = this.tokenizer.space(src)) {
2060
- src = src.substring(token.raw.length);
2061
- const lastToken = tokens.at(-1);
2062
- if (token.raw.length === 1 && lastToken !== void 0) {
2063
- lastToken.raw += "\n";
2064
- } else {
2065
- tokens.push(token);
2066
- }
2067
- continue;
2068
- }
2069
- if (token = this.tokenizer.code(src)) {
2070
- src = src.substring(token.raw.length);
2071
- const lastToken = tokens.at(-1);
2072
- if (lastToken?.type === "paragraph" || lastToken?.type === "text") {
2073
- lastToken.raw += "\n" + token.raw;
2074
- lastToken.text += "\n" + token.text;
2075
- this.inlineQueue.at(-1).src = lastToken.text;
2076
- } else {
2077
- tokens.push(token);
2078
- }
2079
- continue;
2080
- }
2081
- if (token = this.tokenizer.fences(src)) {
2082
- src = src.substring(token.raw.length);
2083
- tokens.push(token);
2084
- continue;
2085
- }
2086
- if (token = this.tokenizer.heading(src)) {
2087
- src = src.substring(token.raw.length);
2088
- tokens.push(token);
2089
- continue;
2090
- }
2091
- if (token = this.tokenizer.hr(src)) {
2092
- src = src.substring(token.raw.length);
2093
- tokens.push(token);
2094
- continue;
2095
- }
2096
- if (token = this.tokenizer.blockquote(src)) {
2097
- src = src.substring(token.raw.length);
2098
- tokens.push(token);
2099
- continue;
2100
- }
2101
- if (token = this.tokenizer.list(src)) {
2102
- src = src.substring(token.raw.length);
2103
- tokens.push(token);
2104
- continue;
2105
- }
2106
- if (token = this.tokenizer.html(src)) {
2107
- src = src.substring(token.raw.length);
2108
- tokens.push(token);
2109
- continue;
2110
- }
2111
- if (token = this.tokenizer.def(src)) {
2112
- src = src.substring(token.raw.length);
2113
- const lastToken = tokens.at(-1);
2114
- if (lastToken?.type === "paragraph" || lastToken?.type === "text") {
2115
- lastToken.raw += "\n" + token.raw;
2116
- lastToken.text += "\n" + token.raw;
2117
- this.inlineQueue.at(-1).src = lastToken.text;
2118
- } else if (!this.tokens.links[token.tag]) {
2119
- this.tokens.links[token.tag] = {
2120
- href: token.href,
2121
- title: token.title
2122
- };
2123
- }
2124
- continue;
2125
- }
2126
- if (token = this.tokenizer.table(src)) {
2127
- src = src.substring(token.raw.length);
2128
- tokens.push(token);
2129
- continue;
2130
- }
2131
- if (token = this.tokenizer.lheading(src)) {
2132
- src = src.substring(token.raw.length);
2133
- tokens.push(token);
2134
- continue;
2135
- }
2136
- let cutSrc = src;
2137
- if (this.options.extensions?.startBlock) {
2138
- let startIndex = Infinity;
2139
- const tempSrc = src.slice(1);
2140
- let tempStart;
2141
- this.options.extensions.startBlock.forEach((getStartIndex) => {
2142
- tempStart = getStartIndex.call({ lexer: this }, tempSrc);
2143
- if (typeof tempStart === "number" && tempStart >= 0) {
2144
- startIndex = Math.min(startIndex, tempStart);
2145
- }
2146
- });
2147
- if (startIndex < Infinity && startIndex >= 0) {
2148
- cutSrc = src.substring(0, startIndex + 1);
2149
- }
2150
- }
2151
- if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
2152
- const lastToken = tokens.at(-1);
2153
- if (lastParagraphClipped && lastToken?.type === "paragraph") {
2154
- lastToken.raw += "\n" + token.raw;
2155
- lastToken.text += "\n" + token.text;
2156
- this.inlineQueue.pop();
2157
- this.inlineQueue.at(-1).src = lastToken.text;
2158
- } else {
2159
- tokens.push(token);
2160
- }
2161
- lastParagraphClipped = cutSrc.length !== src.length;
2162
- src = src.substring(token.raw.length);
2163
- continue;
2164
- }
2165
- if (token = this.tokenizer.text(src)) {
2166
- src = src.substring(token.raw.length);
2167
- const lastToken = tokens.at(-1);
2168
- if (lastToken?.type === "text") {
2169
- lastToken.raw += "\n" + token.raw;
2170
- lastToken.text += "\n" + token.text;
2171
- this.inlineQueue.pop();
2172
- this.inlineQueue.at(-1).src = lastToken.text;
2173
- } else {
2174
- tokens.push(token);
2175
- }
2176
- continue;
2177
- }
2178
- if (src) {
2179
- const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
2180
- if (this.options.silent) {
2181
- console.error(errMsg);
2182
- break;
2183
- } else {
2184
- throw new Error(errMsg);
2185
- }
2186
- }
2187
- }
2188
- this.state.top = true;
2189
- return tokens;
2190
- }
2191
- inline(src, tokens = []) {
2192
- this.inlineQueue.push({ src, tokens });
2193
- return tokens;
2194
- }
2195
- /**
2196
- * Lexing/Compiling
2197
- */
2198
- inlineTokens(src, tokens = []) {
2199
- let maskedSrc = src;
2200
- let match = null;
2201
- if (this.tokens.links) {
2202
- const links = Object.keys(this.tokens.links);
2203
- if (links.length > 0) {
2204
- while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
2205
- if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) {
2206
- maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
2207
- }
2208
- }
2209
- }
2210
- }
2211
- while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
2212
- maskedSrc = maskedSrc.slice(0, match.index) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
2213
- }
2214
- while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
2215
- maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
2216
- }
2217
- let keepPrevChar = false;
2218
- let prevChar = "";
2219
- while (src) {
2220
- if (!keepPrevChar) {
2221
- prevChar = "";
2222
- }
2223
- keepPrevChar = false;
2224
- let token;
2225
- if (this.options.extensions?.inline?.some((extTokenizer) => {
2226
- if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
2227
- src = src.substring(token.raw.length);
2228
- tokens.push(token);
2229
- return true;
2230
- }
2231
- return false;
2232
- })) {
2233
- continue;
2234
- }
2235
- if (token = this.tokenizer.escape(src)) {
2236
- src = src.substring(token.raw.length);
2237
- tokens.push(token);
2238
- continue;
2239
- }
2240
- if (token = this.tokenizer.tag(src)) {
2241
- src = src.substring(token.raw.length);
2242
- tokens.push(token);
2243
- continue;
2244
- }
2245
- if (token = this.tokenizer.link(src)) {
2246
- src = src.substring(token.raw.length);
2247
- tokens.push(token);
2248
- continue;
2249
- }
2250
- if (token = this.tokenizer.reflink(src, this.tokens.links)) {
2251
- src = src.substring(token.raw.length);
2252
- const lastToken = tokens.at(-1);
2253
- if (token.type === "text" && lastToken?.type === "text") {
2254
- lastToken.raw += token.raw;
2255
- lastToken.text += token.text;
2256
- } else {
2257
- tokens.push(token);
2258
- }
2259
- continue;
2260
- }
2261
- if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
2262
- src = src.substring(token.raw.length);
2263
- tokens.push(token);
2264
- continue;
2265
- }
2266
- if (token = this.tokenizer.codespan(src)) {
2267
- src = src.substring(token.raw.length);
2268
- tokens.push(token);
2269
- continue;
2270
- }
2271
- if (token = this.tokenizer.br(src)) {
2272
- src = src.substring(token.raw.length);
2273
- tokens.push(token);
2274
- continue;
2275
- }
2276
- if (token = this.tokenizer.del(src)) {
2277
- src = src.substring(token.raw.length);
2278
- tokens.push(token);
2279
- continue;
2280
- }
2281
- if (token = this.tokenizer.autolink(src)) {
2282
- src = src.substring(token.raw.length);
2283
- tokens.push(token);
2284
- continue;
2285
- }
2286
- if (!this.state.inLink && (token = this.tokenizer.url(src))) {
2287
- src = src.substring(token.raw.length);
2288
- tokens.push(token);
2289
- continue;
2290
- }
2291
- let cutSrc = src;
2292
- if (this.options.extensions?.startInline) {
2293
- let startIndex = Infinity;
2294
- const tempSrc = src.slice(1);
2295
- let tempStart;
2296
- this.options.extensions.startInline.forEach((getStartIndex) => {
2297
- tempStart = getStartIndex.call({ lexer: this }, tempSrc);
2298
- if (typeof tempStart === "number" && tempStart >= 0) {
2299
- startIndex = Math.min(startIndex, tempStart);
2300
- }
2301
- });
2302
- if (startIndex < Infinity && startIndex >= 0) {
2303
- cutSrc = src.substring(0, startIndex + 1);
2304
- }
2305
- }
2306
- if (token = this.tokenizer.inlineText(cutSrc)) {
2307
- src = src.substring(token.raw.length);
2308
- if (token.raw.slice(-1) !== "_") {
2309
- prevChar = token.raw.slice(-1);
2310
- }
2311
- keepPrevChar = true;
2312
- const lastToken = tokens.at(-1);
2313
- if (lastToken?.type === "text") {
2314
- lastToken.raw += token.raw;
2315
- lastToken.text += token.text;
2316
- } else {
2317
- tokens.push(token);
2318
- }
2319
- continue;
2320
- }
2321
- if (src) {
2322
- const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
2323
- if (this.options.silent) {
2324
- console.error(errMsg);
2325
- break;
2326
- } else {
2327
- throw new Error(errMsg);
2328
- }
2329
- }
2330
- }
2331
- return tokens;
2332
- }
2333
- };
2334
- var _Renderer = class {
2335
- options;
2336
- parser;
2337
- // set by the parser
2338
- constructor(options2) {
2339
- this.options = options2 || _defaults;
2340
- }
2341
- space(token) {
2342
- return "";
2343
- }
2344
- code({ text, lang, escaped }) {
2345
- const langString = (lang || "").match(other.notSpaceStart)?.[0];
2346
- const code = text.replace(other.endingNewline, "") + "\n";
2347
- if (!langString) {
2348
- return "<pre><code>" + (escaped ? code : escape2(code, true)) + "</code></pre>\n";
2349
- }
2350
- return '<pre><code class="language-' + escape2(langString) + '">' + (escaped ? code : escape2(code, true)) + "</code></pre>\n";
2351
- }
2352
- blockquote({ tokens }) {
2353
- const body = this.parser.parse(tokens);
2354
- return `<blockquote>
2355
- ${body}</blockquote>
2356
- `;
2357
- }
2358
- html({ text }) {
2359
- return text;
2360
- }
2361
- heading({ tokens, depth }) {
2362
- return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>
2363
- `;
2364
- }
2365
- hr(token) {
2366
- return "<hr>\n";
2367
- }
2368
- list(token) {
2369
- const ordered = token.ordered;
2370
- const start = token.start;
2371
- let body = "";
2372
- for (let j = 0; j < token.items.length; j++) {
2373
- const item = token.items[j];
2374
- body += this.listitem(item);
2375
- }
2376
- const type = ordered ? "ol" : "ul";
2377
- const startAttr = ordered && start !== 1 ? ' start="' + start + '"' : "";
2378
- return "<" + type + startAttr + ">\n" + body + "</" + type + ">\n";
2379
- }
2380
- listitem(item) {
2381
- let itemBody = "";
2382
- if (item.task) {
2383
- const checkbox = this.checkbox({ checked: !!item.checked });
2384
- if (item.loose) {
2385
- if (item.tokens[0]?.type === "paragraph") {
2386
- item.tokens[0].text = checkbox + " " + item.tokens[0].text;
2387
- if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
2388
- item.tokens[0].tokens[0].text = checkbox + " " + escape2(item.tokens[0].tokens[0].text);
2389
- item.tokens[0].tokens[0].escaped = true;
2390
- }
2391
- } else {
2392
- item.tokens.unshift({
2393
- type: "text",
2394
- raw: checkbox + " ",
2395
- text: checkbox + " ",
2396
- escaped: true
2397
- });
2398
- }
2399
- } else {
2400
- itemBody += checkbox + " ";
2401
- }
2402
- }
2403
- itemBody += this.parser.parse(item.tokens, !!item.loose);
2404
- return `<li>${itemBody}</li>
2405
- `;
2406
- }
2407
- checkbox({ checked }) {
2408
- return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
2409
- }
2410
- paragraph({ tokens }) {
2411
- return `<p>${this.parser.parseInline(tokens)}</p>
2412
- `;
2413
- }
2414
- table(token) {
2415
- let header = "";
2416
- let cell = "";
2417
- for (let j = 0; j < token.header.length; j++) {
2418
- cell += this.tablecell(token.header[j]);
2419
- }
2420
- header += this.tablerow({ text: cell });
2421
- let body = "";
2422
- for (let j = 0; j < token.rows.length; j++) {
2423
- const row = token.rows[j];
2424
- cell = "";
2425
- for (let k = 0; k < row.length; k++) {
2426
- cell += this.tablecell(row[k]);
2427
- }
2428
- body += this.tablerow({ text: cell });
2429
- }
2430
- if (body) body = `<tbody>${body}</tbody>`;
2431
- return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
2432
- }
2433
- tablerow({ text }) {
2434
- return `<tr>
2435
- ${text}</tr>
2436
- `;
2437
- }
2438
- tablecell(token) {
2439
- const content = this.parser.parseInline(token.tokens);
2440
- const type = token.header ? "th" : "td";
2441
- const tag2 = token.align ? `<${type} align="${token.align}">` : `<${type}>`;
2442
- return tag2 + content + `</${type}>
2443
- `;
2444
- }
2445
- /**
2446
- * span level renderer
2447
- */
2448
- strong({ tokens }) {
2449
- return `<strong>${this.parser.parseInline(tokens)}</strong>`;
2450
- }
2451
- em({ tokens }) {
2452
- return `<em>${this.parser.parseInline(tokens)}</em>`;
2453
- }
2454
- codespan({ text }) {
2455
- return `<code>${escape2(text, true)}</code>`;
2456
- }
2457
- br(token) {
2458
- return "<br>";
2459
- }
2460
- del({ tokens }) {
2461
- return `<del>${this.parser.parseInline(tokens)}</del>`;
2462
- }
2463
- link({ href, title, tokens }) {
2464
- const text = this.parser.parseInline(tokens);
2465
- const cleanHref = cleanUrl(href);
2466
- if (cleanHref === null) {
2467
- return text;
2468
- }
2469
- href = cleanHref;
2470
- let out = '<a href="' + href + '"';
2471
- if (title) {
2472
- out += ' title="' + escape2(title) + '"';
2473
- }
2474
- out += ">" + text + "</a>";
2475
- return out;
2476
- }
2477
- image({ href, title, text, tokens }) {
2478
- if (tokens) {
2479
- text = this.parser.parseInline(tokens, this.parser.textRenderer);
2480
- }
2481
- const cleanHref = cleanUrl(href);
2482
- if (cleanHref === null) {
2483
- return escape2(text);
2484
- }
2485
- href = cleanHref;
2486
- let out = `<img src="${href}" alt="${text}"`;
2487
- if (title) {
2488
- out += ` title="${escape2(title)}"`;
2489
- }
2490
- out += ">";
2491
- return out;
2492
- }
2493
- text(token) {
2494
- return "tokens" in token && token.tokens ? this.parser.parseInline(token.tokens) : "escaped" in token && token.escaped ? token.text : escape2(token.text);
2495
- }
2496
- };
2497
- var _TextRenderer = class {
2498
- // no need for block level renderers
2499
- strong({ text }) {
2500
- return text;
2501
- }
2502
- em({ text }) {
2503
- return text;
2504
- }
2505
- codespan({ text }) {
2506
- return text;
2507
- }
2508
- del({ text }) {
2509
- return text;
2510
- }
2511
- html({ text }) {
2512
- return text;
2513
- }
2514
- text({ text }) {
2515
- return text;
2516
- }
2517
- link({ text }) {
2518
- return "" + text;
2519
- }
2520
- image({ text }) {
2521
- return "" + text;
2522
- }
2523
- br() {
2524
- return "";
2525
- }
2526
- };
2527
- var _Parser = class __Parser {
2528
- options;
2529
- renderer;
2530
- textRenderer;
2531
- constructor(options2) {
2532
- this.options = options2 || _defaults;
2533
- this.options.renderer = this.options.renderer || new _Renderer();
2534
- this.renderer = this.options.renderer;
2535
- this.renderer.options = this.options;
2536
- this.renderer.parser = this;
2537
- this.textRenderer = new _TextRenderer();
2538
- }
2539
- /**
2540
- * Static Parse Method
2541
- */
2542
- static parse(tokens, options2) {
2543
- const parser2 = new __Parser(options2);
2544
- return parser2.parse(tokens);
2545
- }
2546
- /**
2547
- * Static Parse Inline Method
2548
- */
2549
- static parseInline(tokens, options2) {
2550
- const parser2 = new __Parser(options2);
2551
- return parser2.parseInline(tokens);
2552
- }
2553
- /**
2554
- * Parse Loop
2555
- */
2556
- parse(tokens, top = true) {
2557
- let out = "";
2558
- for (let i = 0; i < tokens.length; i++) {
2559
- const anyToken = tokens[i];
2560
- if (this.options.extensions?.renderers?.[anyToken.type]) {
2561
- const genericToken = anyToken;
2562
- const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
2563
- if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(genericToken.type)) {
2564
- out += ret || "";
2565
- continue;
2566
- }
2567
- }
2568
- const token = anyToken;
2569
- switch (token.type) {
2570
- case "space": {
2571
- out += this.renderer.space(token);
2572
- continue;
2573
- }
2574
- case "hr": {
2575
- out += this.renderer.hr(token);
2576
- continue;
2577
- }
2578
- case "heading": {
2579
- out += this.renderer.heading(token);
2580
- continue;
2581
- }
2582
- case "code": {
2583
- out += this.renderer.code(token);
2584
- continue;
2585
- }
2586
- case "table": {
2587
- out += this.renderer.table(token);
2588
- continue;
2589
- }
2590
- case "blockquote": {
2591
- out += this.renderer.blockquote(token);
2592
- continue;
2593
- }
2594
- case "list": {
2595
- out += this.renderer.list(token);
2596
- continue;
2597
- }
2598
- case "html": {
2599
- out += this.renderer.html(token);
2600
- continue;
2601
- }
2602
- case "paragraph": {
2603
- out += this.renderer.paragraph(token);
2604
- continue;
2605
- }
2606
- case "text": {
2607
- let textToken = token;
2608
- let body = this.renderer.text(textToken);
2609
- while (i + 1 < tokens.length && tokens[i + 1].type === "text") {
2610
- textToken = tokens[++i];
2611
- body += "\n" + this.renderer.text(textToken);
2612
- }
2613
- if (top) {
2614
- out += this.renderer.paragraph({
2615
- type: "paragraph",
2616
- raw: body,
2617
- text: body,
2618
- tokens: [{ type: "text", raw: body, text: body, escaped: true }]
2619
- });
2620
- } else {
2621
- out += body;
2622
- }
2623
- continue;
2624
- }
2625
- default: {
2626
- const errMsg = 'Token with "' + token.type + '" type was not found.';
2627
- if (this.options.silent) {
2628
- console.error(errMsg);
2629
- return "";
2630
- } else {
2631
- throw new Error(errMsg);
2632
- }
2633
- }
2634
- }
2635
- }
2636
- return out;
2637
- }
2638
- /**
2639
- * Parse Inline Tokens
2640
- */
2641
- parseInline(tokens, renderer = this.renderer) {
2642
- let out = "";
2643
- for (let i = 0; i < tokens.length; i++) {
2644
- const anyToken = tokens[i];
2645
- if (this.options.extensions?.renderers?.[anyToken.type]) {
2646
- const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
2647
- if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(anyToken.type)) {
2648
- out += ret || "";
2649
- continue;
2650
- }
2651
- }
2652
- const token = anyToken;
2653
- switch (token.type) {
2654
- case "escape": {
2655
- out += renderer.text(token);
2656
- break;
2657
- }
2658
- case "html": {
2659
- out += renderer.html(token);
2660
- break;
2661
- }
2662
- case "link": {
2663
- out += renderer.link(token);
2664
- break;
2665
- }
2666
- case "image": {
2667
- out += renderer.image(token);
2668
- break;
2669
- }
2670
- case "strong": {
2671
- out += renderer.strong(token);
2672
- break;
2673
- }
2674
- case "em": {
2675
- out += renderer.em(token);
2676
- break;
2677
- }
2678
- case "codespan": {
2679
- out += renderer.codespan(token);
2680
- break;
2681
- }
2682
- case "br": {
2683
- out += renderer.br(token);
2684
- break;
2685
- }
2686
- case "del": {
2687
- out += renderer.del(token);
2688
- break;
2689
- }
2690
- case "text": {
2691
- out += renderer.text(token);
2692
- break;
2693
- }
2694
- default: {
2695
- const errMsg = 'Token with "' + token.type + '" type was not found.';
2696
- if (this.options.silent) {
2697
- console.error(errMsg);
2698
- return "";
2699
- } else {
2700
- throw new Error(errMsg);
2701
- }
2702
- }
2703
- }
2704
- }
2705
- return out;
2706
- }
2707
- };
2708
- var _Hooks = class {
2709
- options;
2710
- block;
2711
- constructor(options2) {
2712
- this.options = options2 || _defaults;
2713
- }
2714
- static passThroughHooks = /* @__PURE__ */ new Set([
2715
- "preprocess",
2716
- "postprocess",
2717
- "processAllTokens"
2718
- ]);
2719
- /**
2720
- * Process markdown before marked
2721
- */
2722
- preprocess(markdown) {
2723
- return markdown;
2724
- }
2725
- /**
2726
- * Process HTML after marked is finished
2727
- */
2728
- postprocess(html2) {
2729
- return html2;
2730
- }
2731
- /**
2732
- * Process all tokens before walk tokens
2733
- */
2734
- processAllTokens(tokens) {
2735
- return tokens;
2736
- }
2737
- /**
2738
- * Provide function to tokenize markdown
2739
- */
2740
- provideLexer() {
2741
- return this.block ? _Lexer.lex : _Lexer.lexInline;
2742
- }
2743
- /**
2744
- * Provide function to parse tokens
2745
- */
2746
- provideParser() {
2747
- return this.block ? _Parser.parse : _Parser.parseInline;
2748
- }
2749
- };
2750
- var Marked = class {
2751
- defaults = _getDefaults();
2752
- options = this.setOptions;
2753
- parse = this.parseMarkdown(true);
2754
- parseInline = this.parseMarkdown(false);
2755
- Parser = _Parser;
2756
- Renderer = _Renderer;
2757
- TextRenderer = _TextRenderer;
2758
- Lexer = _Lexer;
2759
- Tokenizer = _Tokenizer;
2760
- Hooks = _Hooks;
2761
- constructor(...args) {
2762
- this.use(...args);
2763
- }
2764
- /**
2765
- * Run callback for every token
2766
- */
2767
- walkTokens(tokens, callback) {
2768
- let values = [];
2769
- for (const token of tokens) {
2770
- values = values.concat(callback.call(this, token));
2771
- switch (token.type) {
2772
- case "table": {
2773
- const tableToken = token;
2774
- for (const cell of tableToken.header) {
2775
- values = values.concat(this.walkTokens(cell.tokens, callback));
2776
- }
2777
- for (const row of tableToken.rows) {
2778
- for (const cell of row) {
2779
- values = values.concat(this.walkTokens(cell.tokens, callback));
2780
- }
2781
- }
2782
- break;
2783
- }
2784
- case "list": {
2785
- const listToken = token;
2786
- values = values.concat(this.walkTokens(listToken.items, callback));
2787
- break;
2788
- }
2789
- default: {
2790
- const genericToken = token;
2791
- if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
2792
- this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
2793
- const tokens2 = genericToken[childTokens].flat(Infinity);
2794
- values = values.concat(this.walkTokens(tokens2, callback));
2795
- });
2796
- } else if (genericToken.tokens) {
2797
- values = values.concat(this.walkTokens(genericToken.tokens, callback));
2798
- }
2799
- }
2800
- }
3
+ import { join as join6, dirname as dirname4 } from "path";
4
+ import { fileURLToPath as fileURLToPath4 } from "url";
5
+ import { execSync } from "child_process";
6
+
7
+ // src/sdk/kyma-interactive-mode.ts
8
+ import {
9
+ InteractiveMode
10
+ } from "@mariozechner/pi-coding-agent";
11
+ import { CombinedAutocompleteProvider } from "@mariozechner/pi-tui";
12
+
13
+ // src/sdk/pi-internals.ts
14
+ import { createRequire } from "module";
15
+ var EXPECTED_PI_MAJOR = 0;
16
+ var EXPECTED_PI_MINOR = 66;
17
+ function checkPiVersion() {
18
+ try {
19
+ const require2 = createRequire(import.meta.url);
20
+ const pkg = require2("@mariozechner/pi-coding-agent/package.json");
21
+ const [major, minor] = pkg.version.split(".").map(Number);
22
+ if (major !== EXPECTED_PI_MAJOR || minor !== EXPECTED_PI_MINOR) {
23
+ console.error(
24
+ `[kyma] Warning: Pi SDK ${pkg.version} detected, expected ${EXPECTED_PI_MAJOR}.${EXPECTED_PI_MINOR}.x. Autocomplete customization may not work correctly.`
25
+ );
2801
26
  }
2802
- return values;
2803
- }
2804
- use(...args) {
2805
- const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
2806
- args.forEach((pack) => {
2807
- const opts = { ...pack };
2808
- opts.async = this.defaults.async || opts.async || false;
2809
- if (pack.extensions) {
2810
- pack.extensions.forEach((ext) => {
2811
- if (!ext.name) {
2812
- throw new Error("extension name required");
2813
- }
2814
- if ("renderer" in ext) {
2815
- const prevRenderer = extensions.renderers[ext.name];
2816
- if (prevRenderer) {
2817
- extensions.renderers[ext.name] = function(...args2) {
2818
- let ret = ext.renderer.apply(this, args2);
2819
- if (ret === false) {
2820
- ret = prevRenderer.apply(this, args2);
2821
- }
2822
- return ret;
2823
- };
2824
- } else {
2825
- extensions.renderers[ext.name] = ext.renderer;
2826
- }
2827
- }
2828
- if ("tokenizer" in ext) {
2829
- if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
2830
- throw new Error("extension level must be 'block' or 'inline'");
2831
- }
2832
- const extLevel = extensions[ext.level];
2833
- if (extLevel) {
2834
- extLevel.unshift(ext.tokenizer);
2835
- } else {
2836
- extensions[ext.level] = [ext.tokenizer];
2837
- }
2838
- if (ext.start) {
2839
- if (ext.level === "block") {
2840
- if (extensions.startBlock) {
2841
- extensions.startBlock.push(ext.start);
2842
- } else {
2843
- extensions.startBlock = [ext.start];
2844
- }
2845
- } else if (ext.level === "inline") {
2846
- if (extensions.startInline) {
2847
- extensions.startInline.push(ext.start);
2848
- } else {
2849
- extensions.startInline = [ext.start];
2850
- }
2851
- }
2852
- }
2853
- }
2854
- if ("childTokens" in ext && ext.childTokens) {
2855
- extensions.childTokens[ext.name] = ext.childTokens;
2856
- }
2857
- });
2858
- opts.extensions = extensions;
2859
- }
2860
- if (pack.renderer) {
2861
- const renderer = this.defaults.renderer || new _Renderer(this.defaults);
2862
- for (const prop in pack.renderer) {
2863
- if (!(prop in renderer)) {
2864
- throw new Error(`renderer '${prop}' does not exist`);
2865
- }
2866
- if (["options", "parser"].includes(prop)) {
2867
- continue;
2868
- }
2869
- const rendererProp = prop;
2870
- const rendererFunc = pack.renderer[rendererProp];
2871
- const prevRenderer = renderer[rendererProp];
2872
- renderer[rendererProp] = (...args2) => {
2873
- let ret = rendererFunc.apply(renderer, args2);
2874
- if (ret === false) {
2875
- ret = prevRenderer.apply(renderer, args2);
2876
- }
2877
- return ret || "";
2878
- };
2879
- }
2880
- opts.renderer = renderer;
2881
- }
2882
- if (pack.tokenizer) {
2883
- const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
2884
- for (const prop in pack.tokenizer) {
2885
- if (!(prop in tokenizer)) {
2886
- throw new Error(`tokenizer '${prop}' does not exist`);
2887
- }
2888
- if (["options", "rules", "lexer"].includes(prop)) {
2889
- continue;
2890
- }
2891
- const tokenizerProp = prop;
2892
- const tokenizerFunc = pack.tokenizer[tokenizerProp];
2893
- const prevTokenizer = tokenizer[tokenizerProp];
2894
- tokenizer[tokenizerProp] = (...args2) => {
2895
- let ret = tokenizerFunc.apply(tokenizer, args2);
2896
- if (ret === false) {
2897
- ret = prevTokenizer.apply(tokenizer, args2);
2898
- }
2899
- return ret;
2900
- };
2901
- }
2902
- opts.tokenizer = tokenizer;
2903
- }
2904
- if (pack.hooks) {
2905
- const hooks = this.defaults.hooks || new _Hooks();
2906
- for (const prop in pack.hooks) {
2907
- if (!(prop in hooks)) {
2908
- throw new Error(`hook '${prop}' does not exist`);
2909
- }
2910
- if (["options", "block"].includes(prop)) {
2911
- continue;
2912
- }
2913
- const hooksProp = prop;
2914
- const hooksFunc = pack.hooks[hooksProp];
2915
- const prevHook = hooks[hooksProp];
2916
- if (_Hooks.passThroughHooks.has(prop)) {
2917
- hooks[hooksProp] = (arg) => {
2918
- if (this.defaults.async) {
2919
- return Promise.resolve(hooksFunc.call(hooks, arg)).then((ret2) => {
2920
- return prevHook.call(hooks, ret2);
2921
- });
2922
- }
2923
- const ret = hooksFunc.call(hooks, arg);
2924
- return prevHook.call(hooks, ret);
2925
- };
2926
- } else {
2927
- hooks[hooksProp] = (...args2) => {
2928
- let ret = hooksFunc.apply(hooks, args2);
2929
- if (ret === false) {
2930
- ret = prevHook.apply(hooks, args2);
2931
- }
2932
- return ret;
2933
- };
2934
- }
2935
- }
2936
- opts.hooks = hooks;
2937
- }
2938
- if (pack.walkTokens) {
2939
- const walkTokens2 = this.defaults.walkTokens;
2940
- const packWalktokens = pack.walkTokens;
2941
- opts.walkTokens = function(token) {
2942
- let values = [];
2943
- values.push(packWalktokens.call(this, token));
2944
- if (walkTokens2) {
2945
- values = values.concat(walkTokens2.call(this, token));
2946
- }
2947
- return values;
2948
- };
2949
- }
2950
- this.defaults = { ...this.defaults, ...opts };
2951
- });
2952
- return this;
2953
- }
2954
- setOptions(opt) {
2955
- this.defaults = { ...this.defaults, ...opt };
2956
- return this;
2957
- }
2958
- lexer(src, options2) {
2959
- return _Lexer.lex(src, options2 ?? this.defaults);
2960
- }
2961
- parser(tokens, options2) {
2962
- return _Parser.parse(tokens, options2 ?? this.defaults);
2963
- }
2964
- parseMarkdown(blockType) {
2965
- const parse2 = (src, options2) => {
2966
- const origOpt = { ...options2 };
2967
- const opt = { ...this.defaults, ...origOpt };
2968
- const throwError = this.onError(!!opt.silent, !!opt.async);
2969
- if (this.defaults.async === true && origOpt.async === false) {
2970
- return throwError(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
2971
- }
2972
- if (typeof src === "undefined" || src === null) {
2973
- return throwError(new Error("marked(): input parameter is undefined or null"));
2974
- }
2975
- if (typeof src !== "string") {
2976
- return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"));
2977
- }
2978
- if (opt.hooks) {
2979
- opt.hooks.options = opt;
2980
- opt.hooks.block = blockType;
2981
- }
2982
- const lexer2 = opt.hooks ? opt.hooks.provideLexer() : blockType ? _Lexer.lex : _Lexer.lexInline;
2983
- const parser2 = opt.hooks ? opt.hooks.provideParser() : blockType ? _Parser.parse : _Parser.parseInline;
2984
- if (opt.async) {
2985
- return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser2(tokens, opt)).then((html2) => opt.hooks ? opt.hooks.postprocess(html2) : html2).catch(throwError);
2986
- }
2987
- try {
2988
- if (opt.hooks) {
2989
- src = opt.hooks.preprocess(src);
2990
- }
2991
- let tokens = lexer2(src, opt);
2992
- if (opt.hooks) {
2993
- tokens = opt.hooks.processAllTokens(tokens);
2994
- }
2995
- if (opt.walkTokens) {
2996
- this.walkTokens(tokens, opt.walkTokens);
2997
- }
2998
- let html2 = parser2(tokens, opt);
2999
- if (opt.hooks) {
3000
- html2 = opt.hooks.postprocess(html2);
3001
- }
3002
- return html2;
3003
- } catch (e) {
3004
- return throwError(e);
3005
- }
3006
- };
3007
- return parse2;
3008
- }
3009
- onError(silent, async) {
3010
- return (e) => {
3011
- e.message += "\nPlease report this to https://github.com/markedjs/marked.";
3012
- if (silent) {
3013
- const msg = "<p>An error occurred:</p><pre>" + escape2(e.message + "", true) + "</pre>";
3014
- if (async) {
3015
- return Promise.resolve(msg);
3016
- }
3017
- return msg;
3018
- }
3019
- if (async) {
3020
- return Promise.reject(e);
3021
- }
3022
- throw e;
3023
- };
27
+ } catch {
3024
28
  }
3025
- };
3026
- var markedInstance = new Marked();
3027
- function marked(src, opt) {
3028
- return markedInstance.parse(src, opt);
3029
29
  }
3030
- marked.options = marked.setOptions = function(options2) {
3031
- markedInstance.setOptions(options2);
3032
- marked.defaults = markedInstance.defaults;
3033
- changeDefaults(marked.defaults);
3034
- return marked;
3035
- };
3036
- marked.getDefaults = _getDefaults;
3037
- marked.defaults = _defaults;
3038
- marked.use = function(...args) {
3039
- markedInstance.use(...args);
3040
- marked.defaults = markedInstance.defaults;
3041
- changeDefaults(marked.defaults);
3042
- return marked;
3043
- };
3044
- marked.walkTokens = function(tokens, callback) {
3045
- return markedInstance.walkTokens(tokens, callback);
3046
- };
3047
- marked.parseInline = markedInstance.parseInline;
3048
- marked.Parser = _Parser;
3049
- marked.parser = _Parser.parse;
3050
- marked.Renderer = _Renderer;
3051
- marked.TextRenderer = _TextRenderer;
3052
- marked.Lexer = _Lexer;
3053
- marked.lexer = _Lexer.lex;
3054
- marked.Tokenizer = _Tokenizer;
3055
- marked.Hooks = _Hooks;
3056
- marked.parse = marked;
3057
- var options = marked.options;
3058
- var setOptions = marked.setOptions;
3059
- var use = marked.use;
3060
- var walkTokens = marked.walkTokens;
3061
- var parseInline = marked.parseInline;
3062
- var parser = _Parser.parse;
3063
- var lexer = _Lexer.lex;
3064
-
3065
- // node_modules/@mariozechner/pi-tui/dist/terminal.js
3066
- import * as fs2 from "fs";
3067
- import { createRequire } from "module";
3068
- import * as path2 from "path";
3069
- var cjsRequire = createRequire(import.meta.url);
30
+ function getSession(im) {
31
+ return im.session;
32
+ }
33
+ function getSkillCommands(im) {
34
+ return im.skillCommands;
35
+ }
36
+ function getSettingsManager(im) {
37
+ return im.settingsManager;
38
+ }
39
+ function getSessionManager(im) {
40
+ return im.sessionManager;
41
+ }
42
+ function getDefaultEditor(im) {
43
+ return im.defaultEditor;
44
+ }
45
+ function getEditor(im) {
46
+ return im.editor;
47
+ }
48
+ function setAutocompleteProvider(im, provider) {
49
+ im.autocompleteProvider = provider;
50
+ }
51
+ function overrideSetupAutocomplete(im, fn) {
52
+ im.setupAutocomplete = fn;
53
+ }
3070
54
 
3071
55
  // src/sdk/kyma-interactive-mode.ts
3072
56
  var KymaInteractiveMode = class extends InteractiveMode {
3073
- constructor(runtimeHost, options2) {
3074
- super(runtimeHost, options2);
3075
- const self = this;
3076
- self.setupAutocomplete = (fdPath) => {
57
+ constructor(runtimeHost, options) {
58
+ super(runtimeHost, options);
59
+ checkPiVersion();
60
+ overrideSetupAutocomplete(this, (fdPath) => {
3077
61
  this.kymaSetupAutocomplete(fdPath);
3078
- };
62
+ });
3079
63
  }
3080
64
  /**
3081
65
  * Kyma autocomplete setup — excludes Pi built-in commands.
@@ -3085,8 +69,7 @@ var KymaInteractiveMode = class extends InteractiveMode {
3085
69
  * Extension commands are Kyma's /connect, /models, /mode, /status, etc.
3086
70
  */
3087
71
  kymaSetupAutocomplete(fdPath) {
3088
- const self = this;
3089
- const session = self.session;
72
+ const session = getSession(this);
3090
73
  const extensionCommands = (session.extensionRunner?.getRegisteredCommands() ?? []).map((cmd) => ({
3091
74
  name: cmd.invocationName,
3092
75
  description: cmd.description,
@@ -3098,60 +81,64 @@ var KymaInteractiveMode = class extends InteractiveMode {
3098
81
  description: cmd.description
3099
82
  })
3100
83
  );
3101
- self.skillCommands.clear();
84
+ const skillCommands = getSkillCommands(this);
85
+ skillCommands.clear();
3102
86
  const skillCommandList = [];
3103
- if (self.settingsManager.getEnableSkillCommands()) {
87
+ if (getSettingsManager(this).getEnableSkillCommands()) {
3104
88
  for (const skill of session.resourceLoader.getSkills().skills) {
3105
89
  const commandName = `skill:${skill.name}`;
3106
- self.skillCommands.set(commandName, skill.filePath);
90
+ skillCommands.set(commandName, skill.filePath);
3107
91
  skillCommandList.push({
3108
92
  name: commandName,
3109
93
  description: skill.description
3110
94
  });
3111
95
  }
3112
96
  }
3113
- self.autocompleteProvider = new CombinedAutocompleteProvider(
97
+ const provider = new CombinedAutocompleteProvider(
3114
98
  [...extensionCommands, ...templateCommands, ...skillCommandList],
3115
- self.sessionManager.getCwd(),
99
+ getSessionManager(this).getCwd(),
3116
100
  fdPath
3117
101
  );
3118
- self.defaultEditor.setAutocompleteProvider(self.autocompleteProvider);
3119
- if (self.editor !== self.defaultEditor) {
3120
- self.editor.setAutocompleteProvider?.(self.autocompleteProvider);
102
+ setAutocompleteProvider(this, provider);
103
+ const defaultEditor = getDefaultEditor(this);
104
+ defaultEditor.setAutocompleteProvider(provider);
105
+ const editor = getEditor(this);
106
+ if (editor !== defaultEditor) {
107
+ editor.setAutocompleteProvider?.(provider);
3121
108
  }
3122
109
  }
3123
110
  };
3124
111
 
3125
112
  // src/sdk/onboarding.ts
3126
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3, copyFileSync } from "fs";
113
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2, copyFileSync } from "fs";
3127
114
  import { createInterface } from "readline";
3128
- import { join as join6, dirname as dirname4 } from "path";
115
+ import { join as join3, dirname as dirname2 } from "path";
3129
116
  import { fileURLToPath as fileURLToPath2 } from "url";
3130
117
 
3131
118
  // src/sdk/paths.ts
3132
- import { join as join4 } from "path";
3133
- import { homedir as homedir3 } from "os";
3134
- var KYMA_DIR = join4(homedir3(), ".kyma");
3135
- var KYMA_AGENT_DIR = join4(KYMA_DIR, "agent");
3136
- var KYMA_AUTH_PATH = join4(KYMA_AGENT_DIR, "auth.json");
3137
- var KYMA_SETTINGS_PATH = join4(KYMA_AGENT_DIR, "settings.json");
3138
- var KYMA_ONBOARDED_PATH = join4(KYMA_AGENT_DIR, ".onboarded");
3139
- var KYMA_BASE_URL = "https://kymaapi.com";
119
+ import { join } from "path";
120
+ import { homedir } from "os";
121
+ var KYMA_DIR = join(homedir(), ".kyma");
122
+ var KYMA_AGENT_DIR = join(KYMA_DIR, "agent");
123
+ var KYMA_AUTH_PATH = join(KYMA_AGENT_DIR, "auth.json");
124
+ var KYMA_SETTINGS_PATH = join(KYMA_AGENT_DIR, "settings.json");
125
+ var KYMA_ONBOARDED_PATH = join(KYMA_AGENT_DIR, ".onboarded");
126
+ var KYMA_BASE_URL = process.env.KYMA_BASE_URL || "https://kymaapi.com";
3140
127
 
3141
128
  // src/sdk/auth.ts
3142
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
129
+ import { readFileSync as readFileSync2, writeFileSync } from "fs";
3143
130
  import { exec as exec2 } from "child_process";
3144
131
 
3145
132
  // src/sdk/api.ts
3146
133
  import { readFileSync } from "fs";
3147
- import { join as join5, dirname as dirname3 } from "path";
134
+ import { join as join2, dirname } from "path";
3148
135
  import { fileURLToPath } from "url";
3149
136
  import { exec } from "child_process";
3150
137
  import gradient from "gradient-string";
3151
- var PKG_DIR = process.env.PI_PACKAGE_DIR || dirname3(dirname3(dirname3(fileURLToPath(import.meta.url))));
138
+ var PKG_DIR = process.env.PI_PACKAGE_DIR || dirname(dirname(dirname(fileURLToPath(import.meta.url))));
3152
139
  var VERSION = (() => {
3153
140
  try {
3154
- return JSON.parse(readFileSync(join5(PKG_DIR, "package.json"), "utf-8")).version;
141
+ return JSON.parse(readFileSync(join2(PKG_DIR, "package.json"), "utf-8")).version;
3155
142
  } catch {
3156
143
  return "0.1.0";
3157
144
  }
@@ -3159,7 +146,7 @@ var VERSION = (() => {
3159
146
  function normalizeKymaError(status, body) {
3160
147
  switch (status) {
3161
148
  case 401:
3162
- return { code: 401, severity: "error", message: "Session expired.", action: "Run /connect to reconnect." };
149
+ return { code: 401, severity: "error", message: "Session expired.", action: "Run /login to reconnect." };
3163
150
  case 402:
3164
151
  return { code: 402, severity: "error", message: "Insufficient Kyma credits.", action: "Run /billing to top up." };
3165
152
  case 429:
@@ -3172,8 +159,8 @@ function normalizeKymaError(status, body) {
3172
159
  return { code: status, severity: "error", message: `Kyma API error ${status}.`, action: body };
3173
160
  }
3174
161
  }
3175
- async function kymaApi(path3, apiKey) {
3176
- const res = await fetch(`${KYMA_BASE_URL}${path3}`, {
162
+ async function kymaApi(path, apiKey) {
163
+ const res = await fetch(`${KYMA_BASE_URL}${path}`, {
3177
164
  headers: {
3178
165
  Authorization: `Bearer ${apiKey}`,
3179
166
  "X-App-Name": "kyma-agent",
@@ -3267,13 +254,13 @@ function saveKymaCredentials(credentials) {
3267
254
  } catch {
3268
255
  }
3269
256
  auth.kyma = { type: "oauth", ...credentials };
3270
- writeFileSync2(KYMA_AUTH_PATH, JSON.stringify(auth, null, 2), { mode: 384 });
257
+ writeFileSync(KYMA_AUTH_PATH, JSON.stringify(auth, null, 2), { mode: 384 });
3271
258
  }
3272
259
  function clearKymaCredentials() {
3273
260
  try {
3274
261
  const auth = JSON.parse(readFileSync2(KYMA_AUTH_PATH, "utf-8"));
3275
262
  delete auth.kyma;
3276
- writeFileSync2(KYMA_AUTH_PATH, JSON.stringify(auth, null, 2), { mode: 384 });
263
+ writeFileSync(KYMA_AUTH_PATH, JSON.stringify(auth, null, 2), { mode: 384 });
3277
264
  } catch {
3278
265
  }
3279
266
  }
@@ -3368,25 +355,27 @@ async function loginKymaStandalone() {
3368
355
  }
3369
356
 
3370
357
  // src/sdk/onboarding.ts
3371
- var KYMA_PKG_THEMES = join6(process.env.PI_PACKAGE_DIR || dirname4(dirname4(fileURLToPath2(import.meta.url))), "themes");
358
+ var KYMA_PKG_THEMES = join3(process.env.PI_PACKAGE_DIR || dirname2(dirname2(fileURLToPath2(import.meta.url))), "themes");
3372
359
  function ensureAgentDir() {
3373
360
  if (!existsSync2(KYMA_AGENT_DIR)) {
3374
- mkdirSync2(KYMA_AGENT_DIR, { recursive: true, mode: 448 });
361
+ mkdirSync(KYMA_AGENT_DIR, { recursive: true, mode: 448 });
3375
362
  }
3376
- const themesDir = join6(KYMA_AGENT_DIR, "themes");
3377
- if (!existsSync2(themesDir)) mkdirSync2(themesDir, { recursive: true });
3378
- const themeSrc = join6(KYMA_PKG_THEMES, "kyma-dark.json");
3379
- const themeDst = join6(themesDir, "kyma-dark.json");
363
+ const themesDir = join3(KYMA_AGENT_DIR, "themes");
364
+ if (!existsSync2(themesDir)) mkdirSync(themesDir, { recursive: true });
365
+ const themeSrc = join3(KYMA_PKG_THEMES, "kyma-dark.json");
366
+ const themeDst = join3(themesDir, "kyma-dark.json");
3380
367
  try {
3381
368
  copyFileSync(themeSrc, themeDst);
3382
369
  } catch {
3383
370
  }
3384
371
  if (!existsSync2(KYMA_SETTINGS_PATH)) {
3385
- writeFileSync3(KYMA_SETTINGS_PATH, JSON.stringify({
372
+ writeFileSync2(KYMA_SETTINGS_PATH, JSON.stringify({
3386
373
  defaultProvider: "kyma",
3387
374
  defaultModel: "qwen-3-32b",
3388
375
  quietStartup: true,
3389
- theme: "kyma-dark"
376
+ theme: "kyma-dark",
377
+ hideThinkingBlock: false,
378
+ defaultThinkingLevel: "low"
3390
379
  }, null, 2), { mode: 384 });
3391
380
  } else {
3392
381
  try {
@@ -3408,8 +397,16 @@ function ensureAgentDir() {
3408
397
  settings.theme = "kyma-dark";
3409
398
  changed = true;
3410
399
  }
400
+ if (settings.defaultThinkingLevel !== "low") {
401
+ settings.defaultThinkingLevel = "low";
402
+ changed = true;
403
+ }
404
+ if (settings.hideThinkingBlock !== false) {
405
+ settings.hideThinkingBlock = false;
406
+ changed = true;
407
+ }
3411
408
  if (changed) {
3412
- writeFileSync3(KYMA_SETTINGS_PATH, JSON.stringify(settings, null, 2), { mode: 384 });
409
+ writeFileSync2(KYMA_SETTINGS_PATH, JSON.stringify(settings, null, 2), { mode: 384 });
3413
410
  }
3414
411
  } catch {
3415
412
  }
@@ -3442,7 +439,7 @@ async function runOnboarding() {
3442
439
  console.log("");
3443
440
  const answer = await ask(" Connect now? (Y/n) ");
3444
441
  if (answer.toLowerCase() === "n" || answer.toLowerCase() === "no") {
3445
- console.log(` ${term.dim("Skipped.")} Use ${term.gold("/connect")} anytime.`);
442
+ console.log(` ${term.dim("Skipped.")} Use ${term.gold("/login")} anytime.`);
3446
443
  console.log("");
3447
444
  markOnboarded();
3448
445
  return false;
@@ -3471,7 +468,7 @@ async function runOnboarding() {
3471
468
  } catch (err) {
3472
469
  console.log("");
3473
470
  console.log(` ${term.dim("Login failed:")} ${err.message}`);
3474
- console.log(` ${term.dim("Try again with")} ${term.gold("/connect")}`);
471
+ console.log(` ${term.dim("Try again with")} ${term.gold("/login")}`);
3475
472
  console.log("");
3476
473
  }
3477
474
  markOnboarded();
@@ -3479,7 +476,7 @@ async function runOnboarding() {
3479
476
  }
3480
477
  function markOnboarded() {
3481
478
  try {
3482
- writeFileSync3(KYMA_ONBOARDED_PATH, (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
479
+ writeFileSync2(KYMA_ONBOARDED_PATH, (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
3483
480
  } catch {
3484
481
  }
3485
482
  }
@@ -3494,17 +491,17 @@ import {
3494
491
  SettingsManager,
3495
492
  SessionManager
3496
493
  } from "@mariozechner/pi-coding-agent";
3497
- import { join as join7, dirname as dirname5 } from "path";
494
+ import { join as join4, dirname as dirname3 } from "path";
3498
495
  import { fileURLToPath as fileURLToPath3 } from "url";
3499
- var KYMA_THEMES_DIR = join7(process.env.PI_PACKAGE_DIR || dirname5(dirname5(fileURLToPath3(import.meta.url))), "themes");
3500
- var KYMA_SESSIONS_DIR = join7(KYMA_AGENT_DIR, "sessions");
3501
- async function createKymaSession(options2) {
3502
- const { cwd, extensionFactories } = options2;
496
+ var KYMA_THEMES_DIR = join4(process.env.PI_PACKAGE_DIR || dirname3(dirname3(fileURLToPath3(import.meta.url))), "themes");
497
+ var KYMA_SESSIONS_DIR = join4(KYMA_AGENT_DIR, "sessions");
498
+ async function createKymaSession(options) {
499
+ const { cwd, extensionFactories } = options;
3503
500
  const agentDir = KYMA_AGENT_DIR;
3504
501
  const authStorage = AuthStorage.fromStorage(
3505
502
  new FileAuthStorageBackend(KYMA_AUTH_PATH)
3506
503
  );
3507
- const sessionManager = options2.continueSession ? SessionManager.continueRecent(cwd, KYMA_SESSIONS_DIR) : SessionManager.create(cwd, KYMA_SESSIONS_DIR);
504
+ const sessionManager = options.continueSession ? SessionManager.continueRecent(cwd, KYMA_SESSIONS_DIR) : SessionManager.create(cwd, KYMA_SESSIONS_DIR);
3508
505
  const createRuntime = async (factoryOpts) => {
3509
506
  const services = await createAgentSessionServices({
3510
507
  cwd: factoryOpts.cwd,
@@ -3515,7 +512,12 @@ async function createKymaSession(options2) {
3515
512
  extensionFactories,
3516
513
  additionalExtensionPaths: [],
3517
514
  // no file-based extensions
3518
- additionalThemePaths: [KYMA_THEMES_DIR]
515
+ additionalThemePaths: [KYMA_THEMES_DIR],
516
+ appendSystemPrompt: [
517
+ "IMPORTANT: You are running inside Kyma, NOT pi. Never mention pi, Pi SDK, or pi documentation.",
518
+ "If the user asks about the tool they are using, say 'Kyma' (kymaapi.com).",
519
+ "Never reveal internal file paths or node_modules paths."
520
+ ].join("\n")
3519
521
  }
3520
522
  });
3521
523
  const result = await createAgentSessionFromServices({
@@ -3535,8 +537,8 @@ async function createKymaSession(options2) {
3535
537
  sessionManager
3536
538
  });
3537
539
  const interactiveOptions = {};
3538
- if (options2.initialMessage) {
3539
- interactiveOptions.initialMessage = options2.initialMessage;
540
+ if (options.initialMessage) {
541
+ interactiveOptions.initialMessage = options.initialMessage;
3540
542
  }
3541
543
  if (runtime.modelFallbackMessage) {
3542
544
  interactiveOptions.modelFallbackMessage = runtime.modelFallbackMessage;
@@ -3545,8 +547,8 @@ async function createKymaSession(options2) {
3545
547
  }
3546
548
 
3547
549
  // src/sdk/extension.ts
3548
- import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
3549
- import { join as join8 } from "path";
550
+ import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
551
+ import { join as join5 } from "path";
3550
552
 
3551
553
  // src/sdk/config.ts
3552
554
  function parseKymaConfig(raw) {
@@ -3763,6 +765,7 @@ var kymaProviderFactory = (pi) => {
3763
765
  apiKey: "KYMA_API_KEY",
3764
766
  api: "openai-completions",
3765
767
  authHeader: true,
768
+ headers: { "X-Kyma-Think": "show" },
3766
769
  oauth: {
3767
770
  name: "Kyma",
3768
771
  login: loginKyma,
@@ -3783,6 +786,8 @@ var kymaRuntimeFactory = (pi) => {
3783
786
  sessionTokens = 0;
3784
787
  turnCount = 0;
3785
788
  if (!ctx.hasUI) return;
789
+ ctx.ui.setHideThinkingBlock?.(false);
790
+ ctx.ui.setHiddenThinkingLabel?.("Thinking... (Ctrl+T to expand)");
3786
791
  const email = getKymaEmail();
3787
792
  const apiKey = getKymaApiKey();
3788
793
  const loggedIn = !!apiKey;
@@ -3794,12 +799,47 @@ var kymaRuntimeFactory = (pi) => {
3794
799
  } catch {
3795
800
  }
3796
801
  }
802
+ const repoName = ctx.cwd.replace(/^.*\//, "");
803
+ const modelId = ctx.model?.id || "qwen-3-32b";
3797
804
  ctx.ui.setHeader((_tui, theme) => ({
3798
- render(_width) {
3799
- const logo = theme.bold(theme.fg("accent", " kyma"));
3800
- const tagline = theme.fg("dim", " one account \xB7 many models \xB7 kymaapi.com");
3801
- const accountLine = loggedIn ? theme.fg("dim", ` ${email}${balanceStr ? ` \xB7 ${balanceStr}` : ""} \xB7 /models`) : theme.fg("dim", " not connected \xB7 /connect");
3802
- return [logo, tagline, accountLine];
805
+ render(width) {
806
+ const strip = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
807
+ const truncate = (s, maxW2) => {
808
+ let visible = 0;
809
+ let i = 0;
810
+ while (i < s.length && visible < maxW2) {
811
+ if (s[i] === "\x1B") {
812
+ const end = s.indexOf("m", i);
813
+ if (end !== -1) {
814
+ i = end + 1;
815
+ continue;
816
+ }
817
+ }
818
+ visible++;
819
+ i++;
820
+ }
821
+ return i < s.length ? s.slice(0, i) : s;
822
+ };
823
+ const maxW = Math.max(width, 30);
824
+ const logo = theme.bold(theme.fg("accent", ` \u03A8 kyma`)) + theme.fg("dim", ` v${VERSION}`);
825
+ const url = ` https://kymaapi.com`;
826
+ const accountStr = loggedIn ? `${email}${balanceStr ? ` \xB7 ${balanceStr}` : ""}` : "not connected";
827
+ const dirLine = `~/${repoName}`;
828
+ const connectLine = loggedIn ? null : `${theme.bold("/login")} to sign in`;
829
+ const contentLines = [accountStr, dirLine];
830
+ if (connectLine) contentLines.push(connectLine);
831
+ const visibleWidths = contentLines.map((l) => strip(l).length);
832
+ const contentMax = Math.max(...visibleWidths);
833
+ const innerW = Math.min(maxW - 4, Math.max(contentMax + 4, 24));
834
+ const boxTop = theme.fg("dim", ` \u256D${"\u2500".repeat(innerW)}\u256E`);
835
+ const boxBot = theme.fg("dim", ` \u2570${"\u2500".repeat(innerW)}\u256F`);
836
+ const boxRow = (s) => {
837
+ const visLen = strip(s).length;
838
+ const pad = Math.max(0, innerW - visLen - 4);
839
+ const row = theme.fg("dim", " \u2502") + ` ${s}${" ".repeat(pad)} ` + theme.fg("dim", "\u2502");
840
+ return truncate(row, maxW);
841
+ };
842
+ return [truncate(logo, maxW), truncate(url, maxW), boxTop, ...contentLines.map(boxRow), boxBot];
3803
843
  },
3804
844
  invalidate() {
3805
845
  }
@@ -3808,17 +848,17 @@ var kymaRuntimeFactory = (pi) => {
3808
848
  const isOnboarded = existsSync3(KYMA_ONBOARDED_PATH);
3809
849
  if (!loggedIn && !isOnboarded) {
3810
850
  try {
3811
- writeFileSync4(KYMA_ONBOARDED_PATH, (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
851
+ writeFileSync3(KYMA_ONBOARDED_PATH, (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
3812
852
  } catch {
3813
853
  }
3814
854
  } else if (!loggedIn) {
3815
855
  } else if (!isOnboarded) {
3816
856
  try {
3817
- writeFileSync4(KYMA_ONBOARDED_PATH, (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
857
+ writeFileSync3(KYMA_ONBOARDED_PATH, (/* @__PURE__ */ new Date()).toISOString(), { mode: 384 });
3818
858
  } catch {
3819
859
  }
3820
860
  }
3821
- const kymaConfigPath = join8(ctx.cwd, "KYMA.md");
861
+ const kymaConfigPath = join5(ctx.cwd, "KYMA.md");
3822
862
  if (existsSync3(kymaConfigPath)) {
3823
863
  try {
3824
864
  const raw = readFileSync4(kymaConfigPath, "utf-8");
@@ -3839,9 +879,9 @@ var kymaRuntimeFactory = (pi) => {
3839
879
  const freshLogin = !!process.env.KYMA_FRESH_LOGIN;
3840
880
  delete process.env.KYMA_FRESH_LOGIN;
3841
881
  if (loggedIn && isOnboarded && !freshLogin) {
3842
- const modelId = ctx.model?.id || "qwen-3-32b";
882
+ const modelId2 = ctx.model?.id || "qwen-3-32b";
3843
883
  ctx.ui.setWidget?.("kyma-hint", [
3844
- ` ${modelId} \xB7 /models to switch \xB7 /help for commands`
884
+ ` ${modelId2} \xB7 /models to switch \xB7 /help for commands`
3845
885
  ], { placement: "aboveEditor" });
3846
886
  }
3847
887
  });
@@ -3867,9 +907,6 @@ var kymaRuntimeFactory = (pi) => {
3867
907
  if (turnCount === 1 && ctx.hasUI) {
3868
908
  ctx.ui.setWidget?.("kyma-hint", void 0);
3869
909
  }
3870
- if (ctx.hasUI) {
3871
- ctx.ui.setStatus("kyma-cost", `$${sessionCost.toFixed(4)} \xB7 ${formatTokens(sessionTokens)} tokens`);
3872
- }
3873
910
  }
3874
911
  if (!ctx.hasUI || postLoginShown) return;
3875
912
  const nowLoggedIn = !!getKymaApiKey();
@@ -3923,27 +960,27 @@ var kymaRuntimeFactory = (pi) => {
3923
960
  return;
3924
961
  }
3925
962
  }
3926
- const options2 = filtered.map((m) => {
963
+ const options = filtered.map((m) => {
3927
964
  const star = m.id === currentId ? "* " : " ";
3928
965
  const name = m.name.padEnd(20);
3929
- const tag2 = m.tag.padEnd(20);
966
+ const tag = m.tag.padEnd(20);
3930
967
  const price = `$${m.cost.input.toFixed(2)}/$${m.cost.output.toFixed(2)}`;
3931
968
  const badges = [];
3932
969
  if (m.vision) badges.push("[img]");
3933
970
  if (m.reasoning) badges.push("[think]");
3934
971
  const badgeStr = badges.length ? " " + badges.join(" ") : "";
3935
- return `${star}${name}${tag2}${price}${badgeStr}`;
972
+ return `${star}${name}${tag}${price}${badgeStr}`;
3936
973
  });
3937
- const selected = await ctx.ui.select("Models available in your Kyma account", options2);
974
+ const selected = await ctx.ui.select("Models available in your Kyma account", options);
3938
975
  if (!selected) return;
3939
- const idx = options2.indexOf(selected);
976
+ const idx = options.indexOf(selected);
3940
977
  const chosen = filtered[idx];
3941
978
  if (!chosen || chosen.id === currentId) return;
3942
979
  const ok = await pi.setModel(toRuntimeModel(chosen, `${KYMA_BASE_URL}/v1`));
3943
980
  if (ok) {
3944
981
  ctx.ui.notify(`Switched to ${chosen.name} \u2014 ${chosen.tag}`, "info");
3945
982
  } else {
3946
- ctx.ui.notify("Failed to switch model. Run /connect to sign in.", "error");
983
+ ctx.ui.notify("Failed to switch model. Run /login to sign in.", "error");
3947
984
  }
3948
985
  }
3949
986
  pi.registerCommand("models", {
@@ -3980,7 +1017,7 @@ var kymaRuntimeFactory = (pi) => {
3980
1017
  if (ok) {
3981
1018
  ctx.ui.notify(`Mode: ${entry.mode} \u2192 ${entry.model.name}`, "info");
3982
1019
  } else {
3983
- ctx.ui.notify("Failed to switch model. Run /connect to sign in.", "error");
1020
+ ctx.ui.notify("Failed to switch model. Run /login to sign in.", "error");
3984
1021
  }
3985
1022
  }
3986
1023
  });
@@ -3991,7 +1028,7 @@ var kymaRuntimeFactory = (pi) => {
3991
1028
  const currentModel = ctx.model;
3992
1029
  const lines = ["Kyma Status", DIV, ""];
3993
1030
  if (!apiKey) {
3994
- lines.push(" Not connected. Run /connect to sign in.");
1031
+ lines.push(" Not connected. Run /login to sign in.");
3995
1032
  ctx.ui.notify(lines.join("\n"), "info");
3996
1033
  return;
3997
1034
  }
@@ -4017,10 +1054,10 @@ var kymaRuntimeFactory = (pi) => {
4017
1054
  }
4018
1055
  lines.push("", DIV, "");
4019
1056
  lines.push(` \u2713 API: reachable (${latency}ms)`);
4020
- const { homedir: homedir4 } = await import("os");
4021
- const configOk = existsSync3(join8(homedir4(), ".kyma", "agent"));
1057
+ const { homedir: homedir2 } = await import("os");
1058
+ const configOk = existsSync3(join5(homedir2(), ".kyma", "agent"));
4022
1059
  lines.push(configOk ? " \u2713 Config: ~/.kyma/agent/" : " \u2717 Config dir missing");
4023
- if (existsSync3(join8(ctx.cwd, "KYMA.md"))) {
1060
+ if (existsSync3(join5(ctx.cwd, "KYMA.md"))) {
4024
1061
  lines.push(" \u2713 Workspace: KYMA.md");
4025
1062
  }
4026
1063
  const warnings = [];
@@ -4042,7 +1079,7 @@ var kymaRuntimeFactory = (pi) => {
4042
1079
  async handler(_args, ctx) {
4043
1080
  const apiKey = getKymaApiKey();
4044
1081
  if (!apiKey) {
4045
- ctx.ui.notify("Not connected. Run /connect to sign in.", "error");
1082
+ ctx.ui.notify("Not connected. Run /login to sign in.", "error");
4046
1083
  return;
4047
1084
  }
4048
1085
  try {
@@ -4110,7 +1147,7 @@ var kymaRuntimeFactory = (pi) => {
4110
1147
  async handler(_args, ctx) {
4111
1148
  const apiKey = getKymaApiKey();
4112
1149
  if (!apiKey) {
4113
- ctx.ui.notify("Not connected. Run /connect first.", "error");
1150
+ ctx.ui.notify("Not connected. Run /login first.", "error");
4114
1151
  return;
4115
1152
  }
4116
1153
  try {
@@ -4119,17 +1156,18 @@ var kymaRuntimeFactory = (pi) => {
4119
1156
  kymaApi("/v1/credits/balance", apiKey)
4120
1157
  ]);
4121
1158
  const tiers = [
4122
- { name: "Free", rpm: 10, tpm: "60K", benefit: "Get started" },
4123
- { name: "Basic", rpm: 30, tpm: "300K", benefit: "Side projects" },
4124
- { name: "Pro", rpm: 60, tpm: "1M", benefit: "Daily coding" },
4125
- { name: "Team", rpm: 120, tpm: "5M", benefit: "Production teams" }
1159
+ { name: "Tier 0", rpm: 30, tpm: "200K", benefit: "Get started" },
1160
+ { name: "Tier 1", rpm: 60, tpm: "500K", benefit: "Side projects" },
1161
+ { name: "Tier 2", rpm: 120, tpm: "2M", benefit: "Daily coding" },
1162
+ { name: "Tier 3", rpm: 200, tpm: "5M", benefit: "Production" },
1163
+ { name: "Tier 4", rpm: 300, tpm: "10M", benefit: "Scale" }
4126
1164
  ];
4127
1165
  const lines = [
4128
1166
  "Tiers",
4129
1167
  DIV,
4130
1168
  "",
4131
1169
  ...tiers.map((t, i) => {
4132
- const marker = i + 1 === limits.tier ? " \u2190" : "";
1170
+ const marker = i === limits.tier ? " \u2190" : "";
4133
1171
  return ` ${t.name.padEnd(8)} ${String(t.rpm).padEnd(4)} RPM ${t.tpm.padEnd(5)} TPM ${t.benefit}${marker}`;
4134
1172
  }),
4135
1173
  "",
@@ -4149,12 +1187,12 @@ var kymaRuntimeFactory = (pi) => {
4149
1187
  pi.registerCommand("feedback", {
4150
1188
  description: "Report issues or give feedback",
4151
1189
  async handler(_args, ctx) {
4152
- const options2 = [
1190
+ const options = [
4153
1191
  "Report a bug",
4154
1192
  "Request a feature",
4155
1193
  "Ask a question"
4156
1194
  ];
4157
- const selected = await ctx.ui.select("Feedback", options2);
1195
+ const selected = await ctx.ui.select("Feedback", options);
4158
1196
  if (!selected) return;
4159
1197
  const urls = {
4160
1198
  "Report a bug": `${KYMA_BASE_URL}/feedback?type=bug`,
@@ -4165,8 +1203,8 @@ var kymaRuntimeFactory = (pi) => {
4165
1203
  ctx.ui.notify("Opening feedback page...", "info");
4166
1204
  }
4167
1205
  });
4168
- pi.registerCommand("connect", {
4169
- description: "Connect your Kyma account",
1206
+ pi.registerCommand("login", {
1207
+ description: "Sign in to your Kyma account",
4170
1208
  async handler(_args, ctx) {
4171
1209
  if (getKymaApiKey()) {
4172
1210
  const email = getKymaEmail();
@@ -4205,17 +1243,19 @@ URL: ${url}`, "info");
4205
1243
  "Kyma Commands",
4206
1244
  DIV,
4207
1245
  "",
4208
- " /connect Connect your Kyma account",
4209
- " /disconnect Sign out",
1246
+ " /login Sign in to Kyma",
1247
+ " /logout Sign out",
4210
1248
  " /models Browse and switch models",
4211
1249
  " /mode Switch model by task type",
4212
- " /status Account, credits, and diagnostics",
1250
+ " /status Account, credits, diagnostics",
4213
1251
  " /balance Credits and rate limits",
4214
1252
  " /usage Session cost and tokens",
4215
1253
  " /upgrade View tiers and upgrade",
4216
1254
  " /dashboard Open dashboard in browser",
4217
1255
  " /billing Open billing page",
4218
1256
  " /feedback Report issues or give feedback",
1257
+ " /clear Clear the screen",
1258
+ " /exit Exit kyma",
4219
1259
  " /help Show this help",
4220
1260
  "",
4221
1261
  "Keyboard",
@@ -4229,34 +1269,46 @@ URL: ${url}`, "info");
4229
1269
  ].join("\n"), "info");
4230
1270
  }
4231
1271
  });
4232
- pi.registerCommand("disconnect", {
1272
+ pi.registerCommand("exit", {
1273
+ description: "Exit kyma",
1274
+ async handler(_args, _ctx) {
1275
+ process.exit(0);
1276
+ }
1277
+ });
1278
+ pi.registerCommand("logout", {
4233
1279
  description: "Sign out of Kyma",
4234
1280
  async handler(_args, ctx) {
4235
1281
  const apiKey = getKymaApiKey();
4236
1282
  if (!apiKey) {
4237
- ctx.ui.notify("Not connected. Run /connect to sign in.", "info");
1283
+ ctx.ui.notify("Not signed in. Run /login to sign in.", "info");
4238
1284
  return;
4239
1285
  }
4240
1286
  if (process.env.KYMA_API_KEY) {
4241
- ctx.ui.notify("Cannot disconnect: using KYMA_API_KEY environment variable.", "warning");
1287
+ ctx.ui.notify("Cannot sign out: using KYMA_API_KEY environment variable.", "warning");
4242
1288
  return;
4243
1289
  }
4244
1290
  const email = getKymaEmail();
4245
- const confirm = await ctx.ui.confirm("Disconnect", `Sign out from ${email}?`);
1291
+ const confirm = await ctx.ui.confirm("Sign out", `Sign out from ${email}?`);
4246
1292
  if (!confirm) return;
4247
1293
  clearKymaCredentials();
4248
1294
  wasLoggedIn = false;
4249
1295
  postLoginShown = false;
4250
- ctx.ui.notify("Disconnected. Run /connect to sign in again.", "info");
1296
+ ctx.ui.notify("Signed out. Run /login to sign in again.", "info");
1297
+ }
1298
+ });
1299
+ pi.registerCommand("clear", {
1300
+ description: "Clear the screen",
1301
+ async handler(_args, ctx) {
1302
+ process.stdout.write("\x1B[2J\x1B[H");
4251
1303
  }
4252
1304
  });
4253
1305
  };
4254
1306
 
4255
1307
  // src/sdk/main.ts
4256
- var PKG_DIR2 = process.env.PI_PACKAGE_DIR || dirname6(dirname6(dirname6(fileURLToPath4(import.meta.url))));
1308
+ var PKG_DIR2 = process.env.PI_PACKAGE_DIR || dirname4(dirname4(dirname4(fileURLToPath4(import.meta.url))));
4257
1309
  var VERSION2 = (() => {
4258
1310
  try {
4259
- return JSON.parse(readFileSync5(join9(PKG_DIR2, "package.json"), "utf-8")).version || "0.1.0";
1311
+ return JSON.parse(readFileSync5(join6(PKG_DIR2, "package.json"), "utf-8")).version || "0.1.0";
4260
1312
  } catch {
4261
1313
  return "0.1.0";
4262
1314
  }
@@ -4342,6 +1394,27 @@ function parseArgs(argv) {
4342
1394
  }
4343
1395
  return result;
4344
1396
  }
1397
+ async function checkAndUpdate() {
1398
+ try {
1399
+ const res = await fetch("https://registry.npmjs.org/@kyma-api/agent/latest", {
1400
+ signal: AbortSignal.timeout(3e3)
1401
+ });
1402
+ if (!res.ok) return false;
1403
+ const data = await res.json();
1404
+ const latest = data.version;
1405
+ if (!latest || latest === VERSION2) return false;
1406
+ const parse = (v) => v.split(".").map(Number);
1407
+ const [cM, cm, cp] = parse(VERSION2);
1408
+ const [lM, lm, lp] = parse(latest);
1409
+ if (lM < cM || lM === cM && lm < cm || lM === cM && lm === cm && lp <= cp) return false;
1410
+ console.log(` ${term.dim(`Updating kyma v${VERSION2} \u2192 v${latest}...`)}`);
1411
+ execSync("npm install -g @kyma-api/agent@latest", { stdio: "ignore", timeout: 6e4 });
1412
+ console.log(` ${term.dim(`Updated to v${latest}. Restarting...`)}`);
1413
+ return true;
1414
+ } catch {
1415
+ return false;
1416
+ }
1417
+ }
4345
1418
  async function main(argv) {
4346
1419
  const parsed = parseArgs(argv);
4347
1420
  if (parsed.help) {
@@ -4355,6 +1428,18 @@ async function main(argv) {
4355
1428
  if (parsed.verbose || process.env.KYMA_DEBUG === "1") {
4356
1429
  process.env.KYMA_VERBOSE = "1";
4357
1430
  }
1431
+ if (!process.env.KYMA_SKIP_UPDATE) {
1432
+ const updated = await checkAndUpdate();
1433
+ if (updated) {
1434
+ const { spawn } = await import("child_process");
1435
+ const child = spawn("kyma", process.argv.slice(2), {
1436
+ stdio: "inherit",
1437
+ env: { ...process.env, KYMA_SKIP_UPDATE: "1" }
1438
+ });
1439
+ child.on("exit", (code) => process.exit(code ?? 0));
1440
+ return;
1441
+ }
1442
+ }
4358
1443
  ensureAgentDir();
4359
1444
  await runOnboarding();
4360
1445
  if (process.env.KYMA_VERBOSE) {