@kontextmind/kxm 0.7.205 → 0.7.206
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/.claude-plugin/marketplace.json +1 -1
- package/package.json +6 -6
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +94 -27
- package/plugins/kxm/dist/extension.js +70 -26
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontextmind/kxm",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.206",
|
|
4
4
|
"description": "KXM local-first multi-agent orchestration and operator dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "KontextMind",
|
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
]
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
81
|
-
"@earendil-works/pi-tui": "1.
|
|
80
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.303",
|
|
81
|
+
"@earendil-works/pi-tui": "1.3.0",
|
|
82
82
|
"@modelcontextprotocol/sdk": "1.32.1",
|
|
83
83
|
"yaml": "^2.9.0"
|
|
84
84
|
},
|
|
@@ -95,9 +95,9 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
98
|
+
"@earendil-works/pi-coding-agent": "1.3.0",
|
|
99
99
|
"@modelcontextprotocol/sdk": "1.32.1",
|
|
100
|
-
"@playwright/test": "1.64.
|
|
100
|
+
"@playwright/test": "1.64.1",
|
|
101
101
|
"@types/node": "26.6.5",
|
|
102
102
|
"ajv": "8.20.0",
|
|
103
103
|
"commander": "15.0.0",
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"markdownlint-cli2": "0.23.3",
|
|
106
106
|
"nx": "23.3.0",
|
|
107
107
|
"tsx": "^4.23.13",
|
|
108
|
-
"typebox": "1.
|
|
108
|
+
"typebox": "1.4.2",
|
|
109
109
|
"typescript": "7.0.2"
|
|
110
110
|
},
|
|
111
111
|
"files": [
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "kxm",
|
|
4
4
|
"displayName": "KXM",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.206",
|
|
6
6
|
"description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "KontextMind",
|
package/plugins/kxm/dist/cli.js
CHANGED
|
@@ -44219,7 +44219,7 @@ function extractSegments(line, beforeEnd, afterStart, afterLen, strictAfter = fa
|
|
|
44219
44219
|
pooledStyleTracker.process(ansi.code);
|
|
44220
44220
|
if (currentCol < beforeEnd) {
|
|
44221
44221
|
pendingAnsiBefore += ansi.code;
|
|
44222
|
-
} else if (currentCol >= afterStart && currentCol < afterEnd && afterStarted) {
|
|
44222
|
+
} else if (currentCol >= afterStart && currentCol < afterEnd && (afterStarted || ansi.code.startsWith("\x1B_"))) {
|
|
44223
44223
|
after += ansi.code;
|
|
44224
44224
|
}
|
|
44225
44225
|
i += ansi.length;
|
|
@@ -44400,6 +44400,8 @@ var SYMBOL_KEYS = /* @__PURE__ */ new Set([
|
|
|
44400
44400
|
">",
|
|
44401
44401
|
"?"
|
|
44402
44402
|
]);
|
|
44403
|
+
var SHIFTED_SYMBOL_KEYS = new Set("~!@#$%^&*()_+|{}:<>?");
|
|
44404
|
+
var MODIFIER_NAMES = ["shift", "alt", "ctrl", "super"];
|
|
44403
44405
|
var MODIFIERS = {
|
|
44404
44406
|
shift: 1,
|
|
44405
44407
|
alt: 2,
|
|
@@ -44486,6 +44488,14 @@ function normalizeShiftedLetterIdentityCodepoint(codepoint, modifier) {
|
|
|
44486
44488
|
}
|
|
44487
44489
|
return codepoint;
|
|
44488
44490
|
}
|
|
44491
|
+
function getLogicalShiftedSymbolCandidate(codepoint, modifier, allowedSymbols) {
|
|
44492
|
+
if (codepoint === void 0 || (modifier & MODIFIERS.shift) === 0)
|
|
44493
|
+
return void 0;
|
|
44494
|
+
const normalizedCodepoint = normalizeKittyFunctionalCodepoint(codepoint);
|
|
44495
|
+
if (!allowedSymbols.has(String.fromCharCode(normalizedCodepoint)))
|
|
44496
|
+
return void 0;
|
|
44497
|
+
return { codepoint: normalizedCodepoint, modifier: modifier & ~MODIFIERS.shift };
|
|
44498
|
+
}
|
|
44489
44499
|
var LEGACY_KEY_SEQUENCES = {
|
|
44490
44500
|
up: ["\x1B[A", "\x1BOA"],
|
|
44491
44501
|
down: ["\x1B[B", "\x1BOB"],
|
|
@@ -44681,12 +44691,16 @@ function matchesKittySequence(data, expectedCodepoint, expectedModifier) {
|
|
|
44681
44691
|
return false;
|
|
44682
44692
|
const actualMod = parsed.modifier & ~LOCK_MASK;
|
|
44683
44693
|
const expectedMod = expectedModifier & ~LOCK_MASK;
|
|
44684
|
-
if (actualMod !== expectedMod)
|
|
44685
|
-
return false;
|
|
44686
44694
|
const normalizedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(parsed.codepoint), parsed.modifier);
|
|
44687
44695
|
const normalizedExpectedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(expectedCodepoint), expectedModifier);
|
|
44688
|
-
if (normalizedCodepoint === normalizedExpectedCodepoint)
|
|
44696
|
+
if (actualMod === expectedMod && normalizedCodepoint === normalizedExpectedCodepoint)
|
|
44697
|
+
return true;
|
|
44698
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(parsed.shiftedKey, actualMod, SYMBOL_KEYS);
|
|
44699
|
+
if (logicalShiftedSymbol && (logicalShiftedSymbol.modifier & ~LOCK_MASK) === expectedMod && logicalShiftedSymbol.codepoint === normalizeKittyFunctionalCodepoint(expectedCodepoint)) {
|
|
44689
44700
|
return true;
|
|
44701
|
+
}
|
|
44702
|
+
if (actualMod !== expectedMod)
|
|
44703
|
+
return false;
|
|
44690
44704
|
if (parsed.baseLayoutKey !== void 0 && parsed.baseLayoutKey === expectedCodepoint) {
|
|
44691
44705
|
const cp = normalizedCodepoint;
|
|
44692
44706
|
const isLatinLetter = cp >= 97 && cp <= 122;
|
|
@@ -44735,12 +44749,14 @@ function isDigitKey(key) {
|
|
|
44735
44749
|
return key >= "0" && key <= "9";
|
|
44736
44750
|
}
|
|
44737
44751
|
function matchesPrintableModifyOtherKeys(data, expectedKeycode, expectedModifier) {
|
|
44738
|
-
if (expectedModifier === 0)
|
|
44739
|
-
return false;
|
|
44740
44752
|
const parsed = parseModifyOtherKeysSequence(data);
|
|
44741
|
-
if (!parsed
|
|
44753
|
+
if (!parsed)
|
|
44742
44754
|
return false;
|
|
44743
|
-
|
|
44755
|
+
const physicalMatch = parsed.modifier === expectedModifier && normalizeShiftedLetterIdentityCodepoint(parsed.codepoint, parsed.modifier) === normalizeShiftedLetterIdentityCodepoint(expectedKeycode, expectedModifier);
|
|
44756
|
+
if (physicalMatch)
|
|
44757
|
+
return true;
|
|
44758
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(parsed.codepoint, parsed.modifier, SHIFTED_SYMBOL_KEYS);
|
|
44759
|
+
return logicalShiftedSymbol?.modifier === expectedModifier && logicalShiftedSymbol.codepoint === expectedKeycode;
|
|
44744
44760
|
}
|
|
44745
44761
|
function formatKeyNameWithModifiers(keyName, modifier) {
|
|
44746
44762
|
const mods = [];
|
|
@@ -44759,16 +44775,25 @@ function formatKeyNameWithModifiers(keyName, modifier) {
|
|
|
44759
44775
|
return mods.length > 0 ? `${mods.join("+")}+${keyName}` : keyName;
|
|
44760
44776
|
}
|
|
44761
44777
|
function parseKeyId(keyId) {
|
|
44762
|
-
|
|
44763
|
-
const
|
|
44764
|
-
|
|
44778
|
+
let key = keyId.toLowerCase();
|
|
44779
|
+
const modifiers = /* @__PURE__ */ new Set();
|
|
44780
|
+
while (true) {
|
|
44781
|
+
const modifier = MODIFIER_NAMES.find((name) => key.startsWith(`${name}+`));
|
|
44782
|
+
if (!modifier)
|
|
44783
|
+
break;
|
|
44784
|
+
if (modifiers.has(modifier))
|
|
44785
|
+
return null;
|
|
44786
|
+
modifiers.add(modifier);
|
|
44787
|
+
key = key.slice(modifier.length + 1);
|
|
44788
|
+
}
|
|
44789
|
+
if (!key || key.includes("+") && key !== "+")
|
|
44765
44790
|
return null;
|
|
44766
44791
|
return {
|
|
44767
44792
|
key,
|
|
44768
|
-
ctrl:
|
|
44769
|
-
shift:
|
|
44770
|
-
alt:
|
|
44771
|
-
super:
|
|
44793
|
+
ctrl: modifiers.has("ctrl"),
|
|
44794
|
+
shift: modifiers.has("shift"),
|
|
44795
|
+
alt: modifiers.has("alt"),
|
|
44796
|
+
super: modifiers.has("super")
|
|
44772
44797
|
};
|
|
44773
44798
|
}
|
|
44774
44799
|
function matchesKey(data, keyId) {
|
|
@@ -45010,7 +45035,7 @@ function matchesKey(data, keyId) {
|
|
|
45010
45035
|
if (modifier !== 0) {
|
|
45011
45036
|
return matchesKittySequence(data, codepoint, modifier) || matchesPrintableModifyOtherKeys(data, codepoint, modifier);
|
|
45012
45037
|
}
|
|
45013
|
-
return data === key || matchesKittySequence(data, codepoint, 0);
|
|
45038
|
+
return data === key || matchesKittySequence(data, codepoint, 0) || matchesPrintableModifyOtherKeys(data, codepoint, 0);
|
|
45014
45039
|
}
|
|
45015
45040
|
return false;
|
|
45016
45041
|
}
|
|
@@ -45065,11 +45090,13 @@ function formatParsedKey(codepoint, modifier, baseLayoutKey) {
|
|
|
45065
45090
|
function parseKey(data) {
|
|
45066
45091
|
const kitty = parseKittySequence(data);
|
|
45067
45092
|
if (kitty) {
|
|
45068
|
-
|
|
45093
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(kitty.shiftedKey, kitty.modifier, SYMBOL_KEYS);
|
|
45094
|
+
return formatParsedKey(logicalShiftedSymbol?.codepoint ?? kitty.codepoint, logicalShiftedSymbol?.modifier ?? kitty.modifier, kitty.baseLayoutKey);
|
|
45069
45095
|
}
|
|
45070
45096
|
const modifyOtherKeys = parseModifyOtherKeysSequence(data);
|
|
45071
45097
|
if (modifyOtherKeys) {
|
|
45072
|
-
|
|
45098
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(modifyOtherKeys.codepoint, modifyOtherKeys.modifier, SHIFTED_SYMBOL_KEYS);
|
|
45099
|
+
return formatParsedKey(logicalShiftedSymbol?.codepoint ?? modifyOtherKeys.codepoint, logicalShiftedSymbol?.modifier ?? modifyOtherKeys.modifier);
|
|
45073
45100
|
}
|
|
45074
45101
|
if (_kittyProtocolActive) {
|
|
45075
45102
|
if (data === "\x1B\r" || data === "\n")
|
|
@@ -45282,7 +45309,7 @@ function detectCapabilitiesFromEnvironment(tmuxForwardsHyperlink) {
|
|
|
45282
45309
|
return { images: null, trueColor: hasTrueColorHint, hyperlinks: false };
|
|
45283
45310
|
}
|
|
45284
45311
|
if (termProgram === "herdr") {
|
|
45285
|
-
return { images:
|
|
45312
|
+
return { images: "kitty", trueColor: hasTrueColorHint, hyperlinks: true };
|
|
45286
45313
|
}
|
|
45287
45314
|
if (process.env.KITTY_WINDOW_ID || termProgram === "kitty") {
|
|
45288
45315
|
return { images: "kitty", trueColor: true, hyperlinks: true };
|
|
@@ -45512,6 +45539,12 @@ function isFocusable(component) {
|
|
|
45512
45539
|
return component !== null && "focused" in component;
|
|
45513
45540
|
}
|
|
45514
45541
|
var CURSOR_MARKER = "\x1B_pi:c\x07";
|
|
45542
|
+
var FAKE_CURSOR_START = "\x1B_pi:fc\x07";
|
|
45543
|
+
var FAKE_CURSOR_END = "\x1B_pi:/fc\x07";
|
|
45544
|
+
var FOCUSED_FAKE_CURSOR = /(\x1b_pi:c\x07)\x1b_pi:fc\x07(.*?)(?:\x1b_pi:\/fc\x07|$)/s;
|
|
45545
|
+
function renderFakeCursor(text) {
|
|
45546
|
+
return `${FAKE_CURSOR_START}${text}${FAKE_CURSOR_END}`;
|
|
45547
|
+
}
|
|
45515
45548
|
function parseSizeValue(value, referenceSize) {
|
|
45516
45549
|
if (value === void 0)
|
|
45517
45550
|
return void 0;
|
|
@@ -46314,7 +46347,7 @@ var TuiBase = class _TuiBase extends Container {
|
|
|
46314
46347
|
for (const entry of visibleEntries) {
|
|
46315
46348
|
const { component, options } = entry;
|
|
46316
46349
|
const { width, maxHeight } = this.resolveOverlayLayout(options, 0, termWidth, termHeight);
|
|
46317
|
-
let overlayLines = component.render(width);
|
|
46350
|
+
let overlayLines = this.resolveFakeCursors(component.render(width));
|
|
46318
46351
|
if (maxHeight !== void 0 && overlayLines.length > maxHeight) {
|
|
46319
46352
|
overlayLines = overlayLines.slice(0, maxHeight);
|
|
46320
46353
|
}
|
|
@@ -46381,6 +46414,19 @@ var TuiBase = class _TuiBase extends Container {
|
|
|
46381
46414
|
}
|
|
46382
46415
|
return null;
|
|
46383
46416
|
}
|
|
46417
|
+
/**
|
|
46418
|
+
* Resolve fake cursor markers to reverse video. When the hardware cursor is shown, a fake cursor
|
|
46419
|
+
* directly after CURSOR_MARKER is dropped because the terminal cursor is drawn there. Fake cursors
|
|
46420
|
+
* of components without focus have no CURSOR_MARKER and stay visible.
|
|
46421
|
+
*/
|
|
46422
|
+
resolveFakeCursors(lines) {
|
|
46423
|
+
return lines.map((line) => {
|
|
46424
|
+
if (!line.includes(FAKE_CURSOR_START))
|
|
46425
|
+
return line;
|
|
46426
|
+
const resolved = this.showHardwareCursor ? line.replace(FOCUSED_FAKE_CURSOR, "$1$2") : line;
|
|
46427
|
+
return resolved.replaceAll(FAKE_CURSOR_START, "\x1B[7m").replaceAll(FAKE_CURSOR_END, "\x1B[27m");
|
|
46428
|
+
});
|
|
46429
|
+
}
|
|
46384
46430
|
/**
|
|
46385
46431
|
* Query the terminal's theme colors: the default foreground (OSC 10), the default background
|
|
46386
46432
|
* (OSC 11), and ANSI colors 0-15 (OSC 4), followed by a DA1 request that marks the end of the
|
|
@@ -47430,7 +47476,7 @@ var Input = class {
|
|
|
47430
47476
|
const atCursor2 = graphemes2[0]?.segment ?? " ";
|
|
47431
47477
|
const afterCursor2 = placeholder.slice(atCursor2.length);
|
|
47432
47478
|
const marker2 = this.focused ? CURSOR_MARKER : "";
|
|
47433
|
-
const cursorChar2 =
|
|
47479
|
+
const cursorChar2 = renderFakeCursor(this.placeholderStyle(atCursor2));
|
|
47434
47480
|
const textWithCursor2 = marker2 + cursorChar2 + this.placeholderStyle(afterCursor2);
|
|
47435
47481
|
const padding2 = " ".repeat(Math.max(0, availableWidth - visibleWidth(textWithCursor2)));
|
|
47436
47482
|
return [this.prompt + textWithCursor2 + padding2];
|
|
@@ -47469,7 +47515,7 @@ var Input = class {
|
|
|
47469
47515
|
const atCursor = cursorGrapheme?.segment ?? " ";
|
|
47470
47516
|
const afterCursor = visibleText.slice(cursorDisplay + atCursor.length);
|
|
47471
47517
|
const marker = this.focused ? CURSOR_MARKER : "";
|
|
47472
|
-
const cursorChar =
|
|
47518
|
+
const cursorChar = renderFakeCursor(atCursor);
|
|
47473
47519
|
const textWithCursor = beforeCursor + marker + cursorChar + afterCursor;
|
|
47474
47520
|
const visualLength = visibleWidth(textWithCursor);
|
|
47475
47521
|
const padding = " ".repeat(Math.max(0, availableWidth - visualLength));
|
|
@@ -47941,6 +47987,10 @@ var DEFAULT_SEQUENCE_TIMEOUT_MS = 50;
|
|
|
47941
47987
|
var DEFAULT_ESCAPE_TIMEOUT_MS = 10;
|
|
47942
47988
|
var BRACKETED_PASTE_START = "\x1B[200~";
|
|
47943
47989
|
var BRACKETED_PASTE_END = "\x1B[201~";
|
|
47990
|
+
var TERMINAL_REPLY_HEADER_PATTERN = /^\x1b(?:\](?:1[01];|4;\d{1,3};|7501;\?)|P>\||_G(?:[a-z]=\d+,)*[a-z]=\d+;)/;
|
|
47991
|
+
function isControlString(data) {
|
|
47992
|
+
return data.startsWith(`${ESC}]`) || data.startsWith(`${ESC}P`) || data.startsWith(`${ESC}_`);
|
|
47993
|
+
}
|
|
47944
47994
|
function isCompleteSequence(data) {
|
|
47945
47995
|
if (!data.startsWith(ESC)) {
|
|
47946
47996
|
return "not-escape";
|
|
@@ -48040,8 +48090,20 @@ function extractCompleteSequences(buffer) {
|
|
|
48040
48090
|
while (pos < buffer.length) {
|
|
48041
48091
|
const remaining = buffer.slice(pos);
|
|
48042
48092
|
if (remaining.startsWith(ESC)) {
|
|
48093
|
+
const terminalReply = isControlString(remaining) && TERMINAL_REPLY_HEADER_PATTERN.test(remaining);
|
|
48043
48094
|
let seqEnd = 1;
|
|
48044
48095
|
while (seqEnd <= remaining.length) {
|
|
48096
|
+
if (terminalReply && seqEnd > 2) {
|
|
48097
|
+
const char = remaining[seqEnd - 1];
|
|
48098
|
+
if (char === "" || char === "") {
|
|
48099
|
+
pos += seqEnd;
|
|
48100
|
+
break;
|
|
48101
|
+
}
|
|
48102
|
+
if (char === ESC && seqEnd < remaining.length && remaining[seqEnd] !== "\\") {
|
|
48103
|
+
pos += seqEnd - 1;
|
|
48104
|
+
break;
|
|
48105
|
+
}
|
|
48106
|
+
}
|
|
48045
48107
|
const candidate = remaining.slice(0, seqEnd);
|
|
48046
48108
|
const status = isCompleteSequence(candidate);
|
|
48047
48109
|
if (status === "complete") {
|
|
@@ -48163,11 +48225,18 @@ var StdinBuffer = class extends EventEmitter2 {
|
|
|
48163
48225
|
this.emitDataSequence(sequence);
|
|
48164
48226
|
}
|
|
48165
48227
|
if (this.buffer.length > 0) {
|
|
48228
|
+
if (TERMINAL_REPLY_HEADER_PATTERN.test(this.buffer))
|
|
48229
|
+
return;
|
|
48166
48230
|
const timeoutMs = this.buffer === ESC ? this.escapeTimeoutMs : this.timeoutMs;
|
|
48167
48231
|
this.timeout = setTimeout(() => {
|
|
48168
48232
|
const flushed = this.flush();
|
|
48169
48233
|
for (const sequence of flushed) {
|
|
48170
|
-
|
|
48234
|
+
if (sequence.length > 2 && isControlString(sequence)) {
|
|
48235
|
+
this.emitDataSequence(sequence.slice(0, 2));
|
|
48236
|
+
this.process(sequence.slice(2));
|
|
48237
|
+
} else {
|
|
48238
|
+
this.emitDataSequence(sequence);
|
|
48239
|
+
}
|
|
48171
48240
|
}
|
|
48172
48241
|
}, timeoutMs);
|
|
48173
48242
|
}
|
|
@@ -49525,7 +49594,7 @@ var TuiAltScreen = class extends TuiBase {
|
|
|
49525
49594
|
this.terminal.write(`${BEGIN_SYNCHRONIZED_OUTPUT}${EXIT_ALT_SCREEN}\x1B[?25h${END_SYNCHRONIZED_OUTPUT}`);
|
|
49526
49595
|
} else {
|
|
49527
49596
|
const width = Math.max(1, this.terminal.columns);
|
|
49528
|
-
const documentLines = this.render(width).map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
49597
|
+
const documentLines = this.resolveFakeCursors(this.render(width)).map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
49529
49598
|
this.lastDocument = this.applyLineResets(documentLines.map((line) => line.replaceAll(CURSOR_MARKER, ""))).map((line) => isImageLine(line) || visibleWidth(line) <= width ? line : sliceByColumn(line, 0, width, true));
|
|
49530
49599
|
let buffer = `${BEGIN_SYNCHRONIZED_OUTPUT}${EXIT_ALT_SCREEN}${DISABLE_AUTOWRAP}`;
|
|
49531
49600
|
for (let row = 0; row < this.lastDocument.length; row++) {
|
|
@@ -49810,8 +49879,6 @@ var TuiAltScreen = class extends TuiBase {
|
|
|
49810
49879
|
this.requestRender();
|
|
49811
49880
|
return { consume: true };
|
|
49812
49881
|
}
|
|
49813
|
-
if (this.shouldDeferViewportInputToOverlay())
|
|
49814
|
-
return void 0;
|
|
49815
49882
|
this.routeWheel(wheelEvent, wheelDelta);
|
|
49816
49883
|
return { consume: true };
|
|
49817
49884
|
}
|
|
@@ -50682,7 +50749,7 @@ var TuiAltScreen = class extends TuiBase {
|
|
|
50682
50749
|
if (this.refreshSearch(nextLayout)) {
|
|
50683
50750
|
nextLayout = renderLayoutFrame(root, width, height, () => this.requestRender());
|
|
50684
50751
|
}
|
|
50685
|
-
let screen = nextLayout.lines.map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
50752
|
+
let screen = this.resolveFakeCursors(nextLayout.lines.map((line) => line.replace(OSC133_ZONE_PREFIX2, "")));
|
|
50686
50753
|
screen = this.applySearchHighlights(screen, nextLayout);
|
|
50687
50754
|
screen = this.compositeScrollToEndIndicator(screen, nextLayout, width);
|
|
50688
50755
|
screen = this.compositeOverlays(screen, width, height);
|
|
@@ -40794,7 +40794,7 @@ function extractSegments(line, beforeEnd, afterStart, afterLen, strictAfter = fa
|
|
|
40794
40794
|
pooledStyleTracker.process(ansi.code);
|
|
40795
40795
|
if (currentCol < beforeEnd) {
|
|
40796
40796
|
pendingAnsiBefore += ansi.code;
|
|
40797
|
-
} else if (currentCol >= afterStart && currentCol < afterEnd && afterStarted) {
|
|
40797
|
+
} else if (currentCol >= afterStart && currentCol < afterEnd && (afterStarted || ansi.code.startsWith("\x1B_"))) {
|
|
40798
40798
|
after += ansi.code;
|
|
40799
40799
|
}
|
|
40800
40800
|
i += ansi.length;
|
|
@@ -40972,6 +40972,8 @@ var SYMBOL_KEYS = /* @__PURE__ */ new Set([
|
|
|
40972
40972
|
">",
|
|
40973
40973
|
"?"
|
|
40974
40974
|
]);
|
|
40975
|
+
var SHIFTED_SYMBOL_KEYS = new Set("~!@#$%^&*()_+|{}:<>?");
|
|
40976
|
+
var MODIFIER_NAMES = ["shift", "alt", "ctrl", "super"];
|
|
40975
40977
|
var MODIFIERS = {
|
|
40976
40978
|
shift: 1,
|
|
40977
40979
|
alt: 2,
|
|
@@ -41058,6 +41060,14 @@ function normalizeShiftedLetterIdentityCodepoint(codepoint, modifier) {
|
|
|
41058
41060
|
}
|
|
41059
41061
|
return codepoint;
|
|
41060
41062
|
}
|
|
41063
|
+
function getLogicalShiftedSymbolCandidate(codepoint, modifier, allowedSymbols) {
|
|
41064
|
+
if (codepoint === void 0 || (modifier & MODIFIERS.shift) === 0)
|
|
41065
|
+
return void 0;
|
|
41066
|
+
const normalizedCodepoint = normalizeKittyFunctionalCodepoint(codepoint);
|
|
41067
|
+
if (!allowedSymbols.has(String.fromCharCode(normalizedCodepoint)))
|
|
41068
|
+
return void 0;
|
|
41069
|
+
return { codepoint: normalizedCodepoint, modifier: modifier & ~MODIFIERS.shift };
|
|
41070
|
+
}
|
|
41061
41071
|
var LEGACY_KEY_SEQUENCES = {
|
|
41062
41072
|
up: ["\x1B[A", "\x1BOA"],
|
|
41063
41073
|
down: ["\x1B[B", "\x1BOB"],
|
|
@@ -41253,12 +41263,16 @@ function matchesKittySequence(data, expectedCodepoint, expectedModifier) {
|
|
|
41253
41263
|
return false;
|
|
41254
41264
|
const actualMod = parsed.modifier & ~LOCK_MASK;
|
|
41255
41265
|
const expectedMod = expectedModifier & ~LOCK_MASK;
|
|
41256
|
-
if (actualMod !== expectedMod)
|
|
41257
|
-
return false;
|
|
41258
41266
|
const normalizedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(parsed.codepoint), parsed.modifier);
|
|
41259
41267
|
const normalizedExpectedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(expectedCodepoint), expectedModifier);
|
|
41260
|
-
if (normalizedCodepoint === normalizedExpectedCodepoint)
|
|
41268
|
+
if (actualMod === expectedMod && normalizedCodepoint === normalizedExpectedCodepoint)
|
|
41261
41269
|
return true;
|
|
41270
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(parsed.shiftedKey, actualMod, SYMBOL_KEYS);
|
|
41271
|
+
if (logicalShiftedSymbol && (logicalShiftedSymbol.modifier & ~LOCK_MASK) === expectedMod && logicalShiftedSymbol.codepoint === normalizeKittyFunctionalCodepoint(expectedCodepoint)) {
|
|
41272
|
+
return true;
|
|
41273
|
+
}
|
|
41274
|
+
if (actualMod !== expectedMod)
|
|
41275
|
+
return false;
|
|
41262
41276
|
if (parsed.baseLayoutKey !== void 0 && parsed.baseLayoutKey === expectedCodepoint) {
|
|
41263
41277
|
const cp = normalizedCodepoint;
|
|
41264
41278
|
const isLatinLetter = cp >= 97 && cp <= 122;
|
|
@@ -41307,12 +41321,14 @@ function isDigitKey(key) {
|
|
|
41307
41321
|
return key >= "0" && key <= "9";
|
|
41308
41322
|
}
|
|
41309
41323
|
function matchesPrintableModifyOtherKeys(data, expectedKeycode, expectedModifier) {
|
|
41310
|
-
if (expectedModifier === 0)
|
|
41311
|
-
return false;
|
|
41312
41324
|
const parsed = parseModifyOtherKeysSequence(data);
|
|
41313
|
-
if (!parsed
|
|
41325
|
+
if (!parsed)
|
|
41314
41326
|
return false;
|
|
41315
|
-
|
|
41327
|
+
const physicalMatch = parsed.modifier === expectedModifier && normalizeShiftedLetterIdentityCodepoint(parsed.codepoint, parsed.modifier) === normalizeShiftedLetterIdentityCodepoint(expectedKeycode, expectedModifier);
|
|
41328
|
+
if (physicalMatch)
|
|
41329
|
+
return true;
|
|
41330
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(parsed.codepoint, parsed.modifier, SHIFTED_SYMBOL_KEYS);
|
|
41331
|
+
return logicalShiftedSymbol?.modifier === expectedModifier && logicalShiftedSymbol.codepoint === expectedKeycode;
|
|
41316
41332
|
}
|
|
41317
41333
|
function formatKeyNameWithModifiers(keyName, modifier) {
|
|
41318
41334
|
const mods = [];
|
|
@@ -41331,16 +41347,25 @@ function formatKeyNameWithModifiers(keyName, modifier) {
|
|
|
41331
41347
|
return mods.length > 0 ? `${mods.join("+")}+${keyName}` : keyName;
|
|
41332
41348
|
}
|
|
41333
41349
|
function parseKeyId(keyId) {
|
|
41334
|
-
|
|
41335
|
-
const
|
|
41336
|
-
|
|
41350
|
+
let key = keyId.toLowerCase();
|
|
41351
|
+
const modifiers = /* @__PURE__ */ new Set();
|
|
41352
|
+
while (true) {
|
|
41353
|
+
const modifier = MODIFIER_NAMES.find((name) => key.startsWith(`${name}+`));
|
|
41354
|
+
if (!modifier)
|
|
41355
|
+
break;
|
|
41356
|
+
if (modifiers.has(modifier))
|
|
41357
|
+
return null;
|
|
41358
|
+
modifiers.add(modifier);
|
|
41359
|
+
key = key.slice(modifier.length + 1);
|
|
41360
|
+
}
|
|
41361
|
+
if (!key || key.includes("+") && key !== "+")
|
|
41337
41362
|
return null;
|
|
41338
41363
|
return {
|
|
41339
41364
|
key,
|
|
41340
|
-
ctrl:
|
|
41341
|
-
shift:
|
|
41342
|
-
alt:
|
|
41343
|
-
super:
|
|
41365
|
+
ctrl: modifiers.has("ctrl"),
|
|
41366
|
+
shift: modifiers.has("shift"),
|
|
41367
|
+
alt: modifiers.has("alt"),
|
|
41368
|
+
super: modifiers.has("super")
|
|
41344
41369
|
};
|
|
41345
41370
|
}
|
|
41346
41371
|
function matchesKey(data, keyId) {
|
|
@@ -41582,7 +41607,7 @@ function matchesKey(data, keyId) {
|
|
|
41582
41607
|
if (modifier !== 0) {
|
|
41583
41608
|
return matchesKittySequence(data, codepoint, modifier) || matchesPrintableModifyOtherKeys(data, codepoint, modifier);
|
|
41584
41609
|
}
|
|
41585
|
-
return data === key || matchesKittySequence(data, codepoint, 0);
|
|
41610
|
+
return data === key || matchesKittySequence(data, codepoint, 0) || matchesPrintableModifyOtherKeys(data, codepoint, 0);
|
|
41586
41611
|
}
|
|
41587
41612
|
return false;
|
|
41588
41613
|
}
|
|
@@ -41637,11 +41662,13 @@ function formatParsedKey(codepoint, modifier, baseLayoutKey) {
|
|
|
41637
41662
|
function parseKey(data) {
|
|
41638
41663
|
const kitty = parseKittySequence(data);
|
|
41639
41664
|
if (kitty) {
|
|
41640
|
-
|
|
41665
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(kitty.shiftedKey, kitty.modifier, SYMBOL_KEYS);
|
|
41666
|
+
return formatParsedKey(logicalShiftedSymbol?.codepoint ?? kitty.codepoint, logicalShiftedSymbol?.modifier ?? kitty.modifier, kitty.baseLayoutKey);
|
|
41641
41667
|
}
|
|
41642
41668
|
const modifyOtherKeys = parseModifyOtherKeysSequence(data);
|
|
41643
41669
|
if (modifyOtherKeys) {
|
|
41644
|
-
|
|
41670
|
+
const logicalShiftedSymbol = getLogicalShiftedSymbolCandidate(modifyOtherKeys.codepoint, modifyOtherKeys.modifier, SHIFTED_SYMBOL_KEYS);
|
|
41671
|
+
return formatParsedKey(logicalShiftedSymbol?.codepoint ?? modifyOtherKeys.codepoint, logicalShiftedSymbol?.modifier ?? modifyOtherKeys.modifier);
|
|
41645
41672
|
}
|
|
41646
41673
|
if (_kittyProtocolActive) {
|
|
41647
41674
|
if (data === "\x1B\r" || data === "\n")
|
|
@@ -41854,7 +41881,7 @@ function detectCapabilitiesFromEnvironment(tmuxForwardsHyperlink) {
|
|
|
41854
41881
|
return { images: null, trueColor: hasTrueColorHint, hyperlinks: false };
|
|
41855
41882
|
}
|
|
41856
41883
|
if (termProgram === "herdr") {
|
|
41857
|
-
return { images:
|
|
41884
|
+
return { images: "kitty", trueColor: hasTrueColorHint, hyperlinks: true };
|
|
41858
41885
|
}
|
|
41859
41886
|
if (process.env.KITTY_WINDOW_ID || termProgram === "kitty") {
|
|
41860
41887
|
return { images: "kitty", trueColor: true, hyperlinks: true };
|
|
@@ -42084,6 +42111,12 @@ function isFocusable(component) {
|
|
|
42084
42111
|
return component !== null && "focused" in component;
|
|
42085
42112
|
}
|
|
42086
42113
|
var CURSOR_MARKER = "\x1B_pi:c\x07";
|
|
42114
|
+
var FAKE_CURSOR_START = "\x1B_pi:fc\x07";
|
|
42115
|
+
var FAKE_CURSOR_END = "\x1B_pi:/fc\x07";
|
|
42116
|
+
var FOCUSED_FAKE_CURSOR = /(\x1b_pi:c\x07)\x1b_pi:fc\x07(.*?)(?:\x1b_pi:\/fc\x07|$)/s;
|
|
42117
|
+
function renderFakeCursor(text) {
|
|
42118
|
+
return `${FAKE_CURSOR_START}${text}${FAKE_CURSOR_END}`;
|
|
42119
|
+
}
|
|
42087
42120
|
function parseSizeValue(value, referenceSize) {
|
|
42088
42121
|
if (value === void 0)
|
|
42089
42122
|
return void 0;
|
|
@@ -42886,7 +42919,7 @@ var TuiBase = class _TuiBase extends Container {
|
|
|
42886
42919
|
for (const entry of visibleEntries) {
|
|
42887
42920
|
const { component, options } = entry;
|
|
42888
42921
|
const { width, maxHeight } = this.resolveOverlayLayout(options, 0, termWidth, termHeight);
|
|
42889
|
-
let overlayLines = component.render(width);
|
|
42922
|
+
let overlayLines = this.resolveFakeCursors(component.render(width));
|
|
42890
42923
|
if (maxHeight !== void 0 && overlayLines.length > maxHeight) {
|
|
42891
42924
|
overlayLines = overlayLines.slice(0, maxHeight);
|
|
42892
42925
|
}
|
|
@@ -42953,6 +42986,19 @@ var TuiBase = class _TuiBase extends Container {
|
|
|
42953
42986
|
}
|
|
42954
42987
|
return null;
|
|
42955
42988
|
}
|
|
42989
|
+
/**
|
|
42990
|
+
* Resolve fake cursor markers to reverse video. When the hardware cursor is shown, a fake cursor
|
|
42991
|
+
* directly after CURSOR_MARKER is dropped because the terminal cursor is drawn there. Fake cursors
|
|
42992
|
+
* of components without focus have no CURSOR_MARKER and stay visible.
|
|
42993
|
+
*/
|
|
42994
|
+
resolveFakeCursors(lines) {
|
|
42995
|
+
return lines.map((line) => {
|
|
42996
|
+
if (!line.includes(FAKE_CURSOR_START))
|
|
42997
|
+
return line;
|
|
42998
|
+
const resolved = this.showHardwareCursor ? line.replace(FOCUSED_FAKE_CURSOR, "$1$2") : line;
|
|
42999
|
+
return resolved.replaceAll(FAKE_CURSOR_START, "\x1B[7m").replaceAll(FAKE_CURSOR_END, "\x1B[27m");
|
|
43000
|
+
});
|
|
43001
|
+
}
|
|
42956
43002
|
/**
|
|
42957
43003
|
* Query the terminal's theme colors: the default foreground (OSC 10), the default background
|
|
42958
43004
|
* (OSC 11), and ANSI colors 0-15 (OSC 4), followed by a DA1 request that marks the end of the
|
|
@@ -44002,7 +44048,7 @@ var Input = class {
|
|
|
44002
44048
|
const atCursor2 = graphemes2[0]?.segment ?? " ";
|
|
44003
44049
|
const afterCursor2 = placeholder.slice(atCursor2.length);
|
|
44004
44050
|
const marker2 = this.focused ? CURSOR_MARKER : "";
|
|
44005
|
-
const cursorChar2 =
|
|
44051
|
+
const cursorChar2 = renderFakeCursor(this.placeholderStyle(atCursor2));
|
|
44006
44052
|
const textWithCursor2 = marker2 + cursorChar2 + this.placeholderStyle(afterCursor2);
|
|
44007
44053
|
const padding2 = " ".repeat(Math.max(0, availableWidth - visibleWidth(textWithCursor2)));
|
|
44008
44054
|
return [this.prompt + textWithCursor2 + padding2];
|
|
@@ -44041,7 +44087,7 @@ var Input = class {
|
|
|
44041
44087
|
const atCursor = cursorGrapheme?.segment ?? " ";
|
|
44042
44088
|
const afterCursor = visibleText.slice(cursorDisplay + atCursor.length);
|
|
44043
44089
|
const marker = this.focused ? CURSOR_MARKER : "";
|
|
44044
|
-
const cursorChar =
|
|
44090
|
+
const cursorChar = renderFakeCursor(atCursor);
|
|
44045
44091
|
const textWithCursor = beforeCursor + marker + cursorChar + afterCursor;
|
|
44046
44092
|
const visualLength = visibleWidth(textWithCursor);
|
|
44047
44093
|
const padding = " ".repeat(Math.max(0, availableWidth - visualLength));
|
|
@@ -45306,7 +45352,7 @@ var TuiAltScreen = class extends TuiBase {
|
|
|
45306
45352
|
this.terminal.write(`${BEGIN_SYNCHRONIZED_OUTPUT}${EXIT_ALT_SCREEN}\x1B[?25h${END_SYNCHRONIZED_OUTPUT}`);
|
|
45307
45353
|
} else {
|
|
45308
45354
|
const width = Math.max(1, this.terminal.columns);
|
|
45309
|
-
const documentLines = this.render(width).map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
45355
|
+
const documentLines = this.resolveFakeCursors(this.render(width)).map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
45310
45356
|
this.lastDocument = this.applyLineResets(documentLines.map((line) => line.replaceAll(CURSOR_MARKER, ""))).map((line) => isImageLine(line) || visibleWidth(line) <= width ? line : sliceByColumn(line, 0, width, true));
|
|
45311
45357
|
let buffer = `${BEGIN_SYNCHRONIZED_OUTPUT}${EXIT_ALT_SCREEN}${DISABLE_AUTOWRAP}`;
|
|
45312
45358
|
for (let row = 0; row < this.lastDocument.length; row++) {
|
|
@@ -45591,8 +45637,6 @@ var TuiAltScreen = class extends TuiBase {
|
|
|
45591
45637
|
this.requestRender();
|
|
45592
45638
|
return { consume: true };
|
|
45593
45639
|
}
|
|
45594
|
-
if (this.shouldDeferViewportInputToOverlay())
|
|
45595
|
-
return void 0;
|
|
45596
45640
|
this.routeWheel(wheelEvent, wheelDelta);
|
|
45597
45641
|
return { consume: true };
|
|
45598
45642
|
}
|
|
@@ -46463,7 +46507,7 @@ var TuiAltScreen = class extends TuiBase {
|
|
|
46463
46507
|
if (this.refreshSearch(nextLayout)) {
|
|
46464
46508
|
nextLayout = renderLayoutFrame(root, width, height, () => this.requestRender());
|
|
46465
46509
|
}
|
|
46466
|
-
let screen = nextLayout.lines.map((line) => line.replace(OSC133_ZONE_PREFIX2, ""));
|
|
46510
|
+
let screen = this.resolveFakeCursors(nextLayout.lines.map((line) => line.replace(OSC133_ZONE_PREFIX2, "")));
|
|
46467
46511
|
screen = this.applySearchHighlights(screen, nextLayout);
|
|
46468
46512
|
screen = this.compositeScrollToEndIndicator(screen, nextLayout, width);
|
|
46469
46513
|
screen = this.compositeOverlays(screen, width, height);
|
|
@@ -25462,7 +25462,7 @@ function sessionTokenFixHint(policy) {
|
|
|
25462
25462
|
}
|
|
25463
25463
|
|
|
25464
25464
|
// plugins/kxm/src/mcp-server.ts
|
|
25465
|
-
var VERSION = "0.7.
|
|
25465
|
+
var VERSION = "0.7.206";
|
|
25466
25466
|
var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
|
|
25467
25467
|
var inbox = /* @__PURE__ */ new Map();
|
|
25468
25468
|
var notifiedInbox = /* @__PURE__ */ new Set();
|
package/plugins/kxm/package.json
CHANGED
|
@@ -11,7 +11,7 @@ import { deliverInboxNotification } from "./inbox.ts";
|
|
|
11
11
|
import type { HubEvent, MessageRecord } from "./protocol.ts";
|
|
12
12
|
import { sessionTokenFixHint } from "./session-token-hint.ts";
|
|
13
13
|
|
|
14
|
-
const VERSION = "0.7.
|
|
14
|
+
const VERSION = "0.7.206";
|
|
15
15
|
const CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
|
|
16
16
|
const inbox = new Map<string, MessageRecord>();
|
|
17
17
|
const notifiedInbox = new Set<string>();
|