Cesium has this very nice Cartesian3.fromDegreesArray function which will take a packed array of longitude and latitude values and create an array of Cartesian3 objects. I’m looking for the inverse that will take an array of Cartesian3 and create a packed array of longitude and latitude values. Does that exist or do I just have to roll my own conversion loop?

There is not a toDegressArray helper function but it was pretty easy to roll my own:

const longLat = [];
for (const p of positions) {
  const carto = Cartographic.fromCartesian(p);

Not really tested, but maybe a stub if someone wants to add something like this later:

 * Returns an array of longitude and latitude values, in degrees, computed from the given Cartesian3 positions array.
 * If any of the given cartesian objects is too close to the center of the ellipsoid
 * and the resulting cartographic cannot be computed, then the values in the result
 * array will remain unaffected. 
 * @param {Cartesian3[]} cartesians A list of {@link Cartesian3} objects.
 * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the target coordinates lie.
 * @param {Number[]} [result] An array of numbers to store the result.
 * @returns {Number[]} The array of longitude and latitide positions. If this is a typed array, it must have 
 * (cartesians.length * 2) components, else a {@link DeveloperError} will be thrown. If it is a regular array, 
 * it will be resized to have (cartesians.length * 2) elements.
const toDegreesArray = function (cartesians, ellipsoid, result) {
    //>>includeStart('debug', pragmas.debug);
    Check.defined("cartesians", cartesians);
    const length = cartesians.length;
    const resultLength = length * 2;
    if (!defined(result)) {
        result = new Array(resultLength);
    } else if (!Array.isArray(result) && result.length !== resultLength) {
        throw new DeveloperError(
          "If result is a typed array, it must have exactly array.length * 2 elements"
    } else if (result.length !== resultLength) {
        result.length = resultLength;

    const cartographicScratch = new Cartographic();
    for (var i = 0; i < length; i++) {
      const cartesian = cartesians[i];
      const cartographic = Cartographic.fromCartesian(cartesian, ellipsoid, cartographicScratch);
      if (defined(cartographic)) {
        result[i * 2 + 0] = CesiumMath.toDegrees(cartographic.longitude);
        result[i * 2 + 1] = CesiumMath.toDegrees(cartographic.latitude);
    return result;

A sensible handling of the cartesians that are at the ellipsoid center may be tricky, though. And more generally, I think it could make sense to break this down further, so that the body of this function only consists of toRadiansArray(...).map(r => CesiumMath.toDegrees(r));. But if there should be a toDegreesArrayHeights function as well, this would require more thought.