@nmakarov/cli-toolkit 0.21.0 → 0.23.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.
Files changed (68) hide show
  1. package/dist/args.cjs +1 -4
  2. package/dist/args.cjs.map +1 -1
  3. package/dist/args.js +1 -1
  4. package/dist/args.js.map +1 -1
  5. package/dist/cli-runner.cjs +1252 -604
  6. package/dist/cli-runner.cjs.map +1 -1
  7. package/dist/cli-runner.js +1299 -650
  8. package/dist/cli-runner.js.map +1 -1
  9. package/dist/db.cjs +85 -157
  10. package/dist/db.cjs.map +1 -1
  11. package/dist/db.js +84 -150
  12. package/dist/db.js.map +1 -1
  13. package/dist/errors.cjs +2 -2
  14. package/dist/errors.cjs.map +1 -1
  15. package/dist/errors.js +2 -1
  16. package/dist/errors.js.map +1 -1
  17. package/dist/filedatabase.cjs +19 -19
  18. package/dist/filedatabase.cjs.map +1 -1
  19. package/dist/filedatabase.js +19 -16
  20. package/dist/filedatabase.js.map +1 -1
  21. package/dist/http-client.cjs +9 -11
  22. package/dist/http-client.cjs.map +1 -1
  23. package/dist/http-client.js +10 -9
  24. package/dist/http-client.js.map +1 -1
  25. package/dist/http-client2.cjs +34 -37
  26. package/dist/http-client2.cjs.map +1 -1
  27. package/dist/http-client2.js +34 -34
  28. package/dist/http-client2.js.map +1 -1
  29. package/dist/index.cjs +1739 -720
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.js +1746 -721
  32. package/dist/index.js.map +1 -1
  33. package/dist/init.cjs +81 -68
  34. package/dist/init.cjs.map +1 -1
  35. package/dist/init.js +96 -82
  36. package/dist/init.js.map +1 -1
  37. package/dist/logger.cjs +5 -5
  38. package/dist/logger.cjs.map +1 -1
  39. package/dist/logger.js +5 -4
  40. package/dist/logger.js.map +1 -1
  41. package/dist/mock-server.cjs +21 -33
  42. package/dist/mock-server.cjs.map +1 -1
  43. package/dist/mock-server.js +21 -28
  44. package/dist/mock-server.js.map +1 -1
  45. package/dist/params.cjs +6 -9
  46. package/dist/params.cjs.map +1 -1
  47. package/dist/params.js +6 -6
  48. package/dist/params.js.map +1 -1
  49. package/dist/s3.cjs +286 -0
  50. package/dist/s3.cjs.map +1 -0
  51. package/dist/s3.js +273 -0
  52. package/dist/s3.js.map +1 -0
  53. package/dist/screen.cjs +34 -39
  54. package/dist/screen.cjs.map +1 -1
  55. package/dist/screen.js +48 -46
  56. package/dist/screen.js.map +1 -1
  57. package/dist/tasks.cjs +1354 -501
  58. package/dist/tasks.cjs.map +1 -1
  59. package/dist/tasks.js +1369 -527
  60. package/dist/tasks.js.map +1 -1
  61. package/dist/utils.cjs +7 -8
  62. package/dist/utils.cjs.map +1 -1
  63. package/dist/utils.js +6 -6
  64. package/dist/utils.js.map +1 -1
  65. package/package.json +32 -47
  66. package/scripts/ssm/{parse-cli.ts → parse-cli.js} +4 -4
  67. package/scripts/ssm/{ssm-admin.ts → ssm-admin.js} +12 -12
  68. package/scripts/ssm/{ssm-pull.ts → ssm-pull.js} +10 -13
package/dist/init.js CHANGED
@@ -14,7 +14,7 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
- // src/screen/components.ts
17
+ // src/screen/components.js
18
18
  import { createElement as h } from "react";
19
19
  import { Box, Text } from "ink";
