@calltelemetry/cli 0.6.12 → 0.7.1

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 (474) hide show
  1. package/dist/commands/appliance.d.ts +3 -0
  2. package/dist/commands/appliance.d.ts.map +1 -0
  3. package/dist/commands/appliance.js +99 -0
  4. package/dist/commands/appliance.js.map +1 -0
  5. package/dist/commands/config.d.ts.map +1 -1
  6. package/dist/commands/config.js +0 -42
  7. package/dist/commands/config.js.map +1 -1
  8. package/dist/commands/loadtest.d.ts.map +1 -1
  9. package/dist/commands/loadtest.js +214 -1
  10. package/dist/commands/loadtest.js.map +1 -1
  11. package/dist/commands/otel.d.ts +3 -0
  12. package/dist/commands/otel.d.ts.map +1 -0
  13. package/dist/commands/otel.js +89 -0
  14. package/dist/commands/otel.js.map +1 -0
  15. package/dist/commands/seed.d.ts +3 -0
  16. package/dist/commands/seed.d.ts.map +1 -0
  17. package/dist/commands/seed.js +106 -0
  18. package/dist/commands/seed.js.map +1 -0
  19. package/dist/commands/storage.d.ts +3 -0
  20. package/dist/commands/storage.d.ts.map +1 -0
  21. package/dist/commands/storage.js +66 -0
  22. package/dist/commands/storage.js.map +1 -0
  23. package/dist/commands/update.d.ts.map +1 -1
  24. package/dist/commands/update.js +19 -17
  25. package/dist/commands/update.js.map +1 -1
  26. package/dist/index.js +8 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/lib/migration-001-cgnat.d.ts +2 -0
  29. package/dist/lib/migration-001-cgnat.d.ts.map +1 -0
  30. package/dist/lib/migration-001-cgnat.js +59 -0
  31. package/dist/lib/migration-001-cgnat.js.map +1 -0
  32. package/dist/lib/migration-002-swap.d.ts +12 -0
  33. package/dist/lib/migration-002-swap.d.ts.map +1 -0
  34. package/dist/lib/migration-002-swap.js +103 -0
  35. package/dist/lib/migration-002-swap.js.map +1 -0
  36. package/dist/lib/migration-003-nm-heal.d.ts +12 -0
  37. package/dist/lib/migration-003-nm-heal.d.ts.map +1 -0
  38. package/dist/lib/migration-003-nm-heal.js +75 -0
  39. package/dist/lib/migration-003-nm-heal.js.map +1 -0
  40. package/dist/lib/migration-004-systemd-docker.d.ts +13 -0
  41. package/dist/lib/migration-004-systemd-docker.d.ts.map +1 -0
  42. package/dist/lib/migration-004-systemd-docker.js +48 -0
  43. package/dist/lib/migration-004-systemd-docker.js.map +1 -0
  44. package/dist/lib/migration-005-ssh-keys.d.ts +13 -0
  45. package/dist/lib/migration-005-ssh-keys.d.ts.map +1 -0
  46. package/dist/lib/migration-005-ssh-keys.js +49 -0
  47. package/dist/lib/migration-005-ssh-keys.js.map +1 -0
  48. package/dist/lib/migration-006-console-loglevel.d.ts +10 -0
  49. package/dist/lib/migration-006-console-loglevel.d.ts.map +1 -0
  50. package/dist/lib/migration-006-console-loglevel.js +27 -0
  51. package/dist/lib/migration-006-console-loglevel.js.map +1 -0
  52. package/dist/lib/migration-007-nm-keyfile.d.ts +10 -0
  53. package/dist/lib/migration-007-nm-keyfile.d.ts.map +1 -0
  54. package/dist/lib/migration-007-nm-keyfile.js +30 -0
  55. package/dist/lib/migration-007-nm-keyfile.js.map +1 -0
  56. package/dist/lib/migration-008-systemd-restart.d.ts +13 -0
  57. package/dist/lib/migration-008-systemd-restart.d.ts.map +1 -0
  58. package/dist/lib/migration-008-systemd-restart.js +41 -0
  59. package/dist/lib/migration-008-systemd-restart.js.map +1 -0
  60. package/dist/lib/migration-009-bind-mount-files.d.ts +11 -0
  61. package/dist/lib/migration-009-bind-mount-files.d.ts.map +1 -0
  62. package/dist/lib/migration-009-bind-mount-files.js +86 -0
  63. package/dist/lib/migration-009-bind-mount-files.js.map +1 -0
  64. package/dist/lib/migration-010-jtapi-state.d.ts +11 -0
  65. package/dist/lib/migration-010-jtapi-state.d.ts.map +1 -0
  66. package/dist/lib/migration-010-jtapi-state.js +61 -0
  67. package/dist/lib/migration-010-jtapi-state.js.map +1 -0
  68. package/dist/lib/migration-011-docker-memory-limit.d.ts +13 -0
  69. package/dist/lib/migration-011-docker-memory-limit.d.ts.map +1 -0
  70. package/dist/lib/migration-011-docker-memory-limit.js +45 -0
  71. package/dist/lib/migration-011-docker-memory-limit.js.map +1 -0
  72. package/dist/lib/migration-012-db-pool-sizes.d.ts +12 -0
  73. package/dist/lib/migration-012-db-pool-sizes.d.ts.map +1 -0
  74. package/dist/lib/migration-012-db-pool-sizes.js +64 -0
  75. package/dist/lib/migration-012-db-pool-sizes.js.map +1 -0
  76. package/dist/lib/migration-013-grafana-password.d.ts +15 -0
  77. package/dist/lib/migration-013-grafana-password.d.ts.map +1 -0
  78. package/dist/lib/migration-013-grafana-password.js +80 -0
  79. package/dist/lib/migration-013-grafana-password.js.map +1 -0
  80. package/dist/lib/migration-014-docker-firewall-backend.d.ts +16 -0
  81. package/dist/lib/migration-014-docker-firewall-backend.d.ts.map +1 -0
  82. package/dist/lib/migration-014-docker-firewall-backend.js +72 -0
  83. package/dist/lib/migration-014-docker-firewall-backend.js.map +1 -0
  84. package/dist/lib/migrations.d.ts +42 -0
  85. package/dist/lib/migrations.d.ts.map +1 -0
  86. package/dist/lib/migrations.js +231 -0
  87. package/dist/lib/migrations.js.map +1 -0
  88. package/dist/lib/otel.d.ts +7 -7
  89. package/dist/lib/otel.d.ts.map +1 -1
  90. package/dist/lib/otel.js +18 -25
  91. package/dist/lib/otel.js.map +1 -1
  92. package/dist/lib/prefs.d.ts +1 -0
  93. package/dist/lib/prefs.d.ts.map +1 -1
  94. package/dist/lib/prefs.js +1 -0
  95. package/dist/lib/prefs.js.map +1 -1
  96. package/dist/lib/prompts.d.ts +3 -0
  97. package/dist/lib/prompts.d.ts.map +1 -0
  98. package/dist/lib/prompts.js +39 -0
  99. package/dist/lib/prompts.js.map +1 -0
  100. package/dist/lib/rpc-scripts.d.ts +4 -0
  101. package/dist/lib/rpc-scripts.d.ts.map +1 -1
  102. package/dist/lib/rpc-scripts.js +235 -0
  103. package/dist/lib/rpc-scripts.js.map +1 -1
  104. package/dist/lib/secrets.d.ts +2 -2
  105. package/dist/lib/secrets.d.ts.map +1 -1
  106. package/dist/lib/secrets.js +2 -1
  107. package/dist/lib/secrets.js.map +1 -1
  108. package/dist/lib/seed/connection.d.ts +5 -0
  109. package/dist/lib/seed/connection.d.ts.map +1 -0
  110. package/dist/lib/seed/connection.js +168 -0
  111. package/dist/lib/seed/connection.js.map +1 -0
  112. package/dist/lib/seed/copy.d.ts +4 -0
  113. package/dist/lib/seed/copy.d.ts.map +1 -0
  114. package/dist/lib/seed/copy.js +74 -0
  115. package/dist/lib/seed/copy.js.map +1 -0
  116. package/dist/lib/seed/dashboard-templates.d.ts +22 -0
  117. package/dist/lib/seed/dashboard-templates.d.ts.map +1 -0
  118. package/dist/lib/seed/dashboard-templates.js +268 -0
  119. package/dist/lib/seed/dashboard-templates.js.map +1 -0
  120. package/dist/lib/seed/families.d.ts +5 -0
  121. package/dist/lib/seed/families.d.ts.map +1 -0
  122. package/dist/lib/seed/families.js +1541 -0
  123. package/dist/lib/seed/families.js.map +1 -0
  124. package/dist/lib/seed/index.d.ts +12 -0
  125. package/dist/lib/seed/index.d.ts.map +1 -0
  126. package/dist/lib/seed/index.js +327 -0
  127. package/dist/lib/seed/index.js.map +1 -0
  128. package/dist/lib/seed/presets.d.ts +5 -0
  129. package/dist/lib/seed/presets.d.ts.map +1 -0
  130. package/dist/lib/seed/presets.js +114 -0
  131. package/dist/lib/seed/presets.js.map +1 -0
  132. package/dist/lib/seed/schema/columns.d.ts +35 -0
  133. package/dist/lib/seed/schema/columns.d.ts.map +1 -0
  134. package/dist/lib/seed/schema/columns.js +497 -0
  135. package/dist/lib/seed/schema/columns.js.map +1 -0
  136. package/dist/lib/seed/schema/fingerprint.d.ts +2 -0
  137. package/dist/lib/seed/schema/fingerprint.d.ts.map +1 -0
  138. package/dist/lib/seed/schema/fingerprint.js +4 -0
  139. package/dist/lib/seed/schema/fingerprint.js.map +1 -0
  140. package/dist/lib/seed/schema/index.d.ts +4 -0
  141. package/dist/lib/seed/schema/index.d.ts.map +1 -0
  142. package/dist/lib/seed/schema/index.js +6 -0
  143. package/dist/lib/seed/schema/index.js.map +1 -0
  144. package/dist/lib/seed/schema/spec.d.ts +8 -0
  145. package/dist/lib/seed/schema/spec.d.ts.map +1 -0
  146. package/dist/lib/seed/schema/spec.js +655 -0
  147. package/dist/lib/seed/schema/spec.js.map +1 -0
  148. package/dist/lib/seed/schema/tables.d.ts +132 -0
  149. package/dist/lib/seed/schema/tables.d.ts.map +1 -0
  150. package/dist/lib/seed/schema/tables.js +37 -0
  151. package/dist/lib/seed/schema/tables.js.map +1 -0
  152. package/dist/lib/seed/store.d.ts +26 -0
  153. package/dist/lib/seed/store.d.ts.map +1 -0
  154. package/dist/lib/seed/store.js +111 -0
  155. package/dist/lib/seed/store.js.map +1 -0
  156. package/dist/lib/seed/types.d.ts +71 -0
  157. package/dist/lib/seed/types.d.ts.map +1 -0
  158. package/dist/lib/seed/types.js +2 -0
  159. package/dist/lib/seed/types.js.map +1 -0
  160. package/dist/lib/storage.d.ts +4 -0
  161. package/dist/lib/storage.d.ts.map +1 -0
  162. package/dist/lib/storage.js +36 -0
  163. package/dist/lib/storage.js.map +1 -0
  164. package/dist/lib/update-steps.d.ts.map +1 -1
  165. package/dist/lib/update-steps.js +27 -0
  166. package/dist/lib/update-steps.js.map +1 -1
  167. package/dist/lib/update.d.ts.map +1 -1
  168. package/dist/lib/update.js +28 -2
  169. package/dist/lib/update.js.map +1 -1
  170. package/dist/lib/version.d.ts +1 -1
  171. package/dist/lib/version.d.ts.map +1 -1
  172. package/dist/lib/version.js +1 -1
  173. package/dist/lib/version.js.map +1 -1
  174. package/dist/lib/xcc-loadtest-types.d.ts +232 -0
  175. package/dist/lib/xcc-loadtest-types.d.ts.map +1 -0
  176. package/dist/lib/xcc-loadtest-types.js +2 -0
  177. package/dist/lib/xcc-loadtest-types.js.map +1 -0
  178. package/dist/lib/xcc-loadtest.d.ts +4 -0
  179. package/dist/lib/xcc-loadtest.d.ts.map +1 -0
  180. package/dist/lib/xcc-loadtest.js +616 -0
  181. package/dist/lib/xcc-loadtest.js.map +1 -0
  182. package/dist/lib/xcc-overlay.d.ts +3 -0
  183. package/dist/lib/xcc-overlay.d.ts.map +1 -0
  184. package/dist/lib/xcc-overlay.js +74 -0
  185. package/dist/lib/xcc-overlay.js.map +1 -0
  186. package/dist/lib/xcc-scenarios.d.ts +8 -0
  187. package/dist/lib/xcc-scenarios.d.ts.map +1 -0
  188. package/dist/lib/xcc-scenarios.js +129 -0
  189. package/dist/lib/xcc-scenarios.js.map +1 -0
  190. package/dist/lib/xcc-xml.d.ts +18 -0
  191. package/dist/lib/xcc-xml.d.ts.map +1 -0
  192. package/dist/lib/xcc-xml.js +210 -0
  193. package/dist/lib/xcc-xml.js.map +1 -0
  194. package/dist/shell/commands/appliance-migrations.d.ts +7 -0
  195. package/dist/shell/commands/appliance-migrations.d.ts.map +1 -0
  196. package/dist/shell/commands/appliance-migrations.js +128 -0
  197. package/dist/shell/commands/appliance-migrations.js.map +1 -0
  198. package/dist/shell/commands/appliance-performance.d.ts +36 -0
  199. package/dist/shell/commands/appliance-performance.d.ts.map +1 -0
  200. package/dist/shell/commands/appliance-performance.js +221 -0
  201. package/dist/shell/commands/appliance-performance.js.map +1 -0
  202. package/dist/shell/commands/config.d.ts.map +1 -1
  203. package/dist/shell/commands/config.js +6 -5
  204. package/dist/shell/commands/config.js.map +1 -1
  205. package/dist/shell/commands/connect.d.ts.map +1 -1
  206. package/dist/shell/commands/connect.js +3 -2
  207. package/dist/shell/commands/connect.js.map +1 -1
  208. package/dist/shell/commands/db.d.ts.map +1 -1
  209. package/dist/shell/commands/db.js +5 -4
  210. package/dist/shell/commands/db.js.map +1 -1
  211. package/dist/shell/commands/debug.d.ts.map +1 -1
  212. package/dist/shell/commands/debug.js +5 -4
  213. package/dist/shell/commands/debug.js.map +1 -1
  214. package/dist/shell/commands/diag.js +10 -10
  215. package/dist/shell/commands/diag.js.map +1 -1
  216. package/dist/shell/commands/registry.d.ts.map +1 -1
  217. package/dist/shell/commands/registry.js +74 -0
  218. package/dist/shell/commands/registry.js.map +1 -1
  219. package/dist/shell/commands/secrets.d.ts.map +1 -1
  220. package/dist/shell/commands/secrets.js +2 -1
  221. package/dist/shell/commands/secrets.js.map +1 -1
  222. package/dist/shell/commands/seed.d.ts +9 -0
  223. package/dist/shell/commands/seed.d.ts.map +1 -0
  224. package/dist/shell/commands/seed.js +197 -0
  225. package/dist/shell/commands/seed.js.map +1 -0
  226. package/dist/shell/commands/services.d.ts.map +1 -1
  227. package/dist/shell/commands/services.js +5 -4
  228. package/dist/shell/commands/services.js.map +1 -1
  229. package/dist/shell/commands/test.d.ts.map +1 -1
  230. package/dist/shell/commands/test.js +3 -2
  231. package/dist/shell/commands/test.js.map +1 -1
  232. package/dist/shell/commands/users.d.ts.map +1 -1
  233. package/dist/shell/commands/users.js +9 -2
  234. package/dist/shell/commands/users.js.map +1 -1
  235. package/dist/shell/network-onboarding.d.ts +29 -7
  236. package/dist/shell/network-onboarding.d.ts.map +1 -1
  237. package/dist/shell/network-onboarding.js +305 -88
  238. package/dist/shell/network-onboarding.js.map +1 -1
  239. package/dist/ui/components/ActionBar.d.ts +13 -0
  240. package/dist/ui/components/ActionBar.d.ts.map +1 -0
  241. package/dist/ui/components/ActionBar.js +7 -0
  242. package/dist/ui/components/ActionBar.js.map +1 -0
  243. package/dist/ui/components/AppShell.d.ts +6 -1
  244. package/dist/ui/components/AppShell.d.ts.map +1 -1
  245. package/dist/ui/components/AppShell.js +32 -10
  246. package/dist/ui/components/AppShell.js.map +1 -1
  247. package/dist/ui/components/DashboardBlock.d.ts +11 -0
  248. package/dist/ui/components/DashboardBlock.d.ts.map +1 -0
  249. package/dist/ui/components/DashboardBlock.js +6 -0
  250. package/dist/ui/components/DashboardBlock.js.map +1 -0
  251. package/dist/ui/components/DataTable.d.ts +6 -1
  252. package/dist/ui/components/DataTable.d.ts.map +1 -1
  253. package/dist/ui/components/DataTable.js +71 -7
  254. package/dist/ui/components/DataTable.js.map +1 -1
  255. package/dist/ui/components/ErrorBoundary.d.ts +1 -1
  256. package/dist/ui/components/FieldList.d.ts +24 -0
  257. package/dist/ui/components/FieldList.d.ts.map +1 -0
  258. package/dist/ui/components/FieldList.js +67 -0
  259. package/dist/ui/components/FieldList.js.map +1 -0
  260. package/dist/ui/components/KeyValue.d.ts +4 -2
  261. package/dist/ui/components/KeyValue.d.ts.map +1 -1
  262. package/dist/ui/components/KeyValue.js +4 -2
  263. package/dist/ui/components/KeyValue.js.map +1 -1
  264. package/dist/ui/components/KeyboardHint.d.ts +10 -0
  265. package/dist/ui/components/KeyboardHint.d.ts.map +1 -0
  266. package/dist/ui/components/KeyboardHint.js +6 -0
  267. package/dist/ui/components/KeyboardHint.js.map +1 -0
  268. package/dist/ui/components/MenuList.d.ts +10 -0
  269. package/dist/ui/components/MenuList.d.ts.map +1 -0
  270. package/dist/ui/components/MenuList.js +7 -0
  271. package/dist/ui/components/MenuList.js.map +1 -0
  272. package/dist/ui/components/MetricsFooter.d.ts +10 -7
  273. package/dist/ui/components/MetricsFooter.d.ts.map +1 -1
  274. package/dist/ui/components/MetricsFooter.js +16 -3
  275. package/dist/ui/components/MetricsFooter.js.map +1 -1
  276. package/dist/ui/components/PaneSection.d.ts +9 -0
  277. package/dist/ui/components/PaneSection.d.ts.map +1 -0
  278. package/dist/ui/components/PaneSection.js +6 -0
  279. package/dist/ui/components/PaneSection.js.map +1 -0
  280. package/dist/ui/components/PanelState.d.ts +8 -0
  281. package/dist/ui/components/PanelState.d.ts.map +1 -0
  282. package/dist/ui/components/PanelState.js +7 -0
  283. package/dist/ui/components/PanelState.js.map +1 -0
  284. package/dist/ui/components/ScrollViewport.d.ts +16 -0
  285. package/dist/ui/components/ScrollViewport.d.ts.map +1 -0
  286. package/dist/ui/components/ScrollViewport.js +54 -0
  287. package/dist/ui/components/ScrollViewport.js.map +1 -0
  288. package/dist/ui/components/Section.js +1 -1
  289. package/dist/ui/components/Section.js.map +1 -1
  290. package/dist/ui/components/SelectMenu.d.ts.map +1 -1
  291. package/dist/ui/components/SelectMenu.js +3 -3
  292. package/dist/ui/components/SelectMenu.js.map +1 -1
  293. package/dist/ui/components/ShellOutput.d.ts +2 -1
  294. package/dist/ui/components/ShellOutput.d.ts.map +1 -1
  295. package/dist/ui/components/ShellOutput.js +6 -2
  296. package/dist/ui/components/ShellOutput.js.map +1 -1
  297. package/dist/ui/components/SplitPane.d.ts +18 -0
  298. package/dist/ui/components/SplitPane.d.ts.map +1 -0
  299. package/dist/ui/components/SplitPane.js +9 -0
  300. package/dist/ui/components/SplitPane.js.map +1 -0
  301. package/dist/ui/components/StatusList.d.ts +18 -0
  302. package/dist/ui/components/StatusList.d.ts.map +1 -0
  303. package/dist/ui/components/StatusList.js +13 -0
  304. package/dist/ui/components/StatusList.js.map +1 -0
  305. package/dist/ui/components/SummaryStrip.d.ts +9 -0
  306. package/dist/ui/components/SummaryStrip.d.ts.map +1 -0
  307. package/dist/ui/components/SummaryStrip.js +6 -0
  308. package/dist/ui/components/SummaryStrip.js.map +1 -0
  309. package/dist/ui/components/app-shell-viewport.d.ts +7 -0
  310. package/dist/ui/components/app-shell-viewport.d.ts.map +1 -0
  311. package/dist/ui/components/app-shell-viewport.js +6 -0
  312. package/dist/ui/components/app-shell-viewport.js.map +1 -0
  313. package/dist/ui/components/index.d.ts +14 -0
  314. package/dist/ui/components/index.d.ts.map +1 -1
  315. package/dist/ui/components/index.js +12 -0
  316. package/dist/ui/components/index.js.map +1 -1
  317. package/dist/ui/context/MetricsContext.d.ts.map +1 -1
  318. package/dist/ui/context/MetricsContext.js +15 -12
  319. package/dist/ui/context/MetricsContext.js.map +1 -1
  320. package/dist/ui/hooks/index.d.ts +9 -1
  321. package/dist/ui/hooks/index.d.ts.map +1 -1
  322. package/dist/ui/hooks/index.js +7 -0
  323. package/dist/ui/hooks/index.js.map +1 -1
  324. package/dist/ui/hooks/useAsyncTask.d.ts +7 -1
  325. package/dist/ui/hooks/useAsyncTask.d.ts.map +1 -1
  326. package/dist/ui/hooks/useAsyncTask.js +30 -6
  327. package/dist/ui/hooks/useAsyncTask.js.map +1 -1
  328. package/dist/ui/hooks/useBoundedCursor.d.ts +7 -0
  329. package/dist/ui/hooks/useBoundedCursor.d.ts.map +1 -0
  330. package/dist/ui/hooks/useBoundedCursor.js +19 -0
  331. package/dist/ui/hooks/useBoundedCursor.js.map +1 -0
  332. package/dist/ui/hooks/useConfirmBackNav.d.ts +7 -0
  333. package/dist/ui/hooks/useConfirmBackNav.d.ts.map +1 -0
  334. package/dist/ui/hooks/useConfirmBackNav.js +10 -0
  335. package/dist/ui/hooks/useConfirmBackNav.js.map +1 -0
  336. package/dist/ui/hooks/useDismissKeys.d.ts +10 -0
  337. package/dist/ui/hooks/useDismissKeys.d.ts.map +1 -0
  338. package/dist/ui/hooks/useDismissKeys.js +17 -0
  339. package/dist/ui/hooks/useDismissKeys.js.map +1 -0
  340. package/dist/ui/hooks/useListCursor.d.ts +7 -0
  341. package/dist/ui/hooks/useListCursor.d.ts.map +1 -0
  342. package/dist/ui/hooks/useListCursor.js +29 -0
  343. package/dist/ui/hooks/useListCursor.js.map +1 -0
  344. package/dist/ui/hooks/useTwoPaneCursor.d.ts +12 -0
  345. package/dist/ui/hooks/useTwoPaneCursor.d.ts.map +1 -0
  346. package/dist/ui/hooks/useTwoPaneCursor.js +36 -0
  347. package/dist/ui/hooks/useTwoPaneCursor.js.map +1 -0
  348. package/dist/ui/hooks/useXccBackendOverlay.d.ts +9 -0
  349. package/dist/ui/hooks/useXccBackendOverlay.d.ts.map +1 -0
  350. package/dist/ui/hooks/useXccBackendOverlay.js +14 -0
  351. package/dist/ui/hooks/useXccBackendOverlay.js.map +1 -0
  352. package/dist/ui/hooks/useXccLoadTest.d.ts +11 -0
  353. package/dist/ui/hooks/useXccLoadTest.d.ts.map +1 -0
  354. package/dist/ui/hooks/useXccLoadTest.js +37 -0
  355. package/dist/ui/hooks/useXccLoadTest.js.map +1 -0
  356. package/dist/ui/palette.d.ts +23 -0
  357. package/dist/ui/palette.d.ts.map +1 -0
  358. package/dist/ui/palette.js +22 -0
  359. package/dist/ui/palette.js.map +1 -0
  360. package/dist/ui/views/DbHealthView.js +4 -4
  361. package/dist/ui/views/DbHealthView.js.map +1 -1
  362. package/dist/ui/views/DbSizeView.d.ts.map +1 -1
  363. package/dist/ui/views/DbSizeView.js +2 -2
  364. package/dist/ui/views/DbSizeView.js.map +1 -1
  365. package/dist/ui/views/DbTablesView.d.ts.map +1 -1
  366. package/dist/ui/views/DbTablesView.js +2 -2
  367. package/dist/ui/views/DbTablesView.js.map +1 -1
  368. package/dist/ui/views/DiagDatabaseView.d.ts.map +1 -1
  369. package/dist/ui/views/DiagDatabaseView.js +4 -3
  370. package/dist/ui/views/DiagDatabaseView.js.map +1 -1
  371. package/dist/ui/views/DiagNetworkView.js +2 -2
  372. package/dist/ui/views/DiagNetworkView.js.map +1 -1
  373. package/dist/ui/views/DiagServiceView.js +1 -1
  374. package/dist/ui/views/DiagServiceView.js.map +1 -1
  375. package/dist/ui/views/DockerPruneView.d.ts.map +1 -1
  376. package/dist/ui/views/DockerPruneView.js +4 -8
  377. package/dist/ui/views/DockerPruneView.js.map +1 -1
  378. package/dist/ui/views/K8sDeployView.d.ts.map +1 -1
  379. package/dist/ui/views/K8sDeployView.js +5 -5
  380. package/dist/ui/views/K8sDeployView.js.map +1 -1
  381. package/dist/ui/views/K8sServicesView.d.ts.map +1 -1
  382. package/dist/ui/views/K8sServicesView.js +6 -11
  383. package/dist/ui/views/K8sServicesView.js.map +1 -1
  384. package/dist/ui/views/K8sStatusView.d.ts.map +1 -1
  385. package/dist/ui/views/K8sStatusView.js +14 -19
  386. package/dist/ui/views/K8sStatusView.js.map +1 -1
  387. package/dist/ui/views/LoadTestConfigView.d.ts.map +1 -1
  388. package/dist/ui/views/LoadTestConfigView.js +45 -43
  389. package/dist/ui/views/LoadTestConfigView.js.map +1 -1
  390. package/dist/ui/views/LoadTestSummaryView.d.ts.map +1 -1
  391. package/dist/ui/views/LoadTestSummaryView.js +7 -2
  392. package/dist/ui/views/LoadTestSummaryView.js.map +1 -1
  393. package/dist/ui/views/MainMenu.d.ts.map +1 -1
  394. package/dist/ui/views/MainMenu.js +265 -55
  395. package/dist/ui/views/MainMenu.js.map +1 -1
  396. package/dist/ui/views/MigrateHistoryView.d.ts.map +1 -1
  397. package/dist/ui/views/MigrateHistoryView.js +11 -2
  398. package/dist/ui/views/MigrateHistoryView.js.map +1 -1
  399. package/dist/ui/views/MigrateRollbackView.d.ts.map +1 -1
  400. package/dist/ui/views/MigrateRollbackView.js +4 -8
  401. package/dist/ui/views/MigrateRollbackView.js.map +1 -1
  402. package/dist/ui/views/MigrateRunView.d.ts.map +1 -1
  403. package/dist/ui/views/MigrateRunView.js +4 -8
  404. package/dist/ui/views/MigrateRunView.js.map +1 -1
  405. package/dist/ui/views/MigrateStatusView.js +1 -1
  406. package/dist/ui/views/MigrateStatusView.js.map +1 -1
  407. package/dist/ui/views/MigrateWatchView.js +1 -1
  408. package/dist/ui/views/MigrateWatchView.js.map +1 -1
  409. package/dist/ui/views/OfflineApplyView.d.ts.map +1 -1
  410. package/dist/ui/views/OfflineApplyView.js +17 -7
  411. package/dist/ui/views/OfflineApplyView.js.map +1 -1
  412. package/dist/ui/views/OfflineDownloadView.d.ts.map +1 -1
  413. package/dist/ui/views/OfflineDownloadView.js +17 -7
  414. package/dist/ui/views/OfflineDownloadView.js.map +1 -1
  415. package/dist/ui/views/OfflineFetchView.d.ts.map +1 -1
  416. package/dist/ui/views/OfflineFetchView.js +17 -7
  417. package/dist/ui/views/OfflineFetchView.js.map +1 -1
  418. package/dist/ui/views/OfflineInspectView.d.ts.map +1 -1
  419. package/dist/ui/views/OfflineInspectView.js +17 -7
  420. package/dist/ui/views/OfflineInspectView.js.map +1 -1
  421. package/dist/ui/views/OsUpdatesEnableView.js +4 -4
  422. package/dist/ui/views/OsUpdatesEnableView.js.map +1 -1
  423. package/dist/ui/views/OsUpdatesLogView.js +1 -1
  424. package/dist/ui/views/OsUpdatesLogView.js.map +1 -1
  425. package/dist/ui/views/OsUpdatesStatusView.d.ts.map +1 -1
  426. package/dist/ui/views/OsUpdatesStatusView.js +12 -12
  427. package/dist/ui/views/OsUpdatesStatusView.js.map +1 -1
  428. package/dist/ui/views/PowerActionView.d.ts.map +1 -1
  429. package/dist/ui/views/PowerActionView.js +3 -8
  430. package/dist/ui/views/PowerActionView.js.map +1 -1
  431. package/dist/ui/views/SecretsResetPasswordView.d.ts.map +1 -1
  432. package/dist/ui/views/SecretsResetPasswordView.js +23 -7
  433. package/dist/ui/views/SecretsResetPasswordView.js.map +1 -1
  434. package/dist/ui/views/SecretsSetupView.d.ts.map +1 -1
  435. package/dist/ui/views/SecretsSetupView.js +39 -22
  436. package/dist/ui/views/SecretsSetupView.js.map +1 -1
  437. package/dist/ui/views/ServiceLogsView.d.ts.map +1 -1
  438. package/dist/ui/views/ServiceLogsView.js +9 -9
  439. package/dist/ui/views/ServiceLogsView.js.map +1 -1
  440. package/dist/ui/views/ServicesView.d.ts.map +1 -1
  441. package/dist/ui/views/ServicesView.js +51 -28
  442. package/dist/ui/views/ServicesView.js.map +1 -1
  443. package/dist/ui/views/SettingsView.d.ts.map +1 -1
  444. package/dist/ui/views/SettingsView.js +5 -4
  445. package/dist/ui/views/SettingsView.js.map +1 -1
  446. package/dist/ui/views/SetupWizardView.d.ts.map +1 -1
  447. package/dist/ui/views/SetupWizardView.js +37 -32
  448. package/dist/ui/views/SetupWizardView.js.map +1 -1
  449. package/dist/ui/views/StatusView.d.ts.map +1 -1
  450. package/dist/ui/views/StatusView.js +44 -31
  451. package/dist/ui/views/StatusView.js.map +1 -1
  452. package/dist/ui/views/UpdateView.d.ts.map +1 -1
  453. package/dist/ui/views/UpdateView.js +28 -14
  454. package/dist/ui/views/UpdateView.js.map +1 -1
  455. package/dist/ui/views/UserResetPasswordView.d.ts.map +1 -1
  456. package/dist/ui/views/UserResetPasswordView.js +26 -8
  457. package/dist/ui/views/UserResetPasswordView.js.map +1 -1
  458. package/dist/ui/views/XccLoadTestConfigView.d.ts +29 -0
  459. package/dist/ui/views/XccLoadTestConfigView.d.ts.map +1 -0
  460. package/dist/ui/views/XccLoadTestConfigView.js +210 -0
  461. package/dist/ui/views/XccLoadTestConfigView.js.map +1 -0
  462. package/dist/ui/views/XccLoadTestRunView.d.ts +9 -0
  463. package/dist/ui/views/XccLoadTestRunView.d.ts.map +1 -0
  464. package/dist/ui/views/XccLoadTestRunView.js +154 -0
  465. package/dist/ui/views/XccLoadTestRunView.js.map +1 -0
  466. package/dist/ui/views/XccLoadTestSummaryView.d.ts +9 -0
  467. package/dist/ui/views/XccLoadTestSummaryView.d.ts.map +1 -0
  468. package/dist/ui/views/XccLoadTestSummaryView.js +63 -0
  469. package/dist/ui/views/XccLoadTestSummaryView.js.map +1 -0
  470. package/dist/ui/views/XccLoadTestView.d.ts +8 -0
  471. package/dist/ui/views/XccLoadTestView.d.ts.map +1 -0
  472. package/dist/ui/views/XccLoadTestView.js +40 -0
  473. package/dist/ui/views/XccLoadTestView.js.map +1 -0
  474. package/package.json +6 -1
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * network-onboarding.ts — First-boot setup wizard for ct shell.
3
3
  *
