cdd-cli 3.2.2 → 4.1.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 (126) hide show
  1. package/README.es.md +222 -0
  2. package/README.md +108 -26
  3. package/dist/App.js +7 -1
  4. package/dist/components/ContainerCreationPrompt.js +26 -10
  5. package/dist/components/ControlsHUD.js +106 -0
  6. package/dist/components/SuggestionPanel.js +16 -7
  7. package/dist/components/UsageMenu.js +1 -1
  8. package/dist/helpers/appState.js +26 -0
  9. package/dist/helpers/constants.js +60 -21
  10. package/dist/helpers/dockerHubService.js +111 -0
  11. package/dist/helpers/dockerService/serviceComponents/containerExec.js +211 -0
  12. package/dist/helpers/logger.js +1 -1
  13. package/dist/hooks/creation/useContainerActions.js +22 -5
  14. package/dist/hooks/creation/useContainerCreation.js +414 -107
  15. package/dist/hooks/useContainerCommandRouter.js +13 -3
  16. package/dist/hooks/useControls.js +28 -7
  17. package/dist/hooks/useShellMode.js +101 -0
  18. package/dist/index.js +10 -1
  19. package/package.json +4 -1
  20. package/.atl/skill-registry.md +0 -30
  21. package/.editorconfig +0 -12
  22. package/.eslintrc.json +0 -30
  23. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
  24. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  25. package/.github/PULL_REQUEST_TEMPLATE/pull_request.md +0 -14
  26. package/.github/workflows/ci.yml +0 -32
  27. package/.github/workflows/docs.yml +0 -42
  28. package/.prettierignore +0 -4
  29. package/.prettierrc +0 -8
  30. package/CHANGELOG.md +0 -165
  31. package/CODE_OF_CONDUCT.md +0 -12
  32. package/CONTRIBUTING.md +0 -35
  33. package/SECURITY.md +0 -5
  34. package/__mocks__/ink.cjs +0 -17
  35. package/_config.yml +0 -13
  36. package/babel.config.cjs +0 -23
  37. package/coverage/clover.xml +0 -694
  38. package/coverage/coverage-final.json +0 -21
  39. package/coverage/lcov-report/base.css +0 -224
  40. package/coverage/lcov-report/block-navigation.js +0 -87
  41. package/coverage/lcov-report/components/ContainerCreationPrompt.jsx.html +0 -376
  42. package/coverage/lcov-report/components/PromptField.jsx.html +0 -229
  43. package/coverage/lcov-report/components/SuggestionPanel.jsx.html +0 -244
  44. package/coverage/lcov-report/components/index.html +0 -146
  45. package/coverage/lcov-report/favicon.png +0 -0
  46. package/coverage/lcov-report/helpers/constants.js.html +0 -298
  47. package/coverage/lcov-report/helpers/containerOptionsBuilder.js.html +0 -244
  48. package/coverage/lcov-report/helpers/dockerService/serviceComponents/containerActions.js.html +0 -931
  49. package/coverage/lcov-report/helpers/dockerService/serviceComponents/containerList.js.html +0 -307
  50. package/coverage/lcov-report/helpers/dockerService/serviceComponents/index.html +0 -131
  51. package/coverage/lcov-report/helpers/imageNameUtils.js.html +0 -181
  52. package/coverage/lcov-report/helpers/index.html +0 -191
  53. package/coverage/lcov-report/helpers/logger.js.html +0 -424
  54. package/coverage/lcov-report/helpers/safeCall.js.html +0 -139
  55. package/coverage/lcov-report/helpers/validationHelpers.js.html +0 -346
  56. package/coverage/lcov-report/hooks/creation/index.html +0 -146
  57. package/coverage/lcov-report/hooks/creation/useContainerActions.js.html +0 -313
  58. package/coverage/lcov-report/hooks/creation/useContainerCreation.js.html +0 -805
  59. package/coverage/lcov-report/hooks/creation/useLogsViewer.js.html +0 -238
  60. package/coverage/lcov-report/hooks/debug/index.html +0 -116
  61. package/coverage/lcov-report/hooks/debug/useDebugLogs.js.html +0 -187
  62. package/coverage/lcov-report/hooks/index.html +0 -161
  63. package/coverage/lcov-report/hooks/navigation/index.html +0 -116
  64. package/coverage/lcov-report/hooks/navigation/useContainerSelection.js.html +0 -169
  65. package/coverage/lcov-report/hooks/useContainerCommandRouter.js.html +0 -454
  66. package/coverage/lcov-report/hooks/useControls.js.html +0 -826
  67. package/coverage/lcov-report/hooks/useEraseConfirmation.js.html +0 -202
  68. package/coverage/lcov-report/hooks/useExitHandler.js.html +0 -292
  69. package/coverage/lcov-report/index.html +0 -206
  70. package/coverage/lcov-report/prettify.css +0 -1
  71. package/coverage/lcov-report/prettify.js +0 -2
  72. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  73. package/coverage/lcov-report/sorter.js +0 -210
  74. package/coverage/lcov.info +0 -1402
  75. package/fix-imports.cjs +0 -54
  76. package/jest.config.cjs +0 -14
  77. package/src/App.jsx +0 -96
  78. package/src/components/ContainerCreationPrompt.jsx +0 -97
  79. package/src/components/ContainerList.jsx +0 -32
  80. package/src/components/ContainerRow.jsx +0 -84
  81. package/src/components/ContainerSection.jsx +0 -24
  82. package/src/components/Footer.jsx +0 -15
  83. package/src/components/Header.jsx +0 -41
  84. package/src/components/LogViewer.jsx +0 -36
  85. package/src/components/MessageFeedback.jsx +0 -25
  86. package/src/components/PromptField.jsx +0 -48
  87. package/src/components/StatsBar.jsx +0 -70
  88. package/src/components/SuggestionPanel.jsx +0 -53
  89. package/src/components/UsageMenu.jsx +0 -52
  90. package/src/helpers/appInfo.js +0 -23
  91. package/src/helpers/constants.js +0 -71
  92. package/src/helpers/containerOptionsBuilder.js +0 -53
  93. package/src/helpers/dockerService/dockerService.js +0 -28
  94. package/src/helpers/dockerService/serviceComponents/containerActions.js +0 -282
  95. package/src/helpers/dockerService/serviceComponents/containerList.js +0 -74
  96. package/src/helpers/dockerService/serviceComponents/containerLogs.js +0 -60
  97. package/src/helpers/dockerService/serviceComponents/containerStats.js +0 -69
  98. package/src/helpers/dockerService/serviceComponents/imageUtils.js +0 -32
  99. package/src/helpers/exitWithMessage.js +0 -32
  100. package/src/helpers/imageNameUtils.js +0 -32
  101. package/src/helpers/logger.js +0 -113
  102. package/src/helpers/safeCall.js +0 -18
  103. package/src/helpers/validationHelpers.js +0 -87
  104. package/src/hooks/creation/useContainerActions.js +0 -76
  105. package/src/hooks/creation/useContainerCreation.js +0 -240
  106. package/src/hooks/creation/useLogsViewer.js +0 -51
  107. package/src/hooks/debug/useDebugLogs.js +0 -34
  108. package/src/hooks/navigation/useContainerSelection.js +0 -28
  109. package/src/hooks/useContainerCommandRouter.js +0 -123
  110. package/src/hooks/useContainerStats.js +0 -44
  111. package/src/hooks/useContainers.js +0 -26
  112. package/src/hooks/useControls.js +0 -247
  113. package/src/hooks/useEraseConfirmation.js +0 -39
  114. package/src/hooks/useExitHandler.js +0 -69
  115. package/src/index.js +0 -16
  116. package/test/ContainerCreationPrompt.dom.test.js +0 -68
  117. package/test/SuggestionPanel.dom.test.js +0 -53
  118. package/test/constants.test.js +0 -34
  119. package/test/containerActions.test.js +0 -229
  120. package/test/containerList.test.js +0 -79
  121. package/test/containerOptionsBuilder.test.js +0 -36
  122. package/test/jest.setup.js +0 -7
  123. package/test/safeCall.test.js +0 -25
  124. package/test/useContainerCreation.dom.test.js +0 -264
  125. package/test/useControls.dom.test.js +0 -313
  126. package/test/validationHelpers.test.js +0 -111