20
20
  function getScreenWidth(maxWidth = null) {
@@ -89,13 +89,12 @@ function ScreenFooter({ lines, textStyle }) {
89
89
  );
90
90
  }
91
91
  var init_components = __esm({
92
- "src/screen/components.ts"() {
93
- "use strict";
92
+ "src/screen/components.js"() {
94
93
  }
95
94
  });
96
95
 
97
- // src/screen/list-components.ts
98
- import React2, { useState, useEffect, useRef, createElement } from "react";
96
+ // src/screen/list-components.js
97
+ import React, { useState, useEffect, useRef, createElement } from "react";
99
98
  import { Box as Box2, Text as Text2 } from "ink";
100
99
  function MultiColumnListComponent({ items, ctx, selectedIndexRef }) {
101
100
  const [, forceUpdate] = useState({});
@@ -231,11 +230,11 @@ function MultiColumnListWithPreviewComponent({
231
230
  const previewRows = [];
232
231
  if (typeof previewContent === "string") {
233
232
  previewRows.push(h2(ScreenRow, { key: "preview-string", children: h2(Text2, { bold: true }, previewContent) }));
234
- } else if (typeof previewContent === "object" && !React2.isValidElement(previewContent) && previewContent !== null) {
233
+ } else if (typeof previewContent === "object" && !React.isValidElement(previewContent) && previewContent !== null) {
235
234
  Object.entries(previewContent).forEach(([key, value], idx) => {
236
235
  previewRows.push(h2(ScreenRow, { key: `preview-${key}-${idx}`, children: h2(Text2, {}, `${key}: ${value}`) }));
237
236
  });
238
- } else if (React2.isValidElement(previewContent)) {
237
+ } else if (React.isValidElement(previewContent)) {
239
238
  previewRows.push(h2(ScreenRow, { key: "preview-element", children: previewContent }));
240
239
  }
241
240
  return h2(
@@ -248,11 +247,13 @@ function MultiColumnListWithPreviewComponent({
248
247
  ...previewRows
249
248
  );
250
249
  }
251
- function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sortable = false, maxHeight, sortHighlightStyle, selectionMarker = " " }) {
250
+ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sortable = false, maxHeight, sortHighlightStyle, selectionMarker = " ", onSelectionChange }) {
252
251
  const [, forceUpdate] = useState({});
253
252
  const [sortOrder, setSortOrder] = useState("none");
254
253
  const [scrollOffset, setScrollOffset] = useState(0);
255
254
  const scrollStateRef = useRef({ scrollOffset: 0, maxHeight: 0, totalItems: 0 });
255
+ const itemsRef = useRef(items);
256
+ itemsRef.current = items;
256
257
  const defaultGetTitle = (item) => {
257
258
  return getTitle ? getTitle(item) : typeof item.value === "string" ? item.value : item.value?.title || item.name;
258
259
  };
@@ -266,18 +267,24 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
266
267
  return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;
267
268
  }
268
269
  }) : items;
270
+ const displayItemsRef = useRef(displayItems);
271
+ displayItemsRef.current = displayItems;
269
272
  const effectiveMaxHeight = maxHeight || displayItems.length;
270
- const canScroll = displayItems.length > effectiveMaxHeight;
273
+ const _canScroll = displayItems.length > effectiveMaxHeight;
271
274
  const maxScrollOffset = Math.max(0, displayItems.length - effectiveMaxHeight);
272
275
  const clampedScrollOffset = Math.min(Math.max(0, scrollOffset), maxScrollOffset);
273
276
  const visibleItems = displayItems.slice(clampedScrollOffset, clampedScrollOffset + effectiveMaxHeight);
274
277
  const canScrollUp = clampedScrollOffset > 0;
275
278
  const canScrollDown = clampedScrollOffset < maxScrollOffset;
276
279
  scrollStateRef.current = { scrollOffset, maxHeight: effectiveMaxHeight, totalItems: displayItems.length };
