loop-task 2.1.10 → 2.1.11
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.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { t } from "../../shared/i18n/index.js";
|
|
2
2
|
import { cycleSortMode, cycleStatusFilter } from "../../entities/loops/filters.js";
|
|
3
3
|
import { cycleProjectSortMode, cycleProjectHasLoopsFilter, cycleProjectIsSystemFilter } from "../../entities/projects/filters.js";
|
|
4
|
+
import { groupRunsByCycle } from "../../widgets/right-panel/RunHistory.js";
|
|
4
5
|
export function useCommandHandlers(context) {
|
|
5
6
|
const { activeTab, selected, selectedRunIndex, selectedTask, selectedProjectEntity, tasks, projects, currentProjectId, setCloneMode, setEditTarget, setPendingTaskSelection, setEditTask, setEditProject, setActiveTab, setConfirmState, setCommandsBrowserOpen, setSearchValue, setSearchState, setFilters, setSort, setCurrentProjectId, setProjectFilters, setProjectSelectedIndex, setDebugMode, setExportModal, push, pop, refresh, refreshTasks, refreshProjects, pushToast, loopService, taskService, projectService, exportService, runAction, handleOpenRunLog, } = context;
|
|
6
7
|
const commandHandlers = {
|
|
@@ -109,7 +110,7 @@ export function useCommandHandlers(context) {
|
|
|
109
110
|
debug: () => { setDebugMode((prev) => !prev); },
|
|
110
111
|
logs: () => {
|
|
111
112
|
if (activeTab === "loops" && selected) {
|
|
112
|
-
const reversed = [...selected.runHistory].reverse();
|
|
113
|
+
const reversed = [...groupRunsByCycle(selected.runHistory)].reverse();
|
|
113
114
|
if (reversed.length > 0) {
|
|
114
115
|
const run = reversed[Math.min(selectedRunIndex, reversed.length - 1)];
|
|
115
116
|
handleOpenRunLog(run ?? reversed[0]);
|
|
@@ -2,6 +2,7 @@ import { useCallback } from "react";
|
|
|
2
2
|
import { copyToClipboard } from "../../shared/clipboard.js";
|
|
3
3
|
import { commandLine } from "../../shared/ui/format.js";
|
|
4
4
|
import { t } from "../../shared/i18n/index.js";
|
|
5
|
+
import { groupRunsByCycle } from "../../widgets/right-panel/RunHistory.js";
|
|
5
6
|
export function useContextualActions(context) {
|
|
6
7
|
const { activeTab, focusedPanel, selected, selectedRunIndex, selectedTask, selectedProjectEntity, tasks, push, setCloneMode, setEditTarget, setPendingTaskSelection, handleCommand, handleOpenRunLog, pushToast, isBoardView, view, logModalRun, commandsBrowserOpen, confirmState, searchState, setChordState, chordState, } = context;
|
|
7
8
|
const handleContextualCopy = useCallback(() => {
|
|
@@ -57,7 +58,7 @@ export function useContextualActions(context) {
|
|
|
57
58
|
"loops:right": () => {
|
|
58
59
|
if (!selected)
|
|
59
60
|
return;
|
|
60
|
-
const reversed = [...selected.runHistory].reverse();
|
|
61
|
+
const reversed = [...groupRunsByCycle(selected.runHistory)].reverse();
|
|
61
62
|
if (reversed.length > 0) {
|
|
62
63
|
const run = reversed[Math.min(selectedRunIndex, reversed.length - 1)];
|
|
63
64
|
handleOpenRunLog(run ?? reversed[0]);
|
|
@@ -4,7 +4,9 @@ import { TYPES } from "../services/types.js";
|
|
|
4
4
|
import { t } from "../i18n/index.js";
|
|
5
5
|
import { LOG_LINES_MAX } from "../config/constants.js";
|
|
6
6
|
export function useLogStream(selectedId, view, onError) {
|
|
7
|
-
const
|
|
7
|
+
const injectedLogService = useInject(TYPES.LogService);
|
|
8
|
+
const logServiceRef = useRef(injectedLogService);
|
|
9
|
+
const logService = logServiceRef.current;
|
|
8
10
|
const [logLines, setLogLines] = useState([]);
|
|
9
11
|
const logSocket = useRef(null);
|
|
10
12
|
useEffect(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Box, Text, useInput, useStdout } from "ink";
|
|
4
4
|
import { darkTheme as theme } from "../../shared/ui/theme.js";
|
|
5
5
|
import { t } from "../../shared/i18n/index.js";
|
|
@@ -30,7 +30,10 @@ export function LogModal(props) {
|
|
|
30
30
|
const [searchQuery, setSearchQuery] = useState("");
|
|
31
31
|
const [follow, setFollow] = useState(true);
|
|
32
32
|
const [scrollOffset, setScrollOffset] = useState(0);
|
|
33
|
-
const
|
|
33
|
+
const bottomDistanceRef = useRef(0);
|
|
34
|
+
const injectedLogService = useInject(TYPES.LogService);
|
|
35
|
+
const logServiceRef = useRef(injectedLogService);
|
|
36
|
+
const logService = logServiceRef.current;
|
|
34
37
|
const { stdout } = useStdout();
|
|
35
38
|
const terminalHeight = stdout?.rows ?? 24;
|
|
36
39
|
const MAX_VISIBLE_LINES = Math.max(1, Math.floor(terminalHeight * 0.7) - 7);
|
|
@@ -105,13 +108,15 @@ export function LogModal(props) {
|
|
|
105
108
|
return;
|
|
106
109
|
}
|
|
107
110
|
if (key.downArrow) {
|
|
111
|
+
const base = follow ? Math.max(0, totalLines - MAX_VISIBLE_LINES) : scrollOffset;
|
|
108
112
|
setFollow(false);
|
|
109
|
-
setScrollOffset(
|
|
113
|
+
setScrollOffset(Math.min(base + 1, Math.max(0, totalLines - MAX_VISIBLE_LINES)));
|
|
110
114
|
return;
|
|
111
115
|
}
|
|
112
116
|
if (key.upArrow) {
|
|
117
|
+
const base = follow ? Math.max(0, totalLines - MAX_VISIBLE_LINES) : scrollOffset;
|
|
113
118
|
setFollow(false);
|
|
114
|
-
setScrollOffset(
|
|
119
|
+
setScrollOffset(Math.max(0, base - 1));
|
|
115
120
|
return;
|
|
116
121
|
}
|
|
117
122
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loop-task",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.11",
|
|
4
4
|
"description": "Loop engineering toolkit. Run any command on a cadence, in the background, managed from a terminal board. Schedule tests, builds, syncs, or agent prompts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|