4
- * Six-step wizard that collects all configuration atomically before applying:
4
+ * Seven-step wizard that collects all configuration atomically before applying:
5
5
  * 1. Network (IP/DHCP, DNS, search domain)
6
- * 2. System Identity (hostname, location)
7
- * 3. Admin Credentials (root password)
8
- * 4. Timezone
9
- * 5. NTP Time Servers
6
+ * 2. Timezone
7
+ * 3. NTP Time Servers
8
+ * 4. System Identity (hostname, location)
9
+ * 5. Admin Credentials (root password)
10
10
  * 6. Preferences (auto-update, IPv6, JTAPI)
11
+ * 7. Performance Profile (small/medium/large)
11
12
  *
12
13
  * After collection, shows a unified summary and offers Apply/Edit/Cancel.
13
14
  * Apply phase runs all changes sequentially with progress output.
@@ -15,12 +16,14 @@
15
16
  */
16
17
  import * as readline from 'node:readline';
17
18
  import { execSync, spawnSync } from 'node:child_process';
18
- import { writeFileSync } from 'node:fs';
19
+ import { existsSync, writeFileSync } from 'node:fs';
19
20
  import chalk from 'chalk';
20
- import { savePrefs } from '../lib/prefs.js';
21
+ import { loadPrefs, savePrefs } from '../lib/prefs.js';
22
+ import { askMasked } from '../lib/prompts.js';
21
23
  import { getHostname, isValidHostname, buildFqdn, applyHostname, applyAdminPassword, isStrongPassword, } from '../lib/identity.js';