280
+ const onSelectionChangeRef = useRef(onSelectionChange);
281
+ onSelectionChangeRef.current = onSelectionChange;
277
282
  useEffect(() => {
278
283
  ctx.setAction("moveUp", () => {
279
284
  const newIndex = Math.max(0, selectedIndexRef.current - 1);
280
285
  selectedIndexRef.current = newIndex;
286
+ const list = displayItemsRef.current;
287
+ onSelectionChangeRef.current?.(newIndex, list[newIndex]);
281
288
  const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;
282
289
  const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);
283
290
  const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);
@@ -287,18 +294,11 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
287
294
  forceUpdate({});
288
295
  });
289
296
  ctx.setAction("moveDown", () => {
290
- const currentItems = sortable && sortOrder !== "none" ? [...items].sort((a, b) => {
291
- const titleA = titleGetter(a).toLowerCase();
292
- const titleB = titleGetter(b).toLowerCase();
293
- if (sortOrder === "asc") {
294
- return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;
295
- } else {
296
- return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;
297
- }
298
- }) : items;
299
- const maxIndex = currentItems.length - 1;
297
+ const currentItems = displayItemsRef.current;
298
+ const maxIndex = Math.max(0, currentItems.length - 1);
300
299
  const newIndex = Math.min(maxIndex, selectedIndexRef.current + 1);
301
300
  selectedIndexRef.current = newIndex;
301
+ onSelectionChangeRef.current?.(newIndex, currentItems[newIndex]);
302
302
  const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;
303
303
  const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);
304
304
  const currentClampedScrollOffset = Math.min(Math.max(0, currentScrollOffset), currentMaxScrollOffset);
@@ -308,8 +308,7 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
308
308
  forceUpdate({});
309
309
  });
