sisyphi 1.1.18 → 1.1.19
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/README.md +195 -75
- package/dist/chunk-36VJ7ZBD.js +1898 -0
- package/dist/chunk-36VJ7ZBD.js.map +1 -0
- package/dist/{chunk-C2XKXERJ.js → chunk-M6Z3KHOH.js} +159 -46
- package/dist/chunk-M6Z3KHOH.js.map +1 -0
- package/dist/chunk-O4ZHSQ5R.js +544 -0
- package/dist/chunk-O4ZHSQ5R.js.map +1 -0
- package/dist/chunk-P2HHTIPM.js +478 -0
- package/dist/chunk-P2HHTIPM.js.map +1 -0
- package/dist/{chunk-TMBAVPHH.js → chunk-PNDCVKBN.js} +73 -1
- package/dist/chunk-PNDCVKBN.js.map +1 -0
- package/dist/chunk-SVGIQ2G4.js +1076 -0
- package/dist/chunk-SVGIQ2G4.js.map +1 -0
- package/dist/cli.js +4405 -892
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +4340 -1990
- package/dist/daemon.js.map +1 -1
- package/dist/{paths-XRDEEJ5R.js → paths-JXFLR5BN.js} +38 -2
- package/dist/single-ask-6G4BIVY2.js +132 -0
- package/dist/single-ask-6G4BIVY2.js.map +1 -0
- package/dist/templates/CLAUDE.md +1 -56
- package/dist/templates/agent-plugin/agents/CLAUDE.md +2 -65
- package/dist/templates/agent-plugin/agents/debug.md +43 -6
- package/dist/templates/agent-plugin/agents/debug.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/explore.md +28 -1
- package/dist/templates/agent-plugin/agents/explore.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/implementor.md +94 -0
- package/dist/templates/agent-plugin/agents/implementor.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/operator.md +43 -1
- package/dist/templates/agent-plugin/agents/operator.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/plan/sub-planner.md +75 -0
- package/dist/templates/agent-plugin/agents/plan.md +176 -86
- package/dist/templates/agent-plugin/agents/plan.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/problem/adversarial.md +26 -0
- package/dist/templates/agent-plugin/agents/problem/contrarian.md +26 -0
- package/dist/templates/agent-plugin/agents/problem/first-principles.md +26 -0
- package/dist/templates/agent-plugin/agents/problem/precedent.md +25 -0
- package/dist/templates/agent-plugin/agents/problem/simplifier.md +26 -0
- package/dist/templates/agent-plugin/agents/problem/systems-thinker.md +26 -0
- package/dist/templates/agent-plugin/agents/problem/time-traveler.md +26 -0
- package/dist/templates/agent-plugin/agents/problem/user-empathy.md +26 -0
- package/dist/templates/agent-plugin/agents/problem.md +334 -79
- package/dist/templates/agent-plugin/agents/problem.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/research-lead/CLAUDE.md +26 -0
- package/dist/templates/agent-plugin/agents/research-lead/critic.md +61 -0
- package/dist/templates/agent-plugin/agents/research-lead/researcher.md +60 -0
- package/dist/templates/agent-plugin/agents/research-lead.md +184 -0
- package/dist/templates/agent-plugin/agents/research-lead.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/review/CLAUDE.md +3 -29
- package/dist/templates/agent-plugin/agents/review/compliance.md +14 -3
- package/dist/templates/agent-plugin/agents/review/efficiency.md +15 -4
- package/dist/templates/agent-plugin/agents/review/quality.md +20 -6
- package/dist/templates/agent-plugin/agents/review/reuse.md +17 -5
- package/dist/templates/agent-plugin/agents/review/security.md +10 -3
- package/dist/templates/agent-plugin/agents/review/tests.md +58 -0
- package/dist/templates/agent-plugin/agents/review-plan/CLAUDE.md +28 -0
- package/dist/templates/agent-plugin/agents/review-plan/code-smells.md +4 -2
- package/dist/templates/agent-plugin/agents/review-plan/pattern-consistency.md +4 -2
- package/dist/templates/agent-plugin/agents/review-plan/requirements-coverage.md +3 -1
- package/dist/templates/agent-plugin/agents/review-plan/security.md +5 -2
- package/dist/templates/agent-plugin/agents/review-plan.md +52 -5
- package/dist/templates/agent-plugin/agents/review-plan.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/review.md +89 -16
- package/dist/templates/agent-plugin/agents/review.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/spec/engineer.md +175 -0
- package/dist/templates/agent-plugin/agents/spec/requirements-writer.md +149 -0
- package/dist/templates/agent-plugin/agents/spec.md +444 -0
- package/dist/templates/agent-plugin/agents/spec.settings.json +57 -0
- package/dist/templates/agent-plugin/agents/test-spec.md +58 -2
- package/dist/templates/agent-plugin/agents/test-spec.settings.json +57 -0
- package/dist/templates/agent-plugin/hooks/CLAUDE.md +9 -57
- package/dist/templates/agent-plugin/hooks/ask-background-guard.sh +57 -0
- package/dist/templates/agent-plugin/hooks/intercept-send-message.sh +1 -1
- package/dist/templates/agent-plugin/hooks/plan-user-prompt.sh +8 -7
- package/dist/templates/agent-plugin/hooks/plan-validate.sh +97 -0
- package/dist/templates/agent-plugin/hooks/plan-write-path.sh +55 -0
- package/dist/templates/agent-plugin/hooks/problem-user-prompt.sh +26 -0
- package/dist/templates/agent-plugin/hooks/register-bg-task.sh +37 -0
- package/dist/templates/agent-plugin/hooks/require-submit.sh +51 -42
- package/dist/templates/agent-plugin/hooks/review-user-prompt.sh +6 -2
- package/dist/templates/agent-plugin/hooks/spec-user-prompt.sh +43 -0
- package/dist/templates/agent-plugin/skills/humanloop/SKILL.md +147 -0
- package/dist/templates/agent-plugin/skills/perspective-fanout/SKILL.md +115 -0
- package/dist/templates/agent-plugin/skills/problem-document/SKILL.md +105 -0
- package/dist/templates/agent-plugin/skills/problem-plateau-breakers/SKILL.md +83 -0
- package/dist/templates/agent-suffix.md +7 -4
- package/dist/templates/baleia.lua +42 -0
- package/dist/templates/companion-plugin/hooks/user-prompt-context.sh +1 -1
- package/dist/templates/dashboard-claude.md +7 -3
- package/dist/templates/orchestrator-base.md +89 -52
- package/dist/templates/orchestrator-completion.md +47 -24
- package/dist/templates/orchestrator-discovery.md +183 -0
- package/dist/templates/orchestrator-impl.md +47 -18
- package/dist/templates/orchestrator-planning.md +109 -20
- package/dist/templates/orchestrator-plugin/commands/sisyphus/scratch.md +19 -0
- package/dist/templates/orchestrator-plugin/commands/sisyphus/spec.md +11 -0
- package/dist/templates/orchestrator-plugin/commands/sisyphus/strategize.md +5 -5
- package/dist/templates/orchestrator-plugin/hooks/hooks.json +0 -10
- package/dist/templates/orchestrator-plugin/skills/humanloop/SKILL.md +149 -0
- package/dist/templates/orchestrator-plugin/skills/orchestration/CLAUDE.md +1 -0
- package/dist/templates/orchestrator-plugin/skills/orchestration/SKILL.md +2 -1
- package/dist/templates/orchestrator-plugin/skills/orchestration/strategy.md +160 -0
- package/dist/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +26 -28
- package/dist/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +133 -25
- package/dist/templates/orchestrator-settings.json +55 -0
- package/dist/templates/orchestrator-validation.md +17 -14
- package/dist/templates/sisyphus-init.lua +30 -0
- package/dist/templates/sisyphus-tmux-plugin/hooks/hooks.json +54 -0
- package/dist/templates/sisyphus-tmux-plugin/hooks/tmux-state.sh +19 -0
- package/dist/templates/termrender-haiku-system.md +82 -0
- package/dist/templates/whip-animation.sh +345 -0
- package/dist/tui.js +3242 -2189
- package/dist/tui.js.map +1 -1
- package/native/SisyphusNotify/main.swift +15 -5
- package/package.json +8 -6
- package/templates/CLAUDE.md +1 -56
- package/templates/agent-plugin/agents/CLAUDE.md +2 -65
- package/templates/agent-plugin/agents/debug.md +43 -6
- package/templates/agent-plugin/agents/debug.settings.json +57 -0
- package/templates/agent-plugin/agents/explore.md +28 -1
- package/templates/agent-plugin/agents/explore.settings.json +57 -0
- package/templates/agent-plugin/agents/implementor.md +94 -0
- package/templates/agent-plugin/agents/implementor.settings.json +57 -0
- package/templates/agent-plugin/agents/operator.md +43 -1
- package/templates/agent-plugin/agents/operator.settings.json +57 -0
- package/templates/agent-plugin/agents/plan/sub-planner.md +75 -0
- package/templates/agent-plugin/agents/plan.md +176 -86
- package/templates/agent-plugin/agents/plan.settings.json +57 -0
- package/templates/agent-plugin/agents/problem/adversarial.md +26 -0
- package/templates/agent-plugin/agents/problem/contrarian.md +26 -0
- package/templates/agent-plugin/agents/problem/first-principles.md +26 -0
- package/templates/agent-plugin/agents/problem/precedent.md +25 -0
- package/templates/agent-plugin/agents/problem/simplifier.md +26 -0
- package/templates/agent-plugin/agents/problem/systems-thinker.md +26 -0
- package/templates/agent-plugin/agents/problem/time-traveler.md +26 -0
- package/templates/agent-plugin/agents/problem/user-empathy.md +26 -0
- package/templates/agent-plugin/agents/problem.md +334 -79
- package/templates/agent-plugin/agents/problem.settings.json +57 -0
- package/templates/agent-plugin/agents/research-lead/CLAUDE.md +26 -0
- package/templates/agent-plugin/agents/research-lead/critic.md +61 -0
- package/templates/agent-plugin/agents/research-lead/researcher.md +60 -0
- package/templates/agent-plugin/agents/research-lead.md +184 -0
- package/templates/agent-plugin/agents/research-lead.settings.json +57 -0
- package/templates/agent-plugin/agents/review/CLAUDE.md +3 -29
- package/templates/agent-plugin/agents/review/compliance.md +14 -3
- package/templates/agent-plugin/agents/review/efficiency.md +15 -4
- package/templates/agent-plugin/agents/review/quality.md +20 -6
- package/templates/agent-plugin/agents/review/reuse.md +17 -5
- package/templates/agent-plugin/agents/review/security.md +10 -3
- package/templates/agent-plugin/agents/review/tests.md +58 -0
- package/templates/agent-plugin/agents/review-plan/CLAUDE.md +28 -0
- package/templates/agent-plugin/agents/review-plan/code-smells.md +4 -2
- package/templates/agent-plugin/agents/review-plan/pattern-consistency.md +4 -2
- package/templates/agent-plugin/agents/review-plan/requirements-coverage.md +3 -1
- package/templates/agent-plugin/agents/review-plan/security.md +5 -2
- package/templates/agent-plugin/agents/review-plan.md +52 -5
- package/templates/agent-plugin/agents/review-plan.settings.json +57 -0
- package/templates/agent-plugin/agents/review.md +89 -16
- package/templates/agent-plugin/agents/review.settings.json +57 -0
- package/templates/agent-plugin/agents/spec/engineer.md +175 -0
- package/templates/agent-plugin/agents/spec/requirements-writer.md +149 -0
- package/templates/agent-plugin/agents/spec.md +444 -0
- package/templates/agent-plugin/agents/spec.settings.json +57 -0
- package/templates/agent-plugin/agents/test-spec.md +58 -2
- package/templates/agent-plugin/agents/test-spec.settings.json +57 -0
- package/templates/agent-plugin/hooks/CLAUDE.md +9 -57
- package/templates/agent-plugin/hooks/ask-background-guard.sh +57 -0
- package/templates/agent-plugin/hooks/intercept-send-message.sh +1 -1
- package/templates/agent-plugin/hooks/plan-user-prompt.sh +8 -7
- package/templates/agent-plugin/hooks/plan-validate.sh +97 -0
- package/templates/agent-plugin/hooks/plan-write-path.sh +55 -0
- package/templates/agent-plugin/hooks/problem-user-prompt.sh +26 -0
- package/templates/agent-plugin/hooks/register-bg-task.sh +37 -0
- package/templates/agent-plugin/hooks/require-submit.sh +51 -42
- package/templates/agent-plugin/hooks/review-user-prompt.sh +6 -2
- package/templates/agent-plugin/hooks/spec-user-prompt.sh +43 -0
- package/templates/agent-plugin/skills/humanloop/SKILL.md +147 -0
- package/templates/agent-plugin/skills/perspective-fanout/SKILL.md +115 -0
- package/templates/agent-plugin/skills/problem-document/SKILL.md +105 -0
- package/templates/agent-plugin/skills/problem-plateau-breakers/SKILL.md +83 -0
- package/templates/agent-suffix.md +7 -4
- package/templates/baleia.lua +42 -0
- package/templates/companion-plugin/hooks/user-prompt-context.sh +1 -1
- package/templates/dashboard-claude.md +7 -3
- package/templates/orchestrator-base.md +89 -52
- package/templates/orchestrator-completion.md +47 -24
- package/templates/orchestrator-discovery.md +183 -0
- package/templates/orchestrator-impl.md +47 -18
- package/templates/orchestrator-planning.md +109 -20
- package/templates/orchestrator-plugin/commands/sisyphus/scratch.md +19 -0
- package/templates/orchestrator-plugin/commands/sisyphus/spec.md +11 -0
- package/templates/orchestrator-plugin/commands/sisyphus/strategize.md +5 -5
- package/templates/orchestrator-plugin/hooks/hooks.json +0 -10
- package/templates/orchestrator-plugin/skills/humanloop/SKILL.md +149 -0
- package/templates/orchestrator-plugin/skills/orchestration/CLAUDE.md +1 -0
- package/templates/orchestrator-plugin/skills/orchestration/SKILL.md +2 -1
- package/templates/orchestrator-plugin/skills/orchestration/strategy.md +160 -0
- package/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +26 -28
- package/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +133 -25
- package/templates/orchestrator-settings.json +55 -0
- package/templates/orchestrator-validation.md +17 -14
- package/templates/sisyphus-init.lua +30 -0
- package/templates/sisyphus-tmux-plugin/hooks/hooks.json +54 -0
- package/templates/sisyphus-tmux-plugin/hooks/tmux-state.sh +19 -0
- package/templates/termrender-haiku-system.md +82 -0
- package/templates/whip-animation.sh +345 -0
- package/dist/chunk-22ZGZTGY.js +0 -67
- package/dist/chunk-22ZGZTGY.js.map +0 -1
- package/dist/chunk-6PJVJEYQ.js +0 -46
- package/dist/chunk-6PJVJEYQ.js.map +0 -1
- package/dist/chunk-C2XKXERJ.js.map +0 -1
- package/dist/chunk-TMBAVPHH.js.map +0 -1
- package/dist/chunk-V36NXMHP.js +0 -299
- package/dist/chunk-V36NXMHP.js.map +0 -1
- package/dist/templates/agent-plugin/agents/design.md +0 -134
- package/dist/templates/agent-plugin/agents/requirements.md +0 -138
- package/dist/templates/begin.md +0 -22
- package/dist/templates/nvim-tutorial.txt +0 -68
- package/dist/templates/orchestrator-plugin/commands/sisyphus/design.md +0 -13
- package/dist/templates/orchestrator-plugin/commands/sisyphus/requirements.md +0 -13
- package/dist/templates/orchestrator-plugin/hooks/idle-notify.sh +0 -71
- package/dist/templates/orchestrator-strategy.md +0 -238
- package/templates/agent-plugin/agents/design.md +0 -134
- package/templates/agent-plugin/agents/requirements.md +0 -138
- package/templates/begin.md +0 -22
- package/templates/nvim-tutorial.txt +0 -68
- package/templates/orchestrator-plugin/commands/sisyphus/design.md +0 -13
- package/templates/orchestrator-plugin/commands/sisyphus/requirements.md +0 -13
- package/templates/orchestrator-plugin/hooks/idle-notify.sh +0 -71
- package/templates/orchestrator-strategy.md +0 -238
- /package/dist/{paths-XRDEEJ5R.js.map → paths-JXFLR5BN.js.map} +0 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/tui/terminal.ts
|
|
4
|
+
function emptyKey() {
|
|
5
|
+
return {
|
|
6
|
+
upArrow: false,
|
|
7
|
+
downArrow: false,
|
|
8
|
+
leftArrow: false,
|
|
9
|
+
rightArrow: false,
|
|
10
|
+
pageUp: false,
|
|
11
|
+
pageDown: false,
|
|
12
|
+
return: false,
|
|
13
|
+
escape: false,
|
|
14
|
+
ctrl: false,
|
|
15
|
+
shift: false,
|
|
16
|
+
tab: false,
|
|
17
|
+
backspace: false,
|
|
18
|
+
delete: false,
|
|
19
|
+
meta: false
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function setupTerminal() {
|
|
23
|
+
let cleaned = false;
|
|
24
|
+
const cleanup = () => {
|
|
25
|
+
if (cleaned) return;
|
|
26
|
+
cleaned = true;
|
|
27
|
+
process.stdout.write("\x1B[?25h\x1B[?1049l");
|
|
28
|
+
process.stdin.setRawMode(false);
|
|
29
|
+
process.stdin.pause();
|
|
30
|
+
};
|
|
31
|
+
process.stdin.setRawMode(true);
|
|
32
|
+
process.stdin.resume();
|
|
33
|
+
process.stdin.setEncoding("utf-8");
|
|
34
|
+
process.stdout.write("\x1B[?1049h\x1B[?25l\x1B[2J");
|
|
35
|
+
process.on("SIGINT", () => {
|
|
36
|
+
cleanup();
|
|
37
|
+
process.exit(0);
|
|
38
|
+
});
|
|
39
|
+
process.on("SIGTERM", () => {
|
|
40
|
+
cleanup();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
});
|
|
43
|
+
process.on("exit", cleanup);
|
|
44
|
+
process.on("uncaughtException", (err) => {
|
|
45
|
+
cleanup();
|
|
46
|
+
console.error(err);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
49
|
+
return cleanup;
|
|
50
|
+
}
|
|
51
|
+
function writeToStdout(data) {
|
|
52
|
+
process.stdout.write(data);
|
|
53
|
+
}
|
|
54
|
+
function parseBuffer(buf) {
|
|
55
|
+
const events = [];
|
|
56
|
+
let i = 0;
|
|
57
|
+
while (i < buf.length) {
|
|
58
|
+
const ch = buf[i];
|
|
59
|
+
if (ch === "\x1B") {
|
|
60
|
+
const rest = buf.slice(i + 1);
|
|
61
|
+
if (rest.startsWith("[")) {
|
|
62
|
+
const after = rest.slice(1);
|
|
63
|
+
const shiftArrow = after.match(/^1;2([ABCD])/);
|
|
64
|
+
if (shiftArrow) {
|
|
65
|
+
const key2 = emptyKey();
|
|
66
|
+
key2.shift = true;
|
|
67
|
+
const dir = shiftArrow[1];
|
|
68
|
+
if (dir === "A") key2.upArrow = true;
|
|
69
|
+
else if (dir === "B") key2.downArrow = true;
|
|
70
|
+
else if (dir === "C") key2.rightArrow = true;
|
|
71
|
+
else if (dir === "D") key2.leftArrow = true;
|
|
72
|
+
const seq = `\x1B[1;2${dir}`;
|
|
73
|
+
events.push([seq, key2]);
|
|
74
|
+
i += seq.length;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (after.length >= 1 && after[0] === "Z") {
|
|
78
|
+
const key2 = emptyKey();
|
|
79
|
+
key2.tab = true;
|
|
80
|
+
key2.shift = true;
|
|
81
|
+
const seq = `\x1B[Z`;
|
|
82
|
+
events.push([seq, key2]);
|
|
83
|
+
i += seq.length;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (after.length >= 1 && "ABCD".includes(after[0])) {
|
|
87
|
+
const key2 = emptyKey();
|
|
88
|
+
const dir = after[0];
|
|
89
|
+
if (dir === "A") key2.upArrow = true;
|
|
90
|
+
else if (dir === "B") key2.downArrow = true;
|
|
91
|
+
else if (dir === "C") key2.rightArrow = true;
|
|
92
|
+
else if (dir === "D") key2.leftArrow = true;
|
|
93
|
+
const seq = `\x1B[${dir}`;
|
|
94
|
+
events.push([seq, key2]);
|
|
95
|
+
i += seq.length;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const tildeMatch = after.match(/^(\d+)~/);
|
|
99
|
+
if (tildeMatch) {
|
|
100
|
+
const num = tildeMatch[1];
|
|
101
|
+
const key2 = emptyKey();
|
|
102
|
+
if (num === "5") key2.pageUp = true;
|
|
103
|
+
else if (num === "6") key2.pageDown = true;
|
|
104
|
+
else if (num === "3") key2.delete = true;
|
|
105
|
+
const seq = `\x1B[${num}~`;
|
|
106
|
+
events.push([seq, key2]);
|
|
107
|
+
i += seq.length;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
return { events, remaining: buf.slice(i) };
|
|
111
|
+
}
|
|
112
|
+
if (rest.length === 0) {
|
|
113
|
+
return { events, remaining: buf.slice(i) };
|
|
114
|
+
}
|
|
115
|
+
const metaCh = rest[0];
|
|
116
|
+
const key = emptyKey();
|
|
117
|
+
key.meta = true;
|
|
118
|
+
events.push([metaCh, key]);
|
|
119
|
+
i += 2;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (ch === "\r") {
|
|
123
|
+
const key = emptyKey();
|
|
124
|
+
key.return = true;
|
|
125
|
+
events.push([ch, key]);
|
|
126
|
+
i++;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (ch === " ") {
|
|
130
|
+
const key = emptyKey();
|
|
131
|
+
key.tab = true;
|
|
132
|
+
events.push([ch, key]);
|
|
133
|
+
i++;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (ch === "\x7F" || ch === "\b") {
|
|
137
|
+
const key = emptyKey();
|
|
138
|
+
key.backspace = true;
|
|
139
|
+
events.push([ch, key]);
|
|
140
|
+
i++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const code = ch.charCodeAt(0);
|
|
144
|
+
if (code >= 1 && code <= 26) {
|
|
145
|
+
const key = emptyKey();
|
|
146
|
+
key.ctrl = true;
|
|
147
|
+
const letter = String.fromCharCode(code + 96);
|
|
148
|
+
events.push([letter, key]);
|
|
149
|
+
i++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
events.push([ch, emptyKey()]);
|
|
153
|
+
i++;
|
|
154
|
+
}
|
|
155
|
+
return { events, remaining: "" };
|
|
156
|
+
}
|
|
157
|
+
var rawBypassHandler = null;
|
|
158
|
+
function startKeypressListener(handler) {
|
|
159
|
+
let buffer = "";
|
|
160
|
+
let escTimer = null;
|
|
161
|
+
const onData = (data) => {
|
|
162
|
+
if (rawBypassHandler) {
|
|
163
|
+
const handled = rawBypassHandler(data);
|
|
164
|
+
if (handled) return;
|
|
165
|
+
}
|
|
166
|
+
if (escTimer !== null) {
|
|
167
|
+
clearTimeout(escTimer);
|
|
168
|
+
escTimer = null;
|
|
169
|
+
}
|
|
170
|
+
buffer += data;
|
|
171
|
+
const { events, remaining } = parseBuffer(buffer);
|
|
172
|
+
buffer = remaining;
|
|
173
|
+
for (const [input, key] of events) {
|
|
174
|
+
handler(input, key);
|
|
175
|
+
}
|
|
176
|
+
if (buffer === "\x1B") {
|
|
177
|
+
escTimer = setTimeout(() => {
|
|
178
|
+
escTimer = null;
|
|
179
|
+
buffer = "";
|
|
180
|
+
const key = emptyKey();
|
|
181
|
+
key.escape = true;
|
|
182
|
+
handler("\x1B", key);
|
|
183
|
+
}, 50);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
process.stdin.on("data", onData);
|
|
187
|
+
return () => {
|
|
188
|
+
process.stdin.off("data", onData);
|
|
189
|
+
if (escTimer !== null) {
|
|
190
|
+
clearTimeout(escTimer);
|
|
191
|
+
escTimer = null;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function onResize(callback) {
|
|
196
|
+
const onStdoutResize = () => callback();
|
|
197
|
+
const onSigwinch = () => callback();
|
|
198
|
+
process.stdout.on("resize", onStdoutResize);
|
|
199
|
+
process.on("SIGWINCH", onSigwinch);
|
|
200
|
+
return () => {
|
|
201
|
+
process.stdout.off("resize", onStdoutResize);
|
|
202
|
+
process.off("SIGWINCH", onSigwinch);
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/tui/render.ts
|
|
207
|
+
import stringWidth from "string-width";
|
|
208
|
+
var COLOR_SGR = {
|
|
209
|
+
black: 30,
|
|
210
|
+
red: 31,
|
|
211
|
+
green: 32,
|
|
212
|
+
yellow: 33,
|
|
213
|
+
blue: 34,
|
|
214
|
+
magenta: 35,
|
|
215
|
+
cyan: 36,
|
|
216
|
+
white: 37,
|
|
217
|
+
gray: 90
|
|
218
|
+
};
|
|
219
|
+
function colorToSGR(color) {
|
|
220
|
+
const code = COLOR_SGR[color];
|
|
221
|
+
if (code === void 0) throw new Error(`Unknown color: ${color}`);
|
|
222
|
+
return code;
|
|
223
|
+
}
|
|
224
|
+
function renderLine(segs) {
|
|
225
|
+
let out = "";
|
|
226
|
+
for (const s of segs) {
|
|
227
|
+
const codes = [];
|
|
228
|
+
if (s.bold) codes.push("1");
|
|
229
|
+
if (s.dim) codes.push("2");
|
|
230
|
+
if (s.italic) codes.push("3");
|
|
231
|
+
if (s.strikethrough) codes.push("9");
|
|
232
|
+
if (s.inverse) codes.push("7");
|
|
233
|
+
if (s.fg) codes.push(s.fg);
|
|
234
|
+
else if (s.color) codes.push(String(colorToSGR(s.color)));
|
|
235
|
+
if (s.bg) codes.push(s.bg);
|
|
236
|
+
if (codes.length > 0) {
|
|
237
|
+
out += `\x1B[${codes.join(";")}m${s.text}\x1B[0m`;
|
|
238
|
+
} else {
|
|
239
|
+
out += s.text;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
var cachedBlank = "";
|
|
245
|
+
var cachedBlankWidth = 0;
|
|
246
|
+
function createFrameBuffer(width, height) {
|
|
247
|
+
if (width !== cachedBlankWidth) {
|
|
248
|
+
cachedBlank = " ".repeat(width);
|
|
249
|
+
cachedBlankWidth = width;
|
|
250
|
+
}
|
|
251
|
+
const lines = new Array(height);
|
|
252
|
+
for (let i = 0; i < height; i++) lines[i] = cachedBlank;
|
|
253
|
+
return { lines, width, height };
|
|
254
|
+
}
|
|
255
|
+
function copyRows(buf, src, startRow, count) {
|
|
256
|
+
for (let i = 0; i < count && startRow + i < buf.height; i++) {
|
|
257
|
+
buf.lines[startRow + i] = src[startRow + i];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function flushFrame(frame, prevFrame, suffix) {
|
|
261
|
+
let out = "\x1B[?2026h";
|
|
262
|
+
for (let i = 0; i < frame.length; i++) {
|
|
263
|
+
if (frame[i] !== prevFrame[i]) {
|
|
264
|
+
out += `\x1B[${i + 1};1H`;
|
|
265
|
+
out += "\x1B[2K";
|
|
266
|
+
out += frame[i];
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (suffix) out += suffix;
|
|
270
|
+
out += "\x1B[?2026l";
|
|
271
|
+
return out;
|
|
272
|
+
}
|
|
273
|
+
var ANSI_RE = /\x1b\[[0-9;]*[a-zA-Z]/g;
|
|
274
|
+
function clipAnsi(content, maxWidth) {
|
|
275
|
+
let out = "";
|
|
276
|
+
let displayWidth = 0;
|
|
277
|
+
let i = 0;
|
|
278
|
+
while (i < content.length) {
|
|
279
|
+
if (content[i] === "\x1B" && content[i + 1] === "[") {
|
|
280
|
+
const seqLen = ansiLen(content, i);
|
|
281
|
+
if (seqLen > 0) {
|
|
282
|
+
out += content.substring(i, i + seqLen);
|
|
283
|
+
i += seqLen;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const cp = content.codePointAt(i);
|
|
288
|
+
if (cp < 32 && cp !== 27) {
|
|
289
|
+
i++;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const ch = String.fromCodePoint(cp);
|
|
293
|
+
const chWidth = cp < 128 ? 1 : stringWidth(ch);
|
|
294
|
+
if (displayWidth + chWidth > maxWidth) break;
|
|
295
|
+
out += ch;
|
|
296
|
+
displayWidth += chWidth;
|
|
297
|
+
i += ch.length;
|
|
298
|
+
}
|
|
299
|
+
if (out.includes("\x1B[") && !out.endsWith("\x1B[0m")) {
|
|
300
|
+
out += "\x1B[0m";
|
|
301
|
+
}
|
|
302
|
+
const remaining = maxWidth - displayWidth;
|
|
303
|
+
if (remaining > 0) out += " ".repeat(remaining);
|
|
304
|
+
return out;
|
|
305
|
+
}
|
|
306
|
+
function displayWidthFast(s) {
|
|
307
|
+
let w = 0;
|
|
308
|
+
let i = 0;
|
|
309
|
+
while (i < s.length) {
|
|
310
|
+
if (s[i] === "\x1B" && s[i + 1] === "[") {
|
|
311
|
+
const len = ansiLen(s, i);
|
|
312
|
+
if (len > 0) {
|
|
313
|
+
i += len;
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
const cp = s.codePointAt(i);
|
|
318
|
+
const ch = String.fromCodePoint(cp);
|
|
319
|
+
w += cp < 128 ? 1 : stringWidth(ch);
|
|
320
|
+
i += ch.length;
|
|
321
|
+
}
|
|
322
|
+
return w;
|
|
323
|
+
}
|
|
324
|
+
function ansiLen(s, i) {
|
|
325
|
+
let j = i + 2;
|
|
326
|
+
const len = s.length;
|
|
327
|
+
while (j < len) {
|
|
328
|
+
const c = s.charCodeAt(j);
|
|
329
|
+
if (c >= 48 && c <= 57 || c === 59) {
|
|
330
|
+
j++;
|
|
331
|
+
} else {
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (j < len) {
|
|
336
|
+
const c = s.charCodeAt(j);
|
|
337
|
+
if (c >= 65 && c <= 90 || c >= 97 && c <= 122) {
|
|
338
|
+
return j + 1 - i;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return 0;
|
|
342
|
+
}
|
|
343
|
+
function writeAt(buf, x, y, content) {
|
|
344
|
+
if (y < 0 || y >= buf.height) return;
|
|
345
|
+
if (x < 0 || x >= buf.width) return;
|
|
346
|
+
const existing = buf.lines[y];
|
|
347
|
+
const contentDisplayWidth = stringWidth(content.replace(ANSI_RE, ""));
|
|
348
|
+
const prefix = sliceDisplayCols(existing, 0, x);
|
|
349
|
+
const suffix = sliceDisplayCols(existing, x + contentDisplayWidth, buf.width, true);
|
|
350
|
+
const prefixWidth = stringWidth(prefix.replace(ANSI_RE, ""));
|
|
351
|
+
const paddedPrefix = prefix + " ".repeat(Math.max(0, x - prefixWidth));
|
|
352
|
+
buf.lines[y] = paddedPrefix + content + suffix;
|
|
353
|
+
}
|
|
354
|
+
function writeClipped(buf, x, y, content, maxWidth) {
|
|
355
|
+
if (y < 0 || y >= buf.height) return;
|
|
356
|
+
if (x < 0 || x >= buf.width) return;
|
|
357
|
+
let out = "";
|
|
358
|
+
let displayWidth = 0;
|
|
359
|
+
let i = 0;
|
|
360
|
+
while (i < content.length) {
|
|
361
|
+
if (content[i] === "\x1B" && content[i + 1] === "[") {
|
|
362
|
+
const seqLen = ansiLen(content, i);
|
|
363
|
+
if (seqLen > 0) {
|
|
364
|
+
out += content.substring(i, i + seqLen);
|
|
365
|
+
i += seqLen;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
const cp = content.codePointAt(i);
|
|
370
|
+
if (cp < 32 && cp !== 27) {
|
|
371
|
+
i++;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
const ch = String.fromCodePoint(cp);
|
|
375
|
+
const chWidth = cp < 128 ? 1 : stringWidth(ch);
|
|
376
|
+
if (displayWidth + chWidth > maxWidth) break;
|
|
377
|
+
out += ch;
|
|
378
|
+
displayWidth += chWidth;
|
|
379
|
+
i += ch.length;
|
|
380
|
+
}
|
|
381
|
+
if (out.includes("\x1B[") && !out.endsWith("\x1B[0m")) {
|
|
382
|
+
out += "\x1B[0m";
|
|
383
|
+
}
|
|
384
|
+
const remaining = maxWidth - displayWidth;
|
|
385
|
+
if (remaining > 0) {
|
|
386
|
+
out += " ".repeat(remaining);
|
|
387
|
+
}
|
|
388
|
+
const existing = buf.lines[y];
|
|
389
|
+
const prefix = sliceDisplayCols(existing, 0, x);
|
|
390
|
+
const suffix = sliceDisplayCols(existing, x + maxWidth, buf.width, true);
|
|
391
|
+
const prefixDisplayW = displayWidthFast(prefix);
|
|
392
|
+
const paddedPrefix = prefixDisplayW < x ? prefix + " ".repeat(x - prefixDisplayW) : prefix;
|
|
393
|
+
buf.lines[y] = paddedPrefix + out + suffix;
|
|
394
|
+
}
|
|
395
|
+
function writeCenter(buf, row, content) {
|
|
396
|
+
const textWidth = stringWidth(content.replace(ANSI_RE, ""));
|
|
397
|
+
const x = Math.max(0, Math.floor((buf.width - textWidth) / 2));
|
|
398
|
+
writeAt(buf, x, row, content);
|
|
399
|
+
}
|
|
400
|
+
function drawBorder(buf, x, y, w, h, color) {
|
|
401
|
+
const sgr = `\x1B[${colorToSGR(color)}m`;
|
|
402
|
+
const reset = "\x1B[0m";
|
|
403
|
+
writeAt(buf, x, y, sgr + "\u256D" + "\u2500".repeat(w - 2) + "\u256E" + reset);
|
|
404
|
+
writeAt(buf, x, y + h - 1, sgr + "\u2570" + "\u2500".repeat(w - 2) + "\u256F" + reset);
|
|
405
|
+
for (let row = y + 1; row < y + h - 1; row++) {
|
|
406
|
+
writeAt(buf, x, row, sgr + "\u2502" + reset);
|
|
407
|
+
writeAt(buf, x + w - 1, row, sgr + "\u2502" + reset);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function buildPanelRows(rect, lines, scroll, focused, borderColor, renderedCache) {
|
|
411
|
+
const { w, h } = rect;
|
|
412
|
+
const rows = new Array(h);
|
|
413
|
+
const color = focused ? "cyan" : "gray";
|
|
414
|
+
const sgr = `\x1B[${colorToSGR(color)}m`;
|
|
415
|
+
const reset = "\x1B[0m";
|
|
416
|
+
const innerW = w - 4;
|
|
417
|
+
const innerH = h - 2;
|
|
418
|
+
const blankInner = " ".repeat(innerW);
|
|
419
|
+
rows[0] = sgr + "\u256D" + "\u2500".repeat(w - 2) + "\u256E" + reset;
|
|
420
|
+
rows[h - 1] = sgr + "\u2570" + "\u2500".repeat(w - 2) + "\u256F" + reset;
|
|
421
|
+
const borderL = sgr + "\u2502" + reset + " ";
|
|
422
|
+
const borderR = " " + sgr + "\u2502" + reset;
|
|
423
|
+
const emptyRow = borderL + blankInner + borderR;
|
|
424
|
+
for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;
|
|
425
|
+
if (innerW <= 0 || innerH <= 0) return rows;
|
|
426
|
+
let ansiLines;
|
|
427
|
+
if (renderedCache && renderedCache.lines === lines) {
|
|
428
|
+
ansiLines = renderedCache.ansi;
|
|
429
|
+
} else {
|
|
430
|
+
ansiLines = new Array(lines.length);
|
|
431
|
+
for (let i = 0; i < lines.length; i++) {
|
|
432
|
+
ansiLines[i] = renderLine(lines[i]);
|
|
433
|
+
}
|
|
434
|
+
if (renderedCache) {
|
|
435
|
+
renderedCache.lines = lines;
|
|
436
|
+
renderedCache.ansi = ansiLines;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
const hasOverflow = lines.length > innerH;
|
|
440
|
+
const viewableH = hasOverflow ? innerH - 1 : innerH;
|
|
441
|
+
const maxScroll = Math.max(0, lines.length - viewableH);
|
|
442
|
+
scroll.setMax(maxScroll);
|
|
443
|
+
const effectiveOffset = scroll.offset;
|
|
444
|
+
for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {
|
|
445
|
+
const clipped = clipAnsi(ansiLines[effectiveOffset + i], innerW);
|
|
446
|
+
rows[1 + i] = borderL + clipped + borderR;
|
|
447
|
+
}
|
|
448
|
+
if (hasOverflow) {
|
|
449
|
+
const scrollPct = maxScroll > 0 ? Math.round(effectiveOffset / maxScroll * 100) : 100;
|
|
450
|
+
const indicator = ` \u2195 ${scrollPct}% \xB7 ${lines.length} lines`;
|
|
451
|
+
const clipped = clipAnsi(`\x1B[2m${indicator}\x1B[0m`, innerW);
|
|
452
|
+
rows[1 + viewableH] = borderL + clipped + borderR;
|
|
453
|
+
}
|
|
454
|
+
return rows;
|
|
455
|
+
}
|
|
456
|
+
function buildEmptyPanelRows(rect, focused, borderColor, centerText) {
|
|
457
|
+
const { w, h } = rect;
|
|
458
|
+
const rows = new Array(h);
|
|
459
|
+
const color = focused ? "cyan" : "gray";
|
|
460
|
+
const sgr = `\x1B[${colorToSGR(color)}m`;
|
|
461
|
+
const reset = "\x1B[0m";
|
|
462
|
+
const innerW = w - 4;
|
|
463
|
+
const borderL = sgr + "\u2502" + reset + " ";
|
|
464
|
+
const borderR = " " + sgr + "\u2502" + reset;
|
|
465
|
+
const emptyRow = borderL + " ".repeat(innerW) + borderR;
|
|
466
|
+
rows[0] = sgr + "\u256D" + "\u2500".repeat(w - 2) + "\u256E" + reset;
|
|
467
|
+
rows[h - 1] = sgr + "\u2570" + "\u2500".repeat(w - 2) + "\u256F" + reset;
|
|
468
|
+
for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;
|
|
469
|
+
if (centerText) {
|
|
470
|
+
const midRow = Math.floor(h / 2);
|
|
471
|
+
if (midRow > 0 && midRow < h - 1) {
|
|
472
|
+
const clipped = clipAnsi(centerText, innerW);
|
|
473
|
+
const textW = displayWidthFast(centerText);
|
|
474
|
+
const pad = Math.max(0, Math.floor((innerW - textW) / 2));
|
|
475
|
+
const centered = " ".repeat(pad) + clipped;
|
|
476
|
+
rows[midRow] = borderL + clipAnsi(centered, innerW) + borderR;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return rows;
|
|
480
|
+
}
|
|
481
|
+
function sliceDisplayCols(s, start, end, restoreState = false) {
|
|
482
|
+
let out = "";
|
|
483
|
+
let col = 0;
|
|
484
|
+
let i = 0;
|
|
485
|
+
let inSlice = false;
|
|
486
|
+
let hasOpenSGR = false;
|
|
487
|
+
let pendingSGR = "";
|
|
488
|
+
while (i < s.length && col < end) {
|
|
489
|
+
if (s[i] === "\x1B" && s[i + 1] === "[") {
|
|
490
|
+
const seqLen = ansiLen(s, i);
|
|
491
|
+
if (seqLen > 0) {
|
|
492
|
+
const seq = s.substring(i, i + seqLen);
|
|
493
|
+
if (col >= start) {
|
|
494
|
+
out += seq;
|
|
495
|
+
hasOpenSGR = seq !== "\x1B[0m" && seq !== "\x1B[m";
|
|
496
|
+
} else if (restoreState) {
|
|
497
|
+
if (seq === "\x1B[0m" || seq === "\x1B[m") {
|
|
498
|
+
pendingSGR = "";
|
|
499
|
+
} else {
|
|
500
|
+
pendingSGR += seq;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
i += seqLen;
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
const cp = s.codePointAt(i);
|
|
508
|
+
const ch = String.fromCodePoint(cp);
|
|
509
|
+
const chWidth = cp < 128 ? 1 : stringWidth(ch);
|
|
510
|
+
if (col >= start) {
|
|
511
|
+
inSlice = true;
|
|
512
|
+
if (col + chWidth > end) break;
|
|
513
|
+
out += ch;
|
|
514
|
+
}
|
|
515
|
+
col += chWidth;
|
|
516
|
+
i += ch.length;
|
|
517
|
+
}
|
|
518
|
+
if (inSlice && hasOpenSGR) {
|
|
519
|
+
out += "\x1B[0m";
|
|
520
|
+
}
|
|
521
|
+
if (restoreState && pendingSGR) {
|
|
522
|
+
out = pendingSGR + out;
|
|
523
|
+
}
|
|
524
|
+
return out;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export {
|
|
528
|
+
setupTerminal,
|
|
529
|
+
writeToStdout,
|
|
530
|
+
startKeypressListener,
|
|
531
|
+
onResize,
|
|
532
|
+
colorToSGR,
|
|
533
|
+
renderLine,
|
|
534
|
+
createFrameBuffer,
|
|
535
|
+
copyRows,
|
|
536
|
+
flushFrame,
|
|
537
|
+
clipAnsi,
|
|
538
|
+
writeClipped,
|
|
539
|
+
writeCenter,
|
|
540
|
+
drawBorder,
|
|
541
|
+
buildPanelRows,
|
|
542
|
+
buildEmptyPanelRows
|
|
543
|
+
};
|
|
544
|
+
//# sourceMappingURL=chunk-O4ZHSQ5R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tui/terminal.ts","../src/tui/render.ts"],"sourcesContent":["export interface Key {\n upArrow: boolean;\n downArrow: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n pageUp: boolean;\n pageDown: boolean;\n return: boolean;\n escape: boolean;\n ctrl: boolean;\n shift: boolean;\n tab: boolean;\n backspace: boolean;\n delete: boolean;\n meta: boolean;\n}\n\nexport type KeypressHandler = (input: string, key: Key) => void;\n\nfunction emptyKey(): Key {\n return {\n upArrow: false,\n downArrow: false,\n leftArrow: false,\n rightArrow: false,\n pageUp: false,\n pageDown: false,\n return: false,\n escape: false,\n ctrl: false,\n shift: false,\n tab: false,\n backspace: false,\n delete: false,\n meta: false,\n };\n}\n\n// ── Terminal Setup/Teardown ──────────────────────────────────────────────────\n\nexport function setupTerminal(): () => void {\n let cleaned = false;\n\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n process.stdout.write('\\x1b[?25h\\x1b[?1049l');\n process.stdin.setRawMode(false);\n process.stdin.pause();\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding('utf-8');\n process.stdout.write('\\x1b[?1049h\\x1b[?25l\\x1b[2J');\n\n process.on('SIGINT', () => { cleanup(); process.exit(0); });\n process.on('SIGTERM', () => { cleanup(); process.exit(0); });\n process.on('exit', cleanup);\n process.on('uncaughtException', (err) => {\n cleanup();\n console.error(err);\n process.exit(1);\n });\n\n return cleanup;\n}\n\n// ── Stdout Write Helper ──────────────────────────────────────────────────────\n\nexport function writeToStdout(data: string): void {\n process.stdout.write(data);\n}\n\n// ── Keypress Parser ──────────────────────────────────────────────────────────\n\n/**\n * Parse all complete key sequences from a buffer string.\n * Returns an array of [input, Key] pairs and the remaining unparsed buffer.\n */\nfunction parseBuffer(buf: string): { events: Array<[string, Key]>; remaining: string } {\n const events: Array<[string, Key]> = [];\n\n let i = 0;\n while (i < buf.length) {\n const ch = buf[i]!;\n\n // ESC prefix sequences\n if (ch === '\\x1b') {\n const rest = buf.slice(i + 1);\n\n // CSI sequences: \\x1b[...\n if (rest.startsWith('[')) {\n const after = rest.slice(1);\n\n // Shift+Arrow: \\x1b[1;2A/B/C/D\n const shiftArrow = after.match(/^1;2([ABCD])/);\n if (shiftArrow) {\n const key = emptyKey();\n key.shift = true;\n const dir = shiftArrow[1]!;\n if (dir === 'A') key.upArrow = true;\n else if (dir === 'B') key.downArrow = true;\n else if (dir === 'C') key.rightArrow = true;\n else if (dir === 'D') key.leftArrow = true;\n const seq = `\\x1b[1;2${dir}`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Shift+Tab (backtab): \\x1b[Z\n if (after.length >= 1 && after[0] === 'Z') {\n const key = emptyKey();\n key.tab = true;\n key.shift = true;\n const seq = `\\x1b[Z`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Arrow keys: \\x1b[A/B/C/D\n if (after.length >= 1 && 'ABCD'.includes(after[0]!)) {\n const key = emptyKey();\n const dir = after[0]!;\n if (dir === 'A') key.upArrow = true;\n else if (dir === 'B') key.downArrow = true;\n else if (dir === 'C') key.rightArrow = true;\n else if (dir === 'D') key.leftArrow = true;\n const seq = `\\x1b[${dir}`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Tilde sequences: \\x1b[N~\n const tildeMatch = after.match(/^(\\d+)~/);\n if (tildeMatch) {\n const num = tildeMatch[1]!;\n const key = emptyKey();\n if (num === '5') key.pageUp = true;\n else if (num === '6') key.pageDown = true;\n else if (num === '3') key.delete = true;\n const seq = `\\x1b[${num}~`;\n events.push([seq, key]);\n i += seq.length;\n continue;\n }\n\n // Incomplete CSI — need more data\n return { events, remaining: buf.slice(i) };\n }\n\n // Lone ESC — signal caller to wait (disambiguate vs CSI prefix)\n if (rest.length === 0) {\n return { events, remaining: buf.slice(i) };\n }\n\n // \\x1b + regular char → Meta key\n const metaCh = rest[0]!;\n const key = emptyKey();\n key.meta = true;\n events.push([metaCh, key]);\n i += 2;\n continue;\n }\n\n // Return\n if (ch === '\\r') {\n const key = emptyKey();\n key.return = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Tab\n if (ch === '\\t') {\n const key = emptyKey();\n key.tab = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Backspace (DEL or BS)\n if (ch === '\\x7f' || ch === '\\x08') {\n const key = emptyKey();\n key.backspace = true;\n events.push([ch, key]);\n i++;\n continue;\n }\n\n // Ctrl+A–Z (\\x01–\\x1a)\n const code = ch.charCodeAt(0);\n if (code >= 0x01 && code <= 0x1a) {\n const key = emptyKey();\n key.ctrl = true;\n const letter = String.fromCharCode(code + 96);\n events.push([letter, key]);\n i++;\n continue;\n }\n\n // Printable / multibyte char\n events.push([ch, emptyKey()]);\n i++;\n }\n\n return { events, remaining: '' };\n}\n\n// ── Raw Stdin Bypass (for neovim PTY forwarding) ─────────────────────────────\n\nlet rawBypassHandler: ((data: string) => boolean) | null = null;\n\nexport function setRawBypass(handler: ((data: string) => boolean) | null): void {\n rawBypassHandler = handler;\n}\n\nexport function startKeypressListener(handler: KeypressHandler): () => void {\n let buffer = '';\n let escTimer: ReturnType<typeof setTimeout> | null = null;\n\n const onData = (data: string): void => {\n // Raw bypass — forward to neovim PTY if active\n if (rawBypassHandler) {\n const handled = rawBypassHandler(data);\n if (handled) return;\n }\n\n // Cancel pending escape timer — more data arrived\n if (escTimer !== null) {\n clearTimeout(escTimer);\n escTimer = null;\n }\n\n buffer += data;\n\n const { events, remaining } = parseBuffer(buffer);\n buffer = remaining;\n\n for (const [input, key] of events) {\n handler(input, key);\n }\n\n // If buffer ends with lone ESC, start disambiguation timer\n if (buffer === '\\x1b') {\n escTimer = setTimeout(() => {\n escTimer = null;\n buffer = '';\n const key = emptyKey();\n key.escape = true;\n handler('\\x1b', key);\n }, 50);\n }\n };\n\n process.stdin.on('data', onData);\n\n return (): void => {\n process.stdin.off('data', onData);\n if (escTimer !== null) {\n clearTimeout(escTimer);\n escTimer = null;\n }\n };\n}\n\n// ── Resize Handler ───────────────────────────────────────────────────────────\n\nexport function onResize(callback: () => void): () => void {\n const onStdoutResize = (): void => callback();\n const onSigwinch = (): void => callback();\n\n process.stdout.on('resize', onStdoutResize);\n process.on('SIGWINCH', onSigwinch);\n\n return (): void => {\n process.stdout.off('resize', onStdoutResize);\n process.off('SIGWINCH', onSigwinch);\n };\n}\n","import stringWidth from 'string-width';\nimport type { Seg, DetailLine } from './lib/format.js';\nimport type { ThrottledScroll } from './state.js';\n\nexport type { Seg, DetailLine };\n\n// ─── Color mapping ────────────────────────────────────────────────────────────\n\nexport const COLOR_SGR: Record<string, number> = {\n black: 30,\n red: 31,\n green: 32,\n yellow: 33,\n blue: 34,\n magenta: 35,\n cyan: 36,\n white: 37,\n gray: 90,\n};\n\nexport function colorToSGR(color: string): number {\n const code = COLOR_SGR[color];\n if (code === undefined) throw new Error(`Unknown color: ${color}`);\n return code;\n}\n\n// ─── Seg → ANSI conversion (§1.1) ────────────────────────────────────────────\n\nexport function renderLine(segs: Seg[]): string {\n let out = '';\n for (const s of segs) {\n const codes: string[] = [];\n if (s.bold) codes.push('1');\n if (s.dim) codes.push('2');\n if (s.italic) codes.push('3');\n if (s.strikethrough) codes.push('9');\n if (s.inverse) codes.push('7');\n if (s.fg) codes.push(s.fg);\n else if (s.color) codes.push(String(colorToSGR(s.color)));\n if (s.bg) codes.push(s.bg);\n if (codes.length > 0) {\n out += `\\x1b[${codes.join(';')}m${s.text}\\x1b[0m`;\n } else {\n out += s.text;\n }\n }\n return out;\n}\n\n// ─── Frame Buffer (§1.2) ──────────────────────────────────────────────────────\n\nexport interface FrameBuffer {\n lines: string[];\n width: number;\n height: number;\n}\n\nlet cachedBlank = '';\nlet cachedBlankWidth = 0;\n\nexport function createFrameBuffer(width: number, height: number): FrameBuffer {\n if (width !== cachedBlankWidth) {\n cachedBlank = ' '.repeat(width);\n cachedBlankWidth = width;\n }\n const lines = new Array<string>(height);\n for (let i = 0; i < height; i++) lines[i] = cachedBlank;\n return { lines, width, height };\n}\n\n/**\n * Copy rows from a previous frame into the buffer (skip re-render for clean panels).\n */\nexport function copyRows(buf: FrameBuffer, src: string[], startRow: number, count: number): void {\n for (let i = 0; i < count && startRow + i < buf.height; i++) {\n buf.lines[startRow + i] = src[startRow + i]!;\n }\n}\n\n// ─── Frame Diffing (§1.3) ────────────────────────────────────────────────────\n\nexport function flushFrame(frame: string[], prevFrame: string[], suffix?: string): string {\n let out = '\\x1b[?2026h'; // begin synchronized output\n for (let i = 0; i < frame.length; i++) {\n if (frame[i] !== prevFrame[i]) {\n out += `\\x1b[${i + 1};1H`; // cursor to row i+1, col 1\n out += '\\x1b[2K'; // clear entire line\n out += frame[i];\n }\n }\n if (suffix) out += suffix;\n out += '\\x1b[?2026l'; // end synchronized output\n return out;\n}\n\n// ─── ANSI escape sequence regex ───────────────────────────────────────────────\n\nconst ANSI_RE = /\\x1b\\[[0-9;]*[a-zA-Z]/g;\n\n// ─── Clip ANSI string to display width (no buffer interaction) ──────────────\n\n/**\n * Clip an ANSI string to exactly `maxWidth` display columns, padding with spaces.\n * Pure function — no buffer splicing.\n */\nexport function clipAnsi(content: string, maxWidth: number): string {\n let out = '';\n let displayWidth = 0;\n let i = 0;\n\n while (i < content.length) {\n if (content[i] === '\\x1b' && content[i + 1] === '[') {\n const seqLen = ansiLen(content, i);\n if (seqLen > 0) {\n out += content.substring(i, i + seqLen);\n i += seqLen;\n continue;\n }\n }\n const cp = content.codePointAt(i)!;\n // Skip control characters (newlines, tabs, etc.) — they break frame output\n if (cp < 0x20 && cp !== 0x1b) { i++; continue; }\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n if (displayWidth + chWidth > maxWidth) break;\n out += ch;\n displayWidth += chWidth;\n i += ch.length;\n }\n\n if (out.includes('\\x1b[') && !out.endsWith('\\x1b[0m')) {\n out += '\\x1b[0m';\n }\n\n const remaining = maxWidth - displayWidth;\n if (remaining > 0) out += ' '.repeat(remaining);\n return out;\n}\n\n/**\n * Fast display-width calculation that skips ANSI escapes without regex allocation.\n */\nfunction displayWidthFast(s: string): number {\n let w = 0;\n let i = 0;\n while (i < s.length) {\n if (s[i] === '\\x1b' && s[i + 1] === '[') {\n const len = ansiLen(s, i);\n if (len > 0) { i += len; continue; }\n }\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n w += cp < 128 ? 1 : stringWidth(ch);\n i += ch.length;\n }\n return w;\n}\n\n/**\n * Parse ANSI escape sequence at position i. Returns length of sequence or 0.\n * Avoids s.slice(i).match(regex) which allocates a new string each call.\n */\nfunction ansiLen(s: string, i: number): number {\n // Caller already verified s[i] === '\\x1b' && s[i+1] === '['\n let j = i + 2;\n const len = s.length;\n // Consume parameter bytes: digits 0-9 and semicolons\n while (j < len) {\n const c = s.charCodeAt(j);\n if ((c >= 0x30 && c <= 0x39) || c === 0x3b) { // '0'-'9' or ';'\n j++;\n } else {\n break;\n }\n }\n // Must end with a letter (final byte)\n if (j < len) {\n const c = s.charCodeAt(j);\n if ((c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)) { // A-Z or a-z\n return j + 1 - i;\n }\n }\n return 0;\n}\n\n// ─── Write functions ──────────────────────────────────────────────────────────\n\n/**\n * Write content into frame buffer at position (x, y).\n *\n * Strategy: rebuild the target line by splitting into display columns,\n * inserting the new content, then reassembling. Since we build the frame\n * fresh each render, we can treat the existing line as plain chars + ANSI.\n *\n * This implementation replaces display columns [x, x+displayWidth(content))\n * in the buffer line with the new content.\n */\nexport function writeAt(buf: FrameBuffer, x: number, y: number, content: string): void {\n if (y < 0 || y >= buf.height) return;\n if (x < 0 || x >= buf.width) return;\n\n const existing = buf.lines[y]!;\n const contentDisplayWidth = stringWidth(content.replace(ANSI_RE, ''));\n\n // Split the existing line into prefix (0..x) and suffix (x+contentDisplayWidth..)\n // We need to walk the existing line respecting display widths.\n // suffix uses restoreState=true to preserve ANSI bg/fg from before the splice point.\n const prefix = sliceDisplayCols(existing, 0, x);\n const suffix = sliceDisplayCols(existing, x + contentDisplayWidth, buf.width, true);\n\n // Pad prefix if it's shorter than expected (can happen at end of line)\n const prefixWidth = stringWidth(prefix.replace(ANSI_RE, ''));\n const paddedPrefix = prefix + ' '.repeat(Math.max(0, x - prefixWidth));\n\n buf.lines[y] = paddedPrefix + content + suffix;\n}\n\n/**\n * Write ANSI string into buffer at (x, y), truncating to maxWidth display columns.\n * Pads remaining width with spaces.\n */\nexport function writeClipped(\n buf: FrameBuffer,\n x: number,\n y: number,\n content: string,\n maxWidth: number,\n): void {\n if (y < 0 || y >= buf.height) return;\n if (x < 0 || x >= buf.width) return;\n\n let out = '';\n let displayWidth = 0;\n let i = 0;\n\n while (i < content.length) {\n // Check for ANSI escape sequence — pass through without counting width\n if (content[i] === '\\x1b' && content[i + 1] === '[') {\n const seqLen = ansiLen(content, i);\n if (seqLen > 0) {\n out += content.substring(i, i + seqLen);\n i += seqLen;\n continue;\n }\n }\n\n // Get the next character (handle surrogate pairs)\n const cp = content.codePointAt(i)!;\n // Skip control characters (newlines, tabs, etc.) — they break frame output\n if (cp < 0x20 && cp !== 0x1b) { i++; continue; }\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n\n if (displayWidth + chWidth > maxWidth) break;\n\n out += ch;\n displayWidth += chWidth;\n i += ch.length;\n }\n\n // Ensure any open SGR sequences are reset\n if (out.includes('\\x1b[') && !out.endsWith('\\x1b[0m')) {\n out += '\\x1b[0m';\n }\n\n // Pad to maxWidth\n const remaining = maxWidth - displayWidth;\n if (remaining > 0) {\n out += ' '.repeat(remaining);\n }\n\n // Splice directly into buffer line — we already know exact display width is maxWidth,\n // so skip writeAt's redundant stringWidth + double sliceDisplayCols re-parse.\n const existing = buf.lines[y]!;\n const prefix = sliceDisplayCols(existing, 0, x);\n const suffix = sliceDisplayCols(existing, x + maxWidth, buf.width, true);\n const prefixDisplayW = displayWidthFast(prefix);\n const paddedPrefix = prefixDisplayW < x ? prefix + ' '.repeat(x - prefixDisplayW) : prefix;\n buf.lines[y] = paddedPrefix + out + suffix;\n}\n\n/**\n * Write centered text at the given row.\n */\nexport function writeCenter(buf: FrameBuffer, row: number, content: string): void {\n const textWidth = stringWidth(content.replace(ANSI_RE, ''));\n const x = Math.max(0, Math.floor((buf.width - textWidth) / 2));\n writeAt(buf, x, row, content);\n}\n\n// ─── Border Drawing (§1.5) ────────────────────────────────────────────────────\n\nexport function drawBorder(\n buf: FrameBuffer,\n x: number,\n y: number,\n w: number,\n h: number,\n color: string,\n): void {\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n\n // Top: ╭────╮\n writeAt(buf, x, y, sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset);\n // Bottom: ╰────╯\n writeAt(buf, x, y + h - 1, sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset);\n // Sides\n for (let row = y + 1; row < y + h - 1; row++) {\n writeAt(buf, x, row, sgr + '│' + reset);\n writeAt(buf, x + w - 1, row, sgr + '│' + reset);\n }\n}\n\n// ─── Panel Rendering (§4.2) ───────────────────────────────────────────────────\n\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * Cache for pre-rendered ANSI strings. Keyed by the DetailLine[] identity —\n * when the caller provides a `renderedCache`, renderPanel will populate it\n * on first render and reuse on subsequent frames (avoiding renderLine per line).\n */\nexport interface RenderedCache {\n lines: DetailLine[];\n ansi: string[];\n}\n\nexport function renderPanel(\n buf: FrameBuffer,\n rect: Rect,\n lines: DetailLine[],\n scrollOffset: number,\n focused: boolean,\n borderColor: string,\n renderedCache?: RenderedCache | null,\n): void {\n const { x, y, w, h } = rect;\n\n // 1. Draw border\n drawBorder(buf, x, y, w, h, focused ? 'blue' : borderColor);\n\n // 2. Inner dimensions (border + 1 padding each side, matching Ink's paddingX={1})\n const innerX = x + 2;\n const innerW = w - 4;\n const innerY = y + 1;\n const innerH = h - 2;\n\n if (innerW <= 0 || innerH <= 0) return;\n\n // 3. Pre-render ANSI strings (cached across frames)\n let ansiLines: string[];\n if (renderedCache && renderedCache.lines === lines) {\n ansiLines = renderedCache.ansi;\n } else {\n ansiLines = new Array<string>(lines.length);\n for (let i = 0; i < lines.length; i++) {\n ansiLines[i] = renderLine(lines[i]!);\n }\n if (renderedCache) {\n renderedCache.lines = lines;\n renderedCache.ansi = ansiLines;\n }\n }\n\n // 4. Windowed slice\n const hasOverflow = lines.length > innerH;\n const viewableH = hasOverflow ? innerH - 1 : innerH;\n const maxScroll = Math.max(0, lines.length - viewableH);\n const effectiveOffset = Math.min(scrollOffset, maxScroll);\n\n // 5. Render visible lines\n for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {\n writeClipped(buf, innerX, innerY + i, ansiLines[effectiveOffset + i]!, innerW);\n }\n\n // 6. Scroll indicator\n if (hasOverflow) {\n const scrollPct = maxScroll > 0 ? Math.round((effectiveOffset / maxScroll) * 100) : 100;\n const indicator = ` ↕ ${scrollPct}% · ${lines.length} lines`;\n writeClipped(buf, innerX, innerY + viewableH, `\\x1b[2m${indicator}\\x1b[0m`, innerW);\n }\n}\n\n/**\n * Build panel as self-contained row strings (w display-columns each, including borders).\n * Returns h strings. No buffer interaction — avoids sliceDisplayCols entirely.\n */\nexport function buildPanelRows(\n rect: Rect,\n lines: DetailLine[],\n scroll: ThrottledScroll,\n focused: boolean,\n borderColor: string,\n renderedCache?: RenderedCache | null,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n\n const color = focused ? 'cyan' : 'gray';\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4;\n const innerH = h - 2;\n const blankInner = ' '.repeat(innerW);\n\n // Top border\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n // Bottom border\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n\n // Pre-fill interior rows with empty content\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const emptyRow = borderL + blankInner + borderR;\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (innerW <= 0 || innerH <= 0) return rows;\n\n // Pre-render ANSI strings (cached across frames)\n let ansiLines: string[];\n if (renderedCache && renderedCache.lines === lines) {\n ansiLines = renderedCache.ansi;\n } else {\n ansiLines = new Array<string>(lines.length);\n for (let i = 0; i < lines.length; i++) {\n ansiLines[i] = renderLine(lines[i]!);\n }\n if (renderedCache) {\n renderedCache.lines = lines;\n renderedCache.ansi = ansiLines;\n }\n }\n\n // Windowed slice\n const hasOverflow = lines.length > innerH;\n const viewableH = hasOverflow ? innerH - 1 : innerH;\n const maxScroll = Math.max(0, lines.length - viewableH);\n scroll.setMax(maxScroll);\n const effectiveOffset = scroll.offset;\n\n // Content rows — clip and compose without buffer splicing\n for (let i = 0; i < viewableH && effectiveOffset + i < ansiLines.length; i++) {\n const clipped = clipAnsi(ansiLines[effectiveOffset + i]!, innerW);\n rows[1 + i] = borderL + clipped + borderR;\n }\n\n // Scroll indicator\n if (hasOverflow) {\n const scrollPct = maxScroll > 0 ? Math.round((effectiveOffset / maxScroll) * 100) : 100;\n const indicator = ` ↕ ${scrollPct}% · ${lines.length} lines`;\n const clipped = clipAnsi(`\\x1b[2m${indicator}\\x1b[0m`, innerW);\n rows[1 + viewableH] = borderL + clipped + borderR;\n }\n\n return rows;\n}\n\n/**\n * Build empty panel rows (border only, no content).\n */\nexport function buildEmptyPanelRows(\n rect: Rect,\n focused: boolean,\n borderColor: string,\n centerText?: string,\n): string[] {\n const { w, h } = rect;\n const rows = new Array<string>(h);\n const color = focused ? 'cyan' : 'gray';\n const sgr = `\\x1b[${colorToSGR(color)}m`;\n const reset = '\\x1b[0m';\n const innerW = w - 4;\n const borderL = sgr + '│' + reset + ' ';\n const borderR = ' ' + sgr + '│' + reset;\n const emptyRow = borderL + ' '.repeat(innerW) + borderR;\n\n rows[0] = sgr + '╭' + '─'.repeat(w - 2) + '╮' + reset;\n rows[h - 1] = sgr + '╰' + '─'.repeat(w - 2) + '╯' + reset;\n for (let i = 1; i < h - 1; i++) rows[i] = emptyRow;\n\n if (centerText) {\n const midRow = Math.floor(h / 2);\n if (midRow > 0 && midRow < h - 1) {\n const clipped = clipAnsi(centerText, innerW);\n // Center within panel\n const textW = displayWidthFast(centerText);\n const pad = Math.max(0, Math.floor((innerW - textW) / 2));\n const centered = ' '.repeat(pad) + clipped;\n rows[midRow] = borderL + clipAnsi(centered, innerW) + borderR;\n }\n }\n\n return rows;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\n/**\n * Slice a string (which may contain ANSI escapes) to display columns [start, end).\n * ANSI sequences are passed through only within the slice range.\n */\nfunction sliceDisplayCols(s: string, start: number, end: number, restoreState = false): string {\n let out = '';\n let col = 0;\n let i = 0;\n let inSlice = false;\n let hasOpenSGR = false;\n\n // When restoreState is true, track the last ANSI state before the slice\n // so it can be prepended — restores bg/fg colors that were set earlier in the line.\n let pendingSGR = '';\n\n while (i < s.length && col < end) {\n // ANSI escape: pass through if we're in the slice\n if (s[i] === '\\x1b' && s[i + 1] === '[') {\n const seqLen = ansiLen(s, i);\n if (seqLen > 0) {\n const seq = s.substring(i, i + seqLen);\n if (col >= start) {\n out += seq;\n // Track if we have open SGR (non-reset)\n hasOpenSGR = seq !== '\\x1b[0m' && seq !== '\\x1b[m';\n } else if (restoreState) {\n // Accumulate ANSI state from before the slice\n if (seq === '\\x1b[0m' || seq === '\\x1b[m') {\n pendingSGR = '';\n } else {\n pendingSGR += seq;\n }\n }\n i += seqLen;\n continue;\n }\n }\n\n const cp = s.codePointAt(i)!;\n const ch = String.fromCodePoint(cp);\n const chWidth = cp < 128 ? 1 : stringWidth(ch);\n\n if (col >= start) {\n inSlice = true;\n // Don't emit char that would overflow end\n if (col + chWidth > end) break;\n out += ch;\n }\n\n col += chWidth;\n i += ch.length;\n }\n\n // Close any open SGR\n if (inSlice && hasOpenSGR) {\n out += '\\x1b[0m';\n }\n\n // Prepend accumulated state so suffix inherits the correct colors\n if (restoreState && pendingSGR) {\n out = pendingSGR + out;\n }\n\n return out;\n}\n"],"mappings":"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","names":["key"]}
|