openzca 0.1.32 → 0.1.34
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 +128 -13
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -706,30 +706,108 @@ function asThreadType(groupFlag) {
|
|
|
706
706
|
return groupFlag ? ThreadType.Group : ThreadType.User;
|
|
707
707
|
}
|
|
708
708
|
function parseTextStyles(input) {
|
|
709
|
-
const
|
|
709
|
+
const allStyles = [];
|
|
710
|
+
const escapeMap = [];
|
|
711
|
+
const escaped = input.replace(/\\([*_~#\\{}>+\-])/g, (_match, ch) => {
|
|
712
|
+
const idx = escapeMap.length;
|
|
713
|
+
escapeMap.push(ch);
|
|
714
|
+
return `${idx}`;
|
|
715
|
+
});
|
|
716
|
+
const lines = escaped.split("\n");
|
|
717
|
+
const lineStyles = [];
|
|
718
|
+
const processedLines = [];
|
|
719
|
+
for (let i = 0; i < lines.length; i++) {
|
|
720
|
+
let line = lines[i];
|
|
721
|
+
const headingMatch = line.match(/^(#{1,6})\s(.*)$/);
|
|
722
|
+
if (headingMatch) {
|
|
723
|
+
const level = headingMatch[1].length;
|
|
724
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.Bold });
|
|
725
|
+
if (level === 1) lineStyles.push({ lineIndex: i, style: TextStyle.Big });
|
|
726
|
+
else if (level >= 3) lineStyles.push({ lineIndex: i, style: TextStyle.Small });
|
|
727
|
+
processedLines.push(headingMatch[2]);
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
const bqMatch = line.match(/^(>+)\s?(.*)$/);
|
|
731
|
+
if (bqMatch) {
|
|
732
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.Indent, indentSize: bqMatch[1].length });
|
|
733
|
+
line = bqMatch[2];
|
|
734
|
+
}
|
|
735
|
+
const indentContentMatch = line.match(/^(\s+)(.*)$/);
|
|
736
|
+
let indentLevel = 0;
|
|
737
|
+
let content = line;
|
|
738
|
+
if (indentContentMatch) {
|
|
739
|
+
indentLevel = Math.max(1, Math.floor(indentContentMatch[1].length / 2));
|
|
740
|
+
content = indentContentMatch[2];
|
|
741
|
+
}
|
|
742
|
+
const olMatch = content.match(/^(\d+)\.\s(.*)$/);
|
|
743
|
+
if (olMatch) {
|
|
744
|
+
if (indentLevel > 0) {
|
|
745
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.Indent, indentSize: indentLevel });
|
|
746
|
+
}
|
|
747
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.OrderedList });
|
|
748
|
+
processedLines.push(olMatch[2]);
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
const ulMatch = content.match(/^[-*+]\s(.*)$/);
|
|
752
|
+
if (ulMatch) {
|
|
753
|
+
if (indentLevel > 0) {
|
|
754
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.Indent, indentSize: indentLevel });
|
|
755
|
+
}
|
|
756
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.UnorderedList });
|
|
757
|
+
processedLines.push(ulMatch[1]);
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
if (indentLevel > 0) {
|
|
761
|
+
lineStyles.push({ lineIndex: i, style: TextStyle.Indent, indentSize: indentLevel });
|
|
762
|
+
processedLines.push(content);
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
processedLines.push(line);
|
|
766
|
+
}
|
|
767
|
+
const inlineInput = processedLines.join("\n");
|
|
768
|
+
const colorMap = {
|
|
769
|
+
red: TextStyle.Red,
|
|
770
|
+
orange: TextStyle.Orange,
|
|
771
|
+
yellow: TextStyle.Yellow,
|
|
772
|
+
green: TextStyle.Green,
|
|
773
|
+
small: TextStyle.Small,
|
|
774
|
+
big: TextStyle.Big,
|
|
775
|
+
underline: TextStyle.Underline
|
|
776
|
+
};
|
|
777
|
+
const tagNames = Object.keys(colorMap).join("|");
|
|
710
778
|
const markers = [
|
|
711
|
-
|
|
779
|
+
// Tags first so inner markdown markers are preserved for subsequent passes
|
|
780
|
+
{ pattern: new RegExp(`\\{(${tagNames})\\}(.+?)\\{/\\1\\}`, "g"), style: null },
|
|
781
|
+
// *** = bold + italic
|
|
782
|
+
{ pattern: /\*\*\*(.+?)\*\*\*/g, style: TextStyle.Bold, extraStyles: [TextStyle.Italic] },
|
|
783
|
+
// ** and __ = bold (standard markdown)
|
|
712
784
|
{ pattern: /\*\*(.+?)\*\*/g, style: TextStyle.Bold },
|
|
785
|
+
{ pattern: /__(.+?)__/g, style: TextStyle.Bold },
|
|
786
|
+
// * and _ = italic (standard markdown)
|
|
713
787
|
{ pattern: /\*(.+?)\*/g, style: TextStyle.Italic },
|
|
714
|
-
{ pattern: /
|
|
788
|
+
{ pattern: /_(.+?)_/g, style: TextStyle.Italic },
|
|
789
|
+
// ~~ = strikethrough
|
|
715
790
|
{ pattern: /~~(.+?)~~/g, style: TextStyle.StrikeThrough }
|
|
716
791
|
];
|
|
717
|
-
let segments = [{ text:
|
|
718
|
-
for (const
|
|
792
|
+
let segments = [{ text: inlineInput, styles: [] }];
|
|
793
|
+
for (const marker of markers) {
|
|
719
794
|
const next = [];
|
|
720
795
|
for (const seg of segments) {
|
|
721
796
|
let lastIndex = 0;
|
|
722
|
-
const regex = new RegExp(pattern.source, pattern.flags);
|
|
797
|
+
const regex = new RegExp(marker.pattern.source, marker.pattern.flags);
|
|
723
798
|
let m;
|
|
724
799
|
while ((m = regex.exec(seg.text)) !== null) {
|
|
725
800
|
if (m.index > lastIndex) {
|
|
726
801
|
next.push({ text: seg.text.slice(lastIndex, m.index), styles: [...seg.styles] });
|
|
727
802
|
}
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
803
|
+
const isTagPattern = marker.style === null;
|
|
804
|
+
const innerText = isTagPattern ? m[2] : m[1];
|
|
805
|
+
const resolvedStyle = isTagPattern ? colorMap[m[1]] : marker.style;
|
|
806
|
+
const combined = [...seg.styles, resolvedStyle];
|
|
807
|
+
if (marker.extraStyles) {
|
|
808
|
+
combined.push(...marker.extraStyles);
|
|
731
809
|
}
|
|
732
|
-
next.push({ text:
|
|
810
|
+
next.push({ text: innerText, styles: combined });
|
|
733
811
|
lastIndex = regex.lastIndex;
|
|
734
812
|
}
|
|
735
813
|
if (lastIndex < seg.text.length) {
|
|
@@ -745,10 +823,47 @@ function parseTextStyles(input) {
|
|
|
745
823
|
const start = plainText.length;
|
|
746
824
|
plainText += seg.text;
|
|
747
825
|
for (const st of seg.styles) {
|
|
748
|
-
|
|
826
|
+
allStyles.push({ start, len: seg.text.length, st });
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
if (escapeMap.length > 0) {
|
|
830
|
+
const escRegex = /\x01(\d+)\x02/g;
|
|
831
|
+
const shifts = [];
|
|
832
|
+
let cumDelta = 0;
|
|
833
|
+
for (const m of plainText.matchAll(escRegex)) {
|
|
834
|
+
const idx = parseInt(m[1], 10);
|
|
835
|
+
cumDelta += m[0].length - escapeMap[idx].length;
|
|
836
|
+
shifts.push({ pos: m.index + m[0].length, delta: cumDelta });
|
|
837
|
+
}
|
|
838
|
+
for (const s of allStyles) {
|
|
839
|
+
let startDelta = 0;
|
|
840
|
+
let endDelta = 0;
|
|
841
|
+
const end = s.start + s.len;
|
|
842
|
+
for (const sh of shifts) {
|
|
843
|
+
if (sh.pos <= s.start) startDelta = sh.delta;
|
|
844
|
+
if (sh.pos <= end) endDelta = sh.delta;
|
|
845
|
+
}
|
|
846
|
+
s.start -= startDelta;
|
|
847
|
+
s.len -= endDelta - startDelta;
|
|
848
|
+
}
|
|
849
|
+
plainText = plainText.replace(escRegex, (_m, idxStr) => escapeMap[parseInt(idxStr, 10)]);
|
|
850
|
+
}
|
|
851
|
+
const finalLines = plainText.split("\n");
|
|
852
|
+
let offset = 0;
|
|
853
|
+
for (let i = 0; i < finalLines.length; i++) {
|
|
854
|
+
const lineLen = finalLines[i].length;
|
|
855
|
+
for (const ls of lineStyles) {
|
|
856
|
+
if (ls.lineIndex === i && lineLen > 0) {
|
|
857
|
+
if (ls.style === TextStyle.Indent) {
|
|
858
|
+
allStyles.push({ start: offset, len: lineLen, st: TextStyle.Indent, indentSize: ls.indentSize });
|
|
859
|
+
} else {
|
|
860
|
+
allStyles.push({ start: offset, len: lineLen, st: ls.style });
|
|
861
|
+
}
|
|
862
|
+
}
|
|
749
863
|
}
|
|
864
|
+
offset += lineLen + 1;
|
|
750
865
|
}
|
|
751
|
-
return { text: plainText, styles };
|
|
866
|
+
return { text: plainText, styles: allStyles };
|
|
752
867
|
}
|
|
753
868
|
function parseBooleanFromEnv(name, fallback) {
|
|
754
869
|
const raw = process.env[name]?.trim();
|
|
@@ -2933,7 +3048,7 @@ auth.command("cache-clear").description("Clear local cache").action(
|
|
|
2933
3048
|
})
|
|
2934
3049
|
);
|
|
2935
3050
|
var msg = program.command("msg").description("Messaging commands");
|
|
2936
|
-
msg.command("send <threadId> <message>").option("-g, --group", "Send to group").option("--raw", "Send raw text without parsing formatting markers").description("Send text message (
|
|
3051
|
+
msg.command("send <threadId> <message>").option("-g, --group", "Send to group").option("--raw", "Send raw text without parsing formatting markers").description("Send text message with formatting (**bold** *italic* __underline__ ~~strike~~ {red}color{/red} {big}size{/big} lists indents)").action(
|
|
2937
3052
|
wrapAction(async (threadId, message, opts, command) => {
|
|
2938
3053
|
const { api } = await requireApi(command);
|
|
2939
3054
|
if (opts.raw) {
|