310
310
  ctx.setAction("scrollUp", () => {
311
- const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;
312
- const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);
311
+ const { scrollOffset: currentScrollOffset } = scrollStateRef.current;
313
312
  const newScrollOffset = Math.max(0, currentScrollOffset - 1);
314
313
  setScrollOffset(newScrollOffset);
315
314
  forceUpdate({});
@@ -324,9 +323,9 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
324
323
  if (sortable) {
325
324
  ctx.setAction("toggleSort", () => {
326
325
  const nextSort = sortOrder === "none" ? "asc" : sortOrder === "asc" ? "desc" : "none";
327
- const currentSelectedItem = displayItems[selectedIndexRef.current];
326
+ const currentSelectedItem = displayItemsRef.current[selectedIndexRef.current];
328
327
  setSortOrder(nextSort);
329
- const newSortedItems = nextSort !== "none" ? [...items].sort((a, b) => {
328
+ const newSortedItems = nextSort !== "none" ? [...itemsRef.current].sort((a, b) => {
330
329
  const titleA = titleGetter(a).toLowerCase();
331
330
  const titleB = titleGetter(b).toLowerCase();
332
331
  if (nextSort === "asc") {
@@ -334,7 +333,7 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
334
333
  } else {
335
334
  return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;
336
335
  }
337
- }) : items;
336
+ }) : itemsRef.current;
338
337
  const newIndex = newSortedItems.findIndex((item) => item === currentSelectedItem);
339
338
  if (newIndex !== -1) {
340
339
  selectedIndexRef.current = newIndex;
@@ -472,14 +471,13 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
472
471
  }
473
472
  var h2;
474
473
  var init_list_components = __esm({
475
- "src/screen/list-components.ts"() {
476
- "use strict";
474
+ "src/screen/list-components.js"() {
477
475
  init_components();
478
476
  h2 = createElement;
479
477
  }
480
478
  });
481
479
 
482
- // src/screen/screens.ts
480
+ // src/screen/screens.js
483
481
  import { useState as useState2, createElement as h3 } from "react";
484
482
  import { render, useInput, Text as Text3 } from "ink";
485
483
  function groupKeyBindings(bindings) {
@@ -557,7 +555,7 @@ async function showScreen(config2) {
557
555
  let renderResult = null;
558
556
  let initialized = false;
559
557
  const Screen = () => {
560
- const [updateCounter, setUpdateCounter] = useState2(0);
558
+ const [, setUpdateCounter] = useState2(0);
561
559
  if (!initialized) {
562
560
  const defaultBindings = [
563
561
  { key: "escape", caption: "go back", action: "back", protected: true, order: 1 },
@@ -676,7 +674,7 @@ async function showScreen(config2) {
676
674
  }
677
675
  }
678
676
  if (matchedBinding && actions[matchedBinding.action]) {
679
- const actionResult = actions[matchedBinding.action]({
677
+ actions[matchedBinding.action]({
680
678
  input,
681
679
  key,
682
680
  binding: matchedBinding
@@ -806,8 +804,7 @@ async function showMultiColumnListWithPreviewScreen(config2) {
806
804
  }
807
805
  var showMenuScreen, showWordGridScreen;
808
806
  var init_screens = __esm({
809
- "src/screen/screens.ts"() {
810
- "use strict";
807
+ "src/screen/screens.js"() {
811
808
  init_components();
812
809
  init_list_components();
813
810
  showMenuScreen = showListScreen;
@@ -815,9 +812,9 @@ var init_screens = __esm({
815
812
  }
816
813
  });
817
814
 
818
- // src/screen/ui-elements.ts
815
+ // src/screen/ui-elements.js
819
816
  import { createElement as h4 } from "react";
820
- import { Box as Box4, Text as Text4 } from "ink";
817
+ import { Box as Box3, Text as Text4 } from "ink";
821
818
  function ListItem({
822
819
  children,
823
820
  isSelected = false,
@@ -827,7 +824,7 @@ function ListItem({
827
824
  dimColor = false
828
825
  }) {
829
826
  return h4(
830
- Box4,
827
+ Box3,
831
828
  {},
832
829
  h4(Text4, {
833
830
  color: isSelected ? backgroundColor || "green" : color,
@@ -842,10 +839,10 @@ function TextBlock({
842
839
  color = "white",
843
840
  dimmed = false,
844
841
  bold = false,
845
- maxWidth
842
+ maxWidth: _maxWidth
846
843
  }) {
847
844
  return h4(
848
- Box4,
845
+ Box3,
849
846
  {},
850
847
  h4(Text4, {
851
848
  color,
@@ -856,7 +853,7 @@ function TextBlock({
856
853
  }
857
854
  function Divider({ character = "\u2500", width = 80 }) {
858
855
  return h4(
859
- Box4,
856
+ Box3,
860
857
  { marginY: 1 },
861
858
  h4(Text4, { dimColor: true }, character.repeat(width))
862
859
  );
@@ -871,7 +868,7 @@ function GridCell({
871
868
  align = "left"
872
869
  }) {
873
870
  return h4(
874
- Box4,
871
+ Box3,
875
872
  { width },
876
873
  h4(Text4, {
877
874
  color,
@@ -882,25 +879,24 @@ function GridCell({
882
879
  }, children)
883
880
  );
884
881
  }
885
- function InputField({ prompt, value, onChange, onSubmit }) {
882
+ function InputField({ prompt, value, onChange: _onChange, onSubmit: _onSubmit }) {
886
883
  return h4(
887
- Box4,
884
+ Box3,
888
885
  { flexDirection: "column" },
889
886
  h4(Text4, {}, prompt),
890
887
  h4(
891
- Box4,
888
+ Box3,
892
889
  { marginTop: 1 },
893
890
  h4(Text4, { color: "cyan" }, " > ", value, "_")
894
891
  )
895
892
  );
896
893
  }
897
894
  var init_ui_elements = __esm({
898
- "src/screen/ui-elements.ts"() {
899
- "use strict";
895
+ "src/screen/ui-elements.js"() {
900
896
  }
901
897
  });
902
898
 
903
- // src/screen/utils.ts
899
+ // src/screen/utils.js
904
900
  function buildBreadcrumb(parts) {
905
901
  if (parts.length === 0) return "";
906
902
  if (parts.length === 1) return parts[0];
@@ -914,12 +910,11 @@ function buildDetailBreadcrumb(path, suffix = "") {
914
910
  return suffix ? `${breadcrumb} ${suffix}` : breadcrumb;
915
911
  }
916
912
  var init_utils = __esm({
917
- "src/screen/utils.ts"() {
918
- "use strict";
913
+ "src/screen/utils.js"() {
919
914
  }
920
915
  });
921
916
 
922
- // src/screen/footer-builder.ts
917
+ // src/screen/footer-builder.js
923
918
  function buildFooter(config2 = {}) {
924
919
  const {
925
920
  navigation = null,
@@ -970,8 +965,7 @@ function organizeFooterMessages(messages) {
970
965
  }
971
966
  var FooterPresets;
972
967
  var init_footer_builder = __esm({
973
- "src/screen/footer-builder.ts"() {
974
- "use strict";
968
+ "src/screen/footer-builder.js"() {
975
969
  FooterPresets = {
976
970
  /**
977
971
  * Menu screen footer
@@ -1030,10 +1024,10 @@ var init_footer_builder = __esm({
1030
1024
  }
1031
1025
  });
1032
1026
 
1033
- // src/screen/index.ts
1027
+ // src/screen/index.js
1034
1028
  var screen_exports = {};
1035
1029
  __export(screen_exports, {
1036
- Box: () => Box5,
1030
+ Box: () => Box4,
1037
1031
  Divider: () => Divider,
1038
1032
  FooterPresets: () => FooterPresets,
1039
1033
  GridCell: () => GridCell,
@@ -1042,7 +1036,7 @@ __export(screen_exports, {
1042
1036
  ListItem: () => ListItem,
1043
1037
  MultiColumnListComponent: () => MultiColumnListComponent,
1044
1038
  MultiColumnListWithPreviewComponent: () => MultiColumnListWithPreviewComponent,
1045
- React: () => React5,
1039
+ React: () => React2,
1046
1040
  ScreenBody: () => ScreenBody,
1047
1041
  ScreenContainer: () => ScreenContainer,
1048
1042
  ScreenDivider: () => ScreenDivider,
@@ -1056,6 +1050,7 @@ __export(screen_exports, {
1056
1050
  buildFooter: () => buildFooter,
1057
1051
  h: () => createElement2,
1058
1052
  load: () => load,
1053
+ memo: () => memo,
1059
1054
  organizeFooterMessages: () => organizeFooterMessages,
1060
1055
  showListScreen: () => showListScreen,
1061
1056
  showMenuScreen: () => showMenuScreen,
@@ -1064,14 +1059,15 @@ __export(screen_exports, {
1064
1059
  showScreen: () => showScreen,
1065
1060
  showWordGridScreen: () => showWordGridScreen,
1066
1061
  useCallback: () => useCallback,
1067
- useEffect: () => useEffect3,
1062
+ useEffect: () => useEffect2,
1068
1063
  useInput: () => useInput2,
1064
+ useLayoutEffect: () => useLayoutEffect,
1069
1065
  useMemo: () => useMemo,
1070
- useRef: () => useRef3,
1066
+ useRef: () => useRef2,
1071
1067
  useState: () => useState3
1072
1068
  });
1073
- import React5, { useState as useState3, useEffect as useEffect3, useRef as useRef3, useMemo, useCallback, createElement as createElement2 } from "react";
1074
- import { Box as Box5, Text as Text5, useInput as useInput2 } from "ink";
1069
+ import React2, { useState as useState3, useEffect as useEffect2, useLayoutEffect, useRef as useRef2, useMemo, useCallback, memo, createElement as createElement2 } from "react";
1070
+ import { Box as Box4, Text as Text5, useInput as useInput2 } from "ink";
1075
1071
  async function load() {
1076
1072
  if (loadPromise) return loadPromise;
1077
1073
  loadPromise = Promise.all([
@@ -1083,8 +1079,7 @@ async function load() {
1083
1079
  }
1084
1080
  var loadPromise;
1085
1081
  var init_screen = __esm({
1086
- "src/screen/index.ts"() {
1087
- "use strict";
1082
+ "src/screen/index.js"() {
1088
1083
  init_screens();
1089
1084
  init_list_components();
1090
1085
  init_components();
@@ -1099,7 +1094,7 @@ var init_screen = __esm({
1099
1094
  }
1100
1095
  });
1101
1096
 
1102
- // src/args/index.ts
1097
+ // src/args/index.js
1103
1098
  import { readFileSync, existsSync } from "fs";
1104
1099
  import { resolve, dirname, basename, extname, join, isAbsolute } from "path";
1105
1100
  import { config } from "dotenv";
@@ -1582,10 +1577,10 @@ var Args = class _Args {
1582
1577
  }
1583
1578
  };
1584
1579
 
1585
- // src/params/index.ts
1580
+ // src/params/index.js
1586
1581
  import Joi from "joi";
1587
1582
 
1588
- // src/errors.ts
1583
+ // src/errors.js
1589
1584
  var FrameworkError = class extends Error {
1590
1585
  constructor(message) {
1591
1586
  super(message);
@@ -1605,7 +1600,7 @@ var InitError = class extends FrameworkError {
1605
1600
  }
1606
1601
  };
1607
1602
 
1608
- // src/params/custom-types.ts
1603
+ // src/params/custom-types.js
1609
1604
  var joiEdateType = (value, helpers) => {
1610
1605
  if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(value)) {
1611
1606
  const testDate = new Date(value);
@@ -1698,7 +1693,7 @@ function calculateTimeOffset(amount, unit, sign) {
1698
1693
  }
1699
1694
  return sign === "+" ? amount * multiplier : -amount * multiplier;
1700
1695
  }
1701
- var joiStringArrayType = (type) => (value, helpers) => {
1696
+ var joiStringArrayType = (type) => (value, _helpers) => {
1702
1697
  if (value === void 0 || typeof value === "function") {
1703
1698
  return [];
1704
1699
  }
@@ -1724,7 +1719,7 @@ var joiStringArrayType = (type) => (value, helpers) => {
1724
1719
  return arr;
1725
1720
  };
1726
1721
 
1727
- // src/params/index.ts
1722
+ // src/params/index.js
1728
1723
  var Params = class _Params {
1729
1724
  context;
1730
1725
  // Partial context during initialization
@@ -1984,7 +1979,7 @@ var Params = class _Params {
1984
1979
  definition = val;
1985
1980
  val = val.value;
1986
1981
  }
1987
- const def = this.assignDefinition(key, definition);
1982
+ this.assignDefinition(key, definition);
1988
1983
  if (!this.runAllRegisteredSetters(key, val)) {
1989
1984
  this.params[key] = val;
1990
1985
  }
@@ -2103,11 +2098,11 @@ var Params = class _Params {
2103
2098
  }
2104
2099
  };
2105
2100
 
2106
- // src/logger/index.ts
2101
+ // src/logger/index.js
2107
2102
  import chalk from "chalk";
2108
2103
  import util from "util";
2109
2104
 
2110
- // src/logger/transports.ts
2105
+ // src/logger/transports.js
2111
2106
  var ConsoleTransport = class {
2112
2107
  write(payload) {
2113
2108
  console.info(payload);
@@ -2127,7 +2122,7 @@ var ParentProcessTransport = class {
2127
2122
  }
2128
2123
  };
2129
2124
 
2130
- // src/logger/index.ts
2125
+ // src/logger/index.js
2131
2126
  var ALL_LEVELS = [
2132
2127
  "silly",
2133
2128
  "debug",
@@ -2200,6 +2195,7 @@ var Logger = class _Logger {
2200
2195
  }
2201
2196
  /**
2202
2197
  * Initialize logger from context and CLI parameters. Whatever is in options goes (after discovered params).
2198
+ * Params are tracked under the `logger` module for --showUsedParams.
2203
2199
  */
2204
2200
  static init(context, options) {
2205
2201
  const paramDefs = {
@@ -2213,7 +2209,7 @@ var Logger = class _Logger {
2213
2209
  progressWithTimes: "boolean default false",
2214
2210
  progressThrottleMs: "number"
2215
2211
  };
2216
- const discovered = context.params.getAllForModule(paramDefs);
2212
+ const discovered = context.params.getAllForModule("logger", paramDefs);
2217
2213
  const config2 = { ...discovered, ...options };
2218
2214
  const logger = new _Logger(context, config2);
2219
2215
  context.logger = logger;
@@ -2409,9 +2405,9 @@ var Logger = class _Logger {
2409
2405
  }
2410
2406
  };
2411
2407
 
2412
- // src/init/index.ts
2408
+ // src/init/index.js
2413
2409
  import { EventEmitter } from "events";
2414
- function extractComponentOptions(opts, componentName) {
2410
+ function extractComponentOptions(opts, _componentName) {
2415
2411
  const reservedKeys = ["overrides", "defaults", "modules"];
2416
2412
  const componentOptions = {};
2417
2413
  for (const [key, value] of Object.entries(opts)) {
@@ -2478,6 +2474,19 @@ function printAllParameters(context) {
2478
2474
  async function init(flow, opts = {}) {
2479
2475
  let stop = false;
2480
2476
  let context = null;
2477
+ let cleanupRan = false;
2478
+ const runRegisteredCleanups = async (ctx) => {
2479
+ if (cleanupRan) return;
2480
+ cleanupRan = true;
2481
+ const fns = [...ctx.cleanupFunctions].reverse();
2482
+ for (const fn of fns) {
2483
+ try {
2484
+ await fn(ctx);
2485
+ } catch (error) {
2486
+ ctx.logger.warn("[cleanup] error in cleanup function:", error);
2487
+ }
2488
+ }
2489
+ };
2481
2490
  try {
2482
2491
  try {
2483
2492
  const screenModule = await Promise.resolve().then(() => (init_screen(), screen_exports));
@@ -2500,13 +2509,24 @@ async function init(flow, opts = {}) {
2500
2509
  printAllParameters(context);
2501
2510
  process.exit(0);
2502
2511
  }
2512
+ let sigintCount = 0;
2503
2513
  process.on("SIGINT", async () => {
2504
- if (stop) {
2505
- context.logger.warn("[process] killed");
2506
- process.exit(2);
2514
+ if (!context) return;
2515
+ sigintCount += 1;
2516
+ if (sigintCount === 1) {
2517
+ stop = true;
2518
+ context.logger.info(`>> emitting stop with allowance ${stopAllowance}`);
2519
+ context.emitter.emit("stop", stopAllowance);
2520
+ return;
2507
2521
  }
2522
+ context.logger.warn("[process] second SIGINT: running cleanup then exit");
2523
+ await runRegisteredCleanups(context);
2524
+ process.exit(2);
2525
+ });
2526
+ process.on("SIGTERM", () => {
2527
+ if (!context || stop) return;
2508
2528
  stop = true;
2509
- context.logger.info(`>> emitting stop with allowance ${stopAllowance}`);
2529
+ context.logger.info(`>> SIGTERM: emitting stop with allowance ${stopAllowance}`);
2510
2530
  context.emitter.emit("stop", stopAllowance);
2511
2531
  });
2512
2532
  await flow(context);
@@ -2531,13 +2551,7 @@ async function init(flow, opts = {}) {
2531
2551
  }
2532
2552
  } finally {
2533
2553
  if (context) {
2534
- for (const fn of context.cleanupFunctions.reverse()) {
2535
- try {
2536
- await fn(context);
2537
- } catch (error) {
2538
- context.logger.warn("[cleanup] error in cleanup function:", error);
2539
- }
2540
- }
2554
+ await runRegisteredCleanups(context);
2541
2555
  }
2542
2556
  }
2543
2557
  }