agenthud 0.6.4 → 0.7.0
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/index.js +366 -135
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -355,7 +355,9 @@ function getDefaultConfig2() {
|
|
|
355
355
|
}
|
|
356
356
|
},
|
|
357
357
|
panelOrder: ["project", "git", "tests", "claude", "other_sessions"],
|
|
358
|
-
width: DEFAULT_WIDTH
|
|
358
|
+
width: DEFAULT_WIDTH,
|
|
359
|
+
wideLayoutThreshold: null
|
|
360
|
+
// disabled by default
|
|
359
361
|
};
|
|
360
362
|
}
|
|
361
363
|
var BUILTIN_PANELS = ["project", "git", "tests", "claude", "other_sessions"];
|
|
@@ -410,6 +412,18 @@ function parseConfig() {
|
|
|
410
412
|
config.width = parsed.width;
|
|
411
413
|
}
|
|
412
414
|
}
|
|
415
|
+
const MIN_WIDE_THRESHOLD = 140;
|
|
416
|
+
const wideThresholdValue = parsed.wideLayoutThreshold ?? parsed.wide_layout_threshold;
|
|
417
|
+
if (typeof wideThresholdValue === "number") {
|
|
418
|
+
if (wideThresholdValue < MIN_WIDE_THRESHOLD) {
|
|
419
|
+
warnings.push(
|
|
420
|
+
`wideLayoutThreshold ${wideThresholdValue} is too small, using minimum of ${MIN_WIDE_THRESHOLD}`
|
|
421
|
+
);
|
|
422
|
+
config.wideLayoutThreshold = MIN_WIDE_THRESHOLD;
|
|
423
|
+
} else {
|
|
424
|
+
config.wideLayoutThreshold = wideThresholdValue;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
413
427
|
const panels = parsed.panels;
|
|
414
428
|
if (!panels || typeof panels !== "object") {
|
|
415
429
|
return { config, warnings };
|
|
@@ -550,6 +564,9 @@ var ICONS = {
|
|
|
550
564
|
};
|
|
551
565
|
|
|
552
566
|
// src/data/claude.ts
|
|
567
|
+
function stripAnsi(text) {
|
|
568
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
569
|
+
}
|
|
553
570
|
var MAX_LINES_TO_SCAN = 200;
|
|
554
571
|
var DEFAULT_MAX_ACTIVITIES = 10;
|
|
555
572
|
function getClaudeSessionPath2(projectPath) {
|
|
@@ -586,22 +603,84 @@ function findActiveSession(sessionDir, sessionTimeout) {
|
|
|
586
603
|
function getToolDetail(_toolName, input) {
|
|
587
604
|
if (!input) return "";
|
|
588
605
|
if (input.command) {
|
|
589
|
-
return input.command.replace(/\n/g, " ");
|
|
606
|
+
return stripAnsi(input.command.replace(/\n/g, " "));
|
|
590
607
|
}
|
|
591
608
|
if (input.file_path) {
|
|
592
609
|
return basename(input.file_path);
|
|
593
610
|
}
|
|
594
611
|
if (input.pattern) {
|
|
595
|
-
return input.pattern;
|
|
612
|
+
return stripAnsi(input.pattern);
|
|
596
613
|
}
|
|
597
614
|
if (input.query) {
|
|
598
|
-
return input.query;
|
|
615
|
+
return stripAnsi(input.query);
|
|
599
616
|
}
|
|
600
617
|
if (input.description) {
|
|
601
|
-
return input.description;
|
|
618
|
+
return stripAnsi(input.description);
|
|
602
619
|
}
|
|
603
620
|
return "";
|
|
604
621
|
}
|
|
622
|
+
var MAX_SUB_ACTIVITIES = 3;
|
|
623
|
+
function getSubagentFiles(sessionFile) {
|
|
624
|
+
const subagentsDir = join3(sessionFile.replace(/\.jsonl$/, ""), "subagents");
|
|
625
|
+
if (!existsSync4(subagentsDir)) {
|
|
626
|
+
return [];
|
|
627
|
+
}
|
|
628
|
+
try {
|
|
629
|
+
const files = readdirSync(subagentsDir).filter(
|
|
630
|
+
(f) => f.endsWith(".jsonl")
|
|
631
|
+
);
|
|
632
|
+
const fileInfos = files.map((file) => {
|
|
633
|
+
const filePath = join3(subagentsDir, file);
|
|
634
|
+
const stat = statSync(filePath);
|
|
635
|
+
return { filePath, mtimeMs: stat.mtimeMs };
|
|
636
|
+
});
|
|
637
|
+
fileInfos.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
638
|
+
return fileInfos;
|
|
639
|
+
} catch {
|
|
640
|
+
return [];
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
function parseSubagentFile(filePath) {
|
|
644
|
+
try {
|
|
645
|
+
const content = readFileSync5(filePath, "utf-8");
|
|
646
|
+
const lines = content.trim().split("\n").filter(Boolean);
|
|
647
|
+
const allActivities = [];
|
|
648
|
+
for (const line of lines) {
|
|
649
|
+
try {
|
|
650
|
+
const entry = JSON.parse(line);
|
|
651
|
+
if (entry.type === "assistant" && entry.message?.content) {
|
|
652
|
+
const messageContent = entry.message.content;
|
|
653
|
+
if (Array.isArray(messageContent)) {
|
|
654
|
+
for (const block of messageContent) {
|
|
655
|
+
if (block.type === "tool_use" && block.name) {
|
|
656
|
+
const toolName = block.name;
|
|
657
|
+
if (toolName === "TodoWrite") continue;
|
|
658
|
+
const icon = ICONS[toolName] || ICONS.Default;
|
|
659
|
+
const detail = getToolDetail(toolName, block.input);
|
|
660
|
+
const timestamp = entry.timestamp ? new Date(entry.timestamp) : /* @__PURE__ */ new Date();
|
|
661
|
+
allActivities.push({
|
|
662
|
+
timestamp,
|
|
663
|
+
type: "tool",
|
|
664
|
+
icon,
|
|
665
|
+
label: toolName,
|
|
666
|
+
detail
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
} catch {
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
allActivities.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
676
|
+
return {
|
|
677
|
+
activities: allActivities.slice(0, MAX_SUB_ACTIVITIES),
|
|
678
|
+
totalCount: allActivities.length
|
|
679
|
+
};
|
|
680
|
+
} catch {
|
|
681
|
+
return { activities: [], totalCount: 0 };
|
|
682
|
+
}
|
|
683
|
+
}
|
|
605
684
|
function parseSessionState(sessionFile, maxActivities = DEFAULT_MAX_ACTIVITIES) {
|
|
606
685
|
const defaultState = {
|
|
607
686
|
status: "none",
|
|
@@ -699,13 +778,14 @@ function parseSessionState(sessionFile, maxActivities = DEFAULT_MAX_ACTIVITIES)
|
|
|
699
778
|
lastActivity.count = (lastActivity.count || 1) + 1;
|
|
700
779
|
lastActivity.timestamp = lastTimestamp || /* @__PURE__ */ new Date();
|
|
701
780
|
} else {
|
|
702
|
-
|
|
781
|
+
const activity = {
|
|
703
782
|
timestamp: lastTimestamp || /* @__PURE__ */ new Date(),
|
|
704
783
|
type: "tool",
|
|
705
784
|
icon,
|
|
706
785
|
label: toolName,
|
|
707
786
|
detail
|
|
708
|
-
}
|
|
787
|
+
};
|
|
788
|
+
activities.push(activity);
|
|
709
789
|
}
|
|
710
790
|
lastType = "tool";
|
|
711
791
|
} else if (block.type === "text" && block.text) {
|
|
@@ -755,10 +835,10 @@ function parseSessionState(sessionFile, maxActivities = DEFAULT_MAX_ACTIVITIES)
|
|
|
755
835
|
const subagentsDir = join3(sessionFile.replace(/\.jsonl$/, ""), "subagents");
|
|
756
836
|
if (existsSync4(subagentsDir)) {
|
|
757
837
|
try {
|
|
758
|
-
const
|
|
838
|
+
const subagentFiles2 = readdirSync(subagentsDir).filter(
|
|
759
839
|
(f) => f.endsWith(".jsonl")
|
|
760
840
|
);
|
|
761
|
-
for (const file of
|
|
841
|
+
for (const file of subagentFiles2) {
|
|
762
842
|
const filePath = join3(subagentsDir, file);
|
|
763
843
|
try {
|
|
764
844
|
const subContent = readFileSync5(filePath, "utf-8");
|
|
@@ -779,9 +859,22 @@ function parseSessionState(sessionFile, maxActivities = DEFAULT_MAX_ACTIVITIES)
|
|
|
779
859
|
} catch {
|
|
780
860
|
}
|
|
781
861
|
}
|
|
862
|
+
const finalActivities = activities.slice(-maxActivities).reverse();
|
|
863
|
+
const subagentFiles = getSubagentFiles(sessionFile);
|
|
864
|
+
let taskIndex = 0;
|
|
865
|
+
for (const activity of finalActivities) {
|
|
866
|
+
if (activity.label === "Task" && taskIndex < subagentFiles.length) {
|
|
867
|
+
const subagentData = parseSubagentFile(subagentFiles[taskIndex].filePath);
|
|
868
|
+
if (subagentData.totalCount > 0) {
|
|
869
|
+
activity.subActivities = subagentData.activities;
|
|
870
|
+
activity.subActivityCount = subagentData.totalCount;
|
|
871
|
+
}
|
|
872
|
+
taskIndex++;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
782
875
|
return {
|
|
783
876
|
status,
|
|
784
|
-
activities:
|
|
877
|
+
activities: finalActivities,
|
|
785
878
|
tokenCount,
|
|
786
879
|
sessionStartTime,
|
|
787
880
|
todos
|
|
@@ -2050,7 +2143,8 @@ function ClaudePanel({
|
|
|
2050
2143
|
countdown,
|
|
2051
2144
|
width = DEFAULT_PANEL_WIDTH,
|
|
2052
2145
|
isRunning = false,
|
|
2053
|
-
justRefreshed = false
|
|
2146
|
+
justRefreshed = false,
|
|
2147
|
+
maxActivities
|
|
2054
2148
|
}) {
|
|
2055
2149
|
const countdownSuffix = isRunning ? "running..." : formatCountdown(countdown);
|
|
2056
2150
|
const innerWidth = getInnerWidth(width);
|
|
@@ -2109,15 +2203,22 @@ function ClaudePanel({
|
|
|
2109
2203
|
] });
|
|
2110
2204
|
}
|
|
2111
2205
|
const lines = [];
|
|
2112
|
-
|
|
2113
|
-
|
|
2206
|
+
const displayActivities = maxActivities !== void 0 ? state.activities.slice(0, maxActivities) : state.activities;
|
|
2207
|
+
for (let i = 0; i < displayActivities.length; i++) {
|
|
2208
|
+
const activity = displayActivities[i];
|
|
2209
|
+
let modifiedActivity = activity;
|
|
2210
|
+
if (activity.label === "Task" && activity.subActivityCount && activity.subActivityCount > 0) {
|
|
2211
|
+
modifiedActivity = {
|
|
2212
|
+
...activity,
|
|
2213
|
+
detail: activity.detail ? `${activity.detail} (${activity.subActivityCount})` : `(${activity.subActivityCount})`
|
|
2214
|
+
};
|
|
2215
|
+
}
|
|
2114
2216
|
const { timestamp, icon, labelContent, displayWidth } = formatActivityParts(
|
|
2115
|
-
|
|
2217
|
+
modifiedActivity,
|
|
2116
2218
|
contentWidth
|
|
2117
2219
|
);
|
|
2118
2220
|
const padding = Math.max(0, contentWidth - displayWidth);
|
|
2119
2221
|
const style = getActivityStyle(activity);
|
|
2120
|
-
const clearEOL = "\x1B[K";
|
|
2121
2222
|
lines.push(
|
|
2122
2223
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2123
2224
|
BOX.v,
|
|
@@ -2127,10 +2228,62 @@ function ClaudePanel({
|
|
|
2127
2228
|
" ",
|
|
2128
2229
|
/* @__PURE__ */ jsx(Text, { color: style.color, dimColor: style.dimColor, children: labelContent }),
|
|
2129
2230
|
" ".repeat(padding),
|
|
2130
|
-
BOX.v
|
|
2131
|
-
clearEOL
|
|
2231
|
+
BOX.v
|
|
2132
2232
|
] }, `activity-${i}`)
|
|
2133
2233
|
);
|
|
2234
|
+
if (activity.subActivities && activity.subActivities.length > 0) {
|
|
2235
|
+
const subPrefix = " \u2514 ";
|
|
2236
|
+
const subPrefixWidth = getDisplayWidth(subPrefix);
|
|
2237
|
+
for (let j = 0; j < activity.subActivities.length; j++) {
|
|
2238
|
+
const sub = activity.subActivities[j];
|
|
2239
|
+
const subStyle = getActivityStyle(sub);
|
|
2240
|
+
const subIcon = sub.icon;
|
|
2241
|
+
const subIconWidth = getDisplayWidth(subIcon);
|
|
2242
|
+
const subLabel = sub.label;
|
|
2243
|
+
const subDetail = sub.detail;
|
|
2244
|
+
const subContentPrefixWidth = subPrefixWidth + subIconWidth + 1;
|
|
2245
|
+
const availableWidth = contentWidth - subContentPrefixWidth;
|
|
2246
|
+
let subLabelContent;
|
|
2247
|
+
let subDisplayWidth;
|
|
2248
|
+
if (subDetail) {
|
|
2249
|
+
const labelPart = `${subLabel}: `;
|
|
2250
|
+
const detailAvailable = availableWidth - labelPart.length;
|
|
2251
|
+
let truncatedDetail = subDetail;
|
|
2252
|
+
if (getDisplayWidth(subDetail) > detailAvailable) {
|
|
2253
|
+
truncatedDetail = "";
|
|
2254
|
+
let currentWidth = 0;
|
|
2255
|
+
for (const char of subDetail) {
|
|
2256
|
+
const charWidth = getDisplayWidth(char);
|
|
2257
|
+
if (currentWidth + charWidth > detailAvailable - 3) {
|
|
2258
|
+
truncatedDetail += "...";
|
|
2259
|
+
currentWidth += 3;
|
|
2260
|
+
break;
|
|
2261
|
+
}
|
|
2262
|
+
truncatedDetail += char;
|
|
2263
|
+
currentWidth += charWidth;
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
subLabelContent = labelPart + truncatedDetail;
|
|
2267
|
+
subDisplayWidth = subContentPrefixWidth + labelPart.length + getDisplayWidth(truncatedDetail);
|
|
2268
|
+
} else {
|
|
2269
|
+
subLabelContent = subLabel;
|
|
2270
|
+
subDisplayWidth = subContentPrefixWidth + subLabel.length;
|
|
2271
|
+
}
|
|
2272
|
+
const subPadding = Math.max(0, contentWidth - subDisplayWidth);
|
|
2273
|
+
lines.push(
|
|
2274
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2275
|
+
BOX.v,
|
|
2276
|
+
" ",
|
|
2277
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: subPrefix }),
|
|
2278
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: subIcon }),
|
|
2279
|
+
" ",
|
|
2280
|
+
/* @__PURE__ */ jsx(Text, { color: subStyle.color, dimColor: subStyle.dimColor, children: subLabelContent }),
|
|
2281
|
+
" ".repeat(subPadding),
|
|
2282
|
+
BOX.v
|
|
2283
|
+
] }, `activity-${i}-sub-${j}`)
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2134
2287
|
}
|
|
2135
2288
|
const hasTodos = state.todos && state.todos.length > 0;
|
|
2136
2289
|
const allCompleted = hasTodos && state.todos?.every((t) => t.status === "completed");
|
|
@@ -3217,6 +3370,18 @@ function DashboardApp({
|
|
|
3217
3370
|
},
|
|
3218
3371
|
[config.width]
|
|
3219
3372
|
);
|
|
3373
|
+
const getEffectiveMaxActivities = useCallback4(
|
|
3374
|
+
(terminalRows, todoCount = 0, isWideLayout = false) => {
|
|
3375
|
+
const configMax = config.panels.claude.maxActivities ?? 10;
|
|
3376
|
+
if (!terminalRows || !isWideLayout) {
|
|
3377
|
+
return configMax;
|
|
3378
|
+
}
|
|
3379
|
+
const todoHeight = todoCount > 0 ? 1 + todoCount : 0;
|
|
3380
|
+
const heightBasedMax = Math.max(5, terminalRows - 13 - todoHeight);
|
|
3381
|
+
return Math.max(configMax, heightBasedMax);
|
|
3382
|
+
},
|
|
3383
|
+
[config.panels.claude.maxActivities]
|
|
3384
|
+
);
|
|
3220
3385
|
const [width, setWidth] = useState4(() => getEffectiveWidth(stdout?.columns));
|
|
3221
3386
|
useEffect4(() => {
|
|
3222
3387
|
if (!config.width) {
|
|
@@ -3276,12 +3441,12 @@ function DashboardApp({
|
|
|
3276
3441
|
const [gitData, setGitData] = useState4(
|
|
3277
3442
|
() => getGitData(config.panels.git)
|
|
3278
3443
|
);
|
|
3444
|
+
const fetchMaxActivities = Math.max(
|
|
3445
|
+
config.panels.claude.maxActivities ?? 10,
|
|
3446
|
+
stdout?.rows ?? 50
|
|
3447
|
+
);
|
|
3279
3448
|
const [claudeData, setClaudeData] = useState4(
|
|
3280
|
-
() => getClaudeData(
|
|
3281
|
-
cwd,
|
|
3282
|
-
config.panels.claude.maxActivities,
|
|
3283
|
-
config.panels.claude.sessionTimeout
|
|
3284
|
-
)
|
|
3449
|
+
() => getClaudeData(cwd, fetchMaxActivities, config.panels.claude.sessionTimeout)
|
|
3285
3450
|
);
|
|
3286
3451
|
const [otherSessionsData, setOtherSessionsData] = useState4(
|
|
3287
3452
|
() => getOtherSessionsData(cwd, {
|
|
@@ -3294,7 +3459,6 @@ function DashboardApp({
|
|
|
3294
3459
|
}
|
|
3295
3460
|
return getTestData();
|
|
3296
3461
|
}, [config.panels.tests.command]);
|
|
3297
|
-
const [testsDisabled, setTestsDisabled] = useState4(false);
|
|
3298
3462
|
const [testData, setTestData] = useState4({
|
|
3299
3463
|
results: null,
|
|
3300
3464
|
isOutdated: false,
|
|
@@ -3305,14 +3469,10 @@ function DashboardApp({
|
|
|
3305
3469
|
if (testsInitializedRef.current) return;
|
|
3306
3470
|
testsInitializedRef.current = true;
|
|
3307
3471
|
const timer = setTimeout(() => {
|
|
3308
|
-
|
|
3309
|
-
setTestData(data);
|
|
3310
|
-
if (data.error && !config.panels.tests.command) {
|
|
3311
|
-
setTestsDisabled(true);
|
|
3312
|
-
}
|
|
3472
|
+
setTestData(getTestDataFromConfig());
|
|
3313
3473
|
}, 0);
|
|
3314
3474
|
return () => clearTimeout(timer);
|
|
3315
|
-
}, [getTestDataFromConfig
|
|
3475
|
+
}, [getTestDataFromConfig]);
|
|
3316
3476
|
const [customPanelData, setCustomPanelData] = useState4(() => {
|
|
3317
3477
|
const data = {};
|
|
3318
3478
|
if (config.customPanels) {
|
|
@@ -3344,30 +3504,27 @@ function DashboardApp({
|
|
|
3344
3504
|
try {
|
|
3345
3505
|
await new Promise((resolve) => {
|
|
3346
3506
|
setTimeout(() => {
|
|
3347
|
-
|
|
3348
|
-
if (config.panels.tests.command) {
|
|
3349
|
-
setTestsDisabled(!!data.error);
|
|
3350
|
-
}
|
|
3351
|
-
setTestData(data);
|
|
3507
|
+
setTestData(getTestDataFromConfig());
|
|
3352
3508
|
resolve();
|
|
3353
3509
|
}, 0);
|
|
3354
3510
|
});
|
|
3355
3511
|
} finally {
|
|
3356
3512
|
visualFeedback.endAsync("tests", { completed: true });
|
|
3357
3513
|
}
|
|
3358
|
-
}, [getTestDataFromConfig,
|
|
3514
|
+
}, [getTestDataFromConfig, visualFeedback]);
|
|
3359
3515
|
const refreshClaude = useCallback4(() => {
|
|
3516
|
+
const maxFetch = Math.max(
|
|
3517
|
+
config.panels.claude.maxActivities ?? 10,
|
|
3518
|
+
stdout?.rows ?? 50
|
|
3519
|
+
);
|
|
3360
3520
|
setClaudeData(
|
|
3361
|
-
getClaudeData(
|
|
3362
|
-
cwd,
|
|
3363
|
-
config.panels.claude.maxActivities,
|
|
3364
|
-
config.panels.claude.sessionTimeout
|
|
3365
|
-
)
|
|
3521
|
+
getClaudeData(cwd, maxFetch, config.panels.claude.sessionTimeout)
|
|
3366
3522
|
);
|
|
3367
3523
|
visualFeedback.setRefreshed("claude");
|
|
3368
3524
|
resetCountdown("claude");
|
|
3369
3525
|
}, [
|
|
3370
3526
|
cwd,
|
|
3527
|
+
stdout?.rows,
|
|
3371
3528
|
config.panels.claude.maxActivities,
|
|
3372
3529
|
config.panels.claude.sessionTimeout,
|
|
3373
3530
|
visualFeedback,
|
|
@@ -3528,106 +3685,180 @@ function DashboardApp({
|
|
|
3528
3685
|
}
|
|
3529
3686
|
return () => timers.forEach((t) => clearInterval(t));
|
|
3530
3687
|
}, [isWatchMode, config]);
|
|
3688
|
+
const terminalWidth = stdout?.columns ?? 0;
|
|
3689
|
+
const terminalHeight = stdout?.rows ?? 0;
|
|
3690
|
+
const columnGap = 2;
|
|
3691
|
+
const effectiveThreshold = config.wideLayoutThreshold ?? MIN_TERMINAL_WIDTH * 2 + columnGap;
|
|
3692
|
+
const useWideLayout = terminalWidth >= effectiveThreshold;
|
|
3693
|
+
const singleColumnWidth = getClampedWidth(terminalWidth);
|
|
3694
|
+
const leftColumnWidth = useWideLayout ? Math.floor((terminalWidth - columnGap) / 2) : singleColumnWidth;
|
|
3695
|
+
const rightColumnWidth = useWideLayout ? terminalWidth - leftColumnWidth - columnGap : singleColumnWidth;
|
|
3696
|
+
const claudeMaxActivities = useMemo3(() => {
|
|
3697
|
+
if (!useWideLayout) return void 0;
|
|
3698
|
+
const todos = claudeData.state.todos;
|
|
3699
|
+
const hasTodos = todos && todos.length > 0;
|
|
3700
|
+
const allCompleted = hasTodos && todos.every((t) => t.status === "completed");
|
|
3701
|
+
const activeTodoCount = hasTodos && !allCompleted ? todos.length : 0;
|
|
3702
|
+
return getEffectiveMaxActivities(terminalHeight, activeTodoCount, true);
|
|
3703
|
+
}, [
|
|
3704
|
+
useWideLayout,
|
|
3705
|
+
claudeData.state.todos,
|
|
3706
|
+
terminalHeight,
|
|
3707
|
+
getEffectiveMaxActivities
|
|
3708
|
+
]);
|
|
3709
|
+
const renderPanel = (panelName, panelWidth, marginTop) => {
|
|
3710
|
+
if (panelName === "project" && config.panels.project.enabled) {
|
|
3711
|
+
const vs = visualFeedback.getState("project");
|
|
3712
|
+
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3713
|
+
ProjectPanel,
|
|
3714
|
+
{
|
|
3715
|
+
data: projectData,
|
|
3716
|
+
countdown: isWatchMode ? countdowns.project : null,
|
|
3717
|
+
width: panelWidth,
|
|
3718
|
+
justRefreshed: vs.justRefreshed
|
|
3719
|
+
}
|
|
3720
|
+
) }, `panel-${panelName}`);
|
|
3721
|
+
}
|
|
3722
|
+
if (panelName === "git" && config.panels.git.enabled) {
|
|
3723
|
+
const vs = visualFeedback.getState("git");
|
|
3724
|
+
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3725
|
+
GitPanel,
|
|
3726
|
+
{
|
|
3727
|
+
branch: gitData.branch,
|
|
3728
|
+
commits: gitData.commits,
|
|
3729
|
+
stats: gitData.stats,
|
|
3730
|
+
uncommitted: gitData.uncommitted,
|
|
3731
|
+
countdown: isWatchMode ? countdowns.git : null,
|
|
3732
|
+
width: panelWidth,
|
|
3733
|
+
isRunning: vs.isRunning,
|
|
3734
|
+
justRefreshed: vs.justRefreshed
|
|
3735
|
+
}
|
|
3736
|
+
) }, `panel-${panelName}`);
|
|
3737
|
+
}
|
|
3738
|
+
if (panelName === "tests" && config.panels.tests.enabled) {
|
|
3739
|
+
const vs = visualFeedback.getState("tests");
|
|
3740
|
+
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3741
|
+
TestPanel,
|
|
3742
|
+
{
|
|
3743
|
+
results: testData.results,
|
|
3744
|
+
isOutdated: testData.isOutdated,
|
|
3745
|
+
commitsBehind: testData.commitsBehind,
|
|
3746
|
+
error: testData.error,
|
|
3747
|
+
width: panelWidth,
|
|
3748
|
+
isRunning: vs.isRunning,
|
|
3749
|
+
justCompleted: vs.justCompleted
|
|
3750
|
+
}
|
|
3751
|
+
) }, `panel-${panelName}`);
|
|
3752
|
+
}
|
|
3753
|
+
if (panelName === "claude" && config.panels.claude.enabled) {
|
|
3754
|
+
const vs = visualFeedback.getState("claude");
|
|
3755
|
+
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3756
|
+
ClaudePanel,
|
|
3757
|
+
{
|
|
3758
|
+
data: claudeData,
|
|
3759
|
+
countdown: isWatchMode ? countdowns.claude : null,
|
|
3760
|
+
width: panelWidth,
|
|
3761
|
+
justRefreshed: vs.justRefreshed,
|
|
3762
|
+
maxActivities: claudeMaxActivities
|
|
3763
|
+
}
|
|
3764
|
+
) }, `panel-${panelName}`);
|
|
3765
|
+
}
|
|
3766
|
+
if (panelName === "other_sessions" && config.panels.other_sessions.enabled) {
|
|
3767
|
+
const vs = visualFeedback.getState("other_sessions");
|
|
3768
|
+
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3769
|
+
OtherSessionsPanel,
|
|
3770
|
+
{
|
|
3771
|
+
data: otherSessionsData,
|
|
3772
|
+
countdown: isWatchMode ? countdowns.other_sessions : null,
|
|
3773
|
+
width: panelWidth,
|
|
3774
|
+
isRunning: vs.isRunning,
|
|
3775
|
+
messageMaxLength: config.panels.other_sessions.messageMaxLength
|
|
3776
|
+
}
|
|
3777
|
+
) }, `panel-${panelName}`);
|
|
3778
|
+
}
|
|
3779
|
+
const customConfig = config.customPanels?.[panelName];
|
|
3780
|
+
if (customConfig?.enabled) {
|
|
3781
|
+
const result = customPanelData[panelName];
|
|
3782
|
+
if (!result) return null;
|
|
3783
|
+
const vs = visualFeedback.getState(panelName);
|
|
3784
|
+
const isManual = customConfig.interval === null;
|
|
3785
|
+
const relativeTime = isManual ? formatRelativeTime3(result.timestamp) : void 0;
|
|
3786
|
+
const countdown = !isManual && isWatchMode ? countdowns[panelName] : null;
|
|
3787
|
+
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3788
|
+
GenericPanel,
|
|
3789
|
+
{
|
|
3790
|
+
data: result.data,
|
|
3791
|
+
renderer: customConfig.renderer,
|
|
3792
|
+
countdown,
|
|
3793
|
+
relativeTime,
|
|
3794
|
+
error: result.error,
|
|
3795
|
+
width: panelWidth,
|
|
3796
|
+
isRunning: vs.isRunning,
|
|
3797
|
+
justRefreshed: vs.justRefreshed
|
|
3798
|
+
}
|
|
3799
|
+
) }, `panel-${panelName}`);
|
|
3800
|
+
}
|
|
3801
|
+
return null;
|
|
3802
|
+
};
|
|
3803
|
+
if (useWideLayout) {
|
|
3804
|
+
const leftPanels = ["claude", "other_sessions"];
|
|
3805
|
+
const rightPanels = config.panelOrder.filter(
|
|
3806
|
+
(name) => !leftPanels.includes(name)
|
|
3807
|
+
);
|
|
3808
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3809
|
+
warnings.length > 0 && /* @__PURE__ */ jsx8(Box8, { marginBottom: 1, children: /* @__PURE__ */ jsxs8(Text8, { color: "yellow", children: [
|
|
3810
|
+
"\u26A0 ",
|
|
3811
|
+
warnings.join(", ")
|
|
3812
|
+
] }) }),
|
|
3813
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
|
|
3814
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", width: leftColumnWidth, children: [
|
|
3815
|
+
renderPanel("claude", leftColumnWidth, 0),
|
|
3816
|
+
renderPanel("other_sessions", leftColumnWidth, 1)
|
|
3817
|
+
] }),
|
|
3818
|
+
/* @__PURE__ */ jsx8(
|
|
3819
|
+
Box8,
|
|
3820
|
+
{
|
|
3821
|
+
flexDirection: "column",
|
|
3822
|
+
width: rightColumnWidth,
|
|
3823
|
+
marginLeft: columnGap,
|
|
3824
|
+
children: rightPanels.map(
|
|
3825
|
+
(panelName, index) => renderPanel(panelName, rightColumnWidth, index === 0 ? 0 : 1)
|
|
3826
|
+
)
|
|
3827
|
+
}
|
|
3828
|
+
)
|
|
3829
|
+
] }),
|
|
3830
|
+
isWatchMode && /* @__PURE__ */ jsxs8(
|
|
3831
|
+
Box8,
|
|
3832
|
+
{
|
|
3833
|
+
marginTop: 1,
|
|
3834
|
+
width: terminalWidth,
|
|
3835
|
+
justifyContent: "space-between",
|
|
3836
|
+
children: [
|
|
3837
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: statusBarItems.map((item, index) => /* @__PURE__ */ jsxs8(React.Fragment, { children: [
|
|
3838
|
+
index > 0 && " \xB7 ",
|
|
3839
|
+
/* @__PURE__ */ jsxs8(Text8, { color: "cyan", children: [
|
|
3840
|
+
item.split(":")[0],
|
|
3841
|
+
":"
|
|
3842
|
+
] }),
|
|
3843
|
+
item.split(":").slice(1).join(":")
|
|
3844
|
+
] }, index)) }),
|
|
3845
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
3846
|
+
"AgentHUD v",
|
|
3847
|
+
getVersion()
|
|
3848
|
+
] })
|
|
3849
|
+
]
|
|
3850
|
+
}
|
|
3851
|
+
)
|
|
3852
|
+
] });
|
|
3853
|
+
}
|
|
3531
3854
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3532
3855
|
warnings.length > 0 && /* @__PURE__ */ jsx8(Box8, { marginBottom: 1, children: /* @__PURE__ */ jsxs8(Text8, { color: "yellow", children: [
|
|
3533
3856
|
"\u26A0 ",
|
|
3534
3857
|
warnings.join(", ")
|
|
3535
3858
|
] }) }),
|
|
3536
|
-
config.panelOrder.map(
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
if (panelName === "project" && config.panels.project.enabled) {
|
|
3540
|
-
const vs = visualFeedback.getState("project");
|
|
3541
|
-
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3542
|
-
ProjectPanel,
|
|
3543
|
-
{
|
|
3544
|
-
data: projectData,
|
|
3545
|
-
countdown: isWatchMode ? countdowns.project : null,
|
|
3546
|
-
width,
|
|
3547
|
-
justRefreshed: vs.justRefreshed
|
|
3548
|
-
}
|
|
3549
|
-
) }, `panel-${panelName}-${index}`);
|
|
3550
|
-
}
|
|
3551
|
-
if (panelName === "git" && config.panels.git.enabled) {
|
|
3552
|
-
const vs = visualFeedback.getState("git");
|
|
3553
|
-
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3554
|
-
GitPanel,
|
|
3555
|
-
{
|
|
3556
|
-
branch: gitData.branch,
|
|
3557
|
-
commits: gitData.commits,
|
|
3558
|
-
stats: gitData.stats,
|
|
3559
|
-
uncommitted: gitData.uncommitted,
|
|
3560
|
-
countdown: isWatchMode ? countdowns.git : null,
|
|
3561
|
-
width,
|
|
3562
|
-
isRunning: vs.isRunning,
|
|
3563
|
-
justRefreshed: vs.justRefreshed
|
|
3564
|
-
}
|
|
3565
|
-
) }, `panel-${panelName}-${index}`);
|
|
3566
|
-
}
|
|
3567
|
-
if (panelName === "tests" && config.panels.tests.enabled && !testsDisabled) {
|
|
3568
|
-
const vs = visualFeedback.getState("tests");
|
|
3569
|
-
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3570
|
-
TestPanel,
|
|
3571
|
-
{
|
|
3572
|
-
results: testData.results,
|
|
3573
|
-
isOutdated: testData.isOutdated,
|
|
3574
|
-
commitsBehind: testData.commitsBehind,
|
|
3575
|
-
error: testData.error,
|
|
3576
|
-
width,
|
|
3577
|
-
isRunning: vs.isRunning,
|
|
3578
|
-
justCompleted: vs.justCompleted
|
|
3579
|
-
}
|
|
3580
|
-
) }, `panel-${panelName}-${index}`);
|
|
3581
|
-
}
|
|
3582
|
-
if (panelName === "claude" && config.panels.claude.enabled) {
|
|
3583
|
-
const vs = visualFeedback.getState("claude");
|
|
3584
|
-
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3585
|
-
ClaudePanel,
|
|
3586
|
-
{
|
|
3587
|
-
data: claudeData,
|
|
3588
|
-
countdown: isWatchMode ? countdowns.claude : null,
|
|
3589
|
-
width,
|
|
3590
|
-
justRefreshed: vs.justRefreshed
|
|
3591
|
-
}
|
|
3592
|
-
) }, `panel-${panelName}-${index}`);
|
|
3593
|
-
}
|
|
3594
|
-
if (panelName === "other_sessions" && config.panels.other_sessions.enabled) {
|
|
3595
|
-
const vs = visualFeedback.getState("other_sessions");
|
|
3596
|
-
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3597
|
-
OtherSessionsPanel,
|
|
3598
|
-
{
|
|
3599
|
-
data: otherSessionsData,
|
|
3600
|
-
countdown: isWatchMode ? countdowns.other_sessions : null,
|
|
3601
|
-
width,
|
|
3602
|
-
isRunning: vs.isRunning,
|
|
3603
|
-
messageMaxLength: config.panels.other_sessions.messageMaxLength
|
|
3604
|
-
}
|
|
3605
|
-
) }, `panel-${panelName}-${index}`);
|
|
3606
|
-
}
|
|
3607
|
-
const customConfig = config.customPanels?.[panelName];
|
|
3608
|
-
if (customConfig?.enabled) {
|
|
3609
|
-
const result = customPanelData[panelName];
|
|
3610
|
-
if (!result) return null;
|
|
3611
|
-
const vs = visualFeedback.getState(panelName);
|
|
3612
|
-
const isManual = customConfig.interval === null;
|
|
3613
|
-
const relativeTime = isManual ? formatRelativeTime3(result.timestamp) : void 0;
|
|
3614
|
-
const countdown = !isManual && isWatchMode ? countdowns[panelName] : null;
|
|
3615
|
-
return /* @__PURE__ */ jsx8(Box8, { marginTop, children: /* @__PURE__ */ jsx8(
|
|
3616
|
-
GenericPanel,
|
|
3617
|
-
{
|
|
3618
|
-
data: result.data,
|
|
3619
|
-
renderer: customConfig.renderer,
|
|
3620
|
-
countdown,
|
|
3621
|
-
relativeTime,
|
|
3622
|
-
error: result.error,
|
|
3623
|
-
width,
|
|
3624
|
-
isRunning: vs.isRunning,
|
|
3625
|
-
justRefreshed: vs.justRefreshed
|
|
3626
|
-
}
|
|
3627
|
-
) }, `panel-${panelName}-${index}`);
|
|
3628
|
-
}
|
|
3629
|
-
return null;
|
|
3630
|
-
}),
|
|
3859
|
+
config.panelOrder.map(
|
|
3860
|
+
(panelName, index) => renderPanel(panelName, width, index === 0 ? 0 : 1)
|
|
3861
|
+
),
|
|
3631
3862
|
isWatchMode && /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, width, justifyContent: "space-between", children: [
|
|
3632
3863
|
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: statusBarItems.map((item, index) => /* @__PURE__ */ jsxs8(React.Fragment, { children: [
|
|
3633
3864
|
index > 0 && " \xB7 ",
|
package/package.json
CHANGED