@mrciphersmith/keryx 0.3.55 → 0.3.56
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/cli.js +470 -141
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20104,7 +20104,7 @@ var package_default;
|
|
|
20104
20104
|
var init_package = __esm(() => {
|
|
20105
20105
|
package_default = {
|
|
20106
20106
|
name: "@mrciphersmith/keryx",
|
|
20107
|
-
version: "0.3.
|
|
20107
|
+
version: "0.3.56",
|
|
20108
20108
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
20109
20109
|
private: false,
|
|
20110
20110
|
publishConfig: {
|
|
@@ -187340,6 +187340,9 @@ function createHttpBotApi(options) {
|
|
|
187340
187340
|
if (params.messageThreadId !== undefined) {
|
|
187341
187341
|
body.message_thread_id = params.messageThreadId;
|
|
187342
187342
|
}
|
|
187343
|
+
if (params.parseMode !== undefined) {
|
|
187344
|
+
body.parse_mode = params.parseMode;
|
|
187345
|
+
}
|
|
187343
187346
|
if (params.inlineKeyboard !== undefined) {
|
|
187344
187347
|
body.reply_markup = { inline_keyboard: params.inlineKeyboard };
|
|
187345
187348
|
}
|
|
@@ -187385,6 +187388,445 @@ var init_bot_api_http = __esm(() => {
|
|
|
187385
187388
|
init_types11();
|
|
187386
187389
|
});
|
|
187387
187390
|
|
|
187391
|
+
// src/remote/format.ts
|
|
187392
|
+
function fenceOpening(line) {
|
|
187393
|
+
const match = FENCE_LINE2.exec(line);
|
|
187394
|
+
if (match === null) {
|
|
187395
|
+
return;
|
|
187396
|
+
}
|
|
187397
|
+
const marker = match[1];
|
|
187398
|
+
const info = match[2].trim();
|
|
187399
|
+
if (marker.length > MAX_FENCE_MARKER || marker.startsWith("`") && info.includes("`")) {
|
|
187400
|
+
return;
|
|
187401
|
+
}
|
|
187402
|
+
return { marker, info };
|
|
187403
|
+
}
|
|
187404
|
+
function openingFence(line) {
|
|
187405
|
+
const opening = fenceOpening(line);
|
|
187406
|
+
if (opening === undefined) {
|
|
187407
|
+
return;
|
|
187408
|
+
}
|
|
187409
|
+
const { marker, info } = opening;
|
|
187410
|
+
return { marker, header: info.length > 0 && info.length <= MAX_FENCE_INFO ? `${marker}${info}` : marker };
|
|
187411
|
+
}
|
|
187412
|
+
function closesFence(line, fence) {
|
|
187413
|
+
const match = FENCE_LINE2.exec(line);
|
|
187414
|
+
if (match === null) {
|
|
187415
|
+
return false;
|
|
187416
|
+
}
|
|
187417
|
+
const run = match[1];
|
|
187418
|
+
return run[0] === fence.marker[0] && run.length >= fence.marker.length && match[2].trim().length === 0;
|
|
187419
|
+
}
|
|
187420
|
+
function fenceOverhead(fence) {
|
|
187421
|
+
return fence === undefined ? 0 : fence.header.length + 1 + (fence.marker.length + 1);
|
|
187422
|
+
}
|
|
187423
|
+
function cutAt(text, max) {
|
|
187424
|
+
if (text.length <= max) {
|
|
187425
|
+
return text.length;
|
|
187426
|
+
}
|
|
187427
|
+
for (let index = max;index > 0; index -= 1) {
|
|
187428
|
+
const ch = text[index - 1];
|
|
187429
|
+
if (ch === " " || ch === "\t") {
|
|
187430
|
+
return index;
|
|
187431
|
+
}
|
|
187432
|
+
}
|
|
187433
|
+
const code = text.charCodeAt(max - 1);
|
|
187434
|
+
return code >= 55296 && code <= 56319 ? max - 1 : max;
|
|
187435
|
+
}
|
|
187436
|
+
function toPieces(text, capacity) {
|
|
187437
|
+
const pieces = [];
|
|
187438
|
+
let fence;
|
|
187439
|
+
for (const raw of text.split(/(?<=\n)/)) {
|
|
187440
|
+
const line = raw.endsWith(`
|
|
187441
|
+
`) ? raw.slice(0, -1) : raw;
|
|
187442
|
+
const before = fence;
|
|
187443
|
+
if (fence === undefined) {
|
|
187444
|
+
fence = openingFence(line);
|
|
187445
|
+
} else if (closesFence(line, fence)) {
|
|
187446
|
+
fence = undefined;
|
|
187447
|
+
}
|
|
187448
|
+
const room = Math.max(8, capacity - Math.max(fenceOverhead(before), fenceOverhead(fence)));
|
|
187449
|
+
let rest = raw;
|
|
187450
|
+
while (rest.length > room) {
|
|
187451
|
+
const cut = cutAt(rest, room);
|
|
187452
|
+
pieces.push({ text: rest.slice(0, cut), fence: before ?? fence });
|
|
187453
|
+
rest = rest.slice(cut);
|
|
187454
|
+
}
|
|
187455
|
+
if (rest.length > 0) {
|
|
187456
|
+
pieces.push({ text: rest, fence });
|
|
187457
|
+
}
|
|
187458
|
+
}
|
|
187459
|
+
return pieces;
|
|
187460
|
+
}
|
|
187461
|
+
function pack(text, capacity) {
|
|
187462
|
+
const parts = [];
|
|
187463
|
+
let current = "";
|
|
187464
|
+
let hasContent = false;
|
|
187465
|
+
let open;
|
|
187466
|
+
const finish = () => {
|
|
187467
|
+
let body = current.trimEnd();
|
|
187468
|
+
if (!hasContent || body.length === 0) {
|
|
187469
|
+
current = "";
|
|
187470
|
+
hasContent = false;
|
|
187471
|
+
return;
|
|
187472
|
+
}
|
|
187473
|
+
if (open !== undefined) {
|
|
187474
|
+
body += `
|
|
187475
|
+
${open.marker}`;
|
|
187476
|
+
}
|
|
187477
|
+
parts.push(body);
|
|
187478
|
+
current = open === undefined ? "" : `${open.header}
|
|
187479
|
+
`;
|
|
187480
|
+
hasContent = false;
|
|
187481
|
+
};
|
|
187482
|
+
for (const piece of toPieces(text, capacity)) {
|
|
187483
|
+
if (!hasContent && piece.text.trim().length === 0) {
|
|
187484
|
+
continue;
|
|
187485
|
+
}
|
|
187486
|
+
const closing = piece.fence === undefined ? 0 : piece.fence.marker.length + 1;
|
|
187487
|
+
if (hasContent && current.length + piece.text.length + closing > capacity) {
|
|
187488
|
+
finish();
|
|
187489
|
+
if (piece.text.trim().length === 0) {
|
|
187490
|
+
continue;
|
|
187491
|
+
}
|
|
187492
|
+
}
|
|
187493
|
+
current += piece.text;
|
|
187494
|
+
hasContent = true;
|
|
187495
|
+
open = piece.fence;
|
|
187496
|
+
}
|
|
187497
|
+
finish();
|
|
187498
|
+
return parts;
|
|
187499
|
+
}
|
|
187500
|
+
function formatReply(text, limit = TELEGRAM_MAX_TEXT) {
|
|
187501
|
+
if (limit < MIN_LIMIT) {
|
|
187502
|
+
throw new RangeError(`formatReply: limit must be at least ${MIN_LIMIT}`);
|
|
187503
|
+
}
|
|
187504
|
+
text = text.replace(/\r\n?/g, `
|
|
187505
|
+
`);
|
|
187506
|
+
if (text.trim().length === 0) {
|
|
187507
|
+
return [];
|
|
187508
|
+
}
|
|
187509
|
+
if (text.length <= limit) {
|
|
187510
|
+
return [text];
|
|
187511
|
+
}
|
|
187512
|
+
for (let digits = 1;digits <= 3; digits += 1) {
|
|
187513
|
+
const labelLength = 2 * digits + 4;
|
|
187514
|
+
const parts = pack(text, limit - labelLength);
|
|
187515
|
+
if (String(parts.length).length > digits) {
|
|
187516
|
+
continue;
|
|
187517
|
+
}
|
|
187518
|
+
if (parts.length <= 1) {
|
|
187519
|
+
return parts;
|
|
187520
|
+
}
|
|
187521
|
+
return parts.map((part, index) => `(${index + 1}/${parts.length})
|
|
187522
|
+
${part}`);
|
|
187523
|
+
}
|
|
187524
|
+
const parts = pack(text, limit - 12).slice(0, 999);
|
|
187525
|
+
return parts.map((part, index) => `(${index + 1}/${parts.length})
|
|
187526
|
+
${part}`);
|
|
187527
|
+
}
|
|
187528
|
+
var MIN_LIMIT = 64, MAX_FENCE_MARKER = 16, MAX_FENCE_INFO = 40, FENCE_LINE2;
|
|
187529
|
+
var init_format2 = __esm(() => {
|
|
187530
|
+
init_types11();
|
|
187531
|
+
FENCE_LINE2 = /^ {0,3}(`{3,}|~{3,})(.*)$/;
|
|
187532
|
+
});
|
|
187533
|
+
|
|
187534
|
+
// src/remote/format-html.ts
|
|
187535
|
+
function escapeHtml2(text) {
|
|
187536
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
187537
|
+
}
|
|
187538
|
+
function escapeAttribute(text) {
|
|
187539
|
+
return escapeHtml2(text).replace(/"/g, """);
|
|
187540
|
+
}
|
|
187541
|
+
function isWord(char) {
|
|
187542
|
+
return char !== undefined && WORD.test(char);
|
|
187543
|
+
}
|
|
187544
|
+
function isAlnum(char) {
|
|
187545
|
+
return char !== undefined && ALNUM.test(char);
|
|
187546
|
+
}
|
|
187547
|
+
function isSpace(char) {
|
|
187548
|
+
return char !== undefined && SPACE.test(char);
|
|
187549
|
+
}
|
|
187550
|
+
function codeSpan(text, start) {
|
|
187551
|
+
const run = backtickRun(text, start);
|
|
187552
|
+
let index = start + run;
|
|
187553
|
+
while (index < text.length) {
|
|
187554
|
+
if (text[index] === "`") {
|
|
187555
|
+
const next = backtickRun(text, index);
|
|
187556
|
+
if (next === run) {
|
|
187557
|
+
let content = text.slice(start + run, index);
|
|
187558
|
+
if (content.length > 2 && content.startsWith(" ") && content.endsWith(" ") && content.trim().length > 0) {
|
|
187559
|
+
content = content.slice(1, -1);
|
|
187560
|
+
}
|
|
187561
|
+
return content.length === 0 ? undefined : { content, end: index + run };
|
|
187562
|
+
}
|
|
187563
|
+
index += next;
|
|
187564
|
+
} else {
|
|
187565
|
+
index += 1;
|
|
187566
|
+
}
|
|
187567
|
+
}
|
|
187568
|
+
return;
|
|
187569
|
+
}
|
|
187570
|
+
function backtickRun(text, start) {
|
|
187571
|
+
let end = start;
|
|
187572
|
+
while (text[end] === "`") {
|
|
187573
|
+
end += 1;
|
|
187574
|
+
}
|
|
187575
|
+
return end - start;
|
|
187576
|
+
}
|
|
187577
|
+
function opens(text, index, marker) {
|
|
187578
|
+
const next = text[index + marker.length];
|
|
187579
|
+
const prev = text[index - 1];
|
|
187580
|
+
if (next === undefined || isSpace(next) || prev === "/" || prev === "\\") {
|
|
187581
|
+
return false;
|
|
187582
|
+
}
|
|
187583
|
+
const char = marker[0];
|
|
187584
|
+
if (marker.length === 1) {
|
|
187585
|
+
if (next === char || SINGLE_OPEN_BAD.test(next)) {
|
|
187586
|
+
return false;
|
|
187587
|
+
}
|
|
187588
|
+
return char === "*" ? !isAlnum(prev) : !isWord(prev);
|
|
187589
|
+
}
|
|
187590
|
+
return char === "_" ? !isWord(prev) : true;
|
|
187591
|
+
}
|
|
187592
|
+
function closes(text, index, marker) {
|
|
187593
|
+
const prev = text[index - 1];
|
|
187594
|
+
const after = text[index + marker.length];
|
|
187595
|
+
const char = marker[0];
|
|
187596
|
+
if (prev === undefined || isSpace(prev) || after === char) {
|
|
187597
|
+
return false;
|
|
187598
|
+
}
|
|
187599
|
+
if (marker.length === 1) {
|
|
187600
|
+
if (prev === char || SINGLE_CLOSE_BAD.test(prev)) {
|
|
187601
|
+
return false;
|
|
187602
|
+
}
|
|
187603
|
+
return char === "*" ? !isAlnum(after) : !isWord(after);
|
|
187604
|
+
}
|
|
187605
|
+
return char === "_" ? !isWord(after) : true;
|
|
187606
|
+
}
|
|
187607
|
+
function findCloser(text, from, marker) {
|
|
187608
|
+
let index = from;
|
|
187609
|
+
while (index < text.length) {
|
|
187610
|
+
if (text[index] === "`") {
|
|
187611
|
+
const span = codeSpan(text, index);
|
|
187612
|
+
index = span === undefined ? index + backtickRun(text, index) : span.end;
|
|
187613
|
+
continue;
|
|
187614
|
+
}
|
|
187615
|
+
if (text.startsWith(marker, index) && closes(text, index, marker)) {
|
|
187616
|
+
return index;
|
|
187617
|
+
}
|
|
187618
|
+
index += 1;
|
|
187619
|
+
}
|
|
187620
|
+
return -1;
|
|
187621
|
+
}
|
|
187622
|
+
function delimited(text, index, marker, flag, context) {
|
|
187623
|
+
if (!opens(text, index, marker)) {
|
|
187624
|
+
return;
|
|
187625
|
+
}
|
|
187626
|
+
const close = findCloser(text, index + marker.length + 1, marker);
|
|
187627
|
+
if (close < 0) {
|
|
187628
|
+
return;
|
|
187629
|
+
}
|
|
187630
|
+
const content = text.slice(index + marker.length, close);
|
|
187631
|
+
if (content.trim().length === 0 || marker === "__" && !/\s/.test(content.trim())) {
|
|
187632
|
+
return;
|
|
187633
|
+
}
|
|
187634
|
+
const inner = renderInline2(content, { ...context, [flag]: true });
|
|
187635
|
+
const html = context[flag] ? inner : `<${TAGS2[flag]}>${inner}</${TAGS2[flag]}>`;
|
|
187636
|
+
return { html, end: close + marker.length };
|
|
187637
|
+
}
|
|
187638
|
+
function link(text, index, context) {
|
|
187639
|
+
if (context.link) {
|
|
187640
|
+
return;
|
|
187641
|
+
}
|
|
187642
|
+
const middle = text.indexOf("](", index + 1);
|
|
187643
|
+
if (middle < 0) {
|
|
187644
|
+
return;
|
|
187645
|
+
}
|
|
187646
|
+
const label = text.slice(index + 1, middle);
|
|
187647
|
+
if (label.trim().length === 0 || label.includes("]")) {
|
|
187648
|
+
return;
|
|
187649
|
+
}
|
|
187650
|
+
let depth = 1;
|
|
187651
|
+
let end = middle + 2;
|
|
187652
|
+
while (end < text.length && depth > 0) {
|
|
187653
|
+
if (text[end] === "(") {
|
|
187654
|
+
depth += 1;
|
|
187655
|
+
} else if (text[end] === ")") {
|
|
187656
|
+
depth -= 1;
|
|
187657
|
+
}
|
|
187658
|
+
end += 1;
|
|
187659
|
+
}
|
|
187660
|
+
if (depth !== 0) {
|
|
187661
|
+
return;
|
|
187662
|
+
}
|
|
187663
|
+
const url = text.slice(middle + 2, end - 1);
|
|
187664
|
+
if (!HTTP_URL.test(url)) {
|
|
187665
|
+
return;
|
|
187666
|
+
}
|
|
187667
|
+
return { html: `<a href="${escapeAttribute(url)}">${renderInline2(label, { ...context, link: true })}</a>`, end };
|
|
187668
|
+
}
|
|
187669
|
+
function renderInline2(text, context) {
|
|
187670
|
+
let out = "";
|
|
187671
|
+
let index = 0;
|
|
187672
|
+
while (index < text.length) {
|
|
187673
|
+
const char = text[index];
|
|
187674
|
+
if (char === "`") {
|
|
187675
|
+
const span = context.link ? undefined : codeSpan(text, index);
|
|
187676
|
+
if (span === undefined) {
|
|
187677
|
+
const run = backtickRun(text, index);
|
|
187678
|
+
out += text.slice(index, index + run);
|
|
187679
|
+
index += run;
|
|
187680
|
+
} else {
|
|
187681
|
+
out += context.bold || context.italic || context.strike ? escapeHtml2(span.content) : `<code>${escapeHtml2(span.content)}</code>`;
|
|
187682
|
+
index = span.end;
|
|
187683
|
+
}
|
|
187684
|
+
continue;
|
|
187685
|
+
}
|
|
187686
|
+
if (char === "[") {
|
|
187687
|
+
const found = link(text, index, context);
|
|
187688
|
+
if (found !== undefined) {
|
|
187689
|
+
out += found.html;
|
|
187690
|
+
index = found.end;
|
|
187691
|
+
continue;
|
|
187692
|
+
}
|
|
187693
|
+
} else if (text.startsWith("**", index) || text.startsWith("__", index) || text.startsWith("~~", index)) {
|
|
187694
|
+
const marker = text.slice(index, index + 2);
|
|
187695
|
+
const found = delimited(text, index, marker, marker === "~~" ? "strike" : "bold", context);
|
|
187696
|
+
if (found === undefined) {
|
|
187697
|
+
out += marker;
|
|
187698
|
+
index += 2;
|
|
187699
|
+
} else {
|
|
187700
|
+
out += found.html;
|
|
187701
|
+
index = found.end;
|
|
187702
|
+
}
|
|
187703
|
+
continue;
|
|
187704
|
+
} else if (char === "*" || char === "_") {
|
|
187705
|
+
const found = delimited(text, index, char, "italic", context);
|
|
187706
|
+
if (found !== undefined) {
|
|
187707
|
+
out += found.html;
|
|
187708
|
+
index = found.end;
|
|
187709
|
+
continue;
|
|
187710
|
+
}
|
|
187711
|
+
}
|
|
187712
|
+
out += escapeHtml2(char);
|
|
187713
|
+
index += 1;
|
|
187714
|
+
}
|
|
187715
|
+
return out;
|
|
187716
|
+
}
|
|
187717
|
+
function renderTelegramHtml(part) {
|
|
187718
|
+
const lines = part.replace(/\r\n?/g, `
|
|
187719
|
+
`).split(`
|
|
187720
|
+
`);
|
|
187721
|
+
let out = "";
|
|
187722
|
+
let first = true;
|
|
187723
|
+
let afterBlock = false;
|
|
187724
|
+
const push = (html, block) => {
|
|
187725
|
+
if (!first && !afterBlock) {
|
|
187726
|
+
out += `
|
|
187727
|
+
`;
|
|
187728
|
+
}
|
|
187729
|
+
out += html;
|
|
187730
|
+
first = false;
|
|
187731
|
+
afterBlock = block;
|
|
187732
|
+
};
|
|
187733
|
+
let index = 0;
|
|
187734
|
+
while (index < lines.length) {
|
|
187735
|
+
const line = lines[index];
|
|
187736
|
+
const fence = fenceOpening(line);
|
|
187737
|
+
if (fence !== undefined) {
|
|
187738
|
+
const body = [];
|
|
187739
|
+
let cursor = index + 1;
|
|
187740
|
+
while (cursor < lines.length && !closesFence(lines[cursor], fence)) {
|
|
187741
|
+
body.push(lines[cursor]);
|
|
187742
|
+
cursor += 1;
|
|
187743
|
+
}
|
|
187744
|
+
const closed = cursor < lines.length;
|
|
187745
|
+
const code = body.join(`
|
|
187746
|
+
`);
|
|
187747
|
+
if (code.trim().length === 0) {
|
|
187748
|
+
push(escapeHtml2(lines.slice(index, closed ? cursor + 1 : cursor).join(`
|
|
187749
|
+
`)), false);
|
|
187750
|
+
} else {
|
|
187751
|
+
const language = fence.info.split(/\s+/)[0];
|
|
187752
|
+
const open = LANGUAGE.test(language) ? `<pre><code class="language-${escapeAttribute(language)}">` : "<pre><code>";
|
|
187753
|
+
push(`${open}${escapeHtml2(code)}</code></pre>`, true);
|
|
187754
|
+
}
|
|
187755
|
+
index = closed ? cursor + 1 : cursor;
|
|
187756
|
+
continue;
|
|
187757
|
+
}
|
|
187758
|
+
const quote = QUOTE.exec(line);
|
|
187759
|
+
if (quote !== null) {
|
|
187760
|
+
const quoted = [];
|
|
187761
|
+
while (index < lines.length) {
|
|
187762
|
+
const next = QUOTE.exec(lines[index]);
|
|
187763
|
+
if (next === null) {
|
|
187764
|
+
break;
|
|
187765
|
+
}
|
|
187766
|
+
quoted.push(next[1] ?? "");
|
|
187767
|
+
index += 1;
|
|
187768
|
+
}
|
|
187769
|
+
if (quoted.every((entry) => entry.trim().length === 0)) {
|
|
187770
|
+
push(escapeHtml2(lines.slice(index - quoted.length, index).join(`
|
|
187771
|
+
`)), false);
|
|
187772
|
+
} else {
|
|
187773
|
+
const tag = quoted.length >= EXPANDABLE_QUOTE_LINES ? "blockquote expandable" : "blockquote";
|
|
187774
|
+
push(`<${tag}>${quoted.map((entry) => renderInline2(entry, OUTSIDE)).join(`
|
|
187775
|
+
`)}</blockquote>`, true);
|
|
187776
|
+
}
|
|
187777
|
+
continue;
|
|
187778
|
+
}
|
|
187779
|
+
index += 1;
|
|
187780
|
+
const heading = HEADING2.exec(line);
|
|
187781
|
+
if (heading !== null && heading[1].trim().length > 0) {
|
|
187782
|
+
push(`<b>${renderInline2(heading[1], { ...OUTSIDE, bold: true })}</b>`, false);
|
|
187783
|
+
continue;
|
|
187784
|
+
}
|
|
187785
|
+
const bullet = BULLET.exec(line);
|
|
187786
|
+
if (bullet !== null) {
|
|
187787
|
+
push(`${bullet[1]}\u2022 ${renderInline2(bullet[2], OUTSIDE)}`, false);
|
|
187788
|
+
continue;
|
|
187789
|
+
}
|
|
187790
|
+
push(renderInline2(line, OUTSIDE), false);
|
|
187791
|
+
}
|
|
187792
|
+
return out;
|
|
187793
|
+
}
|
|
187794
|
+
function isEntityParseError(error) {
|
|
187795
|
+
return isBotApiError(error) && error.kind === "rejected" && error.status === 400 && /can't parse entities/i.test(error.message);
|
|
187796
|
+
}
|
|
187797
|
+
async function sendHtml(api, params, onFallback) {
|
|
187798
|
+
const { parseMode: _ignored, ...plain } = params;
|
|
187799
|
+
try {
|
|
187800
|
+
return await api.sendMessage({ ...plain, text: renderTelegramHtml(params.text), parseMode: "HTML" });
|
|
187801
|
+
} catch (error) {
|
|
187802
|
+
if (!isEntityParseError(error)) {
|
|
187803
|
+
throw error;
|
|
187804
|
+
}
|
|
187805
|
+
try {
|
|
187806
|
+
onFallback?.(error);
|
|
187807
|
+
} catch {}
|
|
187808
|
+
return api.sendMessage(plain);
|
|
187809
|
+
}
|
|
187810
|
+
}
|
|
187811
|
+
var OUTSIDE, WORD, ALNUM, SPACE, SINGLE_OPEN_BAD, SINGLE_CLOSE_BAD, HTTP_URL, LANGUAGE, EXPANDABLE_QUOTE_LINES = 8, TAGS2, HEADING2, BULLET, QUOTE, SIMPLE_TAGS;
|
|
187812
|
+
var init_format_html = __esm(() => {
|
|
187813
|
+
init_format2();
|
|
187814
|
+
init_types11();
|
|
187815
|
+
OUTSIDE = { bold: false, italic: false, strike: false, link: false };
|
|
187816
|
+
WORD = /[\p{L}\p{N}_]/u;
|
|
187817
|
+
ALNUM = /[\p{L}\p{N}]/u;
|
|
187818
|
+
SPACE = /\s/;
|
|
187819
|
+
SINGLE_OPEN_BAD = /[.,;:!?)\]}/\\|]/;
|
|
187820
|
+
SINGLE_CLOSE_BAD = /[([{/\\|]/;
|
|
187821
|
+
HTTP_URL = /^https?:\/\/[^\s<>"'`]+$/i;
|
|
187822
|
+
LANGUAGE = /^[A-Za-z0-9_+#.-]{1,32}$/;
|
|
187823
|
+
TAGS2 = { bold: "b", italic: "i", strike: "s" };
|
|
187824
|
+
HEADING2 = /^ {0,3}#{1,6}[ \t]+(.*?)(?:[ \t]+#+)?[ \t]*$/;
|
|
187825
|
+
BULLET = /^([ \t]*)[-*][ \t]+(.*)$/;
|
|
187826
|
+
QUOTE = /^ {0,3}>(?: (.*))?$/;
|
|
187827
|
+
SIMPLE_TAGS = new Set(["b", "strong", "i", "em", "u", "ins", "s", "strike", "del"]);
|
|
187828
|
+
});
|
|
187829
|
+
|
|
187388
187830
|
// src/remote/durable-log.ts
|
|
187389
187831
|
import { renameSync as renameSync6 } from "fs";
|
|
187390
187832
|
|
|
@@ -187699,139 +188141,6 @@ var init_journal2 = __esm(() => {
|
|
|
187699
188141
|
init_paths4();
|
|
187700
188142
|
});
|
|
187701
188143
|
|
|
187702
|
-
// src/remote/format.ts
|
|
187703
|
-
function openingFence(line) {
|
|
187704
|
-
const match = FENCE_LINE2.exec(line);
|
|
187705
|
-
if (match === null) {
|
|
187706
|
-
return;
|
|
187707
|
-
}
|
|
187708
|
-
const marker = match[1];
|
|
187709
|
-
const info = match[2].trim();
|
|
187710
|
-
if (marker.length > MAX_FENCE_MARKER || marker.startsWith("`") && info.includes("`")) {
|
|
187711
|
-
return;
|
|
187712
|
-
}
|
|
187713
|
-
return { marker, header: info.length > 0 && info.length <= MAX_FENCE_INFO ? `${marker}${info}` : marker };
|
|
187714
|
-
}
|
|
187715
|
-
function closesFence(line, fence) {
|
|
187716
|
-
const match = FENCE_LINE2.exec(line);
|
|
187717
|
-
if (match === null) {
|
|
187718
|
-
return false;
|
|
187719
|
-
}
|
|
187720
|
-
const run = match[1];
|
|
187721
|
-
return run[0] === fence.marker[0] && run.length >= fence.marker.length && match[2].trim().length === 0;
|
|
187722
|
-
}
|
|
187723
|
-
function fenceOverhead(fence) {
|
|
187724
|
-
return fence === undefined ? 0 : fence.header.length + 1 + (fence.marker.length + 1);
|
|
187725
|
-
}
|
|
187726
|
-
function cutAt(text, max) {
|
|
187727
|
-
if (text.length <= max) {
|
|
187728
|
-
return text.length;
|
|
187729
|
-
}
|
|
187730
|
-
for (let index = max;index > 0; index -= 1) {
|
|
187731
|
-
const ch = text[index - 1];
|
|
187732
|
-
if (ch === " " || ch === "\t") {
|
|
187733
|
-
return index;
|
|
187734
|
-
}
|
|
187735
|
-
}
|
|
187736
|
-
const code = text.charCodeAt(max - 1);
|
|
187737
|
-
return code >= 55296 && code <= 56319 ? max - 1 : max;
|
|
187738
|
-
}
|
|
187739
|
-
function toPieces(text, capacity) {
|
|
187740
|
-
const pieces = [];
|
|
187741
|
-
let fence;
|
|
187742
|
-
for (const raw of text.split(/(?<=\n)/)) {
|
|
187743
|
-
const line = raw.endsWith(`
|
|
187744
|
-
`) ? raw.slice(0, -1) : raw;
|
|
187745
|
-
const before = fence;
|
|
187746
|
-
if (fence === undefined) {
|
|
187747
|
-
fence = openingFence(line);
|
|
187748
|
-
} else if (closesFence(line, fence)) {
|
|
187749
|
-
fence = undefined;
|
|
187750
|
-
}
|
|
187751
|
-
const room = Math.max(8, capacity - Math.max(fenceOverhead(before), fenceOverhead(fence)));
|
|
187752
|
-
let rest = raw;
|
|
187753
|
-
while (rest.length > room) {
|
|
187754
|
-
const cut = cutAt(rest, room);
|
|
187755
|
-
pieces.push({ text: rest.slice(0, cut), fence: before ?? fence });
|
|
187756
|
-
rest = rest.slice(cut);
|
|
187757
|
-
}
|
|
187758
|
-
if (rest.length > 0) {
|
|
187759
|
-
pieces.push({ text: rest, fence });
|
|
187760
|
-
}
|
|
187761
|
-
}
|
|
187762
|
-
return pieces;
|
|
187763
|
-
}
|
|
187764
|
-
function pack(text, capacity) {
|
|
187765
|
-
const parts = [];
|
|
187766
|
-
let current = "";
|
|
187767
|
-
let hasContent = false;
|
|
187768
|
-
let open;
|
|
187769
|
-
const finish = () => {
|
|
187770
|
-
let body = current.trimEnd();
|
|
187771
|
-
if (!hasContent || body.length === 0) {
|
|
187772
|
-
current = "";
|
|
187773
|
-
hasContent = false;
|
|
187774
|
-
return;
|
|
187775
|
-
}
|
|
187776
|
-
if (open !== undefined) {
|
|
187777
|
-
body += `
|
|
187778
|
-
${open.marker}`;
|
|
187779
|
-
}
|
|
187780
|
-
parts.push(body);
|
|
187781
|
-
current = open === undefined ? "" : `${open.header}
|
|
187782
|
-
`;
|
|
187783
|
-
hasContent = false;
|
|
187784
|
-
};
|
|
187785
|
-
for (const piece of toPieces(text, capacity)) {
|
|
187786
|
-
if (!hasContent && piece.text.trim().length === 0) {
|
|
187787
|
-
continue;
|
|
187788
|
-
}
|
|
187789
|
-
const closing = piece.fence === undefined ? 0 : piece.fence.marker.length + 1;
|
|
187790
|
-
if (hasContent && current.length + piece.text.length + closing > capacity) {
|
|
187791
|
-
finish();
|
|
187792
|
-
if (piece.text.trim().length === 0) {
|
|
187793
|
-
continue;
|
|
187794
|
-
}
|
|
187795
|
-
}
|
|
187796
|
-
current += piece.text;
|
|
187797
|
-
hasContent = true;
|
|
187798
|
-
open = piece.fence;
|
|
187799
|
-
}
|
|
187800
|
-
finish();
|
|
187801
|
-
return parts;
|
|
187802
|
-
}
|
|
187803
|
-
function formatReply(text, limit = TELEGRAM_MAX_TEXT) {
|
|
187804
|
-
if (limit < MIN_LIMIT) {
|
|
187805
|
-
throw new RangeError(`formatReply: limit must be at least ${MIN_LIMIT}`);
|
|
187806
|
-
}
|
|
187807
|
-
if (text.trim().length === 0) {
|
|
187808
|
-
return [];
|
|
187809
|
-
}
|
|
187810
|
-
if (text.length <= limit) {
|
|
187811
|
-
return [text];
|
|
187812
|
-
}
|
|
187813
|
-
for (let digits = 1;digits <= 3; digits += 1) {
|
|
187814
|
-
const labelLength = 2 * digits + 4;
|
|
187815
|
-
const parts = pack(text, limit - labelLength);
|
|
187816
|
-
if (String(parts.length).length > digits) {
|
|
187817
|
-
continue;
|
|
187818
|
-
}
|
|
187819
|
-
if (parts.length <= 1) {
|
|
187820
|
-
return parts;
|
|
187821
|
-
}
|
|
187822
|
-
return parts.map((part, index) => `(${index + 1}/${parts.length})
|
|
187823
|
-
${part}`);
|
|
187824
|
-
}
|
|
187825
|
-
const parts = pack(text, limit - 12).slice(0, 999);
|
|
187826
|
-
return parts.map((part, index) => `(${index + 1}/${parts.length})
|
|
187827
|
-
${part}`);
|
|
187828
|
-
}
|
|
187829
|
-
var MIN_LIMIT = 64, MAX_FENCE_MARKER = 16, MAX_FENCE_INFO = 40, FENCE_LINE2;
|
|
187830
|
-
var init_format2 = __esm(() => {
|
|
187831
|
-
init_types11();
|
|
187832
|
-
FENCE_LINE2 = /^ {0,3}(`{3,}|~{3,})(.*)$/;
|
|
187833
|
-
});
|
|
187834
|
-
|
|
187835
188144
|
// src/remote/outbound-queue.ts
|
|
187836
188145
|
import { randomUUID as randomUUID48 } from "crypto";
|
|
187837
188146
|
import path356 from "path";
|
|
@@ -187857,6 +188166,7 @@ class OutboundQueue {
|
|
|
187857
188166
|
now;
|
|
187858
188167
|
log;
|
|
187859
188168
|
onDrop;
|
|
188169
|
+
onFallback;
|
|
187860
188170
|
retryDelayMs;
|
|
187861
188171
|
blockedUntil = 0;
|
|
187862
188172
|
flushing;
|
|
@@ -187866,6 +188176,9 @@ class OutboundQueue {
|
|
|
187866
188176
|
this.onDrop = options.onDrop ?? (() => {
|
|
187867
188177
|
return;
|
|
187868
188178
|
});
|
|
188179
|
+
this.onFallback = options.onFallback ?? (() => {
|
|
188180
|
+
return;
|
|
188181
|
+
});
|
|
187869
188182
|
this.retryDelayMs = options.retryDelayMs ?? 5000;
|
|
187870
188183
|
const directory = ensureRemoteDir(options.dir);
|
|
187871
188184
|
this.log = new DurableLog({
|
|
@@ -187934,12 +188247,12 @@ class OutboundQueue {
|
|
|
187934
188247
|
return { sent, dropped, remaining: this.log.size, retryInMs: wait, stoppedBy: "rate limited" };
|
|
187935
188248
|
}
|
|
187936
188249
|
try {
|
|
187937
|
-
await this.api
|
|
188250
|
+
await sendHtml(this.api, {
|
|
187938
188251
|
chatId: entry.chatId,
|
|
187939
188252
|
text: entry.text,
|
|
187940
188253
|
...entry.threadId === undefined ? {} : { messageThreadId: entry.threadId },
|
|
187941
188254
|
...entry.keyboard === undefined ? {} : { inlineKeyboard: entry.keyboard }
|
|
187942
|
-
});
|
|
188255
|
+
}, () => this.onFallback(entry));
|
|
187943
188256
|
this.log.ack(entry.id);
|
|
187944
188257
|
sent += 1;
|
|
187945
188258
|
} catch (error) {
|
|
@@ -187968,6 +188281,7 @@ var init_outbound_queue = __esm(() => {
|
|
|
187968
188281
|
init_durable_log();
|
|
187969
188282
|
init_paths4();
|
|
187970
188283
|
init_format2();
|
|
188284
|
+
init_format_html();
|
|
187971
188285
|
init_types11();
|
|
187972
188286
|
});
|
|
187973
188287
|
|
|
@@ -188275,7 +188589,8 @@ class RemoteHub {
|
|
|
188275
188589
|
api: this.api,
|
|
188276
188590
|
...options.dir === undefined ? {} : { dir: options.dir },
|
|
188277
188591
|
now: this.now,
|
|
188278
|
-
onDrop: (entry, reason) => this.event("outbound-dropped", `${reason}${entry.threadId === undefined ? "" : ` (topic ${entry.threadId})`}`)
|
|
188592
|
+
onDrop: (entry, reason) => this.event("outbound-dropped", `${reason}${entry.threadId === undefined ? "" : ` (topic ${entry.threadId})`}`),
|
|
188593
|
+
onFallback: (entry) => this.event("format-fallback", `Telegram refused the formatting; sent as plain text${entry.threadId === undefined ? "" : ` (topic ${entry.threadId})`}`)
|
|
188279
188594
|
});
|
|
188280
188595
|
this.journal = new RejectedJournal({ ...options.dir === undefined ? {} : { dir: options.dir }, now: this.now });
|
|
188281
188596
|
this.offset = new PollerState(options.dir === undefined ? {} : { dir: options.dir });
|
|
@@ -188402,7 +188717,7 @@ class RemoteHub {
|
|
|
188402
188717
|
});
|
|
188403
188718
|
}
|
|
188404
188719
|
async sendGeneral(text) {
|
|
188405
|
-
await this.api
|
|
188720
|
+
await sendHtml(this.api, { chatId: this.config.chatId, text }, () => this.event("format-fallback", "Telegram refused the formatting; sent as plain text (General)"));
|
|
188406
188721
|
}
|
|
188407
188722
|
heartbeat(sessionId) {
|
|
188408
188723
|
return this.serial(async () => {
|
|
@@ -188753,6 +189068,7 @@ var realTimers, MAX_EVENTS = 50, ANSWER_CALLBACK_TIMEOUT_MS = 5000;
|
|
|
188753
189068
|
var init_hub = __esm(() => {
|
|
188754
189069
|
init_service2();
|
|
188755
189070
|
init_lease();
|
|
189071
|
+
init_format_html();
|
|
188756
189072
|
init_inbound();
|
|
188757
189073
|
init_journal2();
|
|
188758
189074
|
init_naming();
|
|
@@ -189199,7 +189515,7 @@ class RemoteHttpSurface {
|
|
|
189199
189515
|
timer: this.timers.setTimeout(() => this.expireApproval(approvalId), timeoutMs)
|
|
189200
189516
|
});
|
|
189201
189517
|
const sent = await hub.send(sessionId, `Approval needed:
|
|
189202
|
-
${redactSensitiveText(value.prompt)}`, {
|
|
189518
|
+
${asCodeBlock(redactSensitiveText(value.prompt))}`, {
|
|
189203
189519
|
keyboard: [
|
|
189204
189520
|
[
|
|
189205
189521
|
{ text: "Allow", callback_data: approvalCallbackData(approvalId, "allow") },
|
|
@@ -189414,7 +189730,16 @@ ${redactSensitiveText(value.prompt)}`, {
|
|
|
189414
189730
|
}
|
|
189415
189731
|
}
|
|
189416
189732
|
}
|
|
189417
|
-
|
|
189733
|
+
function asCodeBlock(text) {
|
|
189734
|
+
const safe = (text.trim().length === 0 ? "(empty)" : text).replace(/\r\n?/g, `
|
|
189735
|
+
`).replace(/`{9,}/g, (run) => run.match(/`{1,8}/g).join("\u200B"));
|
|
189736
|
+
const longest = Math.max(0, ...(safe.match(/`+/g) ?? []).map((run) => run.length));
|
|
189737
|
+
const fence = "`".repeat(Math.max(3, Math.min(longest, MAX_BACKTICK_RUN) + 1));
|
|
189738
|
+
return `${fence}
|
|
189739
|
+
${safe}
|
|
189740
|
+
${fence}`;
|
|
189741
|
+
}
|
|
189742
|
+
var MAX_REPLY_CHARS = 20000, MAX_PENDING_APPROVALS_PER_SESSION = 8, MAX_REMEMBERED_IDS_PER_SESSION = 512, MAX_PROJECT_NAME_CHARS = 128, CONTROL_CHARS2, JSON_HEADERS2, MAX_BACKTICK_RUN = 8;
|
|
189418
189743
|
var init_http_surface = __esm(() => {
|
|
189419
189744
|
init_service2();
|
|
189420
189745
|
init_hub();
|
|
@@ -189629,7 +189954,10 @@ class Pairing {
|
|
|
189629
189954
|
this.state = "waiting-for-group";
|
|
189630
189955
|
this.expiresAt = this.now() + this.ttlMs;
|
|
189631
189956
|
this.armExpiryTimer();
|
|
189632
|
-
await this.options.api
|
|
189957
|
+
await sendHtml(this.options.api, {
|
|
189958
|
+
chatId: message.chat.id,
|
|
189959
|
+
text: "Paired. Now add me to your group (a group with Topics turned on) and make me an administrator."
|
|
189960
|
+
}).catch(() => {
|
|
189633
189961
|
return;
|
|
189634
189962
|
});
|
|
189635
189963
|
const early = [...this.earlyGroups.values()];
|
|
@@ -189743,6 +190071,7 @@ class Pairing {
|
|
|
189743
190071
|
var PAIRING_CODE_TTL_MS, CODE_ALPHABET = "ABCDEFGHJKMNPQRSTUVWXYZ23456789", CODE_LENGTH = 8, FINAL, EARLY_GROUP_EVENTS = 20;
|
|
189744
190072
|
var init_pairing = __esm(() => {
|
|
189745
190073
|
init_service2();
|
|
190074
|
+
init_format_html();
|
|
189746
190075
|
init_hub();
|
|
189747
190076
|
init_poller();
|
|
189748
190077
|
init_types11();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.56",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|