22
24
  import { getSystemTimezone, TIMEZONE_REGIONS, searchTimezones, isValidTimezone, applyTimezone, applyNtpServers, checkNtpSync, DEFAULT_NTP, } from '../lib/time.js';
23
25
  import { generateSelfSignedCerts, getCertInfo } from '../lib/certs.js';
26
+ import { PROFILES, getSystemRamMb, getSystemCpuCount, recommendedProfile, meetsRamRequirement, applyProfile, detectCurrentProfile, } from './commands/appliance-performance.js';
24
27
  export { buildFqdn } from '../lib/identity.js';
25
28
  export const NETWORK_SENTINEL = '/etc/ct-network-configured';
26
29
  const DEFAULT_DNS1 = '8.8.8.8';
@@ -99,13 +102,86 @@ export function pingGateway(gateway) {
99
102
  return null;
100
103
  }
101
104
  }
102
- /** Write the network sentinel (falls back to sudo touch). */
103
- export function writeSentinel() {
105
+ /** Test if a DNS server can resolve a well-known domain. Returns true on success. */
106
+ function testDnsServer(server) {
104
107
  try {
105
- writeFileSync(NETWORK_SENTINEL, '');
108
+ const result = spawnSync('nslookup', ['google.com', server], {
109
+ encoding: 'utf-8',
110
+ timeout: 5000,
111
+ });
112
+ return result.status === 0;
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ }
118
+ /** Ask for a DNS server, test resolution, offer retry on failure. */
119
+ async function askAndTestDns(ask, label, defaultValue) {
120
+ const padded = label.length < 13 ? label.padEnd(13) : label;
121
+ while (true) {
122
+ const raw = await ask(chalk.bold(` ${padded} [${defaultValue}] : `));
123
+ const server = parseDnsField(raw, defaultValue);
124
+ if (!isValidIp(server)) {
125
+ console.log(chalk.red(` ✗ Invalid IP address`));
126
+ continue;
127
+ }
128
+ process.stdout.write(chalk.dim(` Testing DNS resolution via ${server} ... `));
129
+ if (testDnsServer(server)) {
130
+ console.log(chalk.green('✓ working'));
131
+ return server;
132
+ }
133
+ else {
134
+ console.log(chalk.yellow('✗ resolution failed'));
135
+ const retry = (await ask(chalk.yellow(' Re-enter DNS server? [Y/n]: '))).trim().toLowerCase();
136
+ if (retry === 'n') {
137
+ console.log(chalk.dim(' Continuing with unresponsive DNS — may work after config is applied'));
138
+ return server;
139
+ }
140
+ }
141
+ }
142
+ }
143
+ /** Write the network sentinel with config state (no sensitive values). */
144
+ export function writeSentinel(state) {
145
+ const sentinel = state ? {
146
+ mode: state.mode ?? 'dhcp',
147
+ ip: state.ip,
148
+ prefix: state.prefix,
149
+ gateway: state.gateway,
150
+ dns1: state.dns1,
151
+ dns2: state.dns2,
152
+ searchDomain: state.searchDomain,
153
+ iface: state.iface,
154
+ hostname: state.hostname,
155
+ location: state.location,
156
+ timezone: state.timezone,
157
+ ntp1: state.ntp1,
158
+ ntp2: state.ntp2,
159
+ configuredAt: new Date().toISOString(),
160
+ } : { mode: 'dhcp', configuredAt: new Date().toISOString() };
161
+ const content = JSON.stringify(sentinel, null, 2);
162
+ try {
163
+ writeFileSync(NETWORK_SENTINEL, content);
164
+ }
165
+ catch {
166
+ // Fall back to sudo write via temp file
167
+ const tmp = `/tmp/ct-sentinel-${Date.now()}.json`;
168
+ writeFileSync(tmp, content);
169
+ spawnSync('sudo', ['mv', tmp, NETWORK_SENTINEL]);
170
+ }
171
+ }
172
+ /** Read saved sentinel state, or null if not configured / empty. */
173
+ export function readSentinel() {
174
+ try {
175
+ if (!existsSync(NETWORK_SENTINEL))
176
+ return null;
177
+ const { readFileSync } = require('node:fs');
178
+ const raw = readFileSync(NETWORK_SENTINEL, 'utf-8').trim();
179
+ if (!raw || raw.length < 2)
180
+ return null;
181
+ return JSON.parse(raw);
106
182
  }
107
183
  catch {
108
- spawnSync('sudo', ['touch', NETWORK_SENTINEL]);
184
+ return null;
109
185
  }
110
186
  }
111
187
  /** Apply static IP via nmcli. Returns true on success. */
@@ -161,7 +237,7 @@ function stepProgress(label, ok) {
161
237
  // ── Step 1: Network ──────────────────────────────────────────────────────────
162
238
  async function stepNetwork(ask, state) {
163
239
  console.log('');
164
- console.log(chalk.bold.cyan(' Step 1 of 6 — Network'));
240
+ console.log(chalk.bold.cyan(' Step 1 of 7 — Network'));
165
241
  console.log(chalk.dim(' ────────────────────────────────────────'));
166
242
  const iface = detectIface();
167
243
  state.iface = iface;
@@ -179,8 +255,11 @@ async function stepNetwork(ask, state) {
179
255
  console.log(chalk.cyan(' Network mode:'));
180
256
  console.log(chalk.dim(' 1 Keep current DHCP configuration'));
181
257
  console.log(chalk.dim(' 2 Configure static IP'));
258
+ console.log(chalk.dim(' 3 Skip setup and exit to shell'));
182
259
  console.log('');
183
260
  const mode = (await ask(chalk.bold(' Choice [1]: '))).trim() || '1';
261
+ if (mode === '3')
262
+ return 'skip';
184
263
  if (mode === '2') {
185
264
  state.mode = 'static';
186
265
  }
@@ -193,8 +272,11 @@ async function stepNetwork(ask, state) {
193
272
  console.log(chalk.cyan(' Network mode:'));
194
273
  console.log(chalk.dim(' 1 Static IP'));
195
274
  console.log(chalk.dim(' 2 DHCP (auto)'));
275
+ console.log(chalk.dim(' 3 Skip setup and exit to shell'));
196
276
  console.log('');
197
277
  const mode = (await ask(chalk.bold(' Choice [1]: '))).trim() || '1';
278
+ if (mode === '3')
279
+ return 'skip';
198
280
  if (mode === '2') {
199
281
  state.mode = 'dhcp';
200
282
  }
@@ -243,55 +325,43 @@ async function stepNetwork(ask, state) {
243
325
  console.log(chalk.green(` ✓ Subnet: /${prefix}`));
244
326
  }
245
327
  state.prefix = prefix;
246
- let gateway = '';
247
- while (!isValidGateway(gateway)) {
248
- gateway = (await ask(chalk.bold(' Gateway (e.g. 192.168.1.1) : '))).trim();
249
- if (!isValidGateway(gateway))
250
- console.log(chalk.red(' Invalid gateway — enter a valid IPv4 address'));
251
- }
252
- state.gateway = gateway;
253
- }
254
- // DNS (applies to both modes)
255
- const dns1Raw = await ask(chalk.bold(` Primary DNS [${DEFAULT_DNS1}] : `));
256
- state.dns1 = parseDnsField(dns1Raw, DEFAULT_DNS1);
257
- const dns2Raw = await ask(chalk.bold(` Secondary DNS [${DEFAULT_DNS2}] : `));
258
- state.dns2 = parseDnsField(dns2Raw, DEFAULT_DNS2);
328
+ // Gateway validate format, then test reachability with retry option
329
+ while (true) {
330
+ let gateway = '';
331
+ while (!isValidGateway(gateway)) {
332
+ gateway = (await ask(chalk.bold(' Gateway (e.g. 192.168.1.1) : '))).trim();
333
+ if (!isValidGateway(gateway))
334
+ console.log(chalk.red(' ✗ Invalid gateway enter a valid IPv4 address'));
335
+ }
336
+ process.stdout.write(chalk.dim(` Checking connectivity to ${gateway} ... `));
337
+ const latency = pingGateway(gateway);
338
+ if (latency !== null) {
339
+ console.log(chalk.green(`✓ reachable (${latency}ms)`));
340
+ state.gateway = gateway;
341
+ break;
342
+ }
343
+ else {
344
+ console.log(chalk.yellow(`✗ unreachable`));
345
+ const retry = (await ask(chalk.yellow(' Re-enter gateway? [Y/n]: '))).trim().toLowerCase();
346
+ if (retry === 'n') {
347
+ console.log(chalk.dim(' Continuing with unreachable gateway — may work after config is applied'));
348
+ state.gateway = gateway;
349
+ break;
350
+ }
351
+ }
352
+ }
353
+ }
354
+ // DNS — validate each server can resolve, with retry option
355
+ state.dns1 = await askAndTestDns(ask, 'Primary DNS', DEFAULT_DNS1);
356
+ state.dns2 = await askAndTestDns(ask, 'Secondary DNS', DEFAULT_DNS2);
259
357
  // Search domain
260
358
  const domainRaw = await ask(chalk.bold(` Search domain [${DEFAULT_SEARCH_DOMAIN}] : `));
261
359
  state.searchDomain = parseDnsField(domainRaw, DEFAULT_SEARCH_DOMAIN);
262
- // Quick connectivity check
263
- console.log('');
264
- console.log(chalk.dim(' Quick connectivity check...'));
265
- if (state.mode === 'static' && state.gateway) {
266
- const ms = pingGateway(state.gateway);
267
- if (ms !== null) {
268
- console.log(chalk.green(` ✓ Gateway ${state.gateway} reachable (${ms}ms)`));
269
- }
270
- else {
271
- console.log(chalk.yellow(` ⚠ Gateway ${state.gateway} not reachable — may work after apply`));
272
- }
273
- }
274
- // DNS resolve test
275
- try {
276
- const result = spawnSync('nslookup', ['google.com', state.dns1], {
277
- encoding: 'utf-8',
278
- timeout: 5000,
279
- });
280
- if (result.status === 0) {
281
- console.log(chalk.green(` ✓ DNS resolution via ${state.dns1} working`));
282
- }
283
- else {
284
- console.log(chalk.yellow(` ⚠ DNS resolution via ${state.dns1} failed — may work after apply`));
285
- }
286
- }
287
- catch {
288
- console.log(chalk.yellow(` ⚠ DNS check skipped — nslookup not available`));
289
- }
290
360
  }
291
- // ── Step 2: System Identity ──────────────────────────────────────────────────
361
+ // ── Step 4: System Identity ──────────────────────────────────────────────────
292
362
  async function stepIdentity(ask, state) {
293
363
  console.log('');
294
- console.log(chalk.bold.cyan(' Step 4 of 6 — System Identity'));
364
+ console.log(chalk.bold.cyan(' Step 4 of 7 — System Identity'));
295
365
  console.log(chalk.dim(' ────────────────────────────────────────'));
296
366
  const currentHostname = getHostname();
297
367
  // Hostname
@@ -316,22 +386,22 @@ async function stepIdentity(ask, state) {
316
386
  console.log(chalk.dim(' To import a CA-signed cert later:'));
317
387
  console.log(chalk.dim(' config certs import <cert.pem> <key.pem>'));
318
388
  }
319
- // ── Step 3: Admin Credentials ────────────────────────────────────────────────
320
- async function stepAdmin(ask, state) {
389
+ // ── Step 5: Admin Credentials ────────────────────────────────────────────────
390
+ async function stepAdmin(_ask, state) {
321
391
  console.log('');
322
- console.log(chalk.bold.cyan(' Step 5 of 6 — Admin Credentials'));
392
+ console.log(chalk.bold.cyan(' Step 5 of 7 — Admin Credentials'));
323
393
  console.log(chalk.dim(' ────────────────────────────────────────'));
324
394
  console.log(chalk.yellow(' Default passwords should be changed before production use.'));
325
395
  console.log(chalk.dim(' Minimum 8 characters.'));
326
396
  console.log('');
327
397
  while (true) {
328
- const pw = (await ask(chalk.bold(' New admin password: '))).trim();
398
+ const pw = (await askMasked(chalk.bold(' New admin password: '))).trim();
329
399
  const check = isStrongPassword(pw);
330
400
  if (!check.valid) {
331
401
  console.log(chalk.red(` ✗ ${check.reason}`));
332
402
  continue;
333
403
  }
334
- const confirm = (await ask(chalk.bold(' Confirm password: '))).trim();
404
+ const confirm = (await askMasked(chalk.bold(' Confirm password: '))).trim();
335
405
  if (confirm !== pw) {
336
406
  console.log(chalk.red(' ✗ Passwords do not match'));
337
407
  continue;
@@ -341,10 +411,10 @@ async function stepAdmin(ask, state) {
341
411
  break;
342
412
  }
343
413
  }
344
- // ── Step 4: Timezone ─────────────────────────────────────────────────────────
414
+ // ── Step 2: Timezone ─────────────────────────────────────────────────────────
345
415
  async function stepTimezone(ask, state) {
346
416
  console.log('');
347
- console.log(chalk.bold.cyan(' Step 2 of 6 — Timezone'));
417
+ console.log(chalk.bold.cyan(' Step 2 of 7 — Timezone'));
348
418
  console.log(chalk.dim(' ────────────────────────────────────────'));
349
419
  const currentTz = getSystemTimezone();
350
420
  console.log(chalk.dim(` Current timezone: ${currentTz}`));
@@ -433,10 +503,10 @@ async function stepTimezone(ask, state) {
433
503
  console.log(chalk.red(' ✗ Invalid selection'));
434
504
  }
435
505
  }
436
- // ── Step 5: NTP ──────────────────────────────────────────────────────────────
506
+ // ── Step 3: NTP ──────────────────────────────────────────────────────────────
437
507
  async function stepNtp(ask, state) {
438
508
  console.log('');
439
- console.log(chalk.bold.cyan(' Step 3 of 6 — NTP Time Servers'));
509
+ console.log(chalk.bold.cyan(' Step 3 of 7 — NTP Time Servers'));
440
510
  console.log(chalk.dim(' ────────────────────────────────────────'));
441
511
  const ntp1Raw = await ask(chalk.bold(` NTP Server 1 [${DEFAULT_NTP[0]}]: `));
442
512
  state.ntp1 = parseDnsField(ntp1Raw, DEFAULT_NTP[0]);
@@ -447,7 +517,7 @@ async function stepNtp(ask, state) {
447
517
  // ── Step 6: Preferences ──────────────────────────────────────────────────────
448
518
  async function stepPreferences(ask, state) {
449
519
  console.log('');
450
- console.log(chalk.bold.cyan(' Step 6 of 6 — Preferences'));
520
+ console.log(chalk.bold.cyan(' Step 6 of 7 — Preferences'));
451
521
  console.log(chalk.dim(' ────────────────────────────────────────'));
452
522
  // Auto-updates
453
523
  const autoUpdate = (await ask(chalk.bold(' Enable automatic CLI updates? [Y/n]: '))).trim().toLowerCase();
@@ -466,6 +536,67 @@ async function stepPreferences(ask, state) {
466
536
  state.jtapi = jtapi === 'y' || jtapi === 'yes';
467
537
  console.log(state.jtapi ? chalk.green(' ✓ JTAPI greeting injection enabled') : chalk.dim(' ○ JTAPI greeting injection disabled'));
468
538
  }
539
+ // ── Step 7: Performance Profile ──────────────────────────────────────────
540
+ const PROFILE_NAMES = ['small', 'medium', 'large'];
541
+ async function stepPerformance(ask, state) {
542
+ console.log('');
543
+ console.log(chalk.bold.cyan(' Step 7 of 7 — Performance Profile'));
544
+ console.log(chalk.dim(' ────────────────────────────────────────'));
545
+ // Check if already configured
546
+ const existing = detectCurrentProfile();
547
+ if (existing) {
548
+ console.log(chalk.dim(` Current profile: ${PROFILES[existing].description}`));
549
+ }
550
+ // Detect hardware
551
+ const ramMb = getSystemRamMb();
552
+ const cpus = getSystemCpuCount();
553
+ const ramStr = ramMb > 0 ? `${(ramMb / 1024).toFixed(0)} GB` : 'unknown';
554
+ const cpuStr = cpus > 0 ? `${cpus} vCPUs` : 'unknown';
555
+ console.log(chalk.dim(` Detected: ${ramStr} RAM, ${cpuStr}`));
556
+ console.log('');
557
+ // Determine recommended profile
558
+ const rec = ramMb > 0 ? recommendedProfile(ramMb) : 'small';
559
+ console.log(chalk.cyan(' Choose a performance profile:'));
560
+ console.log('');
561
+ for (let i = 0; i < PROFILE_NAMES.length; i++) {
562
+ const name = PROFILE_NAMES[i];
563
+ const p = PROFILES[name];
564
+ const isRec = name === rec;
565
+ const label = isRec ? `${p.description} (recommended for this hardware)` : p.description;
566
+ const marker = isRec ? chalk.green(` > ${i + 1} ${label}`) : chalk.dim(` ${i + 1} ${label}`);
567
+ console.log(marker);
568
+ console.log(chalk.dim(` ${p.capacity}`));
569
+ console.log(chalk.dim(` Minimum: ${p.hardware}`));
570
+ console.log('');
571
+ }
572
+ // Default to recommended
573
+ const recIdx = PROFILE_NAMES.indexOf(rec) + 1;
574
+ const choice = (await ask(chalk.bold(` Choice [${recIdx}]: `))).trim() || String(recIdx);
575
+ const idx = parseInt(choice, 10) - 1;
576
+ if (isNaN(idx) || idx < 0 || idx >= PROFILE_NAMES.length) {
577
+ console.log(chalk.red(' ✗ Invalid selection — using recommended profile'));
578
+ state.performanceProfile = rec;
579
+ }
580
+ else {
581
+ state.performanceProfile = PROFILE_NAMES[idx];
582
+ }
583
+ const selected = state.performanceProfile;
584
+ const profile = PROFILES[selected];
585
+ // Warn if hardware doesn't meet requirements
586
+ if (ramMb > 0 && !meetsRamRequirement(ramMb, selected)) {
587
+ const ramGb = (ramMb / 1024).toFixed(1);
588
+ console.log('');
589
+ console.log(chalk.yellow(` ⚠ Your system has ${ramGb} GB RAM but ${profile.description} requires ${profile.hardware}.`));
590
+ console.log(chalk.yellow(' Performance may suffer.'));
591
+ const confirm = (await ask(chalk.bold(' Continue anyway? [y/N]: '))).trim().toLowerCase();
592
+ if (confirm !== 'y' && confirm !== 'yes') {
593
+ console.log(chalk.dim(' Falling back to recommended profile.'));
594
+ state.performanceProfile = rec;
595
+ }
596
+ }
597
+ const final = PROFILES[state.performanceProfile];
598
+ console.log(chalk.green(` ✓ Performance profile: ${final.description}`));
599
+ }
469
600
  // ── Summary ──────────────────────────────────────────────────────────────────
470
601
  /** Render a full summary of the wizard state. Exported for testing. */
471
602
  export function renderSummary(state) {
@@ -512,6 +643,15 @@ export function renderSummary(state) {
512
643
  add(` Auto-updates : ${state.autoUpdate ? chalk.green('Yes') : chalk.dim('No')}`);
513
644
  add(` IPv6 : ${state.ipv6 ? chalk.green('Yes') : chalk.dim('No')}`);
514
645
  add(` JTAPI Greetings: ${state.jtapi ? chalk.green('Yes') : chalk.dim('No')}`);
646
+ // PERFORMANCE
647
+ if (state.performanceProfile) {
648
+ const perf = PROFILES[state.performanceProfile];
649
+ add('');
650
+ add(chalk.cyan(' PERFORMANCE'));
651
+ add(chalk.dim(' ────────────────────────────────────────'));
652
+ add(` Profile : ${chalk.bold(perf.description)}`);
653
+ add(` Capacity : ${perf.capacity}`);
654
+ }
515
655
  add('');
516
656
  return lines.join('\n');
517
657
  }
@@ -563,13 +703,25 @@ async function applyWizardState(state) {
563
703
  stepProgress('Configure NTP servers', ntpOk);
564
704
  if (!ntpOk)
565
705
  allOk = false;
566
- // 7. Save preferences + write sentinel BEFORE cert gen
706
+ // 7. Performance profile
707
+ if (state.performanceProfile) {
708
+ try {
709
+ await applyProfile(state.performanceProfile);
710
+ stepProgress('Apply performance profile', true);
711
+ }
712
+ catch {
713
+ stepProgress('Apply performance profile', false);
714
+ allOk = false;
715
+ }
716
+ }
717
+ // 8. Save preferences + write sentinel BEFORE cert gen
567
718
  // (so wizard doesn't re-run even if cert generation fails)
568
719
  const prefs = {
569
720
  autoUpdate: state.autoUpdate,
570
721
  ipv6: state.ipv6,
571
722
  otel: true,
572
723
  jtapi: state.jtapi,
724
+ paletteRecentCommands: [],
573
725
  deploymentMode: 'docker-compose',
574
726
  k8sNamespace: 'ct',
575
727
  k8sEnvironment: 'ct-dev',
@@ -682,6 +834,7 @@ const STEP_FUNCTIONS = [
682
834
  stepIdentity, // 4. Hostname + location
683
835
  stepAdmin, // 5. Admin password
684
836
  stepPreferences, // 6. Feature preferences
837
+ stepPerformance, // 7. Performance profile
685
838
  ];
686
839
  const STEP_NAMES = [
687
840
  'Network',
@@ -690,6 +843,7 @@ const STEP_NAMES = [
690
843
  'System Identity',
691
844
  'Admin Credentials',
692
845
  'Preferences',
846
+ 'Performance Profile',
693
847
  ];
694
848
  // ── Main entry point ─────────────────────────────────────────────────────────
695
849
  /**
@@ -698,40 +852,100 @@ const STEP_NAMES = [
698
852
  * Collects all configuration, then applies atomically.
699
853
  */
700
854
  export async function runNetworkOnboarding() {
855
+ const saved = readSentinel();
856
+ const isReconfigure = saved !== null;
701
857
  console.log('');
702
- console.log(chalk.bold.cyan(' Call Telemetry — First-Boot Setup'));
858
+ console.log(chalk.bold.cyan(isReconfigure
859
+ ? ' Call Telemetry — Reconfigure'
860
+ : ' Call Telemetry — First-Boot Setup'));
703
861
  console.log(chalk.dim(' ═══════════════════════════════════════'));
704
862
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
705
863
  const ask = makeAsker(rl);
706
864
  try {
707
- // Initialize state with defaults
865
+ // Initialize state restore from sentinel if reconfiguring
866
+ const prefs = loadPrefs();
708
867
  const state = {
709
- mode: 'dhcp',
710
- dns1: DEFAULT_DNS1,
711
- dns2: DEFAULT_DNS2,
712
- searchDomain: DEFAULT_SEARCH_DOMAIN,
713
- iface: 'eth0',
714
- hostname: getHostname(),
715
- location: '',
868
+ mode: saved?.mode ?? 'dhcp',
869
+ ip: saved?.ip,
870
+ prefix: saved?.prefix,
871
+ gateway: saved?.gateway,
872
+ dns1: saved?.dns1 ?? DEFAULT_DNS1,
873
+ dns2: saved?.dns2 ?? DEFAULT_DNS2,
874
+ searchDomain: saved?.searchDomain ?? DEFAULT_SEARCH_DOMAIN,
875
+ iface: saved?.iface ?? detectIface(),
876
+ hostname: saved?.hostname ?? getHostname(),
877
+ location: saved?.location ?? '',
716
878
  adminPassword: '',
717
- timezone: getSystemTimezone(),
718
- ntp1: DEFAULT_NTP[0],
719
- ntp2: DEFAULT_NTP[1],
720
- autoUpdate: true,
721
- ipv6: false,
722
- jtapi: false,
879
+ timezone: saved?.timezone ?? getSystemTimezone(),
880
+ ntp1: saved?.ntp1 ?? DEFAULT_NTP[0],
881
+ ntp2: saved?.ntp2 ?? DEFAULT_NTP[1],
882
+ autoUpdate: prefs?.autoUpdate ?? true,
883
+ ipv6: prefs?.ipv6 ?? false,
884
+ jtapi: prefs?.jtapi ?? false,
723
885
  };
724
- // Run steps 1-6 sequentially
725
- for (const stepFn of STEP_FUNCTIONS) {
726
- await stepFn(ask, state);
886
+ if (isReconfigure) {
887
+ // Show current config and let user pick what to change
888
+ console.log(renderSummary(state));
889
+ console.log(chalk.bold(' Select a section to reconfigure, or press Enter to exit:'));
890
+ console.log('');
891
+ for (let i = 0; i < STEP_NAMES.length; i++) {
892
+ console.log(chalk.dim(` ${i + 1} ${STEP_NAMES[i]}`));
893
+ }
894
+ console.log(chalk.dim(' A Reconfigure everything'));
895
+ console.log('');
896
+ const choice = (await ask(chalk.bold(' Choice [Enter=done]: '))).trim().toLowerCase();
897
+ if (choice === '') {
898
+ console.log(chalk.dim('\n No changes. Current configuration retained.\n'));
899
+ return;
900
+ }
901
+ if (choice === 'a') {
902
+ // Run all steps
903
+ for (const stepFn of STEP_FUNCTIONS) {
904
+ await stepFn(ask, state);
905
+ }
906
+ }
907
+ else {
908
+ const stepIdx = parseInt(choice, 10) - 1;
909
+ if (stepIdx >= 0 && stepIdx < STEP_FUNCTIONS.length) {
910
+ await STEP_FUNCTIONS[stepIdx](ask, state);
911
+ }
912
+ else {
913
+ console.log(chalk.red(' ✗ Invalid choice'));
914
+ return;
915
+ }
916
+ }
917
+ }
918
+ else {
919
+ // First boot — run all steps sequentially
920
+ for (const stepFn of STEP_FUNCTIONS) {
921
+ const result = await stepFn(ask, state);
922
+ // Step 1 returns 'skip' if user chose to skip setup entirely
923
+ if (result === 'skip') {
924
+ writeSentinel(state);
925
+ if (!loadPrefs()) {
926
+ savePrefs({
927
+ autoUpdate: true,
928
+ ipv6: false,
929
+ otel: false,
930
+ jtapi: false,
931
+ paletteRecentCommands: [],
932
+ deploymentMode: 'docker-compose',
933
+ k8sNamespace: 'default',
934
+ k8sEnvironment: 'ct-prod',
935
+ });
936
+ }
937
+ console.log(chalk.green('\n ✓ Setup skipped. Run "ct setup" anytime to configure.\n'));
938
+ return;
939
+ }
940
+ }
727
941
  }
728
942
  // Show/edit/apply loop
729
943
  while (true) {
730
944
  // Show unified summary
731
945
  console.log(renderSummary(state));
732
- console.log(chalk.bold(' [A]pply [E]dit [C]ancel'));
946
+ console.log(chalk.bold(' [Y/A]ccept [E]dit [C]ancel'));
733
947
  console.log('');
734
- const action = (await ask(chalk.bold(' Choice [A]: '))).trim().toLowerCase();
948
+ const action = (await ask(chalk.bold(' Choice [Y]: '))).trim().toLowerCase();
735
949
  if (action === 'c') {
736
950
  console.log(chalk.yellow('\n Cancelled — no changes applied.\n'));
737
951
  return;
@@ -742,7 +956,7 @@ export async function runNetworkOnboarding() {
742
956
  console.log(chalk.dim(` ${i + 1} ${STEP_NAMES[i]}`));
743
957
  }
744
958
  console.log('');
745
- const stepChoice = (await ask(chalk.bold(' Which step? [1-6]: '))).trim();
959
+ const stepChoice = (await ask(chalk.bold(' Which step? [1-7]: '))).trim();
746
960
  const stepIdx = parseInt(stepChoice, 10) - 1;
747
961
  if (stepIdx >= 0 && stepIdx < STEP_FUNCTIONS.length) {
748
962
  await STEP_FUNCTIONS[stepIdx](ask, state);
@@ -752,9 +966,11 @@ export async function runNetworkOnboarding() {
752
966
  }
753
967
  continue; // re-show summary
754
968
  }
755
- if (action === 'a' || action === '') {
969
+ if (action === 'y' || action === 'a' || action === '') {
756
970
  // Apply all
757
971
  const ok = await applyWizardState(state);
972
+ // Save config to sentinel (no sensitive values)
973
+ writeSentinel(state);
758
974
  if (ok) {
759
975
  console.log('');
760
976
  console.log(chalk.green(' ✓ All configuration applied successfully'));
@@ -830,6 +1046,7 @@ export async function runPreferencesOnboarding() {
830
1046
  ipv6: state.ipv6,
831
1047
  otel: true,
832
1048
  jtapi: state.jtapi,
1049
+ paletteRecentCommands: [],
833
1050
  deploymentMode: 'docker-compose',
834
1051
  k8sNamespace: 'ct',
835
1052
  k8sEnvironment: 'ct-dev',