@@ -16,6 +16,7 @@ import { useCallback } from 'react';
16
16
  * l — open logs viewer and start log stream
17
17
  * c — open container creation wizard (reset + activate)
18
18
  * d — toggle debug log panel
19
+ * s — open interactive shell in container
19
20
  *
20
21
  * @param {Object} params
21
22
  * @param {Object} params.actions - API from useContainerActions
@@ -27,6 +28,7 @@ import { useCallback } from 'react';
27
28
  * @param {Function} params.onStartErase - Callback: activates confirmErase state
28
29
  * @param {Function} params.onToggleDebug - Callback: toggles showDebugLogs state
29
30
  * @param {Function} params.onStartCreate - Callback: sets creatingContainer = true
31
+ * @param {Function} params.onOpenShell - Callback: opens interactive shell
30
32
  * @returns {{ handleDockerCommands: Function }}
31
33
  */
32
34
  export function useContainerCommandRouter(_ref) {
@@ -38,7 +40,8 @@ export function useContainerCommandRouter(_ref) {
38
40
  startLogsStream = _ref.startLogsStream,
39
41
  onStartErase = _ref.onStartErase,
40
42
  onToggleDebug = _ref.onToggleDebug,
41
- onStartCreate = _ref.onStartCreate;
43
+ onStartCreate = _ref.onStartCreate,
44
+ onOpenShell = _ref.onOpenShell;
42
45
  var handleDockerCommands = useCallback(function (input) {
43
46
  var container = containers[selected];
44
47
  if (input === 'i') {
@@ -135,16 +138,23 @@ export function useContainerCommandRouter(_ref) {
135
138
  return true;
136
139
  }
137
140
  if (input === 'c') {
138
- onStartCreate();
139
141
  creation.resetCreation();
142
+ onStartCreate();
140
143
  return true;
141
144
  }
142
145
  if (input === 'd') {
143
146
  onToggleDebug();
144
147
  return true;
145
148
  }
149
+ if (input === 's') {
150
+ if (!container) {
151
+ return true;
152
+ }
153
+ onOpenShell(container);
154
+ return true;
155
+ }
146
156
  return false;
147
- }, [actions, containers, creation, logsViewer, onStartCreate, onStartErase, onToggleDebug, selected, startLogsStream]);
157
+ }, [actions, containers, creation, logsViewer, onStartCreate, onStartErase, onToggleDebug, onOpenShell, selected, startLogsStream]);
148
158
  return {
149
159
  handleDockerCommands: handleDockerCommands
150
160
  };
@@ -22,6 +22,7 @@ import { useDebugLogs } from './debug/useDebugLogs.js';
22
22
  import { useEraseConfirmation } from './useEraseConfirmation.js';
23
23
  import { useExitHandler } from './useExitHandler.js';
24
24
  import { useContainerCommandRouter } from './useContainerCommandRouter.js';
25
+ import { useShellMode } from './useShellMode.js';
25
26
  import { getLogsStream } from '../helpers/dockerService/serviceComponents/containerLogs.js';
26
27
  import { createContainer as svcCreateContainer } from '../helpers/dockerService/serviceComponents/containerActions.js';
27
28
  import { buildContainerOptions } from '../helpers/containerOptionsBuilder.js';
@@ -36,7 +37,9 @@ import { DB_IMAGES } from '../helpers/constants.js';
36
37
  * @returns {Object} controls - API for the App component
37
38
  */
38
39
  export function useControls() {
40
+ var _overrides$triggerHub, _overrides$isSearchin;
39
41
  var containers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
42
+ var overrides = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
40
43
  var _React$useState = React.useState(false),
41
44
  _React$useState2 = _slicedToArray(_React$useState, 2),
42
45
  creatingContainer = _React$useState2[0],
@@ -46,6 +49,7 @@ export function useControls() {
46
49
  var actions = useContainerActions({
47
50
  containers: containers
48
51
  });
52
+ var shellMode = useShellMode();
49
53
  var creation = useContainerCreation({
50
54
  onCreate: function () {
51
55
  var _onCreate = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(_ref) {
@@ -60,8 +64,7 @@ export function useControls() {
60
64
  portInput: portInput,
61
65
  envInput: envInput
62
66
  });
63
- actions.setMessage("Creating container ".concat(imageName, "..."));
64
- actions.setMessageColor('yellow');
67
+ actions.setTimedMessage("Creating container ".concat(imageName, "..."), 'yellow');
65
68
  _context.p = 1;
66
69
  _context.n = 2;
67
70
  return svcCreateContainer(imageName, options);
@@ -75,15 +78,13 @@ export function useControls() {
75
78
  return "".concat(p.hostPort, "\u2192").concat(p.containerPort, "/").concat(p.protocol);
76
79
  }).join(', ');
77
80
  }
78
- actions.setMessage("Created container ".concat(id).concat(portMsg));
79
- actions.setMessageColor('green');
81
+ actions.setTimedMessage("Created container ".concat(id).concat(portMsg), 'green');
80
82
  _context.n = 4;
81
83
  break;
82
84
  case 3:
83
85
  _context.p = 3;
84
86
  _t = _context.v;
85
- actions.setMessage("Error creating container: ".concat(_t.message));
86
- actions.setMessageColor('red');
87
+ actions.setTimedMessage("Error creating container: ".concat(_t.message), 'red');
87
88
  case 4:
88
89
  _context.p = 4;
89
90
  setCreatingContainer(false);
@@ -106,6 +107,11 @@ export function useControls() {
106
107
  var logsViewer = useLogsViewer();
107
108
  var selection = useContainerSelection(containers.length);
108
109
  var debugLogs = useDebugLogs();
110
+
111
+ // Allow overrides for testability (e.g. injecting a mock triggerHubSearch)
112
+ var triggerHubSearch = (_overrides$triggerHub = overrides.triggerHubSearch) !== null && _overrides$triggerHub !== void 0 ? _overrides$triggerHub : creation.triggerHubSearch;
113
+ var isSearchingHub = (_overrides$isSearchin = overrides.isSearchingHub) !== null && _overrides$isSearchin !== void 0 ? _overrides$isSearchin : creation.isSearchingHub;
114
+ var insertNextSuggestedEnv = overrides.insertNextSuggestedEnv !== undefined ? overrides.insertNextSuggestedEnv : creation.insertNextSuggestedEnv;
109
115
  var eraseConfirmation = useEraseConfirmation({
110
116
  onConfirm: function onConfirm() {
111
117
  actions.handleAction({
@@ -172,6 +178,9 @@ export function useControls() {
172
178
  },
173
179
  onStartCreate: function onStartCreate() {
174
180
  return setCreatingContainer(true);
181
+ },
182
+ onOpenShell: function onOpenShell(container) {
183
+ return shellMode.openShell(container);
175
184
  }
176
185
  });
177
186
  var exitHandler = useExitHandler({
@@ -211,6 +220,18 @@ export function useControls() {
211
220
  return;
212
221
  }
213
222
 
223
+ // Tab on step 0: trigger Docker Hub search (with guards)
224
+ if (key.tab) {
225
+ if (step === 0) {
226
+ if (!isSearchingHub && (creation.imageName || '').trim() !== '') {
227
+ triggerHubSearch();
228
+ }
229
+ } else if (step === 3) {
230
+ insertNextSuggestedEnv === null || insertNextSuggestedEnv === void 0 || insertNextSuggestedEnv();
231
+ }
232
+ return;
233
+ }
234
+
214
235
  // Arrow keys on step 0: navigate suggestion list
215
236
  if (step === 0 && creation.suggestions.length > 0) {
216
237
  if (key.upArrow) {
@@ -240,7 +261,7 @@ export function useControls() {
240
261
  if (step === 2) appendChar(creation.setPortInput, creation.portInput, input);
241
262
  if (step === 3) appendChar(creation.setEnvInput, creation.envInput, input);
242
263
  }
243
- }, [creation, setCreatingContainer]);
264
+ }, [creation, setCreatingContainer, triggerHubSearch, isSearchingHub, insertNextSuggestedEnv]);
244
265
 
245
266
  // Single keyboard entry point
246
267
  useInput(function (input, key) {
@@ -0,0 +1,101 @@
1
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
2
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
3
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
4
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
5
+ import React from 'react';
6
+ import { render } from 'ink';
7
+ import { execInteractive, detectShell } from '../helpers/dockerService/serviceComponents/containerExec.js';
8
+ import { getInkApp, setInkApp } from '../helpers/appState.js';
9
+ import App from '../App.js';
10
+ import { logger } from '../helpers/logger.js';
11
+
12
+ /**
13
+ * Open an interactive shell inside a Docker container.
14
+ * Unmounts Ink, spawns `docker exec -it`, and re-renders the app on exit.
15
+ *
16
+ * @param {Object} container - Container object from Docker
17
+ * @returns {Promise<void>}
18
+ */
19
+ function openShell(_x) {
20
+ return _openShell.apply(this, arguments);
21
+ }
22
+ /**
23
+ * Hook that provides the shell mode API.
24
+ * In practice, the heavy lifting (unmount/spawn/remount) is handled by
25
+ * `openShell` outside the React tree. This hook just exposes a stable
26
+ * reference for useControls.
27
+ *
28
+ * @returns {{ openShell: Function }}
29
+ */
30
+ function _openShell() {
31
+ _openShell = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(container) {
32
+ var isRunning, containerId, containerName, inkApp, shell, newApp, _t;
33
+ return _regenerator().w(function (_context) {
34
+ while (1) switch (_context.p = _context.n) {
35
+ case 0:
36
+ if (container) {
37
+ _context.n = 1;
38
+ break;
39
+ }
40
+ return _context.a(2);
41
+ case 1:
42
+ isRunning = container.state === 'running' || container.status === 'running';
43
+ if (isRunning) {
44
+ _context.n = 2;
45
+ break;
46
+ }
47
+ logger.warn('Cannot open shell: container %s is not running', container.name);
48
+ return _context.a(2);
49
+ case 2:
50
+ containerId = container.id;
51
+ containerName = container.name || containerId.slice(0, 12); // Unmount Ink to release the terminal
52
+ inkApp = getInkApp();
53
+ if (inkApp && typeof inkApp.unmount === 'function') {
54
+ inkApp.unmount();
55
+ }
56
+
57
+ // Clear the screen for a clean shell experience
58
+ if (process.stdout && process.stdout.isTTY) {
59
+ process.stdout.write("\x1Bc");
60
+ }
61
+ _context.p = 3;
62
+ _context.n = 4;
63
+ return detectShell(containerId);
64
+ case 4:
65
+ shell = _context.v;
66
+ process.stdout.write("\x1B[36m[shell]\x1B[0m Opening ".concat(shell, " in ").concat(containerName, " (").concat(containerId.slice(0, 12), ")...\r\n"));
67
+ process.stdout.write('\x1b[33mType "exit" or press Ctrl+D to return to CDD.\x1b[0m\r\n\r\n');
68
+ _context.n = 5;
69
+ return execInteractive(containerId, {
70
+ shell: shell
71
+ });
72
+ case 5:
73
+ _context.n = 7;
74
+ break;
75
+ case 6:
76
+ _context.p = 6;
77
+ _t = _context.v;
78
+ process.stdout.write("\x1B[31m[shell] Error: ".concat(_t.message, "\x1B[0m\r\n"));
79
+ logger.error('Shell mode error', _t);
80
+ case 7:
81
+ _context.n = 8;
82
+ return new Promise(function (r) {
83
+ return setTimeout(r, 100);
84
+ });
85
+ case 8:
86
+ // Re-render the app
87
+ console.clear();
88
+ newApp = render(/*#__PURE__*/React.createElement(App, null));
89
+ setInkApp(newApp);
90
+ case 9:
91
+ return _context.a(2);
92
+ }
93
+ }, _callee, null, [[3, 6]]);
94
+ }));
95
+ return _openShell.apply(this, arguments);
96
+ }
97
+ export function useShellMode() {
98
+ return {
99
+ openShell: openShell
100
+ };
101
+ }
package/dist/index.js CHANGED
@@ -10,5 +10,14 @@
10
10
  import React from 'react';
11
11
  import { render } from 'ink';
12
12
  import App from './App.js';
13
+ import { logger } from './helpers/logger.js';
14
+ import { setInkApp } from './helpers/appState.js';
15
+ process.on('uncaughtException', function (err) {
16
+ return logger.error('Uncaught exception', err);
17
+ });
18
+ process.on('unhandledRejection', function (reason) {
19
+ return logger.error('Unhandled rejection', reason);
20
+ });
13
21
  console.clear();
14
- render(/*#__PURE__*/React.createElement(App, null));
22
+ var inkApp = render(/*#__PURE__*/React.createElement(App, null));
23
+ setInkApp(inkApp);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdd-cli",
3
- "version": "3.2.2",
3
+ "version": "4.1.0",
4
4
  "description": "CLI Docker Dashboard",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,6 +16,9 @@
16
16
  "author": "",
17
17
  "license": "ISC",
18
18
  "type": "module",
19
+ "files": [
20
+ "dist"
21
+ ],
19
22
  "dependencies": {
20
23
  "chalk": "^5.6.2",
21
24
  "dockerode": "^4.0.9",
@@ -1,30 +0,0 @@
1
- # Skill Registry — CDD
2
-
3
- Generated: 2026-04-25
4
-
5
- ## User Skills (from ~/.config/opencode/skills/)
6
-
7
- | Skill | Trigger |
8
- |-------|---------|
9
- | branch-pr | Creating a pull request, opening a PR, or preparing changes for review |
10
- | go-testing | Writing Go tests, using teatest, or adding test coverage |
11
- | issue-creation | Creating a GitHub issue, reporting a bug, or requesting a feature |
12
- | judgment-day | "judgment day", "review adversarial", "dual review", "juzgar", "que lo juzguen" |
13
- | reporter | Creating a sprint report, updating CHANGELOG, or documenting completed work |
14
- | sdd-apply | Orchestrator launches to implement one or more tasks from a change |
15
- | sdd-archive | Orchestrator launches to archive a change after implementation and verification |
16
- | sdd-design | Orchestrator launches to write or update the technical design for a change |
17
- | sdd-explore | Orchestrator launches to think through a feature, investigate the codebase, or clarify requirements |
18
- | sdd-propose | Orchestrator launches to create or update a proposal for a change |
19
- | sdd-spec | Orchestrator launches to write or update specs for a change |
20
- | sdd-tasks | Orchestrator launches to create or update the task breakdown for a change |
21
- | sdd-verify | Orchestrator launches to verify a completed change |
22
- | skill-creator | Creating a new skill, adding agent instructions, or documenting patterns for AI |
23
- | skill-registry | "update skills", "skill registry", "actualizar skills", "update registry" |
24
-
25
- ## Project Conventions
26
-
27
- - No project-level AGENTS.md / CLAUDE.md / .cursorrules found
28
- - ESLint config: `.eslintrc.json` (eslint:recommended + plugin:react/recommended)
29
- - No Prettier config detected — formatting via Babel only
30
- - No TypeScript (plain JS/JSX with Babel)
package/.editorconfig DELETED
@@ -1,12 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = space
5
- indent_size = 2
6
- end_of_line = lf
7
- charset = utf-8
8
- trim_trailing_whitespace = true
9
- insert_final_newline = true
10
-
11
- [*.md]
12
- trim_trailing_whitespace = false
package/.eslintrc.json DELETED
@@ -1,30 +0,0 @@
1
- {
2
- "env": {
3
- "browser": true,
4
- "node": true,
5
- "es2021": true,
6
- "jest": true
7
- },
8
- "extends": ["eslint:recommended", "plugin:react/recommended", "prettier"],
9
- "parserOptions": {
10
- "ecmaVersion": 2021,
11
- "sourceType": "module",
12
- "ecmaFeatures": { "jsx": true }
13
- },
14
- "rules": {
15
- "no-unsafe-optional-chaining": "error",
16
- "react/react-in-jsx-scope": "off",
17
- "no-console": "off",
18
- "react/prop-types": "warn",
19
- "no-unused-vars": [
20
- "warn",
21
- {
22
- "argsIgnorePattern": "^_",
23
- "varsIgnorePattern": "^(?:_|React)$"
24
- }
25
- ]
26
- },
27
- "settings": {
28
- "react": { "version": "detect" }
29
- }
30
- }
@@ -1,30 +0,0 @@
1
- ---
2
- name: Bug report
3
- about: Create a report to help us improve
4
- title: ''
5
- labels: bug
6
- assignees: ''
7
- ---
8
-
9
- **Describe the bug**
10
- A clear and concise description of what the bug is.
11
-
12
- **To Reproduce**
13
- Steps to reproduce the behavior:
14
- 1. Go to '...'
15
- 2. Run '...'
16
- 3. See error
17
-
18
- **Expected behavior**
19
- A clear and concise description of what you expected to happen.
20
-
21
- **Screenshots or logs**
22
- If applicable, add screenshots or logs to help explain your problem.
23
-
24
- **Environment (please complete the following information):**
25
- - OS: (e.g. Ubuntu 22.04)
26
- - Node version: (e.g. 18.x)
27
- - cdd-cli version: (e.g. 3.1.0)
28
-
29
- **Additional context**
30
- Add any other context about the problem here.
@@ -1,19 +0,0 @@
1
- ---
2
- name: Feature request
3
- about: Suggest an idea for this project
4
- title: ''
5
- labels: enhancement
6
- assignees: ''
7
- ---
8
-
9
- **Is your feature request related to a problem? Please describe.**
10
- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11
-
12
- **Describe the solution you'd like**
13
- A clear and concise description of what you want to happen.
14
-
15
- **Describe alternatives you've considered**
16
- A clear and concise description of any alternative solutions or features you've considered.
17
-
18
- **Additional context**
19
- Add any other context or screenshots about the feature request here.
@@ -1,14 +0,0 @@
1
- <!-- Please replace the placeholders and remove this comment -->
2
- ## Summary
3
-
4
- What does this PR change and why?
5
-
6
- ## Checklist
7
-
8
- - [ ] I have read the contributing guidelines
9
- - [ ] Tests added / updated
10
- - [ ] Documentation updated
11
-
12
- ## Related issues
13
-
14
- Closes: # (issue)
@@ -1,32 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
- pull_request:
7
- branches: [ main ]
8
-
9
- jobs:
10
- test-and-build:
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: Checkout repository
14
- uses: actions/checkout@v4
15
-
16
- - name: Setup Node.js
17
- uses: actions/setup-node@v4
18
- with:
19
- node-version: '18'
20
- cache: 'npm'
21
-
22
- - name: Install dependencies
23
- run: npm ci
24
-
25
- - name: Lint
26
- run: npm run lint
27
-
28
- - name: Run tests
29
- run: npm test
30
-
31
- - name: Build
32
- run: npm run build
@@ -1,42 +0,0 @@
1
- name: Build and deploy docs
2
-
3
- on:
4
- workflow_run:
5
- workflows: ["CI"]
6
- types:
7
- - completed
8
- branches:
9
- - main
10
-
11
- jobs:
12
- build-and-deploy:
13
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
14
- runs-on: ubuntu-latest
15
- permissions:
16
- contents: write
17
- pages: write
18
- id-token: write
19
-
20
- steps:
21
- - name: Checkout repository
22
- uses: actions/checkout@v4
23
-
24
- - name: Setup Node.js
25
- uses: actions/setup-node@v4
26
- with:
27
- node-version: '18'
28
-
29
- - name: Install dependencies
30
- run: npm ci
31
-
32
- - name: Build docs
33
- run: npm run docs
34
-
35
- - name: Ensure .nojekyll
36
- run: mkdir -p docs && touch docs/.nojekyll
37
-
38
- - name: Deploy to GitHub Pages (push to gh-pages)
39
- uses: peaceiris/actions-gh-pages@v3
40
- with:
41
- github_token: ${{ secrets.GITHUB_TOKEN }}
42
- publish_dir: ./docs
package/.prettierignore DELETED
@@ -1,4 +0,0 @@
1
- node_modules/
2
- dist/
3
- coverage/
4
- *.cjs
package/.prettierrc DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "semi": true,
3
- "singleQuote": true,
4
- "trailingComma": "es5",
5
- "printWidth": 80,
6
- "tabWidth": 2,
7
- "arrowParens": "always"
8
- }