sisyphi 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-6G226ZK7.js +11 -0
- package/dist/chunk-6G226ZK7.js.map +1 -0
- package/dist/{chunk-YGBGKMTF.js → chunk-JXKUI4P6.js} +28 -1
- package/dist/{chunk-YGBGKMTF.js.map → chunk-JXKUI4P6.js.map} +1 -1
- package/dist/chunk-LWWRGQWM.js +87 -0
- package/dist/chunk-LWWRGQWM.js.map +1 -0
- package/dist/{chunk-DBR33QHM.js → chunk-T7ETTIQK.js} +81 -2
- package/dist/chunk-T7ETTIQK.js.map +1 -0
- package/dist/cli.js +241 -133
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +332 -313
- package/dist/daemon.js.map +1 -1
- package/dist/{paths-FYYSBD27.js → paths-NUUALUVP.js} +2 -2
- package/dist/tui.js +828 -836
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-DBR33QHM.js.map +0 -1
- package/dist/chunk-KQBSC5KY.js +0 -31
- package/dist/chunk-KQBSC5KY.js.map +0 -1
- /package/dist/{paths-FYYSBD27.js.map → paths-NUUALUVP.js.map} +0 -0
package/dist/tui.js
CHANGED
|
@@ -1,28 +1,135 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
EXEC_ENV,
|
|
4
|
+
augmentedPath,
|
|
5
|
+
exec,
|
|
6
|
+
execSafe,
|
|
3
7
|
loadConfig
|
|
4
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LWWRGQWM.js";
|
|
5
9
|
import {
|
|
6
10
|
buildSessionContext,
|
|
7
11
|
computeActiveTimeMs,
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
formatDuration,
|
|
13
|
+
rawSend,
|
|
14
|
+
resolveReports,
|
|
15
|
+
statusColor
|
|
16
|
+
} from "./chunk-T7ETTIQK.js";
|
|
10
17
|
import {
|
|
18
|
+
shellQuote
|
|
19
|
+
} from "./chunk-6G226ZK7.js";
|
|
20
|
+
import {
|
|
21
|
+
__commonJS,
|
|
22
|
+
__toESM,
|
|
11
23
|
contextDir,
|
|
12
24
|
globalDir,
|
|
13
25
|
goalPath,
|
|
14
26
|
logsDir,
|
|
15
27
|
roadmapPath,
|
|
16
|
-
sessionDir
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
sessionDir
|
|
29
|
+
} from "./chunk-JXKUI4P6.js";
|
|
30
|
+
|
|
31
|
+
// node_modules/eastasianwidth/eastasianwidth.js
|
|
32
|
+
var require_eastasianwidth = __commonJS({
|
|
33
|
+
"node_modules/eastasianwidth/eastasianwidth.js"(exports, module) {
|
|
34
|
+
"use strict";
|
|
35
|
+
var eaw = {};
|
|
36
|
+
if ("undefined" == typeof module) {
|
|
37
|
+
window.eastasianwidth = eaw;
|
|
38
|
+
} else {
|
|
39
|
+
module.exports = eaw;
|
|
40
|
+
}
|
|
41
|
+
eaw.eastAsianWidth = function(character) {
|
|
42
|
+
var x = character.charCodeAt(0);
|
|
43
|
+
var y = character.length == 2 ? character.charCodeAt(1) : 0;
|
|
44
|
+
var codePoint = x;
|
|
45
|
+
if (55296 <= x && x <= 56319 && (56320 <= y && y <= 57343)) {
|
|
46
|
+
x &= 1023;
|
|
47
|
+
y &= 1023;
|
|
48
|
+
codePoint = x << 10 | y;
|
|
49
|
+
codePoint += 65536;
|
|
50
|
+
}
|
|
51
|
+
if (12288 == codePoint || 65281 <= codePoint && codePoint <= 65376 || 65504 <= codePoint && codePoint <= 65510) {
|
|
52
|
+
return "F";
|
|
53
|
+
}
|
|
54
|
+
if (8361 == codePoint || 65377 <= codePoint && codePoint <= 65470 || 65474 <= codePoint && codePoint <= 65479 || 65482 <= codePoint && codePoint <= 65487 || 65490 <= codePoint && codePoint <= 65495 || 65498 <= codePoint && codePoint <= 65500 || 65512 <= codePoint && codePoint <= 65518) {
|
|
55
|
+
return "H";
|
|
56
|
+
}
|
|
57
|
+
if (4352 <= codePoint && codePoint <= 4447 || 4515 <= codePoint && codePoint <= 4519 || 4602 <= codePoint && codePoint <= 4607 || 9001 <= codePoint && codePoint <= 9002 || 11904 <= codePoint && codePoint <= 11929 || 11931 <= codePoint && codePoint <= 12019 || 12032 <= codePoint && codePoint <= 12245 || 12272 <= codePoint && codePoint <= 12283 || 12289 <= codePoint && codePoint <= 12350 || 12353 <= codePoint && codePoint <= 12438 || 12441 <= codePoint && codePoint <= 12543 || 12549 <= codePoint && codePoint <= 12589 || 12593 <= codePoint && codePoint <= 12686 || 12688 <= codePoint && codePoint <= 12730 || 12736 <= codePoint && codePoint <= 12771 || 12784 <= codePoint && codePoint <= 12830 || 12832 <= codePoint && codePoint <= 12871 || 12880 <= codePoint && codePoint <= 13054 || 13056 <= codePoint && codePoint <= 19903 || 19968 <= codePoint && codePoint <= 42124 || 42128 <= codePoint && codePoint <= 42182 || 43360 <= codePoint && codePoint <= 43388 || 44032 <= codePoint && codePoint <= 55203 || 55216 <= codePoint && codePoint <= 55238 || 55243 <= codePoint && codePoint <= 55291 || 63744 <= codePoint && codePoint <= 64255 || 65040 <= codePoint && codePoint <= 65049 || 65072 <= codePoint && codePoint <= 65106 || 65108 <= codePoint && codePoint <= 65126 || 65128 <= codePoint && codePoint <= 65131 || 110592 <= codePoint && codePoint <= 110593 || 127488 <= codePoint && codePoint <= 127490 || 127504 <= codePoint && codePoint <= 127546 || 127552 <= codePoint && codePoint <= 127560 || 127568 <= codePoint && codePoint <= 127569 || 131072 <= codePoint && codePoint <= 194367 || 177984 <= codePoint && codePoint <= 196605 || 196608 <= codePoint && codePoint <= 262141) {
|
|
58
|
+
return "W";
|
|
59
|
+
}
|
|
60
|
+
if (32 <= codePoint && codePoint <= 126 || 162 <= codePoint && codePoint <= 163 || 165 <= codePoint && codePoint <= 166 || 172 == codePoint || 175 == codePoint || 10214 <= codePoint && codePoint <= 10221 || 10629 <= codePoint && codePoint <= 10630) {
|
|
61
|
+
return "Na";
|
|
62
|
+
}
|
|
63
|
+
if (161 == codePoint || 164 == codePoint || 167 <= codePoint && codePoint <= 168 || 170 == codePoint || 173 <= codePoint && codePoint <= 174 || 176 <= codePoint && codePoint <= 180 || 182 <= codePoint && codePoint <= 186 || 188 <= codePoint && codePoint <= 191 || 198 == codePoint || 208 == codePoint || 215 <= codePoint && codePoint <= 216 || 222 <= codePoint && codePoint <= 225 || 230 == codePoint || 232 <= codePoint && codePoint <= 234 || 236 <= codePoint && codePoint <= 237 || 240 == codePoint || 242 <= codePoint && codePoint <= 243 || 247 <= codePoint && codePoint <= 250 || 252 == codePoint || 254 == codePoint || 257 == codePoint || 273 == codePoint || 275 == codePoint || 283 == codePoint || 294 <= codePoint && codePoint <= 295 || 299 == codePoint || 305 <= codePoint && codePoint <= 307 || 312 == codePoint || 319 <= codePoint && codePoint <= 322 || 324 == codePoint || 328 <= codePoint && codePoint <= 331 || 333 == codePoint || 338 <= codePoint && codePoint <= 339 || 358 <= codePoint && codePoint <= 359 || 363 == codePoint || 462 == codePoint || 464 == codePoint || 466 == codePoint || 468 == codePoint || 470 == codePoint || 472 == codePoint || 474 == codePoint || 476 == codePoint || 593 == codePoint || 609 == codePoint || 708 == codePoint || 711 == codePoint || 713 <= codePoint && codePoint <= 715 || 717 == codePoint || 720 == codePoint || 728 <= codePoint && codePoint <= 731 || 733 == codePoint || 735 == codePoint || 768 <= codePoint && codePoint <= 879 || 913 <= codePoint && codePoint <= 929 || 931 <= codePoint && codePoint <= 937 || 945 <= codePoint && codePoint <= 961 || 963 <= codePoint && codePoint <= 969 || 1025 == codePoint || 1040 <= codePoint && codePoint <= 1103 || 1105 == codePoint || 8208 == codePoint || 8211 <= codePoint && codePoint <= 8214 || 8216 <= codePoint && codePoint <= 8217 || 8220 <= codePoint && codePoint <= 8221 || 8224 <= codePoint && codePoint <= 8226 || 8228 <= codePoint && codePoint <= 8231 || 8240 == codePoint || 8242 <= codePoint && codePoint <= 8243 || 8245 == codePoint || 8251 == codePoint || 8254 == codePoint || 8308 == codePoint || 8319 == codePoint || 8321 <= codePoint && codePoint <= 8324 || 8364 == codePoint || 8451 == codePoint || 8453 == codePoint || 8457 == codePoint || 8467 == codePoint || 8470 == codePoint || 8481 <= codePoint && codePoint <= 8482 || 8486 == codePoint || 8491 == codePoint || 8531 <= codePoint && codePoint <= 8532 || 8539 <= codePoint && codePoint <= 8542 || 8544 <= codePoint && codePoint <= 8555 || 8560 <= codePoint && codePoint <= 8569 || 8585 == codePoint || 8592 <= codePoint && codePoint <= 8601 || 8632 <= codePoint && codePoint <= 8633 || 8658 == codePoint || 8660 == codePoint || 8679 == codePoint || 8704 == codePoint || 8706 <= codePoint && codePoint <= 8707 || 8711 <= codePoint && codePoint <= 8712 || 8715 == codePoint || 8719 == codePoint || 8721 == codePoint || 8725 == codePoint || 8730 == codePoint || 8733 <= codePoint && codePoint <= 8736 || 8739 == codePoint || 8741 == codePoint || 8743 <= codePoint && codePoint <= 8748 || 8750 == codePoint || 8756 <= codePoint && codePoint <= 8759 || 8764 <= codePoint && codePoint <= 8765 || 8776 == codePoint || 8780 == codePoint || 8786 == codePoint || 8800 <= codePoint && codePoint <= 8801 || 8804 <= codePoint && codePoint <= 8807 || 8810 <= codePoint && codePoint <= 8811 || 8814 <= codePoint && codePoint <= 8815 || 8834 <= codePoint && codePoint <= 8835 || 8838 <= codePoint && codePoint <= 8839 || 8853 == codePoint || 8857 == codePoint || 8869 == codePoint || 8895 == codePoint || 8978 == codePoint || 9312 <= codePoint && codePoint <= 9449 || 9451 <= codePoint && codePoint <= 9547 || 9552 <= codePoint && codePoint <= 9587 || 9600 <= codePoint && codePoint <= 9615 || 9618 <= codePoint && codePoint <= 9621 || 9632 <= codePoint && codePoint <= 9633 || 9635 <= codePoint && codePoint <= 9641 || 9650 <= codePoint && codePoint <= 9651 || 9654 <= codePoint && codePoint <= 9655 || 9660 <= codePoint && codePoint <= 9661 || 9664 <= codePoint && codePoint <= 9665 || 9670 <= codePoint && codePoint <= 9672 || 9675 == codePoint || 9678 <= codePoint && codePoint <= 9681 || 9698 <= codePoint && codePoint <= 9701 || 9711 == codePoint || 9733 <= codePoint && codePoint <= 9734 || 9737 == codePoint || 9742 <= codePoint && codePoint <= 9743 || 9748 <= codePoint && codePoint <= 9749 || 9756 == codePoint || 9758 == codePoint || 9792 == codePoint || 9794 == codePoint || 9824 <= codePoint && codePoint <= 9825 || 9827 <= codePoint && codePoint <= 9829 || 9831 <= codePoint && codePoint <= 9834 || 9836 <= codePoint && codePoint <= 9837 || 9839 == codePoint || 9886 <= codePoint && codePoint <= 9887 || 9918 <= codePoint && codePoint <= 9919 || 9924 <= codePoint && codePoint <= 9933 || 9935 <= codePoint && codePoint <= 9953 || 9955 == codePoint || 9960 <= codePoint && codePoint <= 9983 || 10045 == codePoint || 10071 == codePoint || 10102 <= codePoint && codePoint <= 10111 || 11093 <= codePoint && codePoint <= 11097 || 12872 <= codePoint && codePoint <= 12879 || 57344 <= codePoint && codePoint <= 63743 || 65024 <= codePoint && codePoint <= 65039 || 65533 == codePoint || 127232 <= codePoint && codePoint <= 127242 || 127248 <= codePoint && codePoint <= 127277 || 127280 <= codePoint && codePoint <= 127337 || 127344 <= codePoint && codePoint <= 127386 || 917760 <= codePoint && codePoint <= 917999 || 983040 <= codePoint && codePoint <= 1048573 || 1048576 <= codePoint && codePoint <= 1114109) {
|
|
64
|
+
return "A";
|
|
65
|
+
}
|
|
66
|
+
return "N";
|
|
67
|
+
};
|
|
68
|
+
eaw.characterLength = function(character) {
|
|
69
|
+
var code = this.eastAsianWidth(character);
|
|
70
|
+
if (code == "F" || code == "W" || code == "A") {
|
|
71
|
+
return 2;
|
|
72
|
+
} else {
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function stringToArray(string) {
|
|
77
|
+
return string.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
78
|
+
}
|
|
79
|
+
eaw.length = function(string) {
|
|
80
|
+
var characters = stringToArray(string);
|
|
81
|
+
var len = 0;
|
|
82
|
+
for (var i = 0; i < characters.length; i++) {
|
|
83
|
+
len = len + this.characterLength(characters[i]);
|
|
84
|
+
}
|
|
85
|
+
return len;
|
|
86
|
+
};
|
|
87
|
+
eaw.slice = function(text, start, end) {
|
|
88
|
+
textLen = eaw.length(text);
|
|
89
|
+
start = start ? start : 0;
|
|
90
|
+
end = end ? end : 1;
|
|
91
|
+
if (start < 0) {
|
|
92
|
+
start = textLen + start;
|
|
93
|
+
}
|
|
94
|
+
if (end < 0) {
|
|
95
|
+
end = textLen + end;
|
|
96
|
+
}
|
|
97
|
+
var result = "";
|
|
98
|
+
var eawLen = 0;
|
|
99
|
+
var chars = stringToArray(text);
|
|
100
|
+
for (var i = 0; i < chars.length; i++) {
|
|
101
|
+
var char = chars[i];
|
|
102
|
+
var charLen = eaw.length(char);
|
|
103
|
+
if (eawLen >= start - (charLen == 2 ? 1 : 0)) {
|
|
104
|
+
if (eawLen + charLen <= end) {
|
|
105
|
+
result += char;
|
|
106
|
+
} else {
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
eawLen += charLen;
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// node_modules/emoji-regex/index.js
|
|
118
|
+
var require_emoji_regex = __commonJS({
|
|
119
|
+
"node_modules/emoji-regex/index.js"(exports, module) {
|
|
120
|
+
"use strict";
|
|
121
|
+
module.exports = function() {
|
|
122
|
+
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
});
|
|
19
126
|
|
|
20
127
|
// src/tui/index.tsx
|
|
21
128
|
import { render } from "ink";
|
|
22
129
|
|
|
23
130
|
// src/tui/App.tsx
|
|
24
|
-
import { useState as useState4, useEffect as useEffect3, useCallback as useCallback2, useMemo as
|
|
25
|
-
import { Box as
|
|
131
|
+
import { useState as useState4, useEffect as useEffect3, useCallback as useCallback2, useMemo as useMemo6, useRef as useRef3 } from "react";
|
|
132
|
+
import { Box as Box11, Text as Text11, useApp, useStdout } from "ink";
|
|
26
133
|
|
|
27
134
|
// src/tui/components/SessionTree.tsx
|
|
28
135
|
import { Box, Text } from "ink";
|
|
@@ -62,25 +169,70 @@ function isAncestorLastSibling(nodes, index, depth) {
|
|
|
62
169
|
return true;
|
|
63
170
|
}
|
|
64
171
|
|
|
65
|
-
//
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
172
|
+
// node_modules/ansi-regex/index.js
|
|
173
|
+
function ansiRegex({ onlyFirst = false } = {}) {
|
|
174
|
+
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
175
|
+
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
176
|
+
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
|
|
177
|
+
const pattern = `${osc}|${csi}`;
|
|
178
|
+
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// node_modules/strip-ansi/index.js
|
|
182
|
+
var regex = ansiRegex();
|
|
183
|
+
function stripAnsi(string) {
|
|
184
|
+
if (typeof string !== "string") {
|
|
185
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
186
|
+
}
|
|
187
|
+
if (!string.includes("\x1B") && !string.includes("\x9B")) {
|
|
188
|
+
return string;
|
|
189
|
+
}
|
|
190
|
+
return string.replace(regex, "");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// node_modules/string-width/index.js
|
|
194
|
+
var import_eastasianwidth = __toESM(require_eastasianwidth(), 1);
|
|
195
|
+
var import_emoji_regex = __toESM(require_emoji_regex(), 1);
|
|
196
|
+
function stringWidth(string, options = {}) {
|
|
197
|
+
if (typeof string !== "string" || string.length === 0) {
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
options = {
|
|
201
|
+
ambiguousIsNarrow: true,
|
|
202
|
+
...options
|
|
203
|
+
};
|
|
204
|
+
string = stripAnsi(string);
|
|
205
|
+
if (string.length === 0) {
|
|
206
|
+
return 0;
|
|
207
|
+
}
|
|
208
|
+
string = string.replace((0, import_emoji_regex.default)(), " ");
|
|
209
|
+
const ambiguousCharacterWidth = options.ambiguousIsNarrow ? 1 : 2;
|
|
210
|
+
let width = 0;
|
|
211
|
+
for (const character of string) {
|
|
212
|
+
const codePoint = character.codePointAt(0);
|
|
213
|
+
if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (codePoint >= 768 && codePoint <= 879) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const code = import_eastasianwidth.default.eastAsianWidth(character);
|
|
220
|
+
switch (code) {
|
|
221
|
+
case "F":
|
|
222
|
+
case "W":
|
|
223
|
+
width += 2;
|
|
224
|
+
break;
|
|
225
|
+
case "A":
|
|
226
|
+
width += ambiguousCharacterWidth;
|
|
227
|
+
break;
|
|
228
|
+
default:
|
|
229
|
+
width += 1;
|
|
230
|
+
}
|
|
74
231
|
}
|
|
75
|
-
|
|
76
|
-
if (totalSeconds < 0) return "0s";
|
|
77
|
-
const hours = Math.floor(totalSeconds / 3600);
|
|
78
|
-
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
79
|
-
const seconds = totalSeconds % 60;
|
|
80
|
-
if (hours > 0) return `${hours}h${minutes}m`;
|
|
81
|
-
if (minutes > 0) return `${minutes}m${seconds}s`;
|
|
82
|
-
return `${seconds}s`;
|
|
232
|
+
return width;
|
|
83
233
|
}
|
|
234
|
+
|
|
235
|
+
// src/tui/lib/format.ts
|
|
84
236
|
function formatTimeAgo(iso) {
|
|
85
237
|
const diff = Date.now() - new Date(iso).getTime();
|
|
86
238
|
const minutes = Math.floor(diff / 6e4);
|
|
@@ -94,11 +246,20 @@ function formatTime(iso) {
|
|
|
94
246
|
return `${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`;
|
|
95
247
|
}
|
|
96
248
|
function truncate(text, max) {
|
|
97
|
-
|
|
98
|
-
if (
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
249
|
+
const clean = text.replace(/\n/g, " ").replace(/✅/g, "\u2713").replace(/❌/g, "\u2717").replace(new RegExp("\\p{Emoji_Presentation}", "gu"), "");
|
|
250
|
+
if (max < 4) return clean.slice(0, max);
|
|
251
|
+
const w = stringWidth(clean);
|
|
252
|
+
if (w <= max) return clean;
|
|
253
|
+
let result = clean;
|
|
254
|
+
while (stringWidth(result) > max - 1 && result.length > 0) {
|
|
255
|
+
const cut = result.lastIndexOf(" ", result.length - 2);
|
|
256
|
+
if (cut > max * 0.4) {
|
|
257
|
+
result = result.slice(0, cut);
|
|
258
|
+
} else {
|
|
259
|
+
result = result.slice(0, result.length - 1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return result + "\u2026";
|
|
102
263
|
}
|
|
103
264
|
function stripMarkdown(text) {
|
|
104
265
|
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/~~(.+?)~~/g, "$1").replace(/`{1,3}[^`]*`{1,3}/g, "").replace(/^[-*+]\s+/gm, "").replace(/^\d+[.)]\s+/gm, "").replace(/\[(.+?)\]\(.+?\)/g, "$1").replace(/^>\s+/gm, "").replace(/---+/g, "").replace(/\n+/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -137,24 +298,6 @@ function durationColor(startOrMs, endIso) {
|
|
|
137
298
|
if (totalMs < 30 * 60 * 1e3) return "yellow";
|
|
138
299
|
return "red";
|
|
139
300
|
}
|
|
140
|
-
function statusColor(status) {
|
|
141
|
-
switch (status) {
|
|
142
|
-
case "active":
|
|
143
|
-
case "running":
|
|
144
|
-
return "green";
|
|
145
|
-
case "completed":
|
|
146
|
-
return "cyan";
|
|
147
|
-
case "paused":
|
|
148
|
-
return "yellow";
|
|
149
|
-
case "killed":
|
|
150
|
-
case "crashed":
|
|
151
|
-
return "red";
|
|
152
|
-
case "lost":
|
|
153
|
-
return "gray";
|
|
154
|
-
default:
|
|
155
|
-
return "white";
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
301
|
function statusIndicator(status) {
|
|
159
302
|
switch (status) {
|
|
160
303
|
case "active":
|
|
@@ -202,20 +345,42 @@ function stripFrontmatter(content) {
|
|
|
202
345
|
return content.slice(end + 4).trimStart();
|
|
203
346
|
}
|
|
204
347
|
function cleanMarkdown(line) {
|
|
205
|
-
return line.replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/~~(.+?)~~/g, "$1").replace(/`(.+?)`/g, "$1").replace(/\[(.+?)\]\(.+?\)/g, "$1");
|
|
348
|
+
return line.replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/~~(.+?)~~/g, "$1").replace(/`(.+?)`/g, "$1").replace(/\[(.+?)\]\(.+?\)/g, "$1").replace(/✅/g, "\u2713").replace(/❌/g, "\u2717").replace(new RegExp("\\p{Emoji_Presentation}", "gu"), "");
|
|
349
|
+
}
|
|
350
|
+
function seg(text, opts) {
|
|
351
|
+
return { text, ...opts };
|
|
352
|
+
}
|
|
353
|
+
function singleLine(text, opts) {
|
|
354
|
+
return [seg(text, opts)];
|
|
206
355
|
}
|
|
207
356
|
function wrapText(text, width) {
|
|
208
357
|
if (width <= 0) return text.split("\n");
|
|
209
358
|
const result = [];
|
|
210
359
|
for (const rawLine of text.split("\n")) {
|
|
211
|
-
if (rawLine
|
|
360
|
+
if (stringWidth(rawLine) <= width) {
|
|
212
361
|
result.push(rawLine);
|
|
213
362
|
continue;
|
|
214
363
|
}
|
|
215
364
|
let remaining = rawLine;
|
|
216
|
-
while (remaining
|
|
217
|
-
let breakAt =
|
|
218
|
-
|
|
365
|
+
while (stringWidth(remaining) > width) {
|
|
366
|
+
let breakAt = -1;
|
|
367
|
+
let estimate = Math.min(remaining.length, width);
|
|
368
|
+
for (let i = estimate; i >= 0; i--) {
|
|
369
|
+
if (remaining[i] === " " && stringWidth(remaining.slice(0, i)) <= width) {
|
|
370
|
+
breakAt = i;
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (breakAt <= 0) {
|
|
375
|
+
breakAt = remaining.length;
|
|
376
|
+
for (let i = 1; i <= remaining.length; i++) {
|
|
377
|
+
if (stringWidth(remaining.slice(0, i)) > width) {
|
|
378
|
+
breakAt = i - 1;
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (breakAt <= 0) breakAt = 1;
|
|
383
|
+
}
|
|
219
384
|
result.push(remaining.slice(0, breakAt));
|
|
220
385
|
remaining = remaining.slice(breakAt).trimStart();
|
|
221
386
|
}
|
|
@@ -239,12 +404,13 @@ function SessionTree({ nodes, cursorIndex, width, height, focused }) {
|
|
|
239
404
|
children: [
|
|
240
405
|
/* @__PURE__ */ jsx(Text, { bold: true, children: " Sessions " }),
|
|
241
406
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "No sessions found." }),
|
|
242
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press [n] to create one." })
|
|
407
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press [n] to create one." }),
|
|
408
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press [?] for all keybindings." })
|
|
243
409
|
]
|
|
244
410
|
}
|
|
245
411
|
);
|
|
246
412
|
}
|
|
247
|
-
const maxVisible = Math.max(1, height -
|
|
413
|
+
const maxVisible = Math.max(1, height - 4);
|
|
248
414
|
const halfVisible = Math.floor(maxVisible / 2);
|
|
249
415
|
const scrollOffset = Math.max(
|
|
250
416
|
0,
|
|
@@ -375,20 +541,22 @@ function renderNodeContent(node, maxWidth) {
|
|
|
375
541
|
color: "white",
|
|
376
542
|
dim: node.fileCount === 0
|
|
377
543
|
};
|
|
378
|
-
case "context-file":
|
|
544
|
+
case "context-file": {
|
|
545
|
+
const maxLabel = Math.max(8, maxWidth - 4);
|
|
379
546
|
return {
|
|
380
547
|
icon: "\xB7",
|
|
381
|
-
label: node.label,
|
|
548
|
+
label: truncate(node.label, maxLabel),
|
|
382
549
|
meta: "",
|
|
383
550
|
color: "gray",
|
|
384
551
|
dim: false
|
|
385
552
|
};
|
|
553
|
+
}
|
|
386
554
|
}
|
|
387
555
|
}
|
|
388
556
|
|
|
389
557
|
// src/tui/components/SessionDetail.tsx
|
|
390
558
|
import { useMemo } from "react";
|
|
391
|
-
import { Box as
|
|
559
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
392
560
|
|
|
393
561
|
// src/tui/components/PlanView.tsx
|
|
394
562
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
@@ -468,15 +636,53 @@ function buildPlanLines(content, maxLines, width) {
|
|
|
468
636
|
return lines;
|
|
469
637
|
}
|
|
470
638
|
|
|
471
|
-
// src/tui/components/
|
|
639
|
+
// src/tui/components/ScrollablePanel.tsx
|
|
640
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
472
641
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
473
|
-
function
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
642
|
+
function ScrollablePanel({
|
|
643
|
+
lines,
|
|
644
|
+
width,
|
|
645
|
+
height,
|
|
646
|
+
scrollOffset = 0,
|
|
647
|
+
focused = false,
|
|
648
|
+
borderColor = "gray"
|
|
649
|
+
}) {
|
|
650
|
+
const innerHeight = height - 2;
|
|
651
|
+
const hasOverflow = lines.length > innerHeight;
|
|
652
|
+
const viewableHeight = hasOverflow ? innerHeight - 1 : innerHeight;
|
|
653
|
+
const maxScroll = Math.max(0, lines.length - viewableHeight);
|
|
654
|
+
const effectiveOffset = Math.min(scrollOffset, maxScroll);
|
|
655
|
+
const visible = lines.slice(effectiveOffset, effectiveOffset + viewableHeight);
|
|
656
|
+
const padCount = Math.max(0, viewableHeight - visible.length);
|
|
657
|
+
const scrollPct = maxScroll > 0 ? Math.round(effectiveOffset / maxScroll * 100) : 100;
|
|
658
|
+
return /* @__PURE__ */ jsxs2(
|
|
659
|
+
Box3,
|
|
660
|
+
{
|
|
661
|
+
flexDirection: "column",
|
|
662
|
+
width,
|
|
663
|
+
overflow: "hidden",
|
|
664
|
+
borderStyle: "round",
|
|
665
|
+
borderColor: focused ? "blue" : borderColor,
|
|
666
|
+
paddingX: 1,
|
|
667
|
+
children: [
|
|
668
|
+
visible.map((segs, i) => /* @__PURE__ */ jsx3(Text3, { children: segs.map((s, j) => /* @__PURE__ */ jsx3(Text3, { color: s.color, bold: s.bold, dimColor: s.dim, italic: s.italic, children: s.text }, j)) }, i)),
|
|
669
|
+
padCount > 0 && Array.from({ length: padCount }, (_, i) => /* @__PURE__ */ jsx3(Text3, { children: " " }, `p${i}`)),
|
|
670
|
+
hasOverflow && /* @__PURE__ */ jsxs2(Text3, { dimColor: true, children: [
|
|
671
|
+
" ",
|
|
672
|
+
"\u2195 ",
|
|
673
|
+
scrollPct,
|
|
674
|
+
"% \xB7 ",
|
|
675
|
+
lines.length,
|
|
676
|
+
" lines"
|
|
677
|
+
] })
|
|
678
|
+
]
|
|
679
|
+
}
|
|
680
|
+
);
|
|
478
681
|
}
|
|
479
|
-
|
|
682
|
+
|
|
683
|
+
// src/tui/components/SessionDetail.tsx
|
|
684
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
685
|
+
function buildLines(session, planContent, goalContent, _logsContent, width, paneAlive) {
|
|
480
686
|
const lines = [];
|
|
481
687
|
const contentWidth = width - 4;
|
|
482
688
|
const agents = session.agents ?? [];
|
|
@@ -486,7 +692,7 @@ function buildLines(session, planContent, goalContent, logsContent, width, paneA
|
|
|
486
692
|
const conflicts = agents.filter((a) => a.mergeStatus === "conflict");
|
|
487
693
|
const goalText = goalContent ? cleanMarkdown(stripFrontmatter(goalContent).trim()) : session.task;
|
|
488
694
|
goalText.split("\n").flatMap((l) => wrapText(l, contentWidth - 2)).forEach((line, i) => {
|
|
489
|
-
lines.push(
|
|
695
|
+
lines.push(singleLine(`${i === 0 ? " " : " "}${line}`, { bold: true }));
|
|
490
696
|
});
|
|
491
697
|
const lastCycle = cycles.length > 0 ? cycles[cycles.length - 1] : null;
|
|
492
698
|
const cycleNum = lastCycle?.cycle ?? 0;
|
|
@@ -519,34 +725,40 @@ function buildLines(session, planContent, goalContent, logsContent, width, paneA
|
|
|
519
725
|
}
|
|
520
726
|
if (conflicts.length > 0) {
|
|
521
727
|
lines.push(
|
|
522
|
-
|
|
728
|
+
singleLine(
|
|
523
729
|
` \u26A0 ${conflicts.length} merge conflict${conflicts.length > 1 ? "s" : ""}`,
|
|
524
730
|
{ color: "red", bold: true }
|
|
525
731
|
)
|
|
526
732
|
);
|
|
733
|
+
lines.push(
|
|
734
|
+
singleLine(
|
|
735
|
+
" resolve in worktree, then [x] restart agent",
|
|
736
|
+
{ color: "red", dim: true }
|
|
737
|
+
)
|
|
738
|
+
);
|
|
527
739
|
}
|
|
528
|
-
lines.push(
|
|
740
|
+
lines.push(singleLine(" "));
|
|
529
741
|
lines.push([
|
|
530
742
|
seg(" \u258E \u25C8 PLAN", { color: "yellow", bold: true })
|
|
531
743
|
]);
|
|
532
744
|
const planLines = buildPlanLines(planContent, 99999, width);
|
|
533
745
|
if (planLines.length === 0) {
|
|
534
|
-
lines.push(
|
|
746
|
+
lines.push(singleLine(" orchestrator will create one", { dim: true, italic: true }));
|
|
535
747
|
} else {
|
|
536
748
|
for (const pl of planLines) {
|
|
537
|
-
lines.push(
|
|
749
|
+
lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));
|
|
538
750
|
}
|
|
539
751
|
}
|
|
540
752
|
if (session.status === "completed" && session.completionReport) {
|
|
541
|
-
lines.push(
|
|
753
|
+
lines.push(singleLine(" "));
|
|
542
754
|
lines.push([seg(" \u258E \u2713 COMPLETION", { color: "cyan", bold: true })]);
|
|
543
755
|
wrapText(cleanMarkdown(session.completionReport), contentWidth - 6).forEach(
|
|
544
756
|
(l) => {
|
|
545
|
-
lines.push(
|
|
757
|
+
lines.push(singleLine(` ${l}`, { dim: true }));
|
|
546
758
|
}
|
|
547
759
|
);
|
|
548
760
|
}
|
|
549
|
-
lines.push(
|
|
761
|
+
lines.push(singleLine(" "));
|
|
550
762
|
lines.push([
|
|
551
763
|
seg(" \u258E \u27F3 CYCLES", { color: "blue", bold: true }),
|
|
552
764
|
seg(` (${cycles.length})`, { dim: true })
|
|
@@ -564,7 +776,7 @@ function buildLines(session, planContent, goalContent, logsContent, width, paneA
|
|
|
564
776
|
]);
|
|
565
777
|
};
|
|
566
778
|
if (cycles.length === 0) {
|
|
567
|
-
lines.push(
|
|
779
|
+
lines.push(singleLine(" waiting for orchestrator\u2026", { dim: true, italic: true }));
|
|
568
780
|
} else {
|
|
569
781
|
const sortedMsgs = [...messages].sort(
|
|
570
782
|
(a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
|
@@ -646,8 +858,8 @@ function SessionDetail({
|
|
|
646
858
|
focused = false
|
|
647
859
|
}) {
|
|
648
860
|
if (!session) {
|
|
649
|
-
return /* @__PURE__ */
|
|
650
|
-
|
|
861
|
+
return /* @__PURE__ */ jsx4(
|
|
862
|
+
Box4,
|
|
651
863
|
{
|
|
652
864
|
flexDirection: "column",
|
|
653
865
|
width,
|
|
@@ -656,7 +868,7 @@ function SessionDetail({
|
|
|
656
868
|
paddingX: 1,
|
|
657
869
|
justifyContent: "center",
|
|
658
870
|
alignItems: "center",
|
|
659
|
-
children: /* @__PURE__ */
|
|
871
|
+
children: /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Select a session to view details" })
|
|
660
872
|
}
|
|
661
873
|
);
|
|
662
874
|
}
|
|
@@ -664,55 +876,22 @@ function SessionDetail({
|
|
|
664
876
|
() => buildLines(session, planContent, goalContent, logsContent, width, paneAlive),
|
|
665
877
|
[session, planContent, goalContent, logsContent, width, paneAlive]
|
|
666
878
|
);
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
const viewableHeight = hasOverflow ? innerHeight - 1 : innerHeight;
|
|
670
|
-
const maxScroll = Math.max(0, allLines.length - viewableHeight);
|
|
671
|
-
const effectiveOffset = Math.min(scrollOffset, maxScroll);
|
|
672
|
-
const visible = allLines.slice(effectiveOffset, effectiveOffset + viewableHeight);
|
|
673
|
-
const padCount = viewableHeight - visible.length;
|
|
674
|
-
const scrollPct = maxScroll > 0 ? Math.round(effectiveOffset / maxScroll * 100) : 100;
|
|
675
|
-
return /* @__PURE__ */ jsxs2(
|
|
676
|
-
Box3,
|
|
879
|
+
return /* @__PURE__ */ jsx4(
|
|
880
|
+
ScrollablePanel,
|
|
677
881
|
{
|
|
678
|
-
|
|
882
|
+
lines: allLines,
|
|
679
883
|
width,
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
children: [
|
|
684
|
-
visible.map((line, i) => /* @__PURE__ */ jsx3(Text3, { children: line.map((s, j) => /* @__PURE__ */ jsx3(
|
|
685
|
-
Text3,
|
|
686
|
-
{
|
|
687
|
-
color: s.color,
|
|
688
|
-
bold: s.bold,
|
|
689
|
-
dimColor: s.dim,
|
|
690
|
-
italic: s.italic,
|
|
691
|
-
children: s.text
|
|
692
|
-
},
|
|
693
|
-
j
|
|
694
|
-
)) }, effectiveOffset + i)),
|
|
695
|
-
padCount > 0 && Array.from({ length: padCount }, (_, i) => /* @__PURE__ */ jsx3(Text3, { children: " " }, `pad-${i}`)),
|
|
696
|
-
hasOverflow && /* @__PURE__ */ jsxs2(Text3, { dimColor: true, children: [
|
|
697
|
-
" ",
|
|
698
|
-
"[tab] scroll \xB7 ",
|
|
699
|
-
scrollPct,
|
|
700
|
-
"% \xB7 ",
|
|
701
|
-
allLines.length,
|
|
702
|
-
" lines"
|
|
703
|
-
] })
|
|
704
|
-
]
|
|
884
|
+
height,
|
|
885
|
+
scrollOffset,
|
|
886
|
+
focused
|
|
705
887
|
}
|
|
706
888
|
);
|
|
707
889
|
}
|
|
708
890
|
|
|
709
891
|
// src/tui/components/LogsPanel.tsx
|
|
710
892
|
import { useMemo as useMemo2 } from "react";
|
|
711
|
-
import { Box as
|
|
712
|
-
import { jsx as
|
|
713
|
-
function seg2(text, opts) {
|
|
714
|
-
return { text, ...opts };
|
|
715
|
-
}
|
|
893
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
894
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
716
895
|
function buildLines2(cycleLogs, width) {
|
|
717
896
|
const lines = [];
|
|
718
897
|
const contentWidth = width - 4;
|
|
@@ -721,17 +900,17 @@ function buildLines2(cycleLogs, width) {
|
|
|
721
900
|
}
|
|
722
901
|
const sorted = [...cycleLogs].sort((a, b) => b.cycle - a.cycle);
|
|
723
902
|
for (const { cycle, content } of sorted) {
|
|
724
|
-
lines.push([
|
|
903
|
+
lines.push([seg(` Cycle ${cycle}`, { color: "blue", bold: true })]);
|
|
725
904
|
const cleaned = cleanMarkdown(stripFrontmatter(content)).trim();
|
|
726
905
|
if (cleaned) {
|
|
727
906
|
for (const rawLine of cleaned.split("\n")) {
|
|
728
907
|
const wrapped = wrapText(rawLine, contentWidth - 2);
|
|
729
908
|
for (const wl of wrapped) {
|
|
730
|
-
lines.push([
|
|
909
|
+
lines.push([seg(` ${wl}`, { dim: true })]);
|
|
731
910
|
}
|
|
732
911
|
}
|
|
733
912
|
}
|
|
734
|
-
lines.push([
|
|
913
|
+
lines.push([seg(" ")]);
|
|
735
914
|
}
|
|
736
915
|
return lines;
|
|
737
916
|
}
|
|
@@ -743,8 +922,8 @@ function LogsPanel({
|
|
|
743
922
|
focused = false
|
|
744
923
|
}) {
|
|
745
924
|
if (cycleLogs.length === 0) {
|
|
746
|
-
return /* @__PURE__ */
|
|
747
|
-
|
|
925
|
+
return /* @__PURE__ */ jsx5(
|
|
926
|
+
Box5,
|
|
748
927
|
{
|
|
749
928
|
flexDirection: "column",
|
|
750
929
|
width,
|
|
@@ -753,7 +932,7 @@ function LogsPanel({
|
|
|
753
932
|
paddingX: 1,
|
|
754
933
|
justifyContent: "center",
|
|
755
934
|
alignItems: "center",
|
|
756
|
-
children: /* @__PURE__ */
|
|
935
|
+
children: /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "No logs" })
|
|
757
936
|
}
|
|
758
937
|
);
|
|
759
938
|
}
|
|
@@ -761,316 +940,235 @@ function LogsPanel({
|
|
|
761
940
|
() => buildLines2(cycleLogs, width),
|
|
762
941
|
[cycleLogs, width]
|
|
763
942
|
);
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
const viewableHeight = hasOverflow ? innerHeight - 1 : innerHeight;
|
|
767
|
-
const maxScroll = Math.max(0, allLines.length - viewableHeight);
|
|
768
|
-
const effectiveOffset = Math.min(scrollOffset, maxScroll);
|
|
769
|
-
const visible = allLines.slice(effectiveOffset, effectiveOffset + viewableHeight);
|
|
770
|
-
const padCount = viewableHeight - visible.length;
|
|
771
|
-
const scrollPct = maxScroll > 0 ? Math.round(effectiveOffset / maxScroll * 100) : 100;
|
|
772
|
-
return /* @__PURE__ */ jsxs3(
|
|
773
|
-
Box4,
|
|
943
|
+
return /* @__PURE__ */ jsx5(
|
|
944
|
+
ScrollablePanel,
|
|
774
945
|
{
|
|
775
|
-
|
|
946
|
+
lines: allLines,
|
|
776
947
|
width,
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
children: [
|
|
781
|
-
visible.map((line, i) => /* @__PURE__ */ jsx4(Text4, { children: line.map((s, j) => /* @__PURE__ */ jsx4(Text4, { color: s.color, bold: s.bold, dimColor: s.dim, children: s.text }, j)) }, effectiveOffset + i)),
|
|
782
|
-
padCount > 0 && Array.from({ length: padCount }, (_, i) => /* @__PURE__ */ jsx4(Text4, { children: " " }, `pad-${i}`)),
|
|
783
|
-
hasOverflow && /* @__PURE__ */ jsxs3(Text4, { dimColor: true, children: [
|
|
784
|
-
" ",
|
|
785
|
-
"[tab] scroll \xB7 ",
|
|
786
|
-
scrollPct,
|
|
787
|
-
"% \xB7 ",
|
|
788
|
-
allLines.length,
|
|
789
|
-
" lines"
|
|
790
|
-
] })
|
|
791
|
-
]
|
|
948
|
+
height,
|
|
949
|
+
scrollOffset,
|
|
950
|
+
focused
|
|
792
951
|
}
|
|
793
952
|
);
|
|
794
953
|
}
|
|
795
954
|
|
|
796
955
|
// src/tui/components/CycleDetail.tsx
|
|
797
|
-
import {
|
|
798
|
-
import {
|
|
799
|
-
function
|
|
956
|
+
import { useMemo as useMemo3 } from "react";
|
|
957
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
958
|
+
function buildLines3(cycle, agents, width) {
|
|
959
|
+
const lines = [];
|
|
800
960
|
const contentWidth = width - 4;
|
|
801
|
-
const dur = cycle.completedAt ? formatDuration(cycle.timestamp, cycle.completedAt) : "running";
|
|
802
961
|
const isRunning = !cycle.completedAt;
|
|
962
|
+
const dur = cycle.completedAt ? formatDuration(cycle.timestamp, cycle.completedAt) : "running";
|
|
803
963
|
const cycleAgents = agents.filter((a) => cycle.agentsSpawned.includes(a.id));
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
964
|
+
lines.push(singleLine(` Cycle ${cycle.cycle}`, { bold: true }));
|
|
965
|
+
lines.push([
|
|
966
|
+
seg(" "),
|
|
967
|
+
seg(isRunning ? "running" : "completed", { color: isRunning ? "green" : "gray" }),
|
|
968
|
+
seg(` \xB7 ${dur} \xB7 ${cycleAgents.length} agent${cycleAgents.length !== 1 ? "s" : ""}`, { dim: true }),
|
|
969
|
+
...cycle.mode ? [
|
|
970
|
+
seg(" \xB7 ", { dim: true }),
|
|
971
|
+
seg(cycle.mode, {
|
|
972
|
+
color: cycle.mode === "planning" ? "blue" : cycle.mode === "implementation" ? "green" : "cyan"
|
|
973
|
+
})
|
|
974
|
+
] : []
|
|
975
|
+
]);
|
|
976
|
+
lines.push(singleLine(
|
|
977
|
+
` ${formatTime(cycle.timestamp)}${cycle.completedAt ? ` \u2192 ${formatTime(cycle.completedAt)}` : ""}`,
|
|
978
|
+
{ dim: true }
|
|
979
|
+
));
|
|
980
|
+
lines.push(singleLine(" "));
|
|
981
|
+
lines.push([seg(" \u258E \u229E AGENTS", { color: "green", bold: true })]);
|
|
982
|
+
if (cycleAgents.length === 0) {
|
|
983
|
+
lines.push(singleLine(" orchestrator spawning agents\u2026", { dim: true, italic: true }));
|
|
984
|
+
} else {
|
|
985
|
+
for (const agent of cycleAgents) {
|
|
986
|
+
const nameLabel = agent.name !== agent.id ? agent.name : agent.agentType;
|
|
987
|
+
const instrPreview = agent.instruction.split("\n")[0] || "";
|
|
988
|
+
const latestReport = agent.reports.length > 0 ? agent.reports[agent.reports.length - 1] : null;
|
|
989
|
+
const reportSummary = latestReport && agent.status === "completed" ? extractFirstSentence(latestReport.summary, contentWidth - 14) : null;
|
|
990
|
+
const agentDur = formatDuration(agent.spawnedAt, agent.completedAt);
|
|
991
|
+
const durClr = durationColor(agent.spawnedAt, agent.completedAt) || void 0;
|
|
992
|
+
lines.push([
|
|
993
|
+
seg(" "),
|
|
994
|
+
seg(agentStatusIcon(agent.status), { color: statusColor(agent.status) }),
|
|
995
|
+
seg(` ${agent.id}`, { bold: true }),
|
|
996
|
+
seg(` ${truncate(nameLabel, contentWidth - 30)}`, {
|
|
997
|
+
color: agentTypeColor(agent.agentType) || void 0,
|
|
998
|
+
dim: !agentTypeColor(agent.agentType)
|
|
999
|
+
}),
|
|
1000
|
+
seg(` \xB7 ${agent.status} \xB7 `, { dim: true }),
|
|
1001
|
+
seg(agentDur, { color: durClr, dim: !durClr })
|
|
1002
|
+
]);
|
|
1003
|
+
if (instrPreview) {
|
|
1004
|
+
lines.push(singleLine(` ${truncate(instrPreview, contentWidth - 10)}`, { dim: true }));
|
|
1005
|
+
}
|
|
1006
|
+
if (reportSummary) {
|
|
1007
|
+
lines.push([
|
|
1008
|
+
seg(" "),
|
|
1009
|
+
seg("\u21B3", { color: "cyan" }),
|
|
1010
|
+
seg(` ${reportSummary}`, { dim: true })
|
|
1011
|
+
]);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
if (cycle.nextPrompt) {
|
|
1016
|
+
lines.push(singleLine(" "));
|
|
1017
|
+
lines.push([seg(" \u258E \u25B7 NEXT PROMPT", { color: "yellow", bold: true })]);
|
|
1018
|
+
for (const wl of wrapText(cycle.nextPrompt, contentWidth - 6)) {
|
|
1019
|
+
lines.push(singleLine(` ${wl}`, { dim: true }));
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return lines;
|
|
1023
|
+
}
|
|
1024
|
+
function CycleDetail({ cycle, agents, width, height, scrollOffset = 0, focused = false }) {
|
|
1025
|
+
const allLines = useMemo3(
|
|
1026
|
+
() => buildLines3(cycle, agents, width),
|
|
1027
|
+
[cycle, agents, width]
|
|
1028
|
+
);
|
|
1029
|
+
return /* @__PURE__ */ jsx6(
|
|
1030
|
+
ScrollablePanel,
|
|
815
1031
|
{
|
|
816
|
-
|
|
1032
|
+
lines: allLines,
|
|
817
1033
|
width,
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
children: [
|
|
822
|
-
/* @__PURE__ */ jsxs4(Text5, { bold: true, children: [
|
|
823
|
-
" Cycle ",
|
|
824
|
-
cycle.cycle
|
|
825
|
-
] }),
|
|
826
|
-
/* @__PURE__ */ jsxs4(Box5, { children: [
|
|
827
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " " }),
|
|
828
|
-
/* @__PURE__ */ jsx5(Text5, { color: isRunning ? "green" : "gray", children: isRunning ? "running" : "completed" }),
|
|
829
|
-
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
830
|
-
" \xB7 ",
|
|
831
|
-
dur,
|
|
832
|
-
" \xB7 ",
|
|
833
|
-
cycleAgents.length,
|
|
834
|
-
" agent",
|
|
835
|
-
cycleAgents.length !== 1 ? "s" : "",
|
|
836
|
-
cycle.mode ? " \xB7 " : ""
|
|
837
|
-
] }),
|
|
838
|
-
cycle.mode && /* @__PURE__ */ jsx5(Text5, { color: cycle.mode === "planning" ? "blue" : cycle.mode === "implementation" ? "green" : "cyan", children: cycle.mode })
|
|
839
|
-
] }),
|
|
840
|
-
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
841
|
-
" ",
|
|
842
|
-
formatTime(cycle.timestamp),
|
|
843
|
-
cycle.completedAt ? ` \u2192 ${formatTime(cycle.completedAt)}` : ""
|
|
844
|
-
] }),
|
|
845
|
-
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
846
|
-
/* @__PURE__ */ jsxs4(Text5, { color: "green", bold: true, children: [
|
|
847
|
-
" ",
|
|
848
|
-
"\u258E \u229E AGENTS"
|
|
849
|
-
] }),
|
|
850
|
-
cycleAgents.length === 0 ? /* @__PURE__ */ jsxs4(Text5, { dimColor: true, italic: true, children: [
|
|
851
|
-
" ",
|
|
852
|
-
"orchestrator spawning agents\u2026"
|
|
853
|
-
] }) : cycleAgents.map((agent) => {
|
|
854
|
-
const nameLabel = agent.name !== agent.id ? agent.name : agent.agentType;
|
|
855
|
-
const instrPreview = agent.instruction.split("\n")[0] || "";
|
|
856
|
-
const latestReport = agent.reports.length > 0 ? agent.reports[agent.reports.length - 1] : null;
|
|
857
|
-
const reportSummary = latestReport && agent.status === "completed" ? extractFirstSentence(latestReport.summary, contentWidth - 14) : null;
|
|
858
|
-
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
859
|
-
/* @__PURE__ */ jsxs4(Box5, { children: [
|
|
860
|
-
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
861
|
-
/* @__PURE__ */ jsx5(Text5, { color: statusColor(agent.status), children: agentStatusIcon(agent.status) }),
|
|
862
|
-
/* @__PURE__ */ jsxs4(Text5, { bold: true, children: [
|
|
863
|
-
" ",
|
|
864
|
-
agent.id
|
|
865
|
-
] }),
|
|
866
|
-
/* @__PURE__ */ jsxs4(Text5, { color: agentTypeColor(agent.agentType), dimColor: !agentTypeColor(agent.agentType), children: [
|
|
867
|
-
" ",
|
|
868
|
-
truncate(nameLabel, contentWidth - 30)
|
|
869
|
-
] }),
|
|
870
|
-
(() => {
|
|
871
|
-
const dur2 = formatDuration(agent.spawnedAt, agent.completedAt);
|
|
872
|
-
const durColor = durationColor(agent.spawnedAt, agent.completedAt) || void 0;
|
|
873
|
-
return /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
874
|
-
" \xB7 ",
|
|
875
|
-
agent.status,
|
|
876
|
-
" \xB7 ",
|
|
877
|
-
/* @__PURE__ */ jsx5(Text5, { color: durColor, children: dur2 })
|
|
878
|
-
] });
|
|
879
|
-
})()
|
|
880
|
-
] }),
|
|
881
|
-
instrPreview && /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
882
|
-
" ",
|
|
883
|
-
truncate(instrPreview, contentWidth - 10)
|
|
884
|
-
] }),
|
|
885
|
-
reportSummary && /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
886
|
-
" ",
|
|
887
|
-
/* @__PURE__ */ jsx5(Text5, { color: "cyan", children: "\u21B3" }),
|
|
888
|
-
" ",
|
|
889
|
-
reportSummary
|
|
890
|
-
] })
|
|
891
|
-
] }, agent.id);
|
|
892
|
-
}),
|
|
893
|
-
cycle.nextPrompt && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
894
|
-
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
895
|
-
/* @__PURE__ */ jsxs4(Text5, { color: "yellow", bold: true, children: [
|
|
896
|
-
" ",
|
|
897
|
-
"\u258E \u25B7 NEXT PROMPT"
|
|
898
|
-
] }),
|
|
899
|
-
wrapText(cycle.nextPrompt, contentWidth - 6).slice(0, Math.max(3, promptAvailable)).map((line, i) => /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
900
|
-
" ",
|
|
901
|
-
line
|
|
902
|
-
] }, i))
|
|
903
|
-
] })
|
|
904
|
-
]
|
|
1034
|
+
height,
|
|
1035
|
+
scrollOffset,
|
|
1036
|
+
focused
|
|
905
1037
|
}
|
|
906
1038
|
);
|
|
907
1039
|
}
|
|
908
1040
|
|
|
909
1041
|
// src/tui/components/AgentDetail.tsx
|
|
910
|
-
import {
|
|
911
|
-
import {
|
|
912
|
-
function
|
|
1042
|
+
import { useMemo as useMemo4 } from "react";
|
|
1043
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1044
|
+
function buildLines4(agent, reportBlocks, width) {
|
|
1045
|
+
const lines = [];
|
|
913
1046
|
const contentWidth = width - 4;
|
|
914
1047
|
const dur = formatDuration(agent.spawnedAt, agent.completedAt);
|
|
915
1048
|
const icon = agentStatusIcon(agent.status);
|
|
916
1049
|
const color = statusColor(agent.status);
|
|
917
1050
|
const nameLabel = agent.name !== agent.id ? agent.name : agent.agentType;
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
const
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1051
|
+
const maxMergeLines = 3;
|
|
1052
|
+
lines.push([
|
|
1053
|
+
seg(" "),
|
|
1054
|
+
seg(icon, { color }),
|
|
1055
|
+
seg(` ${agent.id} \xB7 ${nameLabel}`, { bold: true })
|
|
1056
|
+
]);
|
|
1057
|
+
const mergeSegs = [];
|
|
1058
|
+
if (agent.mergeStatus) {
|
|
1059
|
+
mergeSegs.push(seg(" \xB7 ", { dim: true }));
|
|
1060
|
+
switch (agent.mergeStatus) {
|
|
1061
|
+
case "merged":
|
|
1062
|
+
mergeSegs.push(seg("\u2295 merged", { color: "green" }));
|
|
1063
|
+
break;
|
|
1064
|
+
case "pending":
|
|
1065
|
+
mergeSegs.push(seg("\u25CC pending", { color: "yellow" }));
|
|
1066
|
+
break;
|
|
1067
|
+
case "no-changes":
|
|
1068
|
+
mergeSegs.push(seg("\u2205 no changes", { color: "gray" }));
|
|
1069
|
+
break;
|
|
1070
|
+
case "conflict":
|
|
1071
|
+
mergeSegs.push(seg("\u26A0 conflict", { color: "red" }));
|
|
1072
|
+
break;
|
|
1073
|
+
default:
|
|
1074
|
+
mergeSegs.push(seg(agent.mergeStatus, { dim: true }));
|
|
1075
|
+
}
|
|
934
1076
|
}
|
|
935
|
-
|
|
936
|
-
|
|
1077
|
+
lines.push([
|
|
1078
|
+
seg(" "),
|
|
1079
|
+
seg(agent.status, { color }),
|
|
1080
|
+
seg(` \xB7 ${dur} \xB7 ${agent.agentType}`, { dim: true }),
|
|
1081
|
+
...mergeSegs
|
|
1082
|
+
]);
|
|
1083
|
+
if (agent.killedReason) {
|
|
1084
|
+
lines.push(singleLine(` \u26A0 ${agent.killedReason}`, { color: "red" }));
|
|
1085
|
+
}
|
|
1086
|
+
if (agent.mergeStatus === "conflict" && agent.mergeDetails) {
|
|
1087
|
+
for (const ml of wrapText(agent.mergeDetails, contentWidth - 6).slice(0, maxMergeLines)) {
|
|
1088
|
+
lines.push(singleLine(` \u26A0 ${ml}`, { color: "red" }));
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
if (agent.mergeStatus === "conflict") {
|
|
1092
|
+
lines.push(singleLine(" resolve conflicts in worktree dir, then restart", { color: "red", dim: true }));
|
|
1093
|
+
}
|
|
1094
|
+
lines.push(singleLine(" "));
|
|
1095
|
+
lines.push(singleLine(" \u258E \u25B7 INSTRUCTION", { color: "white", bold: true }));
|
|
1096
|
+
for (const wl of wrapText(agent.instruction, contentWidth - 6)) {
|
|
1097
|
+
lines.push(singleLine(` ${wl}`, { dim: true }));
|
|
1098
|
+
}
|
|
1099
|
+
if (agent.reports.length > 0) {
|
|
1100
|
+
const hasResolved = reportBlocks && reportBlocks.length > 0;
|
|
1101
|
+
lines.push(singleLine(" "));
|
|
1102
|
+
lines.push([seg(` \u258E \u25C7 REPORTS (${agent.reports.length})`, { color: "cyan", bold: true })]);
|
|
1103
|
+
if (hasResolved) {
|
|
1104
|
+
for (let i = 0; i < reportBlocks.length; i++) {
|
|
1105
|
+
const block = reportBlocks[i];
|
|
1106
|
+
const badge = block.type === "final" ? "FINAL" : "UPDATE";
|
|
1107
|
+
const badgeColor = block.type === "final" ? "cyan" : "yellow";
|
|
1108
|
+
if (i > 0) lines.push(singleLine(" "));
|
|
1109
|
+
lines.push([
|
|
1110
|
+
seg(" "),
|
|
1111
|
+
seg(badge, { color: badgeColor, bold: block.type === "final" }),
|
|
1112
|
+
seg(` ${formatTime(block.timestamp)}`, { dim: true })
|
|
1113
|
+
]);
|
|
1114
|
+
for (const wl of wrapText(cleanMarkdown(block.content.trim()), contentWidth - 10)) {
|
|
1115
|
+
lines.push(singleLine(` ${wl}`, { dim: true }));
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
} else {
|
|
1119
|
+
for (const report of agent.reports) {
|
|
1120
|
+
const badge = report.type === "final" ? "FINAL" : "UPDATE";
|
|
1121
|
+
const badgeColor = report.type === "final" ? "cyan" : "yellow";
|
|
1122
|
+
lines.push([
|
|
1123
|
+
seg(" "),
|
|
1124
|
+
seg(badge, { color: badgeColor, bold: report.type === "final" }),
|
|
1125
|
+
seg(` ${formatTime(report.timestamp)} ${report.summary.split("\n")[0]}`, { dim: true })
|
|
1126
|
+
]);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
lines.push(singleLine(" "));
|
|
1131
|
+
lines.push(singleLine(" \u258E \u25E6 META", { color: "gray", bold: true }));
|
|
1132
|
+
lines.push(singleLine(` Spawned: ${formatTime(agent.spawnedAt)}`, { dim: true }));
|
|
1133
|
+
if (agent.completedAt) {
|
|
1134
|
+
lines.push(singleLine(` Completed: ${formatTime(agent.completedAt)}`, { dim: true }));
|
|
1135
|
+
}
|
|
1136
|
+
if (agent.paneId) {
|
|
1137
|
+
lines.push(singleLine(` Pane: ${agent.paneId}`, { dim: true }));
|
|
1138
|
+
}
|
|
1139
|
+
if (agent.worktreePath) {
|
|
1140
|
+
lines.push(singleLine(` Worktree: ${agent.worktreePath}`, { dim: true }));
|
|
1141
|
+
}
|
|
1142
|
+
if (agent.branchName) {
|
|
1143
|
+
lines.push(singleLine(` Branch: ${agent.branchName}`, { dim: true }));
|
|
1144
|
+
}
|
|
1145
|
+
return lines;
|
|
1146
|
+
}
|
|
1147
|
+
function AgentDetail({ agent, reportBlocks, width, height, scrollOffset = 0, focused = false }) {
|
|
1148
|
+
const allLines = useMemo4(
|
|
1149
|
+
() => buildLines4(agent, reportBlocks, width),
|
|
1150
|
+
[agent, reportBlocks, width]
|
|
1151
|
+
);
|
|
1152
|
+
return /* @__PURE__ */ jsx7(
|
|
1153
|
+
ScrollablePanel,
|
|
937
1154
|
{
|
|
938
|
-
|
|
1155
|
+
lines: allLines,
|
|
939
1156
|
width,
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
children: [
|
|
944
|
-
/* @__PURE__ */ jsxs5(Text6, { bold: true, children: [
|
|
945
|
-
" ",
|
|
946
|
-
/* @__PURE__ */ jsx6(Text6, { color, children: icon }),
|
|
947
|
-
" ",
|
|
948
|
-
agent.id,
|
|
949
|
-
" \xB7 ",
|
|
950
|
-
nameLabel
|
|
951
|
-
] }),
|
|
952
|
-
/* @__PURE__ */ jsxs5(Box6, { children: [
|
|
953
|
-
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " " }),
|
|
954
|
-
/* @__PURE__ */ jsx6(Text6, { color, children: agent.status }),
|
|
955
|
-
/* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
956
|
-
" \xB7 ",
|
|
957
|
-
dur,
|
|
958
|
-
" \xB7 ",
|
|
959
|
-
agent.agentType
|
|
960
|
-
] }),
|
|
961
|
-
agent.mergeStatus && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
962
|
-
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " \xB7 " }),
|
|
963
|
-
agent.mergeStatus === "merged" && /* @__PURE__ */ jsx6(Text6, { color: "green", children: "\u2295 merged" }),
|
|
964
|
-
agent.mergeStatus === "pending" && /* @__PURE__ */ jsx6(Text6, { color: "yellow", children: "\u25CC pending" }),
|
|
965
|
-
agent.mergeStatus === "no-changes" && /* @__PURE__ */ jsx6(Text6, { color: "gray", children: "\u2205 no changes" }),
|
|
966
|
-
agent.mergeStatus === "conflict" && /* @__PURE__ */ jsx6(Text6, { color: "red", children: "\u26A0 conflict" }),
|
|
967
|
-
!["merged", "pending", "no-changes", "conflict"].includes(agent.mergeStatus) && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: agent.mergeStatus })
|
|
968
|
-
] })
|
|
969
|
-
] }),
|
|
970
|
-
agent.killedReason && /* @__PURE__ */ jsxs5(Text6, { color: "red", children: [
|
|
971
|
-
" ",
|
|
972
|
-
"\u26A0 ",
|
|
973
|
-
agent.killedReason
|
|
974
|
-
] }),
|
|
975
|
-
agent.mergeStatus === "conflict" && agent.mergeDetails && /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", children: wrapText(agent.mergeDetails, contentWidth - 6).map((line, i) => /* @__PURE__ */ jsxs5(Text6, { color: "red", children: [
|
|
976
|
-
" ",
|
|
977
|
-
"\u26A0 ",
|
|
978
|
-
line
|
|
979
|
-
] }, i)) }),
|
|
980
|
-
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
981
|
-
/* @__PURE__ */ jsxs5(Text6, { color: "white", bold: true, children: [
|
|
982
|
-
" ",
|
|
983
|
-
"\u258E \u25B7 INSTRUCTION"
|
|
984
|
-
] }),
|
|
985
|
-
wrapText(agent.instruction, contentWidth - 6).slice(0, instrMaxLines).map((line, i) => /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
986
|
-
" ",
|
|
987
|
-
line
|
|
988
|
-
] }, i)),
|
|
989
|
-
agent.reports.length > 0 && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
990
|
-
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
991
|
-
/* @__PURE__ */ jsxs5(Text6, { color: "cyan", bold: true, children: [
|
|
992
|
-
" ",
|
|
993
|
-
"\u258E \u25C7 REPORTS (",
|
|
994
|
-
agent.reports.length,
|
|
995
|
-
")"
|
|
996
|
-
] }),
|
|
997
|
-
hasResolvedReports ? /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", children: reportBlocks.slice(0, Math.min(reportBlocks.length, 3)).map((block, i) => {
|
|
998
|
-
const badge = block.type === "final" ? "FINAL" : "UPDATE";
|
|
999
|
-
const badgeColor = block.type === "final" ? "cyan" : "yellow";
|
|
1000
|
-
const linesPerReport = Math.max(2, Math.floor(reportMaxLines / Math.min(reportBlocks.length, 3)) - 2);
|
|
1001
|
-
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
|
|
1002
|
-
i > 0 && /* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1003
|
-
/* @__PURE__ */ jsxs5(Box6, { children: [
|
|
1004
|
-
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1005
|
-
/* @__PURE__ */ jsx6(Text6, { color: badgeColor, bold: block.type === "final", children: badge }),
|
|
1006
|
-
/* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1007
|
-
" ",
|
|
1008
|
-
formatTime(block.timestamp)
|
|
1009
|
-
] })
|
|
1010
|
-
] }),
|
|
1011
|
-
wrapText(cleanMarkdown(block.content.trim()), contentWidth - 10).slice(0, linesPerReport).map((line, j) => /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1012
|
-
" ",
|
|
1013
|
-
line
|
|
1014
|
-
] }, j))
|
|
1015
|
-
] }, i);
|
|
1016
|
-
}) }) : agent.reports.slice(0, reportMaxLines).map((report, i) => {
|
|
1017
|
-
const badge = report.type === "final" ? "FINAL" : "UPDATE";
|
|
1018
|
-
const badgeColor = report.type === "final" ? "cyan" : "yellow";
|
|
1019
|
-
return /* @__PURE__ */ jsxs5(Box6, { children: [
|
|
1020
|
-
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1021
|
-
/* @__PURE__ */ jsx6(Text6, { color: badgeColor, bold: report.type === "final", children: badge }),
|
|
1022
|
-
/* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1023
|
-
" ",
|
|
1024
|
-
formatTime(report.timestamp),
|
|
1025
|
-
" ",
|
|
1026
|
-
report.summary.split("\n")[0]
|
|
1027
|
-
] })
|
|
1028
|
-
] }, i);
|
|
1029
|
-
})
|
|
1030
|
-
] }),
|
|
1031
|
-
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1032
|
-
/* @__PURE__ */ jsxs5(Text6, { color: "gray", bold: true, children: [
|
|
1033
|
-
" ",
|
|
1034
|
-
"\u258E \u25E6 META"
|
|
1035
|
-
] }),
|
|
1036
|
-
/* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1037
|
-
" ",
|
|
1038
|
-
"Spawned: ",
|
|
1039
|
-
formatTime(agent.spawnedAt)
|
|
1040
|
-
] }),
|
|
1041
|
-
agent.completedAt && /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1042
|
-
" ",
|
|
1043
|
-
"Completed: ",
|
|
1044
|
-
formatTime(agent.completedAt)
|
|
1045
|
-
] }),
|
|
1046
|
-
agent.paneId && /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1047
|
-
" ",
|
|
1048
|
-
"Pane: ",
|
|
1049
|
-
agent.paneId
|
|
1050
|
-
] }),
|
|
1051
|
-
agent.worktreePath && /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1052
|
-
" ",
|
|
1053
|
-
"Worktree: ",
|
|
1054
|
-
agent.worktreePath
|
|
1055
|
-
] }),
|
|
1056
|
-
agent.branchName && /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
|
|
1057
|
-
" ",
|
|
1058
|
-
"Branch: ",
|
|
1059
|
-
agent.branchName
|
|
1060
|
-
] })
|
|
1061
|
-
]
|
|
1157
|
+
height,
|
|
1158
|
+
scrollOffset,
|
|
1159
|
+
focused
|
|
1062
1160
|
}
|
|
1063
1161
|
);
|
|
1064
1162
|
}
|
|
1065
1163
|
|
|
1066
1164
|
// src/tui/components/ReportView.tsx
|
|
1067
|
-
import { useState, useMemo as
|
|
1068
|
-
import { Box as
|
|
1069
|
-
import { jsx as
|
|
1165
|
+
import { useState, useMemo as useMemo5 } from "react";
|
|
1166
|
+
import { Box as Box6, Text as Text6, useInput } from "ink";
|
|
1167
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1070
1168
|
function ReportView({ agent, reportBlocks, width, height, onClose }) {
|
|
1071
1169
|
const [scrollOffset, setScrollOffset] = useState(0);
|
|
1072
1170
|
const contentWidth = width - 6;
|
|
1073
|
-
const lines =
|
|
1171
|
+
const lines = useMemo5(() => {
|
|
1074
1172
|
const lines2 = [];
|
|
1075
1173
|
if (reportBlocks.length === 0) {
|
|
1076
1174
|
lines2.push({ text: "", dim: true });
|
|
@@ -1132,8 +1230,8 @@ function ReportView({ agent, reportBlocks, width, height, onClose }) {
|
|
|
1132
1230
|
const icon = agentStatusIcon(agent.status);
|
|
1133
1231
|
const color = statusColor(agent.status);
|
|
1134
1232
|
const dur = formatDuration(agent.spawnedAt, agent.completedAt);
|
|
1135
|
-
return /* @__PURE__ */
|
|
1136
|
-
|
|
1233
|
+
return /* @__PURE__ */ jsxs3(
|
|
1234
|
+
Box6,
|
|
1137
1235
|
{
|
|
1138
1236
|
flexDirection: "column",
|
|
1139
1237
|
width,
|
|
@@ -1142,17 +1240,17 @@ function ReportView({ agent, reportBlocks, width, height, onClose }) {
|
|
|
1142
1240
|
borderColor: "cyan",
|
|
1143
1241
|
paddingX: 1,
|
|
1144
1242
|
children: [
|
|
1145
|
-
/* @__PURE__ */
|
|
1243
|
+
/* @__PURE__ */ jsxs3(Text6, { bold: true, children: [
|
|
1146
1244
|
" ",
|
|
1147
|
-
/* @__PURE__ */
|
|
1245
|
+
/* @__PURE__ */ jsx8(Text6, { color, children: icon }),
|
|
1148
1246
|
" ",
|
|
1149
1247
|
agent.id,
|
|
1150
1248
|
" ",
|
|
1151
|
-
/* @__PURE__ */
|
|
1249
|
+
/* @__PURE__ */ jsx8(Text6, { dimColor: true, children: "\xB7" }),
|
|
1152
1250
|
" ",
|
|
1153
1251
|
agent.name !== agent.id ? agent.name : agent.agentType
|
|
1154
1252
|
] }),
|
|
1155
|
-
/* @__PURE__ */
|
|
1253
|
+
/* @__PURE__ */ jsxs3(Text6, { dimColor: true, children: [
|
|
1156
1254
|
" ",
|
|
1157
1255
|
agent.status,
|
|
1158
1256
|
" \xB7 ",
|
|
@@ -1164,28 +1262,28 @@ function ReportView({ agent, reportBlocks, width, height, onClose }) {
|
|
|
1164
1262
|
" report",
|
|
1165
1263
|
totalReports !== 1 ? "s" : ""
|
|
1166
1264
|
] }),
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
/* @__PURE__ */
|
|
1169
|
-
|
|
1265
|
+
/* @__PURE__ */ jsx8(Text6, { dimColor: true, children: " " + divider(contentWidth - 2) }),
|
|
1266
|
+
/* @__PURE__ */ jsx8(Box6, { flexDirection: "column", flexGrow: 1, children: visible.map((line, i) => /* @__PURE__ */ jsx8(
|
|
1267
|
+
Text6,
|
|
1170
1268
|
{
|
|
1171
1269
|
color: line.color,
|
|
1172
1270
|
bold: line.bold,
|
|
1173
1271
|
dimColor: line.dim,
|
|
1174
1272
|
children: line.text
|
|
1175
1273
|
},
|
|
1176
|
-
|
|
1274
|
+
i
|
|
1177
1275
|
)) }),
|
|
1178
|
-
/* @__PURE__ */
|
|
1179
|
-
/* @__PURE__ */
|
|
1276
|
+
/* @__PURE__ */ jsx8(Text6, { dimColor: true, children: " " + divider(contentWidth - 2) }),
|
|
1277
|
+
/* @__PURE__ */ jsxs3(Text6, { dimColor: true, children: [
|
|
1180
1278
|
" ",
|
|
1181
1279
|
"[esc] back [\u2191\u2193] scroll [",
|
|
1182
1280
|
"] page",
|
|
1183
1281
|
" ",
|
|
1184
|
-
/* @__PURE__ */
|
|
1282
|
+
/* @__PURE__ */ jsxs3(Text6, { children: [
|
|
1185
1283
|
scrollPct,
|
|
1186
1284
|
"%"
|
|
1187
1285
|
] }),
|
|
1188
|
-
maxScroll > 0 && /* @__PURE__ */
|
|
1286
|
+
maxScroll > 0 && /* @__PURE__ */ jsxs3(Text6, { dimColor: true, children: [
|
|
1189
1287
|
" \xB7 ",
|
|
1190
1288
|
lines.length,
|
|
1191
1289
|
" lines"
|
|
@@ -1196,58 +1294,10 @@ function ReportView({ agent, reportBlocks, width, height, onClose }) {
|
|
|
1196
1294
|
);
|
|
1197
1295
|
}
|
|
1198
1296
|
|
|
1199
|
-
// src/tui/components/MessageLog.tsx
|
|
1200
|
-
import { Box as Box8, Text as Text8 } from "ink";
|
|
1201
|
-
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1202
|
-
function sourceLabel(msg) {
|
|
1203
|
-
if (msg.source.type === "user") return "You";
|
|
1204
|
-
if (msg.source.type === "agent") return msg.source.agentId;
|
|
1205
|
-
return "system";
|
|
1206
|
-
}
|
|
1207
|
-
function sourceColor(msg) {
|
|
1208
|
-
if (msg.source.type === "user") return "yellow";
|
|
1209
|
-
if (msg.source.type === "agent") return "cyan";
|
|
1210
|
-
return "gray";
|
|
1211
|
-
}
|
|
1212
|
-
function MessageLog({ messages, maxMessages, width }) {
|
|
1213
|
-
if (messages.length === 0) {
|
|
1214
|
-
return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", children: [
|
|
1215
|
-
/* @__PURE__ */ jsx8(Text8, { bold: true, dimColor: true, children: "Messages" }),
|
|
1216
|
-
/* @__PURE__ */ jsx8(Text8, { dimColor: true, italic: true, children: " No messages" })
|
|
1217
|
-
] });
|
|
1218
|
-
}
|
|
1219
|
-
const recent = messages.slice(-maxMessages);
|
|
1220
|
-
const contentWidth = Math.max(10, width - 20);
|
|
1221
|
-
return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", children: [
|
|
1222
|
-
/* @__PURE__ */ jsx8(Text8, { bold: true, dimColor: true, children: "Messages" }),
|
|
1223
|
-
recent.map((msg) => {
|
|
1224
|
-
const time = formatTime(msg.timestamp);
|
|
1225
|
-
const label = sourceLabel(msg);
|
|
1226
|
-
const color = sourceColor(msg);
|
|
1227
|
-
const content = truncate(msg.summary || msg.content, contentWidth);
|
|
1228
|
-
return /* @__PURE__ */ jsxs7(Text8, { children: [
|
|
1229
|
-
" ",
|
|
1230
|
-
/* @__PURE__ */ jsxs7(Text8, { dimColor: true, children: [
|
|
1231
|
-
"[",
|
|
1232
|
-
time,
|
|
1233
|
-
"]"
|
|
1234
|
-
] }),
|
|
1235
|
-
" ",
|
|
1236
|
-
/* @__PURE__ */ jsxs7(Text8, { color, bold: true, children: [
|
|
1237
|
-
label,
|
|
1238
|
-
":"
|
|
1239
|
-
] }),
|
|
1240
|
-
" ",
|
|
1241
|
-
content
|
|
1242
|
-
] }, msg.id);
|
|
1243
|
-
})
|
|
1244
|
-
] });
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
1297
|
// src/tui/components/InputBar.tsx
|
|
1248
1298
|
import { useState as useState2, useEffect, useRef } from "react";
|
|
1249
|
-
import { Box as
|
|
1250
|
-
import { jsx as jsx9, jsxs as
|
|
1299
|
+
import { Box as Box7, Text as Text7, useInput as useInput2 } from "ink";
|
|
1300
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1251
1301
|
var INPUT_MODES = /* @__PURE__ */ new Set([
|
|
1252
1302
|
"resume",
|
|
1253
1303
|
"continue",
|
|
@@ -1341,163 +1391,163 @@ function InputBar({ mode, defaultText, onSubmit, onCancel }) {
|
|
|
1341
1391
|
{ isActive: INPUT_MODES.has(mode) }
|
|
1342
1392
|
);
|
|
1343
1393
|
if (mode === "navigate") {
|
|
1344
|
-
return /* @__PURE__ */ jsx9(
|
|
1394
|
+
return /* @__PURE__ */ jsx9(Box7, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text7, { dimColor: true, children: "Press [m] to message orchestrator, [n] for new session" }) });
|
|
1345
1395
|
}
|
|
1346
1396
|
if (mode === "report-detail" || mode === "leader" || mode === "copy-menu" || mode === "help" || !INPUT_MODES.has(mode)) {
|
|
1347
1397
|
return null;
|
|
1348
1398
|
}
|
|
1349
1399
|
const prompt = PROMPTS[mode] ?? mode;
|
|
1350
|
-
return /* @__PURE__ */
|
|
1351
|
-
/* @__PURE__ */
|
|
1400
|
+
return /* @__PURE__ */ jsxs4(Box7, { paddingX: 1, children: [
|
|
1401
|
+
/* @__PURE__ */ jsxs4(Text7, { color: "yellow", children: [
|
|
1352
1402
|
prompt,
|
|
1353
1403
|
" > "
|
|
1354
1404
|
] }),
|
|
1355
|
-
/* @__PURE__ */ jsx9(
|
|
1356
|
-
/* @__PURE__ */ jsx9(
|
|
1357
|
-
/* @__PURE__ */ jsx9(
|
|
1358
|
-
/* @__PURE__ */ jsx9(
|
|
1405
|
+
/* @__PURE__ */ jsx9(Text7, { children: text.slice(0, cursorPos) }),
|
|
1406
|
+
/* @__PURE__ */ jsx9(Text7, { inverse: true, children: cursorPos < text.length ? text[cursorPos] : " " }),
|
|
1407
|
+
/* @__PURE__ */ jsx9(Text7, { children: text.slice(cursorPos + 1) }),
|
|
1408
|
+
/* @__PURE__ */ jsx9(Text7, { dimColor: true, children: " (enter to send, esc to cancel)" })
|
|
1359
1409
|
] });
|
|
1360
1410
|
}
|
|
1361
1411
|
|
|
1362
1412
|
// src/tui/components/StatusLine.tsx
|
|
1363
|
-
import { Box as
|
|
1364
|
-
import { Fragment
|
|
1413
|
+
import { Box as Box8, Text as Text8 } from "ink";
|
|
1414
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1365
1415
|
function StatusLine({ mode, detailFocused = false, logsFocused = false, showLogs = false, cursorNodeType }) {
|
|
1366
1416
|
if (mode === "report-detail") {
|
|
1367
1417
|
return null;
|
|
1368
1418
|
}
|
|
1369
1419
|
if (mode === "leader") {
|
|
1370
|
-
return /* @__PURE__ */
|
|
1371
|
-
/* @__PURE__ */ jsx10(
|
|
1372
|
-
/* @__PURE__ */ jsx10(
|
|
1420
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1421
|
+
/* @__PURE__ */ jsx10(Text8, { color: "magenta", bold: true, children: "LEADER" }),
|
|
1422
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " press a command key or [esc] to cancel" })
|
|
1373
1423
|
] });
|
|
1374
1424
|
}
|
|
1375
1425
|
if (mode === "copy-menu") {
|
|
1376
|
-
return /* @__PURE__ */
|
|
1377
|
-
/* @__PURE__ */ jsx10(
|
|
1378
|
-
/* @__PURE__ */ jsx10(
|
|
1426
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1427
|
+
/* @__PURE__ */ jsx10(Text8, { color: "cyan", bold: true, children: "COPY" }),
|
|
1428
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " [p] path [C] context [l] logs [s] session ID [esc] cancel" })
|
|
1379
1429
|
] });
|
|
1380
1430
|
}
|
|
1381
1431
|
if (mode === "help") {
|
|
1382
|
-
return /* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */ jsx10(
|
|
1384
|
-
/* @__PURE__ */ jsx10(
|
|
1432
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1433
|
+
/* @__PURE__ */ jsx10(Text8, { color: "yellow", bold: true, children: "HELP" }),
|
|
1434
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " [esc] or [?] to dismiss" })
|
|
1385
1435
|
] });
|
|
1386
1436
|
}
|
|
1387
1437
|
if (mode === "delete-confirm") {
|
|
1388
|
-
return /* @__PURE__ */
|
|
1389
|
-
/* @__PURE__ */ jsx10(
|
|
1390
|
-
/* @__PURE__ */ jsx10(
|
|
1438
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1439
|
+
/* @__PURE__ */ jsx10(Text8, { color: "red", bold: true, children: "DELETE" }),
|
|
1440
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " type 'yes' to confirm, [esc] to cancel" })
|
|
1391
1441
|
] });
|
|
1392
1442
|
}
|
|
1393
1443
|
if (mode === "spawn-agent") {
|
|
1394
|
-
return /* @__PURE__ */
|
|
1395
|
-
/* @__PURE__ */ jsx10(
|
|
1396
|
-
/* @__PURE__ */ jsx10(
|
|
1444
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1445
|
+
/* @__PURE__ */ jsx10(Text8, { color: "green", bold: true, children: "SPAWN" }),
|
|
1446
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " enter agent instruction, [esc] to cancel" })
|
|
1397
1447
|
] });
|
|
1398
1448
|
}
|
|
1399
1449
|
if (mode === "search") {
|
|
1400
|
-
return /* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */ jsx10(
|
|
1402
|
-
/* @__PURE__ */ jsx10(
|
|
1450
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1451
|
+
/* @__PURE__ */ jsx10(Text8, { color: "blue", bold: true, children: "SEARCH" }),
|
|
1452
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " type to filter, enter to apply, [esc] to cancel" })
|
|
1403
1453
|
] });
|
|
1404
1454
|
}
|
|
1405
1455
|
if (mode === "message-agent") {
|
|
1406
|
-
return /* @__PURE__ */
|
|
1407
|
-
/* @__PURE__ */ jsx10(
|
|
1408
|
-
/* @__PURE__ */ jsx10(
|
|
1456
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1457
|
+
/* @__PURE__ */ jsx10(Text8, { color: "cyan", bold: true, children: "MESSAGE" }),
|
|
1458
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " enter message for agent, [esc] to cancel" })
|
|
1409
1459
|
] });
|
|
1410
1460
|
}
|
|
1411
1461
|
if (mode === "shell-command") {
|
|
1412
|
-
return /* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */ jsx10(
|
|
1414
|
-
/* @__PURE__ */ jsx10(
|
|
1462
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1463
|
+
/* @__PURE__ */ jsx10(Text8, { color: "magenta", bold: true, children: "SHELL" }),
|
|
1464
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " enter command, [esc] to cancel" })
|
|
1415
1465
|
] });
|
|
1416
1466
|
}
|
|
1417
1467
|
if (mode !== "navigate") {
|
|
1418
|
-
return /* @__PURE__ */ jsx10(
|
|
1468
|
+
return /* @__PURE__ */ jsx10(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "[enter] send [esc] cancel" }) });
|
|
1419
1469
|
}
|
|
1420
1470
|
if (logsFocused) {
|
|
1421
|
-
return /* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */ jsx10(
|
|
1423
|
-
/* @__PURE__ */ jsx10(
|
|
1424
|
-
/* @__PURE__ */ jsx10(
|
|
1425
|
-
/* @__PURE__ */ jsx10(
|
|
1426
|
-
/* @__PURE__ */ jsx10(
|
|
1427
|
-
/* @__PURE__ */ jsx10(
|
|
1428
|
-
/* @__PURE__ */ jsx10(
|
|
1429
|
-
/* @__PURE__ */ jsx10(
|
|
1430
|
-
/* @__PURE__ */ jsx10(
|
|
1431
|
-
/* @__PURE__ */ jsx10(
|
|
1432
|
-
/* @__PURE__ */ jsx10(
|
|
1433
|
-
/* @__PURE__ */ jsx10(
|
|
1434
|
-
/* @__PURE__ */ jsx10(
|
|
1435
|
-
/* @__PURE__ */ jsx10(
|
|
1436
|
-
/* @__PURE__ */ jsx10(
|
|
1437
|
-
/* @__PURE__ */ jsx10(
|
|
1438
|
-
/* @__PURE__ */ jsx10(
|
|
1439
|
-
/* @__PURE__ */ jsx10(
|
|
1440
|
-
/* @__PURE__ */ jsx10(
|
|
1441
|
-
/* @__PURE__ */ jsx10(
|
|
1442
|
-
/* @__PURE__ */ jsx10(
|
|
1471
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1472
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[jk/\u2191\u2193]" }),
|
|
1473
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " scroll " }),
|
|
1474
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[h/\u2190/tab]" }),
|
|
1475
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " back " }),
|
|
1476
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[t]" }),
|
|
1477
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "oggle logs " }),
|
|
1478
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "\u2502 " }),
|
|
1479
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[m]" }),
|
|
1480
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "sg " }),
|
|
1481
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[g]" }),
|
|
1482
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "oal " }),
|
|
1483
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[n]" }),
|
|
1484
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "ew " }),
|
|
1485
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[p]" }),
|
|
1486
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "lan " }),
|
|
1487
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[w]" }),
|
|
1488
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "indow " }),
|
|
1489
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[R]" }),
|
|
1490
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "esume " }),
|
|
1491
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[q]" }),
|
|
1492
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "uit" })
|
|
1443
1493
|
] });
|
|
1444
1494
|
}
|
|
1445
1495
|
if (detailFocused) {
|
|
1446
|
-
return /* @__PURE__ */
|
|
1447
|
-
/* @__PURE__ */ jsx10(
|
|
1448
|
-
/* @__PURE__ */ jsx10(
|
|
1449
|
-
/* @__PURE__ */ jsx10(
|
|
1450
|
-
/* @__PURE__ */ jsx10(
|
|
1451
|
-
/* @__PURE__ */ jsx10(
|
|
1452
|
-
/* @__PURE__ */ jsx10(
|
|
1453
|
-
/* @__PURE__ */ jsx10(
|
|
1454
|
-
/* @__PURE__ */ jsx10(
|
|
1455
|
-
/* @__PURE__ */ jsx10(
|
|
1456
|
-
/* @__PURE__ */ jsx10(
|
|
1457
|
-
/* @__PURE__ */ jsx10(
|
|
1458
|
-
/* @__PURE__ */ jsx10(
|
|
1459
|
-
/* @__PURE__ */ jsx10(
|
|
1460
|
-
/* @__PURE__ */ jsx10(
|
|
1461
|
-
/* @__PURE__ */ jsx10(
|
|
1462
|
-
/* @__PURE__ */ jsx10(
|
|
1463
|
-
/* @__PURE__ */ jsx10(
|
|
1464
|
-
/* @__PURE__ */ jsx10(
|
|
1465
|
-
/* @__PURE__ */ jsx10(
|
|
1466
|
-
/* @__PURE__ */ jsx10(
|
|
1467
|
-
/* @__PURE__ */ jsx10(
|
|
1496
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1497
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[jk/\u2191\u2193]" }),
|
|
1498
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " scroll " }),
|
|
1499
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[h/\u2190/tab]" }),
|
|
1500
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " back " }),
|
|
1501
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[t]" }),
|
|
1502
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "oggle logs " }),
|
|
1503
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "\u2502 " }),
|
|
1504
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[m]" }),
|
|
1505
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "sg " }),
|
|
1506
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[g]" }),
|
|
1507
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "oal " }),
|
|
1508
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[n]" }),
|
|
1509
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "ew " }),
|
|
1510
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[p]" }),
|
|
1511
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "lan " }),
|
|
1512
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[w]" }),
|
|
1513
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "indow " }),
|
|
1514
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[R]" }),
|
|
1515
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "esume " }),
|
|
1516
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[q]" }),
|
|
1517
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "uit" })
|
|
1468
1518
|
] });
|
|
1469
1519
|
}
|
|
1470
|
-
return /* @__PURE__ */
|
|
1471
|
-
/* @__PURE__ */ jsx10(
|
|
1472
|
-
/* @__PURE__ */ jsx10(
|
|
1473
|
-
/* @__PURE__ */ jsx10(
|
|
1474
|
-
cursorNodeType === "context-file" && /* @__PURE__ */
|
|
1475
|
-
/* @__PURE__ */ jsx10(
|
|
1476
|
-
/* @__PURE__ */ jsx10(
|
|
1477
|
-
/* @__PURE__ */ jsx10(
|
|
1478
|
-
/* @__PURE__ */ jsx10(
|
|
1520
|
+
return /* @__PURE__ */ jsxs5(Box8, { paddingX: 1, children: [
|
|
1521
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[hjkl]" }),
|
|
1522
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " navigate " }),
|
|
1523
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "\u2502 " }),
|
|
1524
|
+
cursorNodeType === "context-file" && /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1525
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[e]" }),
|
|
1526
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "dit " }),
|
|
1527
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[\u23CE]" }),
|
|
1528
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " open " })
|
|
1479
1529
|
] }),
|
|
1480
|
-
/* @__PURE__ */ jsx10(
|
|
1481
|
-
/* @__PURE__ */ jsx10(
|
|
1482
|
-
/* @__PURE__ */ jsx10(
|
|
1483
|
-
/* @__PURE__ */ jsx10(
|
|
1484
|
-
/* @__PURE__ */ jsx10(
|
|
1485
|
-
/* @__PURE__ */ jsx10(
|
|
1486
|
-
/* @__PURE__ */ jsx10(
|
|
1487
|
-
/* @__PURE__ */ jsx10(
|
|
1488
|
-
/* @__PURE__ */ jsx10(
|
|
1489
|
-
/* @__PURE__ */ jsx10(
|
|
1490
|
-
/* @__PURE__ */ jsx10(
|
|
1491
|
-
/* @__PURE__ */ jsx10(
|
|
1492
|
-
/* @__PURE__ */ jsx10(
|
|
1493
|
-
/* @__PURE__ */ jsx10(
|
|
1494
|
-
/* @__PURE__ */ jsx10(
|
|
1530
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[space]" }),
|
|
1531
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " leader " }),
|
|
1532
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[tab]" }),
|
|
1533
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: " detail " }),
|
|
1534
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[t]" }),
|
|
1535
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "oggle logs " }),
|
|
1536
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "\u2502 " }),
|
|
1537
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[m]" }),
|
|
1538
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "sg " }),
|
|
1539
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[n]" }),
|
|
1540
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "ew " }),
|
|
1541
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[R]" }),
|
|
1542
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "esume " }),
|
|
1543
|
+
/* @__PURE__ */ jsx10(Text8, { bold: true, children: "[q]" }),
|
|
1544
|
+
/* @__PURE__ */ jsx10(Text8, { dimColor: true, children: "uit" })
|
|
1495
1545
|
] });
|
|
1496
1546
|
}
|
|
1497
1547
|
|
|
1498
1548
|
// src/tui/components/LeaderOverlay.tsx
|
|
1499
|
-
import { Box as
|
|
1500
|
-
import { jsx as jsx11, jsxs as
|
|
1549
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
1550
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1501
1551
|
var LEADER_WIDTH = 26;
|
|
1502
1552
|
var LEADER_HEIGHT = 19;
|
|
1503
1553
|
var COPY_HEIGHT = 9;
|
|
@@ -1507,8 +1557,8 @@ function pad(s) {
|
|
|
1507
1557
|
}
|
|
1508
1558
|
function LeaderOverlay({ mode, rows, cols }) {
|
|
1509
1559
|
if (mode === "leader") {
|
|
1510
|
-
return /* @__PURE__ */
|
|
1511
|
-
|
|
1560
|
+
return /* @__PURE__ */ jsxs6(
|
|
1561
|
+
Box9,
|
|
1512
1562
|
{
|
|
1513
1563
|
position: "absolute",
|
|
1514
1564
|
marginTop: rows - LEADER_HEIGHT - 2,
|
|
@@ -1518,30 +1568,30 @@ function LeaderOverlay({ mode, rows, cols }) {
|
|
|
1518
1568
|
borderStyle: "round",
|
|
1519
1569
|
borderColor: "magenta",
|
|
1520
1570
|
children: [
|
|
1521
|
-
/* @__PURE__ */ jsx11(
|
|
1522
|
-
/* @__PURE__ */ jsx11(
|
|
1523
|
-
/* @__PURE__ */ jsx11(
|
|
1524
|
-
/* @__PURE__ */ jsx11(
|
|
1525
|
-
/* @__PURE__ */ jsx11(
|
|
1526
|
-
/* @__PURE__ */ jsx11(
|
|
1527
|
-
/* @__PURE__ */ jsx11(
|
|
1528
|
-
/* @__PURE__ */ jsx11(
|
|
1529
|
-
/* @__PURE__ */ jsx11(
|
|
1530
|
-
/* @__PURE__ */ jsx11(
|
|
1531
|
-
/* @__PURE__ */ jsx11(
|
|
1532
|
-
/* @__PURE__ */ jsx11(
|
|
1533
|
-
/* @__PURE__ */ jsx11(
|
|
1534
|
-
/* @__PURE__ */ jsx11(
|
|
1535
|
-
/* @__PURE__ */ jsx11(
|
|
1536
|
-
/* @__PURE__ */ jsx11(
|
|
1537
|
-
/* @__PURE__ */ jsx11(
|
|
1571
|
+
/* @__PURE__ */ jsx11(Text9, { bold: true, color: "magenta", children: pad(" LEADER") }),
|
|
1572
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" ") }),
|
|
1573
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" y copy menu") }),
|
|
1574
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" d delete session") }),
|
|
1575
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" l daemon logs") }),
|
|
1576
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" o open session dir") }),
|
|
1577
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" a spawn agent") }),
|
|
1578
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" m message agent") }),
|
|
1579
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" / search") }),
|
|
1580
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" ! shell command") }),
|
|
1581
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" j jump to pane") }),
|
|
1582
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" k kill session/agent") }),
|
|
1583
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" q quit") }),
|
|
1584
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" ? help") }),
|
|
1585
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" 1-9 jump to session") }),
|
|
1586
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" ") }),
|
|
1587
|
+
/* @__PURE__ */ jsx11(Text9, { dimColor: true, children: pad(" esc dismiss") })
|
|
1538
1588
|
]
|
|
1539
1589
|
}
|
|
1540
1590
|
);
|
|
1541
1591
|
}
|
|
1542
1592
|
if (mode === "copy-menu") {
|
|
1543
|
-
return /* @__PURE__ */
|
|
1544
|
-
|
|
1593
|
+
return /* @__PURE__ */ jsxs6(
|
|
1594
|
+
Box9,
|
|
1545
1595
|
{
|
|
1546
1596
|
position: "absolute",
|
|
1547
1597
|
marginTop: rows - COPY_HEIGHT - 2,
|
|
@@ -1551,13 +1601,13 @@ function LeaderOverlay({ mode, rows, cols }) {
|
|
|
1551
1601
|
borderStyle: "round",
|
|
1552
1602
|
borderColor: "cyan",
|
|
1553
1603
|
children: [
|
|
1554
|
-
/* @__PURE__ */ jsx11(
|
|
1555
|
-
/* @__PURE__ */ jsx11(
|
|
1556
|
-
/* @__PURE__ */ jsx11(
|
|
1557
|
-
/* @__PURE__ */ jsx11(
|
|
1558
|
-
/* @__PURE__ */ jsx11(
|
|
1559
|
-
/* @__PURE__ */ jsx11(
|
|
1560
|
-
/* @__PURE__ */ jsx11(
|
|
1604
|
+
/* @__PURE__ */ jsx11(Text9, { bold: true, color: "cyan", children: pad(" COPY") }),
|
|
1605
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" ") }),
|
|
1606
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" p session path") }),
|
|
1607
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" C LLM context") }),
|
|
1608
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" l logs content") }),
|
|
1609
|
+
/* @__PURE__ */ jsx11(Text9, { children: pad(" s session ID") }),
|
|
1610
|
+
/* @__PURE__ */ jsx11(Text9, { dimColor: true, children: pad(" esc cancel") })
|
|
1561
1611
|
]
|
|
1562
1612
|
}
|
|
1563
1613
|
);
|
|
@@ -1566,8 +1616,8 @@ function LeaderOverlay({ mode, rows, cols }) {
|
|
|
1566
1616
|
}
|
|
1567
1617
|
|
|
1568
1618
|
// src/tui/components/HelpOverlay.tsx
|
|
1569
|
-
import { Box as
|
|
1570
|
-
import { jsx as jsx12, jsxs as
|
|
1619
|
+
import { Box as Box10, Text as Text10 } from "ink";
|
|
1620
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1571
1621
|
var HELP_WIDTH = 62;
|
|
1572
1622
|
var INNER2 = HELP_WIDTH - 2;
|
|
1573
1623
|
function pad2(s) {
|
|
@@ -1602,8 +1652,8 @@ function HelpOverlay({ mode, rows, cols }) {
|
|
|
1602
1652
|
row(" y \u2192 l logs content", " y \u2192 s session ID")
|
|
1603
1653
|
];
|
|
1604
1654
|
const overlayHeight = Math.min(lines.length + 4, rows - 2);
|
|
1605
|
-
return /* @__PURE__ */
|
|
1606
|
-
|
|
1655
|
+
return /* @__PURE__ */ jsxs7(
|
|
1656
|
+
Box10,
|
|
1607
1657
|
{
|
|
1608
1658
|
position: "absolute",
|
|
1609
1659
|
marginTop: Math.max(0, Math.floor((rows - overlayHeight) / 2)),
|
|
@@ -1613,13 +1663,13 @@ function HelpOverlay({ mode, rows, cols }) {
|
|
|
1613
1663
|
borderStyle: "round",
|
|
1614
1664
|
borderColor: "yellow",
|
|
1615
1665
|
children: [
|
|
1616
|
-
/* @__PURE__ */ jsx12(
|
|
1617
|
-
/* @__PURE__ */ jsx12(
|
|
1666
|
+
/* @__PURE__ */ jsx12(Text10, { bold: true, color: "yellow", children: pad2(" KEYBINDINGS (esc or ? to close)") }),
|
|
1667
|
+
/* @__PURE__ */ jsx12(Text10, { children: pad2(" ") }),
|
|
1618
1668
|
lines.map((line, i) => {
|
|
1619
|
-
if (line === "") return /* @__PURE__ */ jsx12(
|
|
1620
|
-
return /* @__PURE__ */ jsx12(
|
|
1669
|
+
if (line === "") return /* @__PURE__ */ jsx12(Text10, { children: pad2(" ") }, i);
|
|
1670
|
+
return /* @__PURE__ */ jsx12(Text10, { children: pad2(line) }, i);
|
|
1621
1671
|
}),
|
|
1622
|
-
/* @__PURE__ */ jsx12(
|
|
1672
|
+
/* @__PURE__ */ jsx12(Text10, { children: pad2(" ") })
|
|
1623
1673
|
]
|
|
1624
1674
|
}
|
|
1625
1675
|
);
|
|
@@ -1629,38 +1679,8 @@ function HelpOverlay({ mode, rows, cols }) {
|
|
|
1629
1679
|
import { useState as useState3, useEffect as useEffect2, useRef as useRef2, useCallback } from "react";
|
|
1630
1680
|
|
|
1631
1681
|
// src/tui/lib/client.ts
|
|
1632
|
-
import { connect } from "net";
|
|
1633
1682
|
function send(request) {
|
|
1634
|
-
|
|
1635
|
-
return new Promise((resolve, reject) => {
|
|
1636
|
-
const socket = connect(sock);
|
|
1637
|
-
let data = "";
|
|
1638
|
-
const timeout = setTimeout(() => {
|
|
1639
|
-
socket.destroy();
|
|
1640
|
-
reject(new Error("Request timed out"));
|
|
1641
|
-
}, 5e3);
|
|
1642
|
-
socket.on("connect", () => {
|
|
1643
|
-
socket.write(JSON.stringify(request) + "\n");
|
|
1644
|
-
});
|
|
1645
|
-
socket.on("data", (chunk) => {
|
|
1646
|
-
data += chunk.toString();
|
|
1647
|
-
const idx = data.indexOf("\n");
|
|
1648
|
-
if (idx !== -1) {
|
|
1649
|
-
clearTimeout(timeout);
|
|
1650
|
-
const line = data.slice(0, idx);
|
|
1651
|
-
socket.destroy();
|
|
1652
|
-
try {
|
|
1653
|
-
resolve(JSON.parse(line));
|
|
1654
|
-
} catch {
|
|
1655
|
-
reject(new Error(`Invalid JSON from daemon`));
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
});
|
|
1659
|
-
socket.on("error", (err) => {
|
|
1660
|
-
clearTimeout(timeout);
|
|
1661
|
-
reject(err);
|
|
1662
|
-
});
|
|
1663
|
-
});
|
|
1683
|
+
return rawSend(request, 5e3);
|
|
1664
1684
|
}
|
|
1665
1685
|
|
|
1666
1686
|
// src/tui/hooks/usePolling.ts
|
|
@@ -1672,23 +1692,6 @@ import { execSync } from "child_process";
|
|
|
1672
1692
|
import { join } from "path";
|
|
1673
1693
|
import { readFileSync, writeFileSync, mkdtempSync, rmSync, cpSync, existsSync, mkdirSync } from "fs";
|
|
1674
1694
|
import { tmpdir } from "os";
|
|
1675
|
-
var EXEC_ENV = {
|
|
1676
|
-
...process.env,
|
|
1677
|
-
PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env["PATH"] ?? "/usr/bin:/bin"}`
|
|
1678
|
-
};
|
|
1679
|
-
function exec(cmd) {
|
|
1680
|
-
return execSync(cmd, { encoding: "utf-8", env: EXEC_ENV }).trim();
|
|
1681
|
-
}
|
|
1682
|
-
function execSafe(cmd) {
|
|
1683
|
-
try {
|
|
1684
|
-
return execSync(cmd, { encoding: "utf-8", env: EXEC_ENV, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
1685
|
-
} catch {
|
|
1686
|
-
return null;
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
function shellQuote(s) {
|
|
1690
|
-
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
1691
|
-
}
|
|
1692
1695
|
function selectWindow(windowId) {
|
|
1693
1696
|
execSafe(`tmux select-window -t "${windowId}"`);
|
|
1694
1697
|
}
|
|
@@ -1727,7 +1730,7 @@ Run \`sisyphus list\` and \`sisyphus status\` to see current state.`;
|
|
|
1727
1730
|
const rendered = template.replace(/\{\{CWD\}\}/g, cwd2);
|
|
1728
1731
|
const promptPath = join(globalDir(), "dashboard-companion-prompt.md");
|
|
1729
1732
|
writeFileSync(promptPath, rendered, "utf-8");
|
|
1730
|
-
const pathEnv =
|
|
1733
|
+
const pathEnv = augmentedPath();
|
|
1731
1734
|
const claudeCmd = `SISYPHUS_COMPANION_CWD=${shellQuote(cwd2)} PATH=${shellQuote(pathEnv)} claude --dangerously-skip-permissions --plugin-dir ${shellQuote(pluginDir)} --append-system-prompt "$(cat ${shellQuote(promptPath)})"`;
|
|
1732
1735
|
const result = exec(
|
|
1733
1736
|
`tmux split-window -h -d -l 33% -P -F "#{pane_id}" -c ${shellQuote(cwd2)} ${shellQuote(claudeCmd)}`
|
|
@@ -1799,6 +1802,15 @@ function usePolling(cwd2, selectedSessionId, intervalMs = 2500) {
|
|
|
1799
1802
|
const listRes = await send({ type: "list", cwd: cwd2 });
|
|
1800
1803
|
if (!mountedRef.current) return;
|
|
1801
1804
|
const sessions = listRes.ok ? listRes.data?.sessions ?? [] : [];
|
|
1805
|
+
for (const s of sessions) {
|
|
1806
|
+
if (s.status !== "completed" && s.tmuxWindowId) {
|
|
1807
|
+
try {
|
|
1808
|
+
s.windowAlive = windowExists(s.tmuxWindowId);
|
|
1809
|
+
} catch {
|
|
1810
|
+
s.windowAlive = false;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1802
1814
|
let selectedSession = null;
|
|
1803
1815
|
let planContent = "";
|
|
1804
1816
|
let goalContent = "";
|
|
@@ -1812,11 +1824,8 @@ function usePolling(cwd2, selectedSessionId, intervalMs = 2500) {
|
|
|
1812
1824
|
selectedSession = statusRes.data?.session ?? null;
|
|
1813
1825
|
}
|
|
1814
1826
|
if (selectedSession?.tmuxWindowId) {
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
} catch {
|
|
1818
|
-
paneAlive = false;
|
|
1819
|
-
}
|
|
1827
|
+
const cached = sessions.find((s) => s.id === selectedIdRef.current);
|
|
1828
|
+
paneAlive = cached?.windowAlive ?? false;
|
|
1820
1829
|
}
|
|
1821
1830
|
try {
|
|
1822
1831
|
const pp = roadmapPath(cwd2, selectedIdRef.current);
|
|
@@ -1855,7 +1864,11 @@ function usePolling(cwd2, selectedSessionId, intervalMs = 2500) {
|
|
|
1855
1864
|
}
|
|
1856
1865
|
}
|
|
1857
1866
|
if (mountedRef.current) {
|
|
1858
|
-
|
|
1867
|
+
const next = { sessions, selectedSession, planContent, goalContent, logsContent, logsCycles, paneAlive, contextFiles, error: null };
|
|
1868
|
+
setState((prev) => {
|
|
1869
|
+
if (JSON.stringify(prev) === JSON.stringify(next)) return prev;
|
|
1870
|
+
return next;
|
|
1871
|
+
});
|
|
1859
1872
|
}
|
|
1860
1873
|
} catch (err) {
|
|
1861
1874
|
if (mountedRef.current) {
|
|
@@ -2100,15 +2113,14 @@ function copyToClipboard(text) {
|
|
|
2100
2113
|
}
|
|
2101
2114
|
|
|
2102
2115
|
// src/tui/lib/tree.ts
|
|
2103
|
-
import { readdirSync as readdirSync2, existsSync as existsSync3 } from "fs";
|
|
2104
2116
|
import { join as join3 } from "path";
|
|
2105
2117
|
function sessionSortKey(s) {
|
|
2106
2118
|
if (s.status === "completed") return 4;
|
|
2107
|
-
const open = s.
|
|
2119
|
+
const open = s.windowAlive ?? false;
|
|
2108
2120
|
if (s.status === "active") return open ? 0 : 1;
|
|
2109
2121
|
return open ? 2 : 3;
|
|
2110
2122
|
}
|
|
2111
|
-
function buildTree(sessions, selectedSession, expanded, cwd2) {
|
|
2123
|
+
function buildTree(sessions, selectedSession, expanded, cwd2, polledContextFiles = []) {
|
|
2112
2124
|
const nodes = [];
|
|
2113
2125
|
const sorted = [...sessions].sort((a, b) => {
|
|
2114
2126
|
const keyDiff = sessionSortKey(a) - sessionSortKey(b);
|
|
@@ -2213,7 +2225,7 @@ function buildTree(sessions, selectedSession, expanded, cwd2) {
|
|
|
2213
2225
|
});
|
|
2214
2226
|
if (msgsExpanded) {
|
|
2215
2227
|
for (const msg of messages) {
|
|
2216
|
-
const
|
|
2228
|
+
const sourceLabel = msg.source.type === "user" ? "You" : msg.source.type === "agent" ? msg.source.agentId : "system";
|
|
2217
2229
|
nodes.push({
|
|
2218
2230
|
id: `message:${s.id}:${msg.id}`,
|
|
2219
2231
|
type: "message",
|
|
@@ -2222,23 +2234,14 @@ function buildTree(sessions, selectedSession, expanded, cwd2) {
|
|
|
2222
2234
|
expanded: false,
|
|
2223
2235
|
sessionId: s.id,
|
|
2224
2236
|
messageId: msg.id,
|
|
2225
|
-
source:
|
|
2237
|
+
source: sourceLabel,
|
|
2226
2238
|
summary: msg.summary || msg.content,
|
|
2227
2239
|
timestamp: msg.timestamp
|
|
2228
2240
|
});
|
|
2229
2241
|
}
|
|
2230
2242
|
}
|
|
2231
2243
|
}
|
|
2232
|
-
const
|
|
2233
|
-
let contextFiles = [];
|
|
2234
|
-
try {
|
|
2235
|
-
if (existsSync3(ctxDir)) {
|
|
2236
|
-
contextFiles = readdirSync2(ctxDir).filter(
|
|
2237
|
-
(f) => !f.startsWith(".")
|
|
2238
|
-
).sort();
|
|
2239
|
-
}
|
|
2240
|
-
} catch {
|
|
2241
|
-
}
|
|
2244
|
+
const contextFiles = isSelected ? polledContextFiles : [];
|
|
2242
2245
|
const ctxNodeId = `context:${s.id}`;
|
|
2243
2246
|
const ctxExpanded = expanded.has(ctxNodeId);
|
|
2244
2247
|
nodes.push({
|
|
@@ -2260,7 +2263,7 @@ function buildTree(sessions, selectedSession, expanded, cwd2) {
|
|
|
2260
2263
|
expanded: false,
|
|
2261
2264
|
sessionId: s.id,
|
|
2262
2265
|
label: filename,
|
|
2263
|
-
filePath: join3(
|
|
2266
|
+
filePath: join3(contextDir(cwd2, s.id), filename)
|
|
2264
2267
|
});
|
|
2265
2268
|
}
|
|
2266
2269
|
}
|
|
@@ -2279,8 +2282,8 @@ function findParentIndex(nodes, index) {
|
|
|
2279
2282
|
}
|
|
2280
2283
|
|
|
2281
2284
|
// src/tui/App.tsx
|
|
2282
|
-
import { readFileSync as readFileSync3, existsSync as
|
|
2283
|
-
import {
|
|
2285
|
+
import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
|
|
2286
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2284
2287
|
function resolveEditor(configEditor) {
|
|
2285
2288
|
if (configEditor) return configEditor;
|
|
2286
2289
|
if (process.env.EDITOR) return process.env.EDITOR;
|
|
@@ -2306,16 +2309,16 @@ function App({ cwd: cwd2 }) {
|
|
|
2306
2309
|
const cursorNodeIdRef = useRef3(null);
|
|
2307
2310
|
const prevNodesRef = useRef3([]);
|
|
2308
2311
|
const { sessions, selectedSession, planContent, goalContent, logsContent, logsCycles, paneAlive, contextFiles, error } = usePolling(cwd2, selectedSessionId);
|
|
2309
|
-
const filteredSessions =
|
|
2312
|
+
const filteredSessions = useMemo6(() => {
|
|
2310
2313
|
if (!searchFilter) return sessions;
|
|
2311
2314
|
const q = searchFilter.toLowerCase();
|
|
2312
2315
|
return sessions.filter(
|
|
2313
2316
|
(s) => s.task.toLowerCase().includes(q) || s.id.toLowerCase().includes(q)
|
|
2314
2317
|
);
|
|
2315
2318
|
}, [sessions, searchFilter]);
|
|
2316
|
-
const nodes =
|
|
2317
|
-
() => buildTree(filteredSessions, selectedSession, expanded, cwd2),
|
|
2318
|
-
[filteredSessions, selectedSession, expanded, cwd2]
|
|
2319
|
+
const nodes = useMemo6(
|
|
2320
|
+
() => buildTree(filteredSessions, selectedSession, expanded, cwd2, contextFiles),
|
|
2321
|
+
[filteredSessions, selectedSession, expanded, cwd2, contextFiles]
|
|
2319
2322
|
);
|
|
2320
2323
|
if (nodes === prevNodesRef.current) {
|
|
2321
2324
|
const node = nodes[cursorIndex];
|
|
@@ -2989,29 +2992,29 @@ function App({ cwd: cwd2 }) {
|
|
|
2989
2992
|
setFocusPane("tree");
|
|
2990
2993
|
setTargetAgentId(null);
|
|
2991
2994
|
}, []);
|
|
2992
|
-
const reportAgent =
|
|
2995
|
+
const reportAgent = useMemo6(() => {
|
|
2993
2996
|
if (mode === "report-detail") return getAgentForNode(cursorNode);
|
|
2994
2997
|
return null;
|
|
2995
2998
|
}, [mode, cursorNode, getAgentForNode]);
|
|
2996
|
-
const reportBlocks =
|
|
2999
|
+
const reportBlocks = useMemo6(
|
|
2997
3000
|
() => reportAgent ? resolveReports(reportAgent.reports) : [],
|
|
2998
3001
|
[reportAgent]
|
|
2999
3002
|
);
|
|
3000
|
-
const detailAgent =
|
|
3003
|
+
const detailAgent = useMemo6(() => {
|
|
3001
3004
|
if (!cursorNode) return null;
|
|
3002
3005
|
if (cursorNode.type === "agent" || cursorNode.type === "report") {
|
|
3003
3006
|
return getAgentForNode(cursorNode);
|
|
3004
3007
|
}
|
|
3005
3008
|
return null;
|
|
3006
3009
|
}, [cursorNode, getAgentForNode]);
|
|
3007
|
-
const detailReportBlocks =
|
|
3010
|
+
const detailReportBlocks = useMemo6(
|
|
3008
3011
|
() => detailAgent ? resolveReports(detailAgent.reports) : [],
|
|
3009
3012
|
[detailAgent]
|
|
3010
3013
|
);
|
|
3011
|
-
const contextFileContent =
|
|
3014
|
+
const contextFileContent = useMemo6(() => {
|
|
3012
3015
|
if (!cursorNode || cursorNode.type !== "context-file") return null;
|
|
3013
3016
|
try {
|
|
3014
|
-
if (
|
|
3017
|
+
if (existsSync3(cursorNode.filePath)) {
|
|
3015
3018
|
return readFileSync3(cursorNode.filePath, "utf-8");
|
|
3016
3019
|
}
|
|
3017
3020
|
} catch {
|
|
@@ -3075,7 +3078,9 @@ function App({ cwd: cwd2 }) {
|
|
|
3075
3078
|
logsContent,
|
|
3076
3079
|
width: detailWidth2,
|
|
3077
3080
|
height: contentHeight2,
|
|
3078
|
-
paneAlive
|
|
3081
|
+
paneAlive,
|
|
3082
|
+
scrollOffset: detailScrollOffset,
|
|
3083
|
+
focused: focusPane === "detail"
|
|
3079
3084
|
}
|
|
3080
3085
|
);
|
|
3081
3086
|
}
|
|
@@ -3085,7 +3090,9 @@ function App({ cwd: cwd2 }) {
|
|
|
3085
3090
|
cycle,
|
|
3086
3091
|
agents: session.agents,
|
|
3087
3092
|
width: detailWidth2,
|
|
3088
|
-
height: contentHeight2
|
|
3093
|
+
height: contentHeight2,
|
|
3094
|
+
scrollOffset: detailScrollOffset,
|
|
3095
|
+
focused: focusPane === "detail"
|
|
3089
3096
|
}
|
|
3090
3097
|
);
|
|
3091
3098
|
}
|
|
@@ -3100,7 +3107,9 @@ function App({ cwd: cwd2 }) {
|
|
|
3100
3107
|
logsContent,
|
|
3101
3108
|
width: detailWidth2,
|
|
3102
3109
|
height: contentHeight2,
|
|
3103
|
-
paneAlive
|
|
3110
|
+
paneAlive,
|
|
3111
|
+
scrollOffset: detailScrollOffset,
|
|
3112
|
+
focused: focusPane === "detail"
|
|
3104
3113
|
}
|
|
3105
3114
|
);
|
|
3106
3115
|
}
|
|
@@ -3110,7 +3119,9 @@ function App({ cwd: cwd2 }) {
|
|
|
3110
3119
|
agent,
|
|
3111
3120
|
reportBlocks: detailReportBlocks,
|
|
3112
3121
|
width: detailWidth2,
|
|
3113
|
-
height: contentHeight2
|
|
3122
|
+
height: contentHeight2,
|
|
3123
|
+
scrollOffset: detailScrollOffset,
|
|
3124
|
+
focused: focusPane === "detail"
|
|
3114
3125
|
}
|
|
3115
3126
|
);
|
|
3116
3127
|
}
|
|
@@ -3125,7 +3136,9 @@ function App({ cwd: cwd2 }) {
|
|
|
3125
3136
|
logsContent,
|
|
3126
3137
|
width: detailWidth2,
|
|
3127
3138
|
height: contentHeight2,
|
|
3128
|
-
paneAlive
|
|
3139
|
+
paneAlive,
|
|
3140
|
+
scrollOffset: detailScrollOffset,
|
|
3141
|
+
focused: focusPane === "detail"
|
|
3129
3142
|
}
|
|
3130
3143
|
);
|
|
3131
3144
|
}
|
|
@@ -3137,45 +3150,22 @@ function App({ cwd: cwd2 }) {
|
|
|
3137
3150
|
if (specificBlock) {
|
|
3138
3151
|
const badge = specificBlock.type === "final" ? "FINAL" : "UPDATE";
|
|
3139
3152
|
const badgeColor = specificBlock.type === "final" ? "cyan" : "yellow";
|
|
3140
|
-
const
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3153
|
+
const reportContentLines = [
|
|
3154
|
+
[seg(" "), seg(badge, { color: badgeColor }), seg(` ${agent.id} \xB7 ${agent.name !== agent.id ? agent.name : agent.agentType}`, { bold: true })],
|
|
3155
|
+
singleLine(` ${formatTime(specificBlock.timestamp)}`, { dim: true }),
|
|
3156
|
+
singleLine(" "),
|
|
3157
|
+
[seg(" \u258E CONTENT", { color: badgeColor, bold: true })],
|
|
3158
|
+
...wrapText(specificBlock.content.trim(), detailWidth2 - 8).map((l) => singleLine(` ${l}`))
|
|
3159
|
+
];
|
|
3160
|
+
return /* @__PURE__ */ jsx13(
|
|
3161
|
+
ScrollablePanel,
|
|
3144
3162
|
{
|
|
3145
|
-
|
|
3163
|
+
lines: reportContentLines,
|
|
3146
3164
|
width: detailWidth2,
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
/* @__PURE__ */ jsxs12(Text13, { bold: true, children: [
|
|
3152
|
-
" ",
|
|
3153
|
-
/* @__PURE__ */ jsx13(Text13, { color: badgeColor, children: badge }),
|
|
3154
|
-
" ",
|
|
3155
|
-
agent.id,
|
|
3156
|
-
" \xB7 ",
|
|
3157
|
-
agent.name !== agent.id ? agent.name : agent.agentType
|
|
3158
|
-
] }),
|
|
3159
|
-
/* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3160
|
-
" ",
|
|
3161
|
-
formatTime(specificBlock.timestamp)
|
|
3162
|
-
] }),
|
|
3163
|
-
/* @__PURE__ */ jsx13(Text13, { children: " " }),
|
|
3164
|
-
/* @__PURE__ */ jsxs12(Text13, { color: badgeColor, bold: true, children: [
|
|
3165
|
-
" ",
|
|
3166
|
-
"\u258E CONTENT"
|
|
3167
|
-
] }),
|
|
3168
|
-
reportLines.slice(0, viewableLines).map((line, i) => /* @__PURE__ */ jsxs12(Text13, { children: [
|
|
3169
|
-
" ",
|
|
3170
|
-
line
|
|
3171
|
-
] }, i)),
|
|
3172
|
-
reportLines.length > viewableLines && /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3173
|
-
" ",
|
|
3174
|
-
"\u2026 ",
|
|
3175
|
-
reportLines.length - viewableLines,
|
|
3176
|
-
" more lines [enter] full view"
|
|
3177
|
-
] })
|
|
3178
|
-
]
|
|
3165
|
+
height: contentHeight2,
|
|
3166
|
+
scrollOffset: detailScrollOffset,
|
|
3167
|
+
focused: focusPane === "detail",
|
|
3168
|
+
borderColor: badgeColor
|
|
3179
3169
|
}
|
|
3180
3170
|
);
|
|
3181
3171
|
}
|
|
@@ -3185,127 +3175,114 @@ function App({ cwd: cwd2 }) {
|
|
|
3185
3175
|
agent,
|
|
3186
3176
|
reportBlocks: detailReportBlocks,
|
|
3187
3177
|
width: detailWidth2,
|
|
3188
|
-
height: contentHeight2
|
|
3178
|
+
height: contentHeight2,
|
|
3179
|
+
scrollOffset: detailScrollOffset,
|
|
3180
|
+
focused: focusPane === "detail"
|
|
3189
3181
|
}
|
|
3190
3182
|
);
|
|
3191
3183
|
}
|
|
3192
|
-
case "messages":
|
|
3193
|
-
|
|
3194
|
-
|
|
3184
|
+
case "messages": {
|
|
3185
|
+
const msgsLines = [
|
|
3186
|
+
singleLine(` Messages (${session.messages.length})`, { bold: true })
|
|
3187
|
+
];
|
|
3188
|
+
if (session.messages.length === 0) {
|
|
3189
|
+
msgsLines.push(singleLine(" No messages", { dim: true, italic: true }));
|
|
3190
|
+
} else {
|
|
3191
|
+
for (const msg of session.messages) {
|
|
3192
|
+
const time = formatTime(msg.timestamp);
|
|
3193
|
+
const label = msg.source.type === "user" ? "You" : msg.source.type === "agent" ? msg.source.agentId : "system";
|
|
3194
|
+
const labelColor = msg.source.type === "user" ? "yellow" : msg.source.type === "agent" ? "cyan" : "gray";
|
|
3195
|
+
const maxContent = Math.max(10, detailWidth2 - label.length - 20);
|
|
3196
|
+
msgsLines.push([
|
|
3197
|
+
seg(` [${time}] `, { dim: true }),
|
|
3198
|
+
seg(`${label}: `, { color: labelColor, bold: true }),
|
|
3199
|
+
seg(wrapText(msg.summary || msg.content, maxContent)[0] || "", {})
|
|
3200
|
+
]);
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
return /* @__PURE__ */ jsx13(
|
|
3204
|
+
ScrollablePanel,
|
|
3195
3205
|
{
|
|
3196
|
-
|
|
3206
|
+
lines: msgsLines,
|
|
3197
3207
|
width: detailWidth2,
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
children: [
|
|
3202
|
-
/* @__PURE__ */ jsxs12(Text13, { bold: true, children: [
|
|
3203
|
-
" Messages (",
|
|
3204
|
-
session.messages.length,
|
|
3205
|
-
")"
|
|
3206
|
-
] }),
|
|
3207
|
-
/* @__PURE__ */ jsx13(
|
|
3208
|
-
MessageLog,
|
|
3209
|
-
{
|
|
3210
|
-
messages: session.messages,
|
|
3211
|
-
maxMessages: contentHeight2 - 4,
|
|
3212
|
-
width: detailWidth2 - 4
|
|
3213
|
-
}
|
|
3214
|
-
)
|
|
3215
|
-
]
|
|
3208
|
+
height: contentHeight2,
|
|
3209
|
+
scrollOffset: detailScrollOffset,
|
|
3210
|
+
focused: focusPane === "detail"
|
|
3216
3211
|
}
|
|
3217
3212
|
);
|
|
3213
|
+
}
|
|
3218
3214
|
case "message": {
|
|
3219
3215
|
const msg = session.messages.find((m) => m.id === cursorNode.messageId);
|
|
3220
|
-
|
|
3221
|
-
|
|
3216
|
+
const msgContentLines = [
|
|
3217
|
+
singleLine(" Message", { bold: true })
|
|
3218
|
+
];
|
|
3219
|
+
if (msg) {
|
|
3220
|
+
msgContentLines.push(singleLine(` ${cursorNode.source} \xB7 ${cursorNode.timestamp}`, { dim: true }));
|
|
3221
|
+
for (const l of wrapText(msg.content, detailWidth2 - 8)) {
|
|
3222
|
+
msgContentLines.push(singleLine(` ${l}`));
|
|
3223
|
+
}
|
|
3224
|
+
} else {
|
|
3225
|
+
msgContentLines.push(singleLine(" Message not found", { dim: true }));
|
|
3226
|
+
}
|
|
3227
|
+
return /* @__PURE__ */ jsx13(
|
|
3228
|
+
ScrollablePanel,
|
|
3222
3229
|
{
|
|
3223
|
-
|
|
3230
|
+
lines: msgContentLines,
|
|
3224
3231
|
width: detailWidth2,
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
children: [
|
|
3229
|
-
/* @__PURE__ */ jsx13(Text13, { bold: true, children: " Message" }),
|
|
3230
|
-
msg ? /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
3231
|
-
/* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3232
|
-
" ",
|
|
3233
|
-
cursorNode.source,
|
|
3234
|
-
" \xB7 ",
|
|
3235
|
-
cursorNode.timestamp
|
|
3236
|
-
] }),
|
|
3237
|
-
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
3238
|
-
" ",
|
|
3239
|
-
msg.content
|
|
3240
|
-
] })
|
|
3241
|
-
] }) : /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "Message not found" })
|
|
3242
|
-
]
|
|
3232
|
+
height: contentHeight2,
|
|
3233
|
+
scrollOffset: detailScrollOffset,
|
|
3234
|
+
focused: focusPane === "detail"
|
|
3243
3235
|
}
|
|
3244
3236
|
);
|
|
3245
3237
|
}
|
|
3246
|
-
case "context":
|
|
3247
|
-
|
|
3248
|
-
|
|
3238
|
+
case "context": {
|
|
3239
|
+
const ctxLines = [
|
|
3240
|
+
[seg(" "), seg("\u229E", { color: "white" }), seg(` Context (${contextFiles.length})`, { bold: true })]
|
|
3241
|
+
];
|
|
3242
|
+
if (contextFiles.length === 0) {
|
|
3243
|
+
ctxLines.push(singleLine(" No context files found.", { dim: true }));
|
|
3244
|
+
} else {
|
|
3245
|
+
for (const f of contextFiles) {
|
|
3246
|
+
ctxLines.push(singleLine(` \xB7 ${f}`, { dim: true }));
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
return /* @__PURE__ */ jsx13(
|
|
3250
|
+
ScrollablePanel,
|
|
3249
3251
|
{
|
|
3250
|
-
|
|
3252
|
+
lines: ctxLines,
|
|
3251
3253
|
width: detailWidth2,
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
children: [
|
|
3256
|
-
/* @__PURE__ */ jsxs12(Text13, { bold: true, children: [
|
|
3257
|
-
" ",
|
|
3258
|
-
/* @__PURE__ */ jsx13(Text13, { color: "white", children: "\u229E" }),
|
|
3259
|
-
" Context (",
|
|
3260
|
-
contextFiles.length,
|
|
3261
|
-
")"
|
|
3262
|
-
] }),
|
|
3263
|
-
contextFiles.length === 0 ? /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3264
|
-
" ",
|
|
3265
|
-
"No context files found."
|
|
3266
|
-
] }) : contextFiles.map((f) => /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3267
|
-
" \xB7 ",
|
|
3268
|
-
f
|
|
3269
|
-
] }, f))
|
|
3270
|
-
]
|
|
3254
|
+
height: contentHeight2,
|
|
3255
|
+
scrollOffset: detailScrollOffset,
|
|
3256
|
+
focused: focusPane === "detail"
|
|
3271
3257
|
}
|
|
3272
3258
|
);
|
|
3259
|
+
}
|
|
3273
3260
|
case "context-file": {
|
|
3274
|
-
const
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3261
|
+
const ctxFileLines = [
|
|
3262
|
+
[seg(" "), seg("\u229E", { color: "white" }), seg(` ${cursorNode.label}`, { bold: true })],
|
|
3263
|
+
singleLine(" ")
|
|
3264
|
+
];
|
|
3265
|
+
if (contextFileContent == null) {
|
|
3266
|
+
ctxFileLines.push(singleLine(" File not found or unreadable.", { dim: true }));
|
|
3267
|
+
} else {
|
|
3268
|
+
const wrapped = wrapText(cleanMarkdown(stripFrontmatter(contextFileContent)), detailWidth2 - 8);
|
|
3269
|
+
if (wrapped.length === 0) {
|
|
3270
|
+
ctxFileLines.push(singleLine(" (empty)", { dim: true }));
|
|
3271
|
+
} else {
|
|
3272
|
+
for (const l of wrapped) {
|
|
3273
|
+
ctxFileLines.push(singleLine(` ${l}`));
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3277
|
+
return /* @__PURE__ */ jsx13(
|
|
3278
|
+
ScrollablePanel,
|
|
3278
3279
|
{
|
|
3279
|
-
|
|
3280
|
+
lines: ctxFileLines,
|
|
3280
3281
|
width: detailWidth2,
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
/* @__PURE__ */ jsxs12(Text13, { bold: true, children: [
|
|
3286
|
-
" ",
|
|
3287
|
-
/* @__PURE__ */ jsx13(Text13, { color: "white", children: "\u229E" }),
|
|
3288
|
-
" ",
|
|
3289
|
-
cursorNode.label
|
|
3290
|
-
] }),
|
|
3291
|
-
/* @__PURE__ */ jsx13(Text13, { children: " " }),
|
|
3292
|
-
contextFileContent == null ? /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3293
|
-
" ",
|
|
3294
|
-
"File not found or unreadable."
|
|
3295
|
-
] }) : fileLines.length === 0 ? /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3296
|
-
" ",
|
|
3297
|
-
"(empty)"
|
|
3298
|
-
] }) : fileLines.slice(0, viewableLines).map((line, i) => /* @__PURE__ */ jsxs12(Text13, { children: [
|
|
3299
|
-
" ",
|
|
3300
|
-
line
|
|
3301
|
-
] }, i)),
|
|
3302
|
-
fileLines.length > viewableLines && /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
|
|
3303
|
-
" ",
|
|
3304
|
-
"\u2026 ",
|
|
3305
|
-
fileLines.length - viewableLines,
|
|
3306
|
-
" more lines"
|
|
3307
|
-
] })
|
|
3308
|
-
]
|
|
3282
|
+
height: contentHeight2,
|
|
3283
|
+
scrollOffset: detailScrollOffset,
|
|
3284
|
+
focused: focusPane === "detail",
|
|
3285
|
+
borderColor: "white"
|
|
3309
3286
|
}
|
|
3310
3287
|
);
|
|
3311
3288
|
}
|
|
@@ -3318,15 +3295,30 @@ function App({ cwd: cwd2 }) {
|
|
|
3318
3295
|
goalContent,
|
|
3319
3296
|
width: detailWidth2,
|
|
3320
3297
|
height: contentHeight2,
|
|
3321
|
-
paneAlive
|
|
3298
|
+
paneAlive,
|
|
3299
|
+
scrollOffset: detailScrollOffset,
|
|
3300
|
+
focused: focusPane === "detail"
|
|
3322
3301
|
}
|
|
3323
3302
|
);
|
|
3324
3303
|
}
|
|
3325
3304
|
},
|
|
3326
3305
|
[cursorNode, session, planContent, goalContent, logsContent, paneAlive, agents, mode, reportAgent, reportBlocks, detailReportBlocks, handleCancel, detailScrollOffset, focusPane, contextFiles, contextFileContent]
|
|
3327
3306
|
);
|
|
3328
|
-
|
|
3329
|
-
/* @__PURE__ */
|
|
3307
|
+
if (cols < 60 || rows < 12) {
|
|
3308
|
+
return /* @__PURE__ */ jsxs8(Box11, { flexDirection: "column", width: cols, height: rows, justifyContent: "center", alignItems: "center", children: [
|
|
3309
|
+
/* @__PURE__ */ jsx13(Text11, { color: "yellow", bold: true, children: "Terminal too small" }),
|
|
3310
|
+
/* @__PURE__ */ jsxs8(Text11, { dimColor: true, children: [
|
|
3311
|
+
"Minimum: 60\xD712 (current: ",
|
|
3312
|
+
cols,
|
|
3313
|
+
"\xD7",
|
|
3314
|
+
rows,
|
|
3315
|
+
")"
|
|
3316
|
+
] }),
|
|
3317
|
+
/* @__PURE__ */ jsx13(Text11, { dimColor: true, children: "Resize your terminal and try again." })
|
|
3318
|
+
] });
|
|
3319
|
+
}
|
|
3320
|
+
return /* @__PURE__ */ jsxs8(Box11, { flexDirection: "column", width: cols, height: rows, children: [
|
|
3321
|
+
/* @__PURE__ */ jsxs8(Box11, { flexDirection: "row", height: contentHeight, children: [
|
|
3330
3322
|
/* @__PURE__ */ jsx13(
|
|
3331
3323
|
SessionTree,
|
|
3332
3324
|
{
|
|
@@ -3349,8 +3341,8 @@ function App({ cwd: cwd2 }) {
|
|
|
3349
3341
|
}
|
|
3350
3342
|
)
|
|
3351
3343
|
] }),
|
|
3352
|
-
notification && /* @__PURE__ */ jsx13(
|
|
3353
|
-
error && !notification && /* @__PURE__ */ jsx13(
|
|
3344
|
+
notification && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text11, { color: "yellow", bold: true, children: /error|failed/i.test(notification) ? `\u2715 ${notification}` : /success|created|killed|sent|copied|deleted/i.test(notification) ? `\u2713 ${notification}` : `\u2139 ${notification}` }) }),
|
|
3345
|
+
error && !notification && /* @__PURE__ */ jsx13(Box11, { paddingX: 1, children: /* @__PURE__ */ jsxs8(Text11, { color: "red", children: [
|
|
3354
3346
|
"\u26A0 ",
|
|
3355
3347
|
error
|
|
3356
3348
|
] }) }),
|