loop-task 2.0.5 → 2.0.7
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.
|
@@ -7,7 +7,7 @@ function quoteArg(arg) {
|
|
|
7
7
|
return /[\s"]/.test(arg) ? `"${arg.replace(/"/g, '\\"')}"` : arg;
|
|
8
8
|
}
|
|
9
9
|
function formatCommandLine(command, commandArgs) {
|
|
10
|
-
return [command, ...commandArgs.map((a) => quoteArg(a))].join(" ").trim();
|
|
10
|
+
return [command, ...commandArgs.map((a) => quoteArg(a.replace(/\n/g, " ").replace(/\r/g, " ")))].join(" ").trim();
|
|
11
11
|
}
|
|
12
12
|
export function extractExitCode(error) {
|
|
13
13
|
return error && typeof error === "object" && "exitCode" in error
|
|
@@ -371,7 +371,7 @@ export class LoopController extends EventEmitter {
|
|
|
371
371
|
break;
|
|
372
372
|
if (this.logStream) {
|
|
373
373
|
this.logStream.write(t("loop.chainHeader", { name: chainTask.name, branch: prevBranch, prevExit }));
|
|
374
|
-
this.logStream.write(t("loop.commandLine", { command: [chainTask.command, ...chainTask.commandArgs.map((a) => /[\s"]/.test(a) ? `"${a.replace(/"/g, '\\"')}"` : a)].join(" ").trim() }));
|
|
374
|
+
this.logStream.write(t("loop.commandLine", { command: [chainTask.command, ...chainTask.commandArgs.map((a) => /[\s"]/.test(a) ? `"${a.replace(/"/g, '\\"')}"` : a).map((a) => a.replace(/\n/g, " ").replace(/\r/g, " "))].join(" ").trim() }));
|
|
375
375
|
}
|
|
376
376
|
const chainStartedAt = new Date().toISOString();
|
|
377
377
|
const chainOffset = fs.existsSync(this.logPath) ? fs.statSync(this.logPath).size : 0;
|
package/dist/i18n/en.json
CHANGED
|
@@ -191,8 +191,8 @@
|
|
|
191
191
|
"board.logModalRunning": "Running",
|
|
192
192
|
"board.logModalExit": "exit {code}",
|
|
193
193
|
"board.logModalDuration": "duration",
|
|
194
|
-
"board.logModalSearchHint": "type to filter, enter to apply, esc to
|
|
195
|
-
"board.logModalFooterHints": "/:search
|
|
194
|
+
"board.logModalSearchHint": "type to filter, enter to apply, esc to exit search",
|
|
195
|
+
"board.logModalFooterHints": "/:search ctrl+x:copy up/down:scroll esc:close",
|
|
196
196
|
"board.logModalEscClose": "esc to close",
|
|
197
197
|
"board.logModalRunning": "running…",
|
|
198
198
|
"board.detailTitle": " Loop Detail ",
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { Box, Text, useInput } from "ink";
|
|
4
4
|
import { darkTheme as theme } from "../theme.js";
|
|
5
|
-
import { Modal } from "./Modal.js";
|
|
6
5
|
import { t } from "../../i18n/index.js";
|
|
7
6
|
import { streamRunLog } from "../daemon.js";
|
|
8
7
|
import { formatDate } from "../format.js";
|
|
@@ -69,7 +68,7 @@ export function LogModal(props) {
|
|
|
69
68
|
return;
|
|
70
69
|
}
|
|
71
70
|
if (key.escape) {
|
|
72
|
-
|
|
71
|
+
props.onClose();
|
|
73
72
|
return;
|
|
74
73
|
}
|
|
75
74
|
if (input === "/") {
|
|
@@ -77,7 +76,7 @@ export function LogModal(props) {
|
|
|
77
76
|
setSearchQuery("");
|
|
78
77
|
return;
|
|
79
78
|
}
|
|
80
|
-
if (input === "
|
|
79
|
+
if (key.ctrl && input === "x") {
|
|
81
80
|
copyToClipboard(lines.join("\n"));
|
|
82
81
|
props.onCopy?.();
|
|
83
82
|
return;
|
|
@@ -104,20 +103,18 @@ export function LogModal(props) {
|
|
|
104
103
|
: props.run.exitCode === 0
|
|
105
104
|
? theme.semantic.success
|
|
106
105
|
: theme.semantic.danger;
|
|
107
|
-
return (_jsxs(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
? t("board.logModalSearchHint")
|
|
122
|
-
: t("board.logModalFooterHints") }) })] }));
|
|
106
|
+
return (_jsx(Box, { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", justifyContent: "center", alignItems: "center", children: _jsxs(Box, { borderStyle: "round", borderColor: theme.accent.brand, backgroundColor: theme.bg.elevated, paddingX: 2, paddingY: 1, flexDirection: "column", width: "95%", height: "70%", children: [_jsx(Text, { color: theme.accent.brand, bold: true, children: `Run #${props.run.runNumber} - ${formatDate(props.run.startedAt)}` }), _jsxs(Box, { flexDirection: "column", marginTop: 1, flexGrow: 1, children: [_jsxs(Box, { marginBottom: 1, justifyContent: "space-between", children: [_jsxs(Text, { color: statusColor, children: [statusIcon, " ", props.run.status === "running"
|
|
107
|
+
? t("board.logModalRunning")
|
|
108
|
+
: t("board.logModalExit", { code: props.run.exitCode })] }), props.run.duration > 0 ? (_jsxs(Text, { color: theme.text.muted, children: [" ", t("board.logModalDuration"), " ", props.run.duration, "ms"] })) : null, _jsx(Text, { color: theme.text.muted, children: searchMode
|
|
109
|
+
? `/${searchQuery}`
|
|
110
|
+
: `[${startIdx}-${endIdx}/${totalLines}]` })] }), searchMode ? (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.text.muted, children: "Search: " }), _jsxs(Text, { color: theme.text.primary, children: [searchQuery, "_"] })] })) : null, _jsx(Box, { flexDirection: "column", flexGrow: 1, children: visible.length === 0 ? (_jsx(Text, { color: theme.text.muted, children: isLoading
|
|
111
|
+
? t("board.logModalLoading")
|
|
112
|
+
: searchQuery
|
|
113
|
+
? t("board.logModalNoMatches")
|
|
114
|
+
: t("board.logModalEmpty") })) : (visible.map((line, i) => {
|
|
115
|
+
const realIdx = startIdx + i;
|
|
116
|
+
return (_jsx(Text, { color: colorForLine(line, props.run), wrap: "truncate", children: line }, realIdx));
|
|
117
|
+
})) }), _jsx(Box, { marginTop: 1, justifyContent: "space-between", children: _jsx(Text, { color: theme.text.muted, children: searchMode
|
|
118
|
+
? t("board.logModalSearchHint")
|
|
119
|
+
: t("board.logModalFooterHints") }) })] })] }) }));
|
|
123
120
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loop-task",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
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": {
|