@nmakarov/cli-toolkit 0.69.0 → 0.71.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/cli-runner.cjs +386 -192
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +386 -192
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +440 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +430 -208
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +129 -91
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +129 -91
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +124 -90
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +121 -90
- package/dist/screen.js.map +1 -1
- package/dist/tasks.cjs +308 -117
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.js +301 -117
- package/dist/tasks.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -109,7 +109,46 @@ var init_components = __esm({
|
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
// src/screen/scrollbar.js
|
|
113
|
+
function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {
|
|
114
|
+
const view = Math.max(1, Math.floor(viewportRows));
|
|
115
|
+
const total = Math.max(0, Math.floor(totalLines));
|
|
116
|
+
if (total <= view) return null;
|
|
117
|
+
const maxScroll = total - view;
|
|
118
|
+
const thumbSize = Math.max(1, Math.round(view / total * view));
|
|
119
|
+
const travel = Math.max(0, view - thumbSize);
|
|
120
|
+
const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);
|
|
121
|
+
const thumbStart = maxScroll === 0 ? 0 : Math.round(s / maxScroll * travel);
|
|
122
|
+
const glyphs = [];
|
|
123
|
+
for (let i = 0; i < view; i++) {
|
|
124
|
+
glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);
|
|
125
|
+
}
|
|
126
|
+
return glyphs;
|
|
127
|
+
}
|
|
128
|
+
var BAR_THUMB, BAR_TRACK, PAGE_SCROLL_KEY_BINDINGS;
|
|
129
|
+
var init_scrollbar = __esm({
|
|
130
|
+
"src/screen/scrollbar.js"() {
|
|
131
|
+
BAR_THUMB = "#";
|
|
132
|
+
BAR_TRACK = "|";
|
|
133
|
+
PAGE_SCROLL_KEY_BINDINGS = [
|
|
134
|
+
{ key: "upArrow", meta: true, caption: "page", action: "pageUp", order: 0 },
|
|
135
|
+
{ key: "downArrow", meta: true, caption: "page", action: "pageDown", order: 0 },
|
|
136
|
+
{ key: "upArrow", ctrl: true, caption: "page", action: "pageUp", order: 0 },
|
|
137
|
+
{ key: "downArrow", ctrl: true, caption: "page", action: "pageDown", order: 0 },
|
|
138
|
+
{ key: "pageUp", caption: "page", action: "pageUp", order: 0 },
|
|
139
|
+
{ key: "pageDown", caption: "page", action: "pageDown", order: 0 }
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
112
144
|
// src/screen/list-components.js
|
|
145
|
+
function clipNameForScrollbar(name, needsBar) {
|
|
146
|
+
if (!needsBar || name == null) return name;
|
|
147
|
+
const s = String(name);
|
|
148
|
+
if (s.length <= 1) return s;
|
|
149
|
+
if (/\s$/.test(s)) return s.slice(0, -1);
|
|
150
|
+
return s;
|
|
151
|
+
}
|
|
113
152
|
function MultiColumnListComponent({ items, ctx, selectedIndexRef }) {
|
|
114
153
|
const [, forceUpdate] = (0, import_react2.useState)({});
|
|
115
154
|
const termWidth = (process.stdout.columns || 80) - 8;
|
|
@@ -323,17 +362,42 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
323
362
|
});
|
|
324
363
|
ctx.setAction("scrollUp", () => {
|
|
325
364
|
const { scrollOffset: currentScrollOffset } = scrollStateRef.current;
|
|
326
|
-
|
|
327
|
-
setScrollOffset(newScrollOffset);
|
|
365
|
+
setScrollOffset(Math.max(0, currentScrollOffset - 1));
|
|
328
366
|
forceUpdate({});
|
|
329
367
|
});
|
|
330
368
|
ctx.setAction("scrollDown", () => {
|
|
331
369
|
const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;
|
|
332
370
|
const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);
|
|
333
|
-
|
|
334
|
-
|
|
371
|
+
setScrollOffset(Math.min(currentMaxScrollOffset, currentScrollOffset + 1));
|
|
372
|
+
forceUpdate({});
|
|
373
|
+
});
|
|
374
|
+
ctx.setAction("pageUp", () => {
|
|
375
|
+
const { maxHeight: vh } = scrollStateRef.current;
|
|
376
|
+
const page = Math.max(1, vh || 1);
|
|
377
|
+
const newIndex = Math.max(0, selectedIndexRef.current - page);
|
|
378
|
+
selectedIndexRef.current = newIndex;
|
|
379
|
+
const list = displayItemsRef.current;
|
|
380
|
+
onSelectionChangeRef.current?.(newIndex, list[newIndex]);
|
|
381
|
+
setScrollOffset(newIndex);
|
|
382
|
+
forceUpdate({});
|
|
383
|
+
});
|
|
384
|
+
ctx.setAction("pageDown", () => {
|
|
385
|
+
const { maxHeight: vh, totalItems } = scrollStateRef.current;
|
|
386
|
+
const page = Math.max(1, vh || 1);
|
|
387
|
+
const maxIndex = Math.max(0, totalItems - 1);
|
|
388
|
+
const newIndex = Math.min(maxIndex, selectedIndexRef.current + page);
|
|
389
|
+
selectedIndexRef.current = newIndex;
|
|
390
|
+
const list = displayItemsRef.current;
|
|
391
|
+
onSelectionChangeRef.current?.(newIndex, list[newIndex]);
|
|
392
|
+
const maxScroll = Math.max(0, totalItems - page);
|
|
393
|
+
setScrollOffset(Math.min(maxScroll, Math.max(0, newIndex - page + 1)));
|
|
335
394
|
forceUpdate({});
|
|
336
395
|
});
|
|
396
|
+
const navBindings = [
|
|
397
|
+
{ key: "upArrow", caption: "navigate", action: "moveUp", order: 0 },
|
|
398
|
+
{ key: "downArrow", caption: "navigate", action: "moveDown", order: 0 },
|
|
399
|
+
...PAGE_SCROLL_KEY_BINDINGS
|
|
400
|
+
];
|
|
337
401
|
if (sortable) {
|
|
338
402
|
ctx.setAction("toggleSort", () => {
|
|
339
403
|
const nextSort = sortOrder === "none" ? "asc" : sortOrder === "asc" ? "desc" : "none";
|
|
@@ -380,8 +444,7 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
380
444
|
}
|
|
381
445
|
};
|
|
382
446
|
ctx.setKeyBinding([
|
|
383
|
-
|
|
384
|
-
{ key: "downArrow", caption: "navigate", action: "moveDown", order: 0 },
|
|
447
|
+
...navBindings,
|
|
385
448
|
{
|
|
386
449
|
key: "s",
|
|
387
450
|
caption: sortCaption,
|
|
@@ -391,47 +454,47 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
391
454
|
]);
|
|
392
455
|
ctx.update();
|
|
393
456
|
} else {
|
|
394
|
-
ctx.setKeyBinding(
|
|
395
|
-
{ key: "upArrow", caption: "navigate", action: "moveUp", order: 0 },
|
|
396
|
-
{ key: "downArrow", caption: "navigate", action: "moveDown", order: 0 }
|
|
397
|
-
]);
|
|
457
|
+
ctx.setKeyBinding(navBindings);
|
|
398
458
|
}
|
|
399
459
|
}, [sortOrder, sortable]);
|
|
400
460
|
const selectedIndex = selectedIndexRef.current;
|
|
461
|
+
const needsBar = displayItems.length > effectiveMaxHeight;
|
|
462
|
+
const barGlyphs = needsBar ? scrollbarGlyphs(effectiveMaxHeight, displayItems.length, clampedScrollOffset) : null;
|
|
463
|
+
const appendBar = (rowContent, displayIndex) => {
|
|
464
|
+
if (!barGlyphs) return rowContent;
|
|
465
|
+
const glyph = barGlyphs[displayIndex] ?? BAR_TRACK;
|
|
466
|
+
return h2(
|
|
467
|
+
import_ink2.Box,
|
|
468
|
+
{ flexDirection: "row" },
|
|
469
|
+
rowContent,
|
|
470
|
+
h2(import_ink2.Text, { color: glyph === BAR_THUMB ? "cyan" : "gray" }, glyph)
|
|
471
|
+
);
|
|
472
|
+
};
|
|
401
473
|
const defaultRenderItem = (item, isSelected, displayIndex, actualIndex) => {
|
|
402
474
|
const isFirstVisible = displayIndex === 0;
|
|
403
475
|
const isLastVisible = displayIndex === visibleItems.length - 1;
|
|
404
|
-
let arrowPrefix = "";
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
arrowPrefix = "\
|
|
408
|
-
} else if (isLastVisible && canScrollDown) {
|
|
409
|
-
arrowPrefix = "\u2193 ";
|
|
410
|
-
} else {
|
|
411
|
-
arrowPrefix = " ";
|
|
412
|
-
}
|
|
413
|
-
if (isSelected) {
|
|
414
|
-
selectionPrefix = selectionMarker;
|
|
415
|
-
} else {
|
|
416
|
-
selectionPrefix = " ".repeat(selectionMarker.length);
|
|
476
|
+
let arrowPrefix = " ";
|
|
477
|
+
if (!needsBar) {
|
|
478
|
+
if (isFirstVisible && canScrollUp) arrowPrefix = "\u2191 ";
|
|
479
|
+
else if (isLastVisible && canScrollDown) arrowPrefix = "\u2193 ";
|
|
417
480
|
}
|
|
481
|
+
const selectionPrefix = isSelected ? selectionMarker : " ".repeat(selectionMarker.length);
|
|
482
|
+
const label = clipNameForScrollbar(item.name, needsBar);
|
|
418
483
|
return h2(
|
|
419
484
|
import_ink2.Box,
|
|
420
485
|
{ flexDirection: "row" },
|
|
421
|
-
|
|
422
|
-
h2(import_ink2.Text, {
|
|
423
|
-
key: `arrow-${actualIndex}`,
|
|
424
|
-
color: "white"
|
|
425
|
-
}, arrowPrefix),
|
|
426
|
-
// Selection marker space (always same width, not highlighted)
|
|
486
|
+
h2(import_ink2.Text, { key: `arrow-${actualIndex}`, color: "white" }, arrowPrefix),
|
|
427
487
|
h2(import_ink2.Text, { key: `marker-${actualIndex}`, color: "white" }, selectionPrefix),
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
488
|
+
h2(
|
|
489
|
+
import_ink2.Text,
|
|
490
|
+
{
|
|
491
|
+
key: `name-${actualIndex}`,
|
|
492
|
+
color: isSelected ? "black" : "white",
|
|
493
|
+
backgroundColor: isSelected ? "cyan" : void 0,
|
|
494
|
+
bold: isSelected
|
|
495
|
+
},
|
|
496
|
+
label
|
|
497
|
+
)
|
|
435
498
|
);
|
|
436
499
|
};
|
|
437
500
|
const itemRenderer = renderItem || defaultRenderItem;
|
|
@@ -444,42 +507,32 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
444
507
|
if (renderItem) {
|
|
445
508
|
const isFirstVisible = displayIndex === 0;
|
|
446
509
|
const isLastVisible = displayIndex === visibleItems.length - 1;
|
|
447
|
-
let arrowPrefix = "";
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
arrowPrefix = "\
|
|
451
|
-
} else if (isLastVisible && canScrollDown) {
|
|
452
|
-
arrowPrefix = "\u2193 ";
|
|
453
|
-
} else {
|
|
454
|
-
arrowPrefix = " ";
|
|
510
|
+
let arrowPrefix = " ";
|
|
511
|
+
if (!needsBar) {
|
|
512
|
+
if (isFirstVisible && canScrollUp) arrowPrefix = "\u2191 ";
|
|
513
|
+
else if (isLastVisible && canScrollDown) arrowPrefix = "\u2193 ";
|
|
455
514
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
key: `
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
{ flexDirection: "row" },
|
|
466
|
-
// Arrow (clickable if functional, not highlighted)
|
|
467
|
-
h2(import_ink2.Text, {
|
|
468
|
-
key: `arrow-${actualIndex}`,
|
|
469
|
-
color: "white"
|
|
470
|
-
}, arrowPrefix),
|
|
471
|
-
// Selection marker space (always same width, not highlighted)
|
|
472
|
-
h2(import_ink2.Text, { key: `marker-${actualIndex}`, color: "white" }, selectionPrefix),
|
|
473
|
-
// Custom rendered content
|
|
474
|
-
renderItem(item, isSelected, displayIndex)
|
|
475
|
-
)
|
|
476
|
-
});
|
|
477
|
-
} else {
|
|
515
|
+
const selectionPrefix = isSelected ? selectionMarker : " ".repeat(selectionMarker.length);
|
|
516
|
+
const clipped = needsBar ? { ...item, name: clipNameForScrollbar(item.name, true) } : item;
|
|
517
|
+
const row = h2(
|
|
518
|
+
import_ink2.Box,
|
|
519
|
+
{ flexDirection: "row" },
|
|
520
|
+
h2(import_ink2.Text, { key: `arrow-${actualIndex}`, color: "white" }, arrowPrefix),
|
|
521
|
+
h2(import_ink2.Text, { key: `marker-${actualIndex}`, color: "white" }, selectionPrefix),
|
|
522
|
+
renderItem(clipped, isSelected, displayIndex)
|
|
523
|
+
);
|
|
478
524
|
return h2(ScreenRow, {
|
|
479
525
|
key: `item-${actualIndex}`,
|
|
480
|
-
children:
|
|
526
|
+
children: appendBar(row, displayIndex)
|
|
481
527
|
});
|
|
482
528
|
}
|
|
529
|
+
return h2(ScreenRow, {
|
|
530
|
+
key: `item-${actualIndex}`,
|
|
531
|
+
children: appendBar(
|
|
532
|
+
itemRenderer(item, isSelected, displayIndex, actualIndex),
|
|
533
|
+
displayIndex
|
|
534
|
+
)
|
|
535
|
+
});
|
|
483
536
|
})
|
|
484
537
|
);
|
|
485
538
|
}
|
|
@@ -489,6 +542,7 @@ var init_list_components = __esm({
|
|
|
489
542
|
import_react2 = __toESM(require("react"), 1);
|
|
490
543
|
import_ink2 = require("ink");
|
|
491
544
|
init_components();
|
|
545
|
+
init_scrollbar();
|
|
492
546
|
h2 = import_react2.createElement;
|
|
493
547
|
}
|
|
494
548
|
});
|
|
@@ -982,21 +1036,6 @@ function wrapTextLines(text, cols) {
|
|
|
982
1036
|
}
|
|
983
1037
|
return out;
|
|
984
1038
|
}
|
|
985
|
-
function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {
|
|
986
|
-
const view = Math.max(1, Math.floor(viewportRows));
|
|
987
|
-
const total = Math.max(0, Math.floor(totalLines));
|
|
988
|
-
if (total <= view) return null;
|
|
989
|
-
const maxScroll = total - view;
|
|
990
|
-
const thumbSize = Math.max(1, Math.round(view / total * view));
|
|
991
|
-
const travel = Math.max(0, view - thumbSize);
|
|
992
|
-
const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);
|
|
993
|
-
const thumbStart = maxScroll === 0 ? 0 : Math.round(s / maxScroll * travel);
|
|
994
|
-
const glyphs = [];
|
|
995
|
-
for (let i = 0; i < view; i++) {
|
|
996
|
-
glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);
|
|
997
|
-
}
|
|
998
|
-
return glyphs;
|
|
999
|
-
}
|
|
1000
1039
|
function padEndVisible(s, w) {
|
|
1001
1040
|
const t = String(s ?? "");
|
|
1002
1041
|
if (t.length >= w) return t.slice(0, w);
|
|
@@ -1097,24 +1136,19 @@ function ScrollableText({
|
|
|
1097
1136
|
...rowNodes
|
|
1098
1137
|
);
|
|
1099
1138
|
}
|
|
1100
|
-
var import_react5, import_ink5, h5,
|
|
1139
|
+
var import_react5, import_ink5, h5, SCROLL_KEYS;
|
|
1101
1140
|
var init_scrollable_text = __esm({
|
|
1102
1141
|
"src/screen/scrollable-text.js"() {
|
|
1103
1142
|
import_react5 = require("react");
|
|
1104
1143
|
import_ink5 = require("ink");
|
|
1105
1144
|
init_components();
|
|
1145
|
+
init_scrollbar();
|
|
1146
|
+
init_scrollbar();
|
|
1106
1147
|
h5 = import_react5.createElement;
|
|
1107
|
-
BAR_THUMB = "#";
|
|
1108
|
-
BAR_TRACK = "|";
|
|
1109
1148
|
SCROLL_KEYS = [
|
|
1110
1149
|
{ key: "upArrow", caption: "scroll", action: "scrollUp", order: 0 },
|
|
1111
1150
|
{ key: "downArrow", caption: "scroll", action: "scrollDown", order: 0 },
|
|
1112
|
-
|
|
1113
|
-
{ key: "downArrow", meta: true, caption: "page", action: "pageDown", order: 0 },
|
|
1114
|
-
{ key: "upArrow", ctrl: true, caption: "page", action: "pageUp", order: 0 },
|
|
1115
|
-
{ key: "downArrow", ctrl: true, caption: "page", action: "pageDown", order: 0 },
|
|
1116
|
-
{ key: "pageUp", caption: "page", action: "pageUp", order: 0 },
|
|
1117
|
-
{ key: "pageDown", caption: "page", action: "pageDown", order: 0 }
|
|
1151
|
+
...PAGE_SCROLL_KEY_BINDINGS
|
|
1118
1152
|
];
|
|
1119
1153
|
}
|
|
1120
1154
|
});
|
|
@@ -1264,6 +1298,7 @@ var init_screen = __esm({
|
|
|
1264
1298
|
init_components();
|
|
1265
1299
|
init_ui_elements();
|
|
1266
1300
|
init_scrollable_text();
|
|
1301
|
+
init_scrollbar();
|
|
1267
1302
|
init_key_bindings();
|
|
1268
1303
|
init_utils();
|
|
1269
1304
|
init_footer_builder();
|
|
@@ -1281,7 +1316,10 @@ __export(src_exports, {
|
|
|
1281
1316
|
AbstractTask: () => AbstractTask,
|
|
1282
1317
|
Args: () => Args,
|
|
1283
1318
|
Aws: () => Aws,
|
|
1319
|
+
BAR_THUMB: () => BAR_THUMB,
|
|
1320
|
+
BAR_TRACK: () => BAR_TRACK,
|
|
1284
1321
|
Box: () => import_ink6.Box,
|
|
1322
|
+
DEFAULT_RUNTIME_PARAM_SPECS: () => DEFAULT_RUNTIME_PARAM_SPECS,
|
|
1285
1323
|
Db: () => Db,
|
|
1286
1324
|
Divider: () => Divider,
|
|
1287
1325
|
FileDatabase: () => FileDatabase,
|
|
@@ -1295,6 +1333,7 @@ __export(src_exports, {
|
|
|
1295
1333
|
ListItem: () => ListItem,
|
|
1296
1334
|
MultiColumnListComponent: () => MultiColumnListComponent,
|
|
1297
1335
|
MultiColumnListWithPreviewComponent: () => MultiColumnListWithPreviewComponent,
|
|
1336
|
+
PAGE_SCROLL_KEY_BINDINGS: () => PAGE_SCROLL_KEY_BINDINGS,
|
|
1298
1337
|
Params: () => Params,
|
|
1299
1338
|
REMOTE_CLI_REL: () => REMOTE_CLI_REL,
|
|
1300
1339
|
React: () => import_react6.default,
|
|
@@ -1308,6 +1347,7 @@ __export(src_exports, {
|
|
|
1308
1347
|
ScreenTitle: () => ScreenTitle,
|
|
1309
1348
|
ScrollableText: () => ScrollableText,
|
|
1310
1349
|
TaskGetLogs: () => TaskGetLogs,
|
|
1350
|
+
TaskPauseRunner: () => TaskPauseRunner,
|
|
1311
1351
|
TaskPing: () => TaskPing,
|
|
1312
1352
|
TaskSampleProcess: () => TaskSampleProcess,
|
|
1313
1353
|
TaskSetRuntimeParam: () => TaskSetRuntimeParam,
|
|
@@ -1315,6 +1355,7 @@ __export(src_exports, {
|
|
|
1315
1355
|
TaskStopRunner: () => TaskStopRunner,
|
|
1316
1356
|
TaskSumAB: () => TaskSumAB,
|
|
1317
1357
|
TaskSystemInfo: () => TaskSystemInfo,
|
|
1358
|
+
TaskUnpauseRunner: () => TaskUnpauseRunner,
|
|
1318
1359
|
TasksManager: () => TasksManager,
|
|
1319
1360
|
TasksRegistry: () => TasksRegistry,
|
|
1320
1361
|
Text: () => import_ink6.Text,
|
|
@@ -1322,6 +1363,7 @@ __export(src_exports, {
|
|
|
1322
1363
|
activateRelease: () => activateRelease,
|
|
1323
1364
|
appendDeployLog: () => appendDeployLog,
|
|
1324
1365
|
appendTaskIpcLog: () => appendTaskIpcLog,
|
|
1366
|
+
applyRunnerPaused: () => applyRunnerPaused,
|
|
1325
1367
|
applyRuntimeParam: () => applyRuntimeParam,
|
|
1326
1368
|
applyRuntimePatch: () => applyRuntimePatch,
|
|
1327
1369
|
bindingIdentity: () => bindingIdentity,
|
|
@@ -1380,6 +1422,7 @@ __export(src_exports, {
|
|
|
1380
1422
|
matchesParsedPattern: () => matchesParsedPattern,
|
|
1381
1423
|
memo: () => import_react6.memo,
|
|
1382
1424
|
mergeAllowedTasksWithServiceTasks: () => mergeAllowedTasksWithServiceTasks,
|
|
1425
|
+
mergeRuntimeParamSpecs: () => mergeRuntimeParamSpecs,
|
|
1383
1426
|
nextTimeMatch: () => nextTimeMatch,
|
|
1384
1427
|
normalizeAllowedTasks: () => normalizeAllowedTasks,
|
|
1385
1428
|
npmEnv: () => npmEnv,
|
|
@@ -1416,6 +1459,8 @@ __export(src_exports, {
|
|
|
1416
1459
|
runRemoteStatus: () => runRemoteStatus,
|
|
1417
1460
|
runShell: () => runShell,
|
|
1418
1461
|
runTasksLoop: () => runTasksLoop,
|
|
1462
|
+
runtimeParamSpecsFromMetadata: () => runtimeParamSpecsFromMetadata,
|
|
1463
|
+
runtimeValuesForSpecs: () => runtimeValuesForSpecs,
|
|
1419
1464
|
scrollbarGlyphs: () => scrollbarGlyphs,
|
|
1420
1465
|
scrubEnvContent: () => scrubEnvContent,
|
|
1421
1466
|
servicePaths: () => servicePaths,
|
|
@@ -7189,12 +7234,13 @@ function tasksSchemaSpec(queueName = "tasks") {
|
|
|
7189
7234
|
}
|
|
7190
7235
|
};
|
|
7191
7236
|
}
|
|
7192
|
-
function taskHistoryInsertFromQueueRow(row, overrides) {
|
|
7237
|
+
function taskHistoryInsertFromQueueRow(row, overrides = {}) {
|
|
7193
7238
|
const { id, ...snapshot } = row;
|
|
7194
|
-
void id;
|
|
7239
|
+
const opid = overrides.opid !== void 0 ? overrides.opid : snapshot.opid != null && String(snapshot.opid).trim() !== "" ? snapshot.opid : id;
|
|
7195
7240
|
return {
|
|
7196
7241
|
...snapshot,
|
|
7197
|
-
...overrides
|
|
7242
|
+
...overrides,
|
|
7243
|
+
opid
|
|
7198
7244
|
};
|
|
7199
7245
|
}
|
|
7200
7246
|
async function ensureTaskTables(context, options = {}) {
|
|
@@ -8457,69 +8503,6 @@ var TaskStopRunner = class extends AbstractTask {
|
|
|
8457
8503
|
}
|
|
8458
8504
|
};
|
|
8459
8505
|
|
|
8460
|
-
// src/tasks/coreTasks/TaskGetLogs.js
|
|
8461
|
-
var TaskGetLogs = class extends AbstractTask {
|
|
8462
|
-
/**
|
|
8463
|
-
* @param {object} context
|
|
8464
|
-
* @param {Record<string, unknown>} [overrides]
|
|
8465
|
-
* @returns {Promise<{ source: string, resource: string, tail: number, afterTs?: string }>}
|
|
8466
|
-
*/
|
|
8467
|
-
static async resolveCustomParams(context, overrides = {}) {
|
|
8468
|
-
const merged = AbstractTask._mergeTypedParams(context, "task-get-logs", {
|
|
8469
|
-
source: "string",
|
|
8470
|
-
resource: "string",
|
|
8471
|
-
tail: "number default 100",
|
|
8472
|
-
afterTs: "string"
|
|
8473
|
-
}, overrides);
|
|
8474
|
-
const source = typeof merged.source === "string" ? merged.source.trim() : "";
|
|
8475
|
-
const resource = typeof merged.resource === "string" ? merged.resource.trim() : "";
|
|
8476
|
-
if (!source) throw new ParamError('getLogs: param "source" is required');
|
|
8477
|
-
if (!resource) throw new ParamError('getLogs: param "resource" is required');
|
|
8478
|
-
let tail = Number(merged.tail);
|
|
8479
|
-
if (!Number.isFinite(tail) || tail < 1) tail = 100;
|
|
8480
|
-
tail = Math.min(1e4, Math.max(1, Math.floor(tail)));
|
|
8481
|
-
const out = { source, resource, tail };
|
|
8482
|
-
if (typeof merged.afterTs === "string" && merged.afterTs.trim()) {
|
|
8483
|
-
out.afterTs = merged.afterTs.trim();
|
|
8484
|
-
}
|
|
8485
|
-
return out;
|
|
8486
|
-
}
|
|
8487
|
-
/**
|
|
8488
|
-
* @param {unknown} _reportProgress Unused (single-shot read, no progress events).
|
|
8489
|
-
* @returns {Promise<{ success: boolean, results: unknown }>}
|
|
8490
|
-
*/
|
|
8491
|
-
async run(_reportProgress) {
|
|
8492
|
-
const p = this.task.params ?? {};
|
|
8493
|
-
const source = String(p.source ?? "").trim();
|
|
8494
|
-
const resource = String(p.resource ?? "").trim();
|
|
8495
|
-
const tail = Math.max(1, Math.min(1e4, Number(p.tail) > 0 ? Number(p.tail) : 100));
|
|
8496
|
-
const afterTs = p.afterTs != null && String(p.afterTs).trim() ? String(p.afterTs).trim() : null;
|
|
8497
|
-
if (!source || !resource) {
|
|
8498
|
-
return {
|
|
8499
|
-
success: false,
|
|
8500
|
-
results: { error: 'getLogs requires params "source" and "resource"' }
|
|
8501
|
-
};
|
|
8502
|
-
}
|
|
8503
|
-
try {
|
|
8504
|
-
const { records, latestTs } = await readTaskIpcLogsSnapshot(this.context, {
|
|
8505
|
-
source,
|
|
8506
|
-
resource,
|
|
8507
|
-
tail,
|
|
8508
|
-
afterTs
|
|
8509
|
-
});
|
|
8510
|
-
return {
|
|
8511
|
-
success: true,
|
|
8512
|
-
results: { records, latestTs, source, resource }
|
|
8513
|
-
};
|
|
8514
|
-
} catch (e) {
|
|
8515
|
-
return {
|
|
8516
|
-
success: false,
|
|
8517
|
-
results: { error: e?.message ?? String(e) }
|
|
8518
|
-
};
|
|
8519
|
-
}
|
|
8520
|
-
}
|
|
8521
|
-
};
|
|
8522
|
-
|
|
8523
8506
|
// src/tasks/runtimeParams.js
|
|
8524
8507
|
var LOOP_RUNTIME_KEYS = ["maxParallel", "pollMs", "claimJitterMs", "scanLimit"];
|
|
8525
8508
|
var LOGGER_RUNTIME_KEYS = [
|
|
@@ -8533,7 +8516,77 @@ var LOGGER_RUNTIME_KEYS = [
|
|
|
8533
8516
|
"progressWithTimes",
|
|
8534
8517
|
"progressThrottleMs"
|
|
8535
8518
|
];
|
|
8536
|
-
var
|
|
8519
|
+
var DEFAULT_RUNTIME_PARAM_SPECS = [
|
|
8520
|
+
{
|
|
8521
|
+
key: "maxParallel",
|
|
8522
|
+
type: "number",
|
|
8523
|
+
label: "Max parallel",
|
|
8524
|
+
description: "Worker-lane concurrency (how many tasks claim at once)"
|
|
8525
|
+
},
|
|
8526
|
+
{
|
|
8527
|
+
key: "pollMs",
|
|
8528
|
+
type: "number",
|
|
8529
|
+
label: "Poll ms",
|
|
8530
|
+
description: "Idle poll interval between claim attempts"
|
|
8531
|
+
},
|
|
8532
|
+
{
|
|
8533
|
+
key: "claimJitterMs",
|
|
8534
|
+
type: "number",
|
|
8535
|
+
label: "Claim jitter ms",
|
|
8536
|
+
description: "Random delay before worker claims (0 = off)"
|
|
8537
|
+
},
|
|
8538
|
+
{
|
|
8539
|
+
key: "scanLimit",
|
|
8540
|
+
type: "number",
|
|
8541
|
+
label: "Scan limit",
|
|
8542
|
+
description: "Max idle rows scanned per claim attempt"
|
|
8543
|
+
}
|
|
8544
|
+
];
|
|
8545
|
+
function mergeRuntimeParamSpecs(extra) {
|
|
8546
|
+
const byKey = new Map(DEFAULT_RUNTIME_PARAM_SPECS.map((s) => [s.key, { ...s }]));
|
|
8547
|
+
if (Array.isArray(extra)) {
|
|
8548
|
+
for (const raw of extra) {
|
|
8549
|
+
if (!raw || typeof raw !== "object") continue;
|
|
8550
|
+
const key = String(raw.key ?? "").trim();
|
|
8551
|
+
if (!key) continue;
|
|
8552
|
+
const prev = byKey.get(key) ?? {};
|
|
8553
|
+
const type = ["number", "boolean", "string"].includes(raw.type) ? raw.type : prev.type ?? "string";
|
|
8554
|
+
byKey.set(key, {
|
|
8555
|
+
key,
|
|
8556
|
+
type,
|
|
8557
|
+
label: String(raw.label ?? prev.label ?? key),
|
|
8558
|
+
description: raw.description != null ? String(raw.description) : prev.description != null ? String(prev.description) : void 0
|
|
8559
|
+
});
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
return Array.from(byKey.values());
|
|
8563
|
+
}
|
|
8564
|
+
function runtimeValuesForSpecs(context, specs = DEFAULT_RUNTIME_PARAM_SPECS) {
|
|
8565
|
+
const rt = ensureTasksRuntime(context);
|
|
8566
|
+
const out = {};
|
|
8567
|
+
for (const s of specs) {
|
|
8568
|
+
if (rt[s.key] !== void 0) out[s.key] = rt[s.key];
|
|
8569
|
+
}
|
|
8570
|
+
return out;
|
|
8571
|
+
}
|
|
8572
|
+
function runtimeParamSpecsFromMetadata(metadata) {
|
|
8573
|
+
const meta = metadata && typeof metadata === "object" ? metadata : null;
|
|
8574
|
+
const raw = meta?.runtimeParams;
|
|
8575
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
8576
|
+
return mergeRuntimeParamSpecs();
|
|
8577
|
+
}
|
|
8578
|
+
return mergeRuntimeParamSpecs(raw);
|
|
8579
|
+
}
|
|
8580
|
+
var CONTROL_LANE_TASK_NAMES = [
|
|
8581
|
+
"stopRunner",
|
|
8582
|
+
"stop",
|
|
8583
|
+
"pauseRunner",
|
|
8584
|
+
"pause",
|
|
8585
|
+
"unpauseRunner",
|
|
8586
|
+
"unpause",
|
|
8587
|
+
"setRuntimeParam",
|
|
8588
|
+
"setRunnerParam"
|
|
8589
|
+
];
|
|
8537
8590
|
function controlLaneTaskNames(extra) {
|
|
8538
8591
|
const names = [...CONTROL_LANE_TASK_NAMES];
|
|
8539
8592
|
if (extra == null || extra === "") return names;
|
|
@@ -8596,6 +8649,7 @@ function ensureTasksRuntime(context, seed = {}) {
|
|
|
8596
8649
|
if (rt.pollMs === void 0) rt.pollMs = seed.pollMs ?? 1e3;
|
|
8597
8650
|
if (rt.claimJitterMs === void 0) rt.claimJitterMs = seed.claimJitterMs ?? 0;
|
|
8598
8651
|
if (rt.scanLimit === void 0) rt.scanLimit = seed.scanLimit ?? 100;
|
|
8652
|
+
if (rt.paused === void 0) rt.paused = seed.paused === true;
|
|
8599
8653
|
return rt;
|
|
8600
8654
|
}
|
|
8601
8655
|
async function applyRuntimeParam(context, key, value) {
|
|
@@ -8619,12 +8673,15 @@ async function applyRuntimeParam(context, key, value) {
|
|
|
8619
8673
|
const reg = context.servicesRegistry;
|
|
8620
8674
|
if (reg?.rowId && reg?.registryTable) {
|
|
8621
8675
|
try {
|
|
8622
|
-
const
|
|
8676
|
+
const specs = Array.isArray(context.tasksRuntimeParamSpecs) ? context.tasksRuntimeParamSpecs : DEFAULT_RUNTIME_PARAM_SPECS;
|
|
8677
|
+
const runtimeSnapshot = runtimeValuesForSpecs(context, specs);
|
|
8623
8678
|
for (const lk of LOOP_RUNTIME_KEYS) {
|
|
8624
|
-
if (runtime[lk] !== void 0
|
|
8679
|
+
if (runtime[lk] !== void 0 && runtimeSnapshot[lk] === void 0) {
|
|
8680
|
+
runtimeSnapshot[lk] = runtime[lk];
|
|
8681
|
+
}
|
|
8625
8682
|
}
|
|
8626
8683
|
await updateServicesRegistryMetadata(context, reg, {
|
|
8627
|
-
runtime:
|
|
8684
|
+
runtime: runtimeSnapshot,
|
|
8628
8685
|
runtimeUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8629
8686
|
});
|
|
8630
8687
|
applied.push("servicesRegistry");
|
|
@@ -8660,6 +8717,140 @@ function readLoopRuntime(context) {
|
|
|
8660
8717
|
};
|
|
8661
8718
|
}
|
|
8662
8719
|
|
|
8720
|
+
// src/tasks/coreTasks/TaskPauseRunner.js
|
|
8721
|
+
async function applyRunnerPaused(context, paused) {
|
|
8722
|
+
const runtime = ensureTasksRuntime(context);
|
|
8723
|
+
const was = runtime.paused === true;
|
|
8724
|
+
runtime.paused = paused === true;
|
|
8725
|
+
const registry = context.servicesRegistry;
|
|
8726
|
+
if (registry && typeof registry === "object") {
|
|
8727
|
+
await updateServicesRegistryMetadata(context, registry, {
|
|
8728
|
+
paused: runtime.paused,
|
|
8729
|
+
pausedAt: runtime.paused ? (/* @__PURE__ */ new Date()).toISOString() : null
|
|
8730
|
+
});
|
|
8731
|
+
}
|
|
8732
|
+
const message = runtime.paused ? was ? "Runner already paused (no new worker tasks)." : "Runner paused: finishing in-flight work; no new worker tasks until unpause." : was ? "Runner unpaused: claiming worker tasks again." : "Runner already running (not paused).";
|
|
8733
|
+
context.logger?.warn?.(
|
|
8734
|
+
runtime.paused ? `[TaskPauseRunner] ${message}` : `[TaskUnpauseRunner] ${message}`
|
|
8735
|
+
);
|
|
8736
|
+
return {
|
|
8737
|
+
success: true,
|
|
8738
|
+
results: {
|
|
8739
|
+
paused: runtime.paused,
|
|
8740
|
+
message
|
|
8741
|
+
}
|
|
8742
|
+
};
|
|
8743
|
+
}
|
|
8744
|
+
var TaskPauseRunner = class extends AbstractTask {
|
|
8745
|
+
static taskName = "pauseRunner";
|
|
8746
|
+
static description = "Pause a runner: finish in-flight tasks, claim no new worker tasks until unpaused";
|
|
8747
|
+
static aliases = ["pause"];
|
|
8748
|
+
static defaultWaitForResult = true;
|
|
8749
|
+
/**
|
|
8750
|
+
* @param {object} context
|
|
8751
|
+
* @param {Record<string, unknown>} [overrides]
|
|
8752
|
+
* @returns {Promise<object>}
|
|
8753
|
+
*/
|
|
8754
|
+
static async resolveParams(context, overrides = {}) {
|
|
8755
|
+
const main = await super.resolveParams(context, overrides);
|
|
8756
|
+
if (!main.serviceName) {
|
|
8757
|
+
throw new ParamError(
|
|
8758
|
+
"pause/pauseRunner requires --serviceName (registry instance name; optional --serviceGroup, --instanceNumber, --serverName to narrow targeting)"
|
|
8759
|
+
);
|
|
8760
|
+
}
|
|
8761
|
+
return main;
|
|
8762
|
+
}
|
|
8763
|
+
async run() {
|
|
8764
|
+
return applyRunnerPaused(this.context, true);
|
|
8765
|
+
}
|
|
8766
|
+
};
|
|
8767
|
+
var TaskUnpauseRunner = class extends AbstractTask {
|
|
8768
|
+
static taskName = "unpauseRunner";
|
|
8769
|
+
static description = "Unpause a runner: resume claiming worker tasks";
|
|
8770
|
+
static aliases = ["unpause"];
|
|
8771
|
+
static defaultWaitForResult = true;
|
|
8772
|
+
/**
|
|
8773
|
+
* @param {object} context
|
|
8774
|
+
* @param {Record<string, unknown>} [overrides]
|
|
8775
|
+
* @returns {Promise<object>}
|
|
8776
|
+
*/
|
|
8777
|
+
static async resolveParams(context, overrides = {}) {
|
|
8778
|
+
const main = await super.resolveParams(context, overrides);
|
|
8779
|
+
if (!main.serviceName) {
|
|
8780
|
+
throw new ParamError(
|
|
8781
|
+
"unpause/unpauseRunner requires --serviceName (registry instance name; optional --serviceGroup, --instanceNumber, --serverName to narrow targeting)"
|
|
8782
|
+
);
|
|
8783
|
+
}
|
|
8784
|
+
return main;
|
|
8785
|
+
}
|
|
8786
|
+
async run() {
|
|
8787
|
+
return applyRunnerPaused(this.context, false);
|
|
8788
|
+
}
|
|
8789
|
+
};
|
|
8790
|
+
|
|
8791
|
+
// src/tasks/coreTasks/TaskGetLogs.js
|
|
8792
|
+
var TaskGetLogs = class extends AbstractTask {
|
|
8793
|
+
/**
|
|
8794
|
+
* @param {object} context
|
|
8795
|
+
* @param {Record<string, unknown>} [overrides]
|
|
8796
|
+
* @returns {Promise<{ source: string, resource: string, tail: number, afterTs?: string }>}
|
|
8797
|
+
*/
|
|
8798
|
+
static async resolveCustomParams(context, overrides = {}) {
|
|
8799
|
+
const merged = AbstractTask._mergeTypedParams(context, "task-get-logs", {
|
|
8800
|
+
source: "string",
|
|
8801
|
+
resource: "string",
|
|
8802
|
+
tail: "number default 100",
|
|
8803
|
+
afterTs: "string"
|
|
8804
|
+
}, overrides);
|
|
8805
|
+
const source = typeof merged.source === "string" ? merged.source.trim() : "";
|
|
8806
|
+
const resource = typeof merged.resource === "string" ? merged.resource.trim() : "";
|
|
8807
|
+
if (!source) throw new ParamError('getLogs: param "source" is required');
|
|
8808
|
+
if (!resource) throw new ParamError('getLogs: param "resource" is required');
|
|
8809
|
+
let tail = Number(merged.tail);
|
|
8810
|
+
if (!Number.isFinite(tail) || tail < 1) tail = 100;
|
|
8811
|
+
tail = Math.min(1e4, Math.max(1, Math.floor(tail)));
|
|
8812
|
+
const out = { source, resource, tail };
|
|
8813
|
+
if (typeof merged.afterTs === "string" && merged.afterTs.trim()) {
|
|
8814
|
+
out.afterTs = merged.afterTs.trim();
|
|
8815
|
+
}
|
|
8816
|
+
return out;
|
|
8817
|
+
}
|
|
8818
|
+
/**
|
|
8819
|
+
* @param {unknown} _reportProgress Unused (single-shot read, no progress events).
|
|
8820
|
+
* @returns {Promise<{ success: boolean, results: unknown }>}
|
|
8821
|
+
*/
|
|
8822
|
+
async run(_reportProgress) {
|
|
8823
|
+
const p = this.task.params ?? {};
|
|
8824
|
+
const source = String(p.source ?? "").trim();
|
|
8825
|
+
const resource = String(p.resource ?? "").trim();
|
|
8826
|
+
const tail = Math.max(1, Math.min(1e4, Number(p.tail) > 0 ? Number(p.tail) : 100));
|
|
8827
|
+
const afterTs = p.afterTs != null && String(p.afterTs).trim() ? String(p.afterTs).trim() : null;
|
|
8828
|
+
if (!source || !resource) {
|
|
8829
|
+
return {
|
|
8830
|
+
success: false,
|
|
8831
|
+
results: { error: 'getLogs requires params "source" and "resource"' }
|
|
8832
|
+
};
|
|
8833
|
+
}
|
|
8834
|
+
try {
|
|
8835
|
+
const { records, latestTs } = await readTaskIpcLogsSnapshot(this.context, {
|
|
8836
|
+
source,
|
|
8837
|
+
resource,
|
|
8838
|
+
tail,
|
|
8839
|
+
afterTs
|
|
8840
|
+
});
|
|
8841
|
+
return {
|
|
8842
|
+
success: true,
|
|
8843
|
+
results: { records, latestTs, source, resource }
|
|
8844
|
+
};
|
|
8845
|
+
} catch (e) {
|
|
8846
|
+
return {
|
|
8847
|
+
success: false,
|
|
8848
|
+
results: { error: e?.message ?? String(e) }
|
|
8849
|
+
};
|
|
8850
|
+
}
|
|
8851
|
+
}
|
|
8852
|
+
};
|
|
8853
|
+
|
|
8663
8854
|
// src/tasks/coreTasks/TaskSetRuntimeParam.js
|
|
8664
8855
|
var TaskSetRuntimeParam = class extends AbstractTask {
|
|
8665
8856
|
static defaultWaitForResult = true;
|
|
@@ -8815,7 +9006,7 @@ var TasksRegistry = class _TasksRegistry {
|
|
|
8815
9006
|
* @returns {TasksRegistry}
|
|
8816
9007
|
*/
|
|
8817
9008
|
static withCoreTasks() {
|
|
8818
|
-
return new _TasksRegistry().add("ping", TaskPing).add("sampleProcess", TaskSampleProcess).add("shellCommand", TaskShellCommand).add("systemInfo", TaskSystemInfo).add("info", TaskSystemInfo).add("taskSumAB", TaskSumAB).add("stopRunner", TaskStopRunner).add("stop", TaskStopRunner).add("getLogs", TaskGetLogs).add("setRuntimeParam", TaskSetRuntimeParam).add("setRunnerParam", TaskSetRuntimeParam);
|
|
9009
|
+
return new _TasksRegistry().add("ping", TaskPing).add("sampleProcess", TaskSampleProcess).add("shellCommand", TaskShellCommand).add("systemInfo", TaskSystemInfo).add("info", TaskSystemInfo).add("taskSumAB", TaskSumAB).add("stopRunner", TaskStopRunner).add("stop", TaskStopRunner).add("pauseRunner", TaskPauseRunner).add("pause", TaskPauseRunner).add("unpauseRunner", TaskUnpauseRunner).add("unpause", TaskUnpauseRunner).add("getLogs", TaskGetLogs).add("setRuntimeParam", TaskSetRuntimeParam).add("setRunnerParam", TaskSetRuntimeParam);
|
|
8819
9010
|
}
|
|
8820
9011
|
/**
|
|
8821
9012
|
* Register a single task class under a name. Overwrites any previous entry.
|
|
@@ -8918,6 +9109,10 @@ var SERVICE_TASK_NAMES = [
|
|
|
8918
9109
|
"ping",
|
|
8919
9110
|
"stop",
|
|
8920
9111
|
"stopRunner",
|
|
9112
|
+
"pause",
|
|
9113
|
+
"pauseRunner",
|
|
9114
|
+
"unpause",
|
|
9115
|
+
"unpauseRunner",
|
|
8921
9116
|
"shellCommand",
|
|
8922
9117
|
"systemInfo",
|
|
8923
9118
|
"info",
|
|
@@ -9379,17 +9574,25 @@ async function runTasksLoop(context, options) {
|
|
|
9379
9574
|
if (hbGroup) {
|
|
9380
9575
|
const hbIntervalMs = options.runnerHeartbeatIntervalMs ?? 1e4;
|
|
9381
9576
|
const staleMs = options.runnerHeartbeatStaleMs ?? 45e3;
|
|
9382
|
-
const
|
|
9577
|
+
const runtimeParamSpecs = mergeRuntimeParamSpecs(options.runnerRuntimeParams);
|
|
9578
|
+
context.tasksRuntimeParamSpecs = runtimeParamSpecs;
|
|
9383
9579
|
const defaultMeta = {
|
|
9384
9580
|
component: "tasks-runner",
|
|
9385
9581
|
allowedTasks: allowedTasks?.length ? allowedTasks.join(",") : "all",
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
claimJitterMs: loop0.claimJitterMs,
|
|
9390
|
-
scanLimit: loop0.scanLimit
|
|
9391
|
-
}
|
|
9582
|
+
paused: false,
|
|
9583
|
+
runtimeParams: runtimeParamSpecs,
|
|
9584
|
+
runtime: runtimeValuesForSpecs(context, runtimeParamSpecs)
|
|
9392
9585
|
};
|
|
9586
|
+
const metadata = {
|
|
9587
|
+
...defaultMeta,
|
|
9588
|
+
...options.runnerMetadata && typeof options.runnerMetadata === "object" ? options.runnerMetadata : {}
|
|
9589
|
+
};
|
|
9590
|
+
if (!Array.isArray(metadata.runtimeParams) || metadata.runtimeParams.length === 0) {
|
|
9591
|
+
metadata.runtimeParams = defaultMeta.runtimeParams;
|
|
9592
|
+
}
|
|
9593
|
+
if (!metadata.runtime || typeof metadata.runtime !== "object") {
|
|
9594
|
+
metadata.runtime = defaultMeta.runtime;
|
|
9595
|
+
}
|
|
9393
9596
|
registryReg = await registerInServicesRegistry(context, {
|
|
9394
9597
|
queueName,
|
|
9395
9598
|
target,
|
|
@@ -9399,7 +9602,7 @@ async function runTasksLoop(context, options) {
|
|
|
9399
9602
|
staleMs,
|
|
9400
9603
|
groupMaxInstances: options.runnerGroupMaxInstances,
|
|
9401
9604
|
enforceMaxInstances: options.runnerEnforceMaxInstances ?? true,
|
|
9402
|
-
metadata
|
|
9605
|
+
metadata
|
|
9403
9606
|
});
|
|
9404
9607
|
context.servicesRegistry = registryReg;
|
|
9405
9608
|
runnerIdentity = {
|
|
@@ -9449,28 +9652,38 @@ async function runTasksLoop(context, options) {
|
|
|
9449
9652
|
if (claimJitterMs > 0) {
|
|
9450
9653
|
await sleepMs(Math.floor(Math.random() * (claimJitterMs + 1)));
|
|
9451
9654
|
}
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
if (
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9655
|
+
const paused = context.tasksRuntime?.paused === true;
|
|
9656
|
+
if (!paused) {
|
|
9657
|
+
while (runningPromises.size < maxParallel) {
|
|
9658
|
+
const claimed = await claimNextRunnableTask(
|
|
9659
|
+
context,
|
|
9660
|
+
tasksTable,
|
|
9661
|
+
target,
|
|
9662
|
+
registry,
|
|
9663
|
+
scanLimit,
|
|
9664
|
+
allowedTasks,
|
|
9665
|
+
runnerIdentity
|
|
9666
|
+
);
|
|
9667
|
+
if (!claimed) break;
|
|
9668
|
+
const p = executeClaimedTask(
|
|
9669
|
+
context,
|
|
9670
|
+
tasksTable,
|
|
9671
|
+
historyTable,
|
|
9672
|
+
claimed,
|
|
9673
|
+
registry,
|
|
9674
|
+
runningTaskInstances
|
|
9675
|
+
).then(async (outcome) => {
|
|
9676
|
+
if (outcome.stopRunnerRequested && !stopRequested) {
|
|
9677
|
+
stopRequested = true;
|
|
9678
|
+
stopAllowanceMs = outcome.stopAllowanceMs || stopAllowanceMs;
|
|
9679
|
+
context.tasksRunnerStop = true;
|
|
9680
|
+
await signalRunningTasksStop(context, runningTaskInstances, stopAllowanceMs);
|
|
9681
|
+
}
|
|
9682
|
+
}).finally(() => {
|
|
9683
|
+
runningPromises.delete(p);
|
|
9684
|
+
});
|
|
9685
|
+
runningPromises.add(p);
|
|
9686
|
+
}
|
|
9474
9687
|
}
|
|
9475
9688
|
const wakePromises = [...runningPromises];
|
|
9476
9689
|
if (runningControlPromise) {
|
|
@@ -9524,16 +9737,26 @@ async function waitForTaskResult(context, taskId, options = {}) {
|
|
|
9524
9737
|
const pollMs = options.pollMs ?? 500;
|
|
9525
9738
|
const { tasksTable, historyTable } = queueToTableNames(queueName);
|
|
9526
9739
|
const deadline = Date.now() + timeoutMs;
|
|
9527
|
-
const waitStartedAt =
|
|
9528
|
-
let cachedNameOpid = null
|
|
9529
|
-
|
|
9530
|
-
|
|
9740
|
+
const waitStartedAt = new Date(Date.now() - 5e3);
|
|
9741
|
+
let cachedNameOpid = options.name != null && String(options.name).trim() !== "" ? {
|
|
9742
|
+
name: String(options.name).trim(),
|
|
9743
|
+
opid: options.opid !== void 0 ? options.opid : null
|
|
9744
|
+
} : null;
|
|
9745
|
+
async function findHistory(name, opid) {
|
|
9746
|
+
const base = () => db(historyTable).where({ name }).where("completed_at", ">=", waitStartedAt);
|
|
9747
|
+
if (opid != null && String(opid).trim() !== "") {
|
|
9748
|
+
const byOpid = await base().where({ opid }).orderBy("completed_at", "desc").first();
|
|
9749
|
+
if (byOpid) return byOpid;
|
|
9750
|
+
}
|
|
9751
|
+
const byQueueId = await base().where({ opid: taskId }).orderBy("completed_at", "desc").first();
|
|
9752
|
+
if (byQueueId) return byQueueId;
|
|
9753
|
+
const byQueueIdAny = await db(historyTable).where({ name, opid: taskId }).orderBy("completed_at", "desc").first();
|
|
9754
|
+
if (byQueueIdAny) return byQueueIdAny;
|
|
9531
9755
|
if (opid == null || opid === "") {
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
q = q.where({ opid });
|
|
9756
|
+
const byNull = await base().whereNull("opid").orderBy("completed_at", "desc").first();
|
|
9757
|
+
if (byNull) return byNull;
|
|
9535
9758
|
}
|
|
9536
|
-
return
|
|
9759
|
+
return void 0;
|
|
9537
9760
|
}
|
|
9538
9761
|
while (Date.now() <= deadline) {
|
|
9539
9762
|
const legacy = await db(historyTable).where({ id: taskId }).orderBy("created_at", "desc").first();
|
|
@@ -9543,18 +9766,17 @@ async function waitForTaskResult(context, taskId, options = {}) {
|
|
|
9543
9766
|
const pending = await db(tasksTable).where({ id: taskId }).first();
|
|
9544
9767
|
if (pending) {
|
|
9545
9768
|
cachedNameOpid = { name: pending.name, opid: pending.opid };
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
}
|
|
9550
|
-
} else if (cachedNameOpid) {
|
|
9551
|
-
const done = await historySinceWait(cachedNameOpid.name, cachedNameOpid.opid);
|
|
9769
|
+
}
|
|
9770
|
+
if (cachedNameOpid) {
|
|
9771
|
+
const done = await findHistory(cachedNameOpid.name, cachedNameOpid.opid);
|
|
9552
9772
|
if (done) {
|
|
9553
9773
|
return done;
|
|
9554
9774
|
}
|
|
9555
|
-
return null;
|
|
9556
9775
|
} else {
|
|
9557
|
-
|
|
9776
|
+
const byQueueId = await db(historyTable).where({ opid: taskId }).orderBy("completed_at", "desc").first();
|
|
9777
|
+
if (byQueueId) {
|
|
9778
|
+
return byQueueId;
|
|
9779
|
+
}
|
|
9558
9780
|
}
|
|
9559
9781
|
await sleepMs(pollMs);
|
|
9560
9782
|
}
|
|
@@ -9697,7 +9919,10 @@ var TasksManager = class _TasksManager {
|
|
|
9697
9919
|
AbstractTask,
|
|
9698
9920
|
Args,
|
|
9699
9921
|
Aws,
|
|
9922
|
+
BAR_THUMB,
|
|
9923
|
+
BAR_TRACK,
|
|
9700
9924
|
Box,
|
|
9925
|
+
DEFAULT_RUNTIME_PARAM_SPECS,
|
|
9701
9926
|
Db,
|
|
9702
9927
|
Divider,
|
|
9703
9928
|
FileDatabase,
|
|
@@ -9711,6 +9936,7 @@ var TasksManager = class _TasksManager {
|
|
|
9711
9936
|
ListItem,
|
|
9712
9937
|
MultiColumnListComponent,
|
|
9713
9938
|
MultiColumnListWithPreviewComponent,
|
|
9939
|
+
PAGE_SCROLL_KEY_BINDINGS,
|
|
9714
9940
|
Params,
|
|
9715
9941
|
REMOTE_CLI_REL,
|
|
9716
9942
|
React,
|
|
@@ -9724,6 +9950,7 @@ var TasksManager = class _TasksManager {
|
|
|
9724
9950
|
ScreenTitle,
|
|
9725
9951
|
ScrollableText,
|
|
9726
9952
|
TaskGetLogs,
|
|
9953
|
+
TaskPauseRunner,
|
|
9727
9954
|
TaskPing,
|
|
9728
9955
|
TaskSampleProcess,
|
|
9729
9956
|
TaskSetRuntimeParam,
|
|
@@ -9731,6 +9958,7 @@ var TasksManager = class _TasksManager {
|
|
|
9731
9958
|
TaskStopRunner,
|
|
9732
9959
|
TaskSumAB,
|
|
9733
9960
|
TaskSystemInfo,
|
|
9961
|
+
TaskUnpauseRunner,
|
|
9734
9962
|
TasksManager,
|
|
9735
9963
|
TasksRegistry,
|
|
9736
9964
|
Text,
|
|
@@ -9738,6 +9966,7 @@ var TasksManager = class _TasksManager {
|
|
|
9738
9966
|
activateRelease,
|
|
9739
9967
|
appendDeployLog,
|
|
9740
9968
|
appendTaskIpcLog,
|
|
9969
|
+
applyRunnerPaused,
|
|
9741
9970
|
applyRuntimeParam,
|
|
9742
9971
|
applyRuntimePatch,
|
|
9743
9972
|
bindingIdentity,
|
|
@@ -9796,6 +10025,7 @@ var TasksManager = class _TasksManager {
|
|
|
9796
10025
|
matchesParsedPattern,
|
|
9797
10026
|
memo,
|
|
9798
10027
|
mergeAllowedTasksWithServiceTasks,
|
|
10028
|
+
mergeRuntimeParamSpecs,
|
|
9799
10029
|
nextTimeMatch,
|
|
9800
10030
|
normalizeAllowedTasks,
|
|
9801
10031
|
npmEnv,
|
|
@@ -9832,6 +10062,8 @@ var TasksManager = class _TasksManager {
|
|
|
9832
10062
|
runRemoteStatus,
|
|
9833
10063
|
runShell,
|
|
9834
10064
|
runTasksLoop,
|
|
10065
|
+
runtimeParamSpecsFromMetadata,
|
|
10066
|
+
runtimeValuesForSpecs,
|
|
9835
10067
|
scrollbarGlyphs,
|
|
9836
10068
|
scrubEnvContent,
|
|
9837
10069
|
servicePaths,
|