cdx-chores 0.0.8 → 0.0.9-canary.2

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.
@@ -974,6 +974,14 @@ function normalizeOptionalPositiveInteger(value, context) {
974
974
  exitCode: 2
975
975
  });
976
976
  }
977
+ function normalizeOptionalBoolean(value, context) {
978
+ if (value === void 0 || value === null || value === "") return;
979
+ if (typeof value === "boolean") return value;
980
+ throw new CliError(`Invalid header mapping artifact: ${context} must be a boolean.`, {
981
+ code: "INVALID_INPUT",
982
+ exitCode: 2
983
+ });
984
+ }
977
985
  function throwUnsupportedHeaderMappingVersion(version, options = {}) {
978
986
  const suffix = options.rewriting ? " Cannot preserve it safely while rewriting." : "";
979
987
  throw new CliError(`Unsupported header mapping artifact version: ${String(version)}.${suffix}`, {
@@ -993,6 +1001,7 @@ function createHeaderMappingInputReference(options) {
993
1001
  ...options.shape?.bodyStartRow !== void 0 ? { bodyStartRow: options.shape.bodyStartRow } : {},
994
1002
  format: options.format,
995
1003
  ...options.shape?.headerRow !== void 0 ? { headerRow: options.shape.headerRow } : {},
1004
+ ...options.shape?.noHeader ? { noHeader: true } : {},
996
1005
  path: normalizedRelativePath,
997
1006
  ...options.shape?.range ? { range: options.shape.range } : {},
998
1007
  ...options.shape?.source ? { source: options.shape.source } : {}
@@ -1206,10 +1215,12 @@ function parseDataHeaderMappingArtifact(parsed, options = {}) {
1206
1215
  };
1207
1216
  const bodyStartRow = normalizeOptionalPositiveInteger(input.bodyStartRow, "input.bodyStartRow");
1208
1217
  const headerRow = normalizeOptionalPositiveInteger(input.headerRow, "input.headerRow");
1218
+ const noHeader = normalizeOptionalBoolean(input.noHeader, "input.noHeader");
1209
1219
  const source = normalizeOptionalString(input.source);
1210
1220
  const range = normalizeOptionalString(input.range);
1211
1221
  if (bodyStartRow !== void 0) normalizedInput.bodyStartRow = bodyStartRow;
1212
1222
  if (headerRow !== void 0) normalizedInput.headerRow = headerRow;
1223
+ if (noHeader) normalizedInput.noHeader = true;
1213
1224
  if (source) normalizedInput.source = source;
1214
1225
  if (range) normalizedInput.range = range;
1215
1226
  if (!Array.isArray(parsed.mappings)) throw new CliError("Invalid header mapping artifact: mappings must be an array.", {
@@ -1317,7 +1328,7 @@ async function writeDataHeaderMappingArtifact(path, artifact, options = {}) {
1317
1328
  function resolveReusableHeaderMappings(options) {
1318
1329
  const expected = options.currentInput;
1319
1330
  const actual = options.artifact.input;
1320
- if (!(actual.bodyStartRow === expected.bodyStartRow && actual.path === expected.path && actual.format === expected.format && actual.headerRow === expected.headerRow && actual.source === expected.source && actual.range === expected.range)) throw new CliError("Header mapping artifact does not match the current input context exactly.", {
1331
+ if (!(actual.bodyStartRow === expected.bodyStartRow && actual.path === expected.path && actual.format === expected.format && actual.headerRow === expected.headerRow && actual.noHeader === expected.noHeader && actual.source === expected.source && actual.range === expected.range)) throw new CliError("Header mapping artifact does not match the current input context exactly.", {
1321
1332
  code: "INVALID_INPUT",
1322
1333
  exitCode: 2
1323
1334
  });
@@ -1340,8 +1351,9 @@ function isGeneratedQueryPlaceholderSequence(names) {
1340
1351
  return Number.isInteger(detectedIndex) && detectedIndex === index;
1341
1352
  });
1342
1353
  }
1343
- async function shouldNormalizeGeneratedQueryColumnNames(connection, inputPath, format, columnNames) {
1354
+ async function shouldNormalizeGeneratedQueryColumnNames(connection, inputPath, format, columnNames, options = {}) {
1344
1355
  if (format !== "csv" && format !== "tsv" || !isGeneratedQueryPlaceholderSequence(columnNames)) return false;
1356
+ if (options.noHeader) return true;
1345
1357
  try {
1346
1358
  const delimiter = format === "tsv" ? " " : ",";
1347
1359
  return (await connection.runAndReadAll(`select HasHeader from sniff_csv(${escapeSqlStringLiteral(inputPath)}, delim = ${escapeSqlStringLiteral(delimiter)})`)).getRowObjectsJson()[0]?.HasHeader === false;
@@ -1353,7 +1365,7 @@ async function collectQueryRelationColumns(connection, relationName, options) {
1353
1365
  const reader = await connection.runAndReadAll(`select * from ${quoteSqlIdentifier$1(relationName)} limit 0`);
1354
1366
  const columnNames = reader.deduplicatedColumnNames();
1355
1367
  const columnTypes = reader.columnTypes();
1356
- const shouldNormalizeGeneratedColumns = await shouldNormalizeGeneratedQueryColumnNames(connection, options.inputPath, options.format, columnNames);
1368
+ const shouldNormalizeGeneratedColumns = await shouldNormalizeGeneratedQueryColumnNames(connection, options.inputPath, options.format, columnNames, { noHeader: options.noHeader });
1357
1369
  return columnNames.map((name, index) => ({
1358
1370
  name: shouldNormalizeGeneratedColumns ? normalizeGeneratedQueryColumnName(name) : name,
1359
1371
  sourceName: name,
@@ -1365,8 +1377,16 @@ async function collectQueryRelationColumns(connection, relationName, options) {
1365
1377
  function buildRelationSql(inputPath, format, shape = {}, options = {}) {
1366
1378
  const escapedInput = escapeSqlStringLiteral(inputPath);
1367
1379
  switch (format) {
1368
- case "csv": return `select * from read_csv_auto(${escapedInput}, delim = ',')`;
1369
- case "tsv": return `select * from read_csv_auto(${escapedInput}, delim = '\t')`;
1380
+ case "csv": return `select * from read_csv_auto(${[
1381
+ escapedInput,
1382
+ "delim = ','",
1383
+ ...shape.noHeader ? ["header = false"] : []
1384
+ ].join(", ")})`;
1385
+ case "tsv": return `select * from read_csv_auto(${[
1386
+ escapedInput,
1387
+ "delim = ' '",
1388
+ ...shape.noHeader ? ["header = false"] : []
1389
+ ].join(", ")})`;
1370
1390
  case "parquet": return `select * from read_parquet(${escapedInput})`;
1371
1391
  case "sqlite": return `select * from sqlite_scan(${escapedInput}, ${escapeSqlStringLiteral(shape.source ?? "")})`;
1372
1392
  case "excel": return `select * from read_xlsx(${[
@@ -1525,8 +1545,13 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
1525
1545
  const selectedBodyStartRow = shape.bodyStartRow !== void 0 ? normalizeExcelBodyStartRow(shape.bodyStartRow) : void 0;
1526
1546
  const selectedRange = shape.range?.trim() ? normalizeExcelRange(shape.range) : void 0;
1527
1547
  const selectedHeaderRow = shape.headerRow !== void 0 ? normalizeExcelHeaderRow(shape.headerRow) : void 0;
1548
+ const noHeader = shape.noHeader === true;
1528
1549
  let effectiveRange = selectedRange;
1529
1550
  let boundaryRangeParts;
1551
+ if (noHeader && format !== "csv" && format !== "tsv") throw new CliError("--no-header is only valid for CSV and TSV query inputs.", {
1552
+ code: "INVALID_INPUT",
1553
+ exitCode: 2
1554
+ });
1530
1555
  if (format === "sqlite") {
1531
1556
  if (selectedRange) throw new CliError("--range is only valid for Excel query inputs.", {
1532
1557
  code: "INVALID_INPUT",
@@ -1594,7 +1619,8 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
1594
1619
  });
1595
1620
  const relationColumns = await collectQueryRelationColumns(connection, "file_source", {
1596
1621
  format,
1597
- inputPath
1622
+ inputPath,
1623
+ noHeader
1598
1624
  });
1599
1625
  const appliedHeaderMappings = normalizeAndValidateAcceptedHeaderMappings({
1600
1626
  availableColumns: relationColumns.map((column) => column.name),
@@ -1618,6 +1644,7 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
1618
1644
  const excelImportMode = excelImportModes[index] ?? "default";
1619
1645
  try {
1620
1646
  await connection.run(`create or replace temp view file_source as ${buildRelationSql(inputPath, format, {
1647
+ noHeader,
1621
1648
  range: effectiveRange,
1622
1649
  source: selectedSource
1623
1650
  }, {
@@ -1626,7 +1653,8 @@ async function prepareDataQuerySource(connection, inputPath, format, shape = {},
1626
1653
  })}`);
1627
1654
  const relationColumns = await collectQueryRelationColumns(connection, "file_source", {
1628
1655
  format,
1629
- inputPath
1656
+ inputPath,
1657
+ noHeader
1630
1658
  });
1631
1659
  const appliedHeaderMappings = normalizeAndValidateAcceptedHeaderMappings({
1632
1660
  availableColumns: relationColumns.map((column) => column.name),
@@ -2646,6 +2674,86 @@ async function actionDataDuckDbExtensionInstall(runtime, options) {
2646
2674
  }
2647
2675
  }
2648
2676
  //#endregion
2677
+ //#region src/cli/interactive/analyzer-status.ts
2678
+ const ANALYZER_WAITING_FRAMES = [
2679
+ ". ",
2680
+ ".. ",
2681
+ "...",
2682
+ ".. ",
2683
+ ". "
2684
+ ];
2685
+ const ANALYZER_WAITING_INTERVAL_MS = 360;
2686
+ function clearStatusLine(stream) {
2687
+ stream.write("\r\x1B[2K");
2688
+ }
2689
+ function normalizeAnalyzerStatusMessage(message) {
2690
+ if (message.includes("Sampling filenames")) return "sampling";
2691
+ if (message.includes("Grouping filename patterns")) return "grouping";
2692
+ if (message.includes("Waiting for Codex cleanup suggestions")) return "waiting";
2693
+ return message;
2694
+ }
2695
+ function renderStatusLine(stream, message, colorEnabled) {
2696
+ const pc = (0, import_picocolors.createColors)(colorEnabled);
2697
+ const normalizedMessage = normalizeAnalyzerStatusMessage(message);
2698
+ const content = ` ${pc.dim("Codex")} ${pc.white("Thinking...")} ${pc.dim(normalizedMessage)} `;
2699
+ stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
2700
+ }
2701
+ function renderWaitingStatusLine(stream, message, tick, colorEnabled) {
2702
+ const pc = (0, import_picocolors.createColors)(colorEnabled);
2703
+ const normalizedMessage = normalizeAnalyzerStatusMessage(message);
2704
+ const dots = ANALYZER_WAITING_FRAMES[tick % ANALYZER_WAITING_FRAMES.length] ?? "...";
2705
+ const content = ` ${pc.dim("Codex")} ${pc.white("Thinking")} ${pc.dim(normalizedMessage)} ${pc.gray(dots)} `;
2706
+ stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
2707
+ }
2708
+ function createInteractiveAnalyzerStatus(stream, colorEnabled = true) {
2709
+ if (!stream.isTTY) return {
2710
+ start(message) {
2711
+ printLine(stream, message);
2712
+ },
2713
+ update(message) {
2714
+ printLine(stream, message);
2715
+ },
2716
+ wait(message) {
2717
+ printLine(stream, message);
2718
+ },
2719
+ stop() {}
2720
+ };
2721
+ let currentMessage = "";
2722
+ let timer;
2723
+ let tick = 0;
2724
+ const stopTimer = () => {
2725
+ if (!timer) return;
2726
+ clearInterval(timer);
2727
+ timer = void 0;
2728
+ };
2729
+ return {
2730
+ start(message) {
2731
+ stopTimer();
2732
+ currentMessage = message;
2733
+ renderStatusLine(stream, currentMessage, colorEnabled);
2734
+ },
2735
+ update(message) {
2736
+ stopTimer();
2737
+ currentMessage = message;
2738
+ renderStatusLine(stream, currentMessage, colorEnabled);
2739
+ },
2740
+ wait(message) {
2741
+ stopTimer();
2742
+ currentMessage = message;
2743
+ tick = 0;
2744
+ renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
2745
+ timer = setInterval(() => {
2746
+ tick += 1;
2747
+ renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
2748
+ }, ANALYZER_WAITING_INTERVAL_MS);
2749
+ },
2750
+ stop() {
2751
+ stopTimer();
2752
+ clearStatusLine(stream);
2753
+ }
2754
+ };
2755
+ }
2756
+ //#endregion
2649
2757
  //#region src/cli/data-workflows/header-mapping-flow.ts
2650
2758
  function classifyHeaderSuggestionFailure(message, options) {
2651
2759
  if (/codex exec exited/i.test(message) || /missing optional dependency/i.test(message) || /spawn/i.test(message) || /enoent/i.test(message) || /auth/i.test(message) || /sign in/i.test(message) || /api key/i.test(message)) return {
@@ -2682,6 +2790,7 @@ function buildHeaderSuggestionFollowUpCommand(options) {
2682
2790
  options.format,
2683
2791
  ...options.shape.source ? ["--source", JSON.stringify(options.shape.source)] : [],
2684
2792
  ...options.shape.range ? ["--range", options.shape.range] : [],
2793
+ ...options.shape.noHeader ? ["--no-header"] : [],
2685
2794
  ...options.shape.bodyStartRow !== void 0 ? ["--body-start-row", String(options.shape.bodyStartRow)] : [],
2686
2795
  ...options.shape.headerRow !== void 0 ? ["--header-row", String(options.shape.headerRow)] : [],
2687
2796
  "--header-mapping",
@@ -2702,13 +2811,21 @@ async function resolveReusableHeaderMappingsForDataFlow(options) {
2702
2811
  }
2703
2812
  async function runCodexHeaderSuggestionFlow(options) {
2704
2813
  const artifactPath = options.writeHeaderMapping?.trim() ? resolveFromCwd(options.runtime, options.writeHeaderMapping.trim()) : (0, node_path.join)(options.runtime.cwd, generateDataHeaderMappingFileName());
2705
- const introspection = await options.collectIntrospection();
2706
- const suggestionResult = await suggestDataHeaderMappingsWithCodex({
2707
- format: options.format,
2708
- introspection,
2709
- runner: options.headerSuggestionRunner,
2710
- workingDirectory: options.runtime.cwd
2711
- });
2814
+ const status = createInteractiveAnalyzerStatus(options.runtime.stdout, options.runtime.colorEnabled);
2815
+ let suggestionResult;
2816
+ try {
2817
+ status.start("Inspecting shaped source");
2818
+ const introspection = await options.collectIntrospection();
2819
+ status.wait("Waiting for Codex header suggestions");
2820
+ suggestionResult = await suggestDataHeaderMappingsWithCodex({
2821
+ format: options.format,
2822
+ introspection,
2823
+ runner: options.headerSuggestionRunner,
2824
+ workingDirectory: options.runtime.cwd
2825
+ });
2826
+ } finally {
2827
+ status.stop();
2828
+ }
2712
2829
  if (suggestionResult.errorMessage) {
2713
2830
  const failure = classifyHeaderSuggestionFailure(suggestionResult.errorMessage, {
2714
2831
  failureCode: options.failureCode,
@@ -2999,7 +3116,7 @@ function buildSourceShapeHeaderSuggestionFollowUpCommand(options) {
2999
3116
  ].join(" ");
3000
3117
  }
3001
3118
  async function resolveReusableSourceShapeForDataFlow(options) {
3002
- if (!isSourceShapeFormat(options.format)) throw new CliError("--source-shape is only valid for Excel extract inputs.", {
3119
+ if (!isSourceShapeFormat(options.format)) throw new CliError(`--source-shape is only valid for Excel ${options.commandName} inputs.`, {
3003
3120
  code: "INVALID_INPUT",
3004
3121
  exitCode: 2
3005
3122
  });
@@ -3166,14 +3283,18 @@ async function runCodexSourceShapeSuggestionFlow(runtime, options) {
3166
3283
  });
3167
3284
  const selectedSource = assertNonEmpty(options.source, "Source");
3168
3285
  const artifactPath = options.writeSourceShape?.trim() ? resolveFromCwd(runtime, options.writeSourceShape.trim()) : (0, node_path.join)(runtime.cwd, generateDataSourceShapeFileName());
3286
+ const status = createInteractiveAnalyzerStatus(runtime.stdout, runtime.colorEnabled);
3169
3287
  let connection;
3170
3288
  try {
3171
3289
  connection = await createDuckDbConnection$1();
3290
+ status.start("Inspecting worksheet structure");
3172
3291
  const currentIntrospection = await collectDataQuerySourceIntrospection(connection, options.inputPath, options.format, { source: selectedSource }, 5);
3292
+ const sheetSnapshot = await collectXlsxSheetSnapshot(options.inputPath, selectedSource, { maxRows: 24 });
3293
+ status.wait("Waiting for Codex source-shape suggestions");
3173
3294
  const suggestionResult = await suggestDataSourceShapeWithCodex({
3174
3295
  context: {
3175
3296
  currentIntrospection,
3176
- sheetSnapshot: await collectXlsxSheetSnapshot(options.inputPath, selectedSource, { maxRows: 24 })
3297
+ sheetSnapshot
3177
3298
  },
3178
3299
  currentBodyStartRow: currentIntrospection.selectedBodyStartRow,
3179
3300
  currentHeaderRow: currentIntrospection.selectedHeaderRow,
@@ -3181,6 +3302,7 @@ async function runCodexSourceShapeSuggestionFlow(runtime, options) {
3181
3302
  runner: options.sourceShapeSuggestionRunner,
3182
3303
  workingDirectory: runtime.cwd
3183
3304
  });
3305
+ status.stop();
3184
3306
  if (suggestionResult.errorMessage || !suggestionResult.shape || !suggestionResult.reasoningSummary) {
3185
3307
  const failure = classifySourceShapeSuggestionFailure(suggestionResult.errorMessage ?? "Codex did not return a valid source-shape suggestion.");
3186
3308
  throw new CliError(`${failure.prefix}: ${suggestionResult.errorMessage ?? "Codex did not return a valid source-shape suggestion."}`, {
@@ -3220,6 +3342,7 @@ async function runCodexSourceShapeSuggestionFlow(runtime, options) {
3220
3342
  runtime
3221
3343
  }));
3222
3344
  } finally {
3345
+ status.stop();
3223
3346
  connection?.closeSync();
3224
3347
  }
3225
3348
  }
@@ -3295,6 +3418,11 @@ async function actionDataExtract(runtime, options) {
3295
3418
  const format = detectDataQueryInputFormat(inputPath, options.inputFormat);
3296
3419
  const bodyStartRow = options.bodyStartRow;
3297
3420
  const headerRow = options.headerRow;
3421
+ const noHeader = options.noHeader === true;
3422
+ if (noHeader && format !== "csv" && format !== "tsv") throw new CliError("--no-header is only valid for CSV and TSV extract inputs.", {
3423
+ code: "INVALID_INPUT",
3424
+ exitCode: 2
3425
+ });
3298
3426
  const explicitRange = options.range?.trim() || void 0;
3299
3427
  const explicitSource = options.source?.trim() || void 0;
3300
3428
  if (options.codexSuggestShape) {
@@ -3309,6 +3437,7 @@ async function actionDataExtract(runtime, options) {
3309
3437
  return;
3310
3438
  }
3311
3439
  const resolvedSourceShape = options.sourceShape?.trim() ? await resolveReusableSourceShapeForDataFlow({
3440
+ commandName: "extract",
3312
3441
  format,
3313
3442
  inputPath,
3314
3443
  runtime,
@@ -3329,6 +3458,7 @@ async function actionDataExtract(runtime, options) {
3329
3458
  shape: {
3330
3459
  bodyStartRow: effectiveBodyStartRow,
3331
3460
  headerRow: effectiveHeaderRow,
3461
+ noHeader,
3332
3462
  range,
3333
3463
  source
3334
3464
  },
@@ -3338,6 +3468,7 @@ async function actionDataExtract(runtime, options) {
3338
3468
  collectIntrospection: async () => await collectDataQuerySourceIntrospection(connection, inputPath, format, {
3339
3469
  bodyStartRow: effectiveBodyStartRow,
3340
3470
  headerRow: effectiveHeaderRow,
3471
+ noHeader,
3341
3472
  range,
3342
3473
  source
3343
3474
  }, 5),
@@ -3360,6 +3491,7 @@ async function actionDataExtract(runtime, options) {
3360
3491
  shape: {
3361
3492
  ...effectiveBodyStartRow !== void 0 ? { bodyStartRow: effectiveBodyStartRow } : {},
3362
3493
  ...effectiveHeaderRow !== void 0 ? { headerRow: effectiveHeaderRow } : {},
3494
+ ...noHeader ? { noHeader: true } : {},
3363
3495
  range,
3364
3496
  source
3365
3497
  }
@@ -3371,6 +3503,7 @@ async function actionDataExtract(runtime, options) {
3371
3503
  bodyStartRow: effectiveBodyStartRow,
3372
3504
  headerMappings: resolvedHeaderMappings,
3373
3505
  headerRow: effectiveHeaderRow,
3506
+ noHeader,
3374
3507
  range,
3375
3508
  source
3376
3509
  });
@@ -3522,6 +3655,22 @@ function validateDataQueryOptions(options) {
3522
3655
  code: "INVALID_INPUT",
3523
3656
  exitCode: 2
3524
3657
  });
3658
+ if (options.sourceShape?.trim() && options.source?.trim()) throw new CliError("--source-shape cannot be used together with --source in the current replay flow.", {
3659
+ code: "INVALID_INPUT",
3660
+ exitCode: 2
3661
+ });
3662
+ if (options.sourceShape?.trim() && options.range?.trim()) throw new CliError("--source-shape cannot be used together with --range in the current replay flow.", {
3663
+ code: "INVALID_INPUT",
3664
+ exitCode: 2
3665
+ });
3666
+ if (options.sourceShape?.trim() && options.headerRow !== void 0) throw new CliError("--source-shape cannot be used together with --header-row in the current replay flow.", {
3667
+ code: "INVALID_INPUT",
3668
+ exitCode: 2
3669
+ });
3670
+ if (options.sourceShape?.trim() && options.bodyStartRow !== void 0) throw new CliError("--source-shape cannot be used together with --body-start-row in the current replay flow.", {
3671
+ code: "INVALID_INPUT",
3672
+ exitCode: 2
3673
+ });
3525
3674
  }
3526
3675
  function isDuckDbBuiltInQueryFormat(format) {
3527
3676
  return format === "csv" || format === "tsv" || format === "parquet";
@@ -3545,12 +3694,29 @@ async function actionDataQuery(runtime, options) {
3545
3694
  const format = detectDataQueryInputFormat(inputPath, options.inputFormat);
3546
3695
  const bodyStartRow = options.bodyStartRow;
3547
3696
  const headerRow = options.headerRow;
3697
+ const noHeader = options.noHeader === true;
3698
+ if (noHeader && format !== "csv" && format !== "tsv") throw new CliError("--no-header is only valid for CSV and TSV query inputs.", {
3699
+ code: "INVALID_INPUT",
3700
+ exitCode: 2
3701
+ });
3548
3702
  if (options.installMissingExtension && isDuckDbBuiltInQueryFormat(format)) throw new CliError("--install-missing-extension is only valid for extension-backed query formats (sqlite, excel).", {
3549
3703
  code: "INVALID_INPUT",
3550
3704
  exitCode: 2
3551
3705
  });
3552
- const range = options.range?.trim() || void 0;
3553
- const source = options.source?.trim() || void 0;
3706
+ const explicitRange = options.range?.trim() || void 0;
3707
+ const explicitSource = options.source?.trim() || void 0;
3708
+ const resolvedSourceShape = options.sourceShape?.trim() ? await resolveReusableSourceShapeForDataFlow({
3709
+ commandName: "query",
3710
+ format,
3711
+ inputPath,
3712
+ runtime,
3713
+ source: explicitSource,
3714
+ sourceShapePath: resolveFromCwd(runtime, options.sourceShape.trim())
3715
+ }) : void 0;
3716
+ const range = resolvedSourceShape?.range ?? explicitRange;
3717
+ const source = resolvedSourceShape?.source ?? explicitSource;
3718
+ const effectiveBodyStartRow = resolvedSourceShape?.bodyStartRow ?? bodyStartRow;
3719
+ const effectiveHeaderRow = resolvedSourceShape?.headerRow ?? headerRow;
3554
3720
  const rowCount = options.rows ?? DEFAULT_QUERY_ROWS;
3555
3721
  if (options.codexSuggestHeaders) {
3556
3722
  const collectSourceIntrospection = options.sourceIntrospectionCollector ?? collectDataQuerySourceIntrospection;
@@ -3561,18 +3727,20 @@ async function actionDataQuery(runtime, options) {
3561
3727
  format,
3562
3728
  inputPath,
3563
3729
  shape: {
3564
- bodyStartRow,
3730
+ bodyStartRow: effectiveBodyStartRow,
3565
3731
  range,
3566
- headerRow,
3732
+ headerRow: effectiveHeaderRow,
3733
+ noHeader,
3567
3734
  source
3568
3735
  },
3569
3736
  overwrite: options.overwrite,
3570
3737
  writeHeaderMapping: options.writeHeaderMapping,
3571
3738
  headerSuggestionRunner: options.headerSuggestionRunner,
3572
3739
  collectIntrospection: async () => await collectSourceIntrospection(connection, inputPath, format, {
3573
- bodyStartRow,
3740
+ bodyStartRow: effectiveBodyStartRow,
3574
3741
  range,
3575
- headerRow,
3742
+ headerRow: effectiveHeaderRow,
3743
+ noHeader,
3576
3744
  source
3577
3745
  }, DATA_QUERY_HEADER_SUGGESTION_SAMPLE_ROWS, {
3578
3746
  installMissingExtension: options.installMissingExtension,
@@ -3595,9 +3763,10 @@ async function actionDataQuery(runtime, options) {
3595
3763
  inputPath,
3596
3764
  runtime,
3597
3765
  shape: {
3598
- bodyStartRow,
3766
+ ...effectiveBodyStartRow !== void 0 ? { bodyStartRow: effectiveBodyStartRow } : {},
3599
3767
  range,
3600
- headerRow,
3768
+ ...effectiveHeaderRow !== void 0 ? { headerRow: effectiveHeaderRow } : {},
3769
+ noHeader,
3601
3770
  source
3602
3771
  }
3603
3772
  }) : void 0;
@@ -3606,9 +3775,10 @@ async function actionDataQuery(runtime, options) {
3606
3775
  try {
3607
3776
  connection = await createDuckDbConnection$1();
3608
3777
  const preparedSource = await prepareDataQuerySource(connection, inputPath, format, {
3609
- bodyStartRow,
3778
+ bodyStartRow: effectiveBodyStartRow,
3610
3779
  headerMappings: resolvedHeaderMappings,
3611
- headerRow,
3780
+ headerRow: effectiveHeaderRow,
3781
+ noHeader,
3612
3782
  range,
3613
3783
  source
3614
3784
  }, {
@@ -3651,86 +3821,6 @@ async function actionDataQuery(runtime, options) {
3651
3821
  }
3652
3822
  }
3653
3823
  //#endregion
3654
- //#region src/cli/interactive/analyzer-status.ts
3655
- const ANALYZER_WAITING_FRAMES = [
3656
- ". ",
3657
- ".. ",
3658
- "...",
3659
- ".. ",
3660
- ". "
3661
- ];
3662
- const ANALYZER_WAITING_INTERVAL_MS = 360;
3663
- function clearStatusLine(stream) {
3664
- stream.write("\r\x1B[2K");
3665
- }
3666
- function normalizeAnalyzerStatusMessage(message) {
3667
- if (message.includes("Sampling filenames")) return "sampling";
3668
- if (message.includes("Grouping filename patterns")) return "grouping";
3669
- if (message.includes("Waiting for Codex cleanup suggestions")) return "waiting";
3670
- return message;
3671
- }
3672
- function renderStatusLine(stream, message, colorEnabled) {
3673
- const pc = (0, import_picocolors.createColors)(colorEnabled);
3674
- const normalizedMessage = normalizeAnalyzerStatusMessage(message);
3675
- const content = ` ${pc.dim("Codex")} ${pc.white("Thinking...")} ${pc.dim(normalizedMessage)} `;
3676
- stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
3677
- }
3678
- function renderWaitingStatusLine(stream, message, tick, colorEnabled) {
3679
- const pc = (0, import_picocolors.createColors)(colorEnabled);
3680
- const normalizedMessage = normalizeAnalyzerStatusMessage(message);
3681
- const dots = ANALYZER_WAITING_FRAMES[tick % ANALYZER_WAITING_FRAMES.length] ?? "...";
3682
- const content = ` ${pc.dim("Codex")} ${pc.white("Thinking")} ${pc.dim(normalizedMessage)} ${pc.gray(dots)} `;
3683
- stream.write(`\r\x1b[2K${pc.bgBlack(content)}`);
3684
- }
3685
- function createInteractiveAnalyzerStatus(stream, colorEnabled = true) {
3686
- if (!stream.isTTY) return {
3687
- start(message) {
3688
- printLine(stream, message);
3689
- },
3690
- update(message) {
3691
- printLine(stream, message);
3692
- },
3693
- wait(message) {
3694
- printLine(stream, message);
3695
- },
3696
- stop() {}
3697
- };
3698
- let currentMessage = "";
3699
- let timer;
3700
- let tick = 0;
3701
- const stopTimer = () => {
3702
- if (!timer) return;
3703
- clearInterval(timer);
3704
- timer = void 0;
3705
- };
3706
- return {
3707
- start(message) {
3708
- stopTimer();
3709
- currentMessage = message;
3710
- renderStatusLine(stream, currentMessage, colorEnabled);
3711
- },
3712
- update(message) {
3713
- stopTimer();
3714
- currentMessage = message;
3715
- renderStatusLine(stream, currentMessage, colorEnabled);
3716
- },
3717
- wait(message) {
3718
- stopTimer();
3719
- currentMessage = message;
3720
- tick = 0;
3721
- renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
3722
- timer = setInterval(() => {
3723
- tick += 1;
3724
- renderWaitingStatusLine(stream, currentMessage, tick, colorEnabled);
3725
- }, ANALYZER_WAITING_INTERVAL_MS);
3726
- },
3727
- stop() {
3728
- stopTimer();
3729
- clearStatusLine(stream);
3730
- }
3731
- };
3732
- }
3733
- //#endregion
3734
3824
  //#region src/cli/data-query/codex.ts
3735
3825
  const DATA_QUERY_CODEX_OUTPUT_SCHEMA = {
3736
3826
  type: "object",
@@ -9626,6 +9716,13 @@ async function promptOptionalSourceSelection(format, sources) {
9626
9716
  }))
9627
9717
  });
9628
9718
  }
9719
+ async function promptDelimitedHeaderMode(format) {
9720
+ if (format !== "csv" && format !== "tsv") return;
9721
+ return await (0, _inquirer_prompts.confirm)({
9722
+ message: "Treat CSV/TSV input as headerless?",
9723
+ default: false
9724
+ });
9725
+ }
9629
9726
  //#endregion
9630
9727
  //#region src/cli/interactive/data-query/types.ts
9631
9728
  const QUERY_CONTINUATION_LABELS = {
@@ -9749,7 +9846,7 @@ function renderIntrospectionSummary(runtime, options) {
9749
9846
  }
9750
9847
  async function collectInteractiveIntrospection(options) {
9751
9848
  const labels = options.labels ?? QUERY_CONTINUATION_LABELS;
9752
- let sourceShape = {};
9849
+ let sourceShape = options.initialNoHeader ? { selectedNoHeader: true } : {};
9753
9850
  let cachedSheetSnapshot;
9754
9851
  const getSheetSnapshot = async () => {
9755
9852
  const selectedSource = options.selectedSource?.trim();
@@ -9767,6 +9864,7 @@ async function collectInteractiveIntrospection(options) {
9767
9864
  const introspection = await collectDataQuerySourceIntrospection(options.connection, options.inputPath, options.format, {
9768
9865
  bodyStartRow: sourceShape.selectedBodyStartRow,
9769
9866
  headerRow: sourceShape.selectedHeaderRow,
9867
+ noHeader: sourceShape.selectedNoHeader,
9770
9868
  range: sourceShape.selectedRange,
9771
9869
  source: options.selectedSource
9772
9870
  }, DATA_QUERY_INTERACTIVE_SAMPLE_ROWS$1);
@@ -9992,6 +10090,7 @@ async function reviewInteractiveHeaderMappings(options) {
9992
10090
  bodyStartRow: options.selectedBodyStartRow,
9993
10091
  headerMappings: acceptedMappings,
9994
10092
  headerRow: options.selectedHeaderRow,
10093
+ noHeader: options.selectedNoHeader,
9995
10094
  range: options.selectedRange,
9996
10095
  source: options.selectedSource
9997
10096
  }, DATA_QUERY_INTERACTIVE_SAMPLE_ROWS);
@@ -10121,6 +10220,7 @@ async function executeInteractiveCandidate(runtime, pathPromptContext, options)
10121
10220
  ...options.headerMappings ? { headerMappings: options.headerMappings } : {},
10122
10221
  ...options.selectedBodyStartRow !== void 0 ? { bodyStartRow: options.selectedBodyStartRow } : {},
10123
10222
  ...options.selectedHeaderRow !== void 0 ? { headerRow: options.selectedHeaderRow } : {},
10223
+ ...options.selectedNoHeader ? { noHeader: true } : {},
10124
10224
  ...options.selectedRange ? { range: options.selectedRange } : {},
10125
10225
  ...options.selectedSource ? { source: options.selectedSource } : {},
10126
10226
  sql: options.sql
@@ -10200,6 +10300,7 @@ async function runCodexInteractiveQuery(runtime, pathPromptContext, options) {
10200
10300
  input: options.input,
10201
10301
  selectedBodyStartRow: options.selectedBodyStartRow,
10202
10302
  selectedHeaderRow: options.selectedHeaderRow,
10303
+ selectedNoHeader: options.selectedNoHeader,
10203
10304
  selectedRange: options.selectedRange,
10204
10305
  selectedSource: options.selectedSource,
10205
10306
  sql: draftResult.draft.sql
@@ -10446,6 +10547,7 @@ async function runFormalGuideInteractiveQuery(runtime, pathPromptContext, option
10446
10547
  input: options.input,
10447
10548
  selectedBodyStartRow: options.selectedBodyStartRow,
10448
10549
  selectedHeaderRow: options.selectedHeaderRow,
10550
+ selectedNoHeader: options.selectedNoHeader,
10449
10551
  selectedRange: options.selectedRange,
10450
10552
  selectedSource: options.selectedSource,
10451
10553
  sql
@@ -10477,6 +10579,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
10477
10579
  });
10478
10580
  const inputPath = resolveFromCwd(runtime, input);
10479
10581
  const format = await promptInteractiveInputFormat(runtime, inputPath);
10582
+ const noHeader = await promptDelimitedHeaderMode(format);
10480
10583
  let connection;
10481
10584
  try {
10482
10585
  connection = await createDuckDbConnection$1();
@@ -10484,6 +10587,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
10484
10587
  const { introspection, sourceShape } = await collectInteractiveIntrospection({
10485
10588
  connection,
10486
10589
  format,
10590
+ initialNoHeader: noHeader,
10487
10591
  inputPath,
10488
10592
  labels: QUERY_CONTINUATION_LABELS,
10489
10593
  runtime,
@@ -10498,6 +10602,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
10498
10602
  runtime,
10499
10603
  selectedBodyStartRow: sourceShape.selectedBodyStartRow,
10500
10604
  selectedHeaderRow: sourceShape.selectedHeaderRow,
10605
+ selectedNoHeader: sourceShape.selectedNoHeader,
10501
10606
  selectedRange: sourceShape.selectedRange,
10502
10607
  selectedSource
10503
10608
  });
@@ -10525,6 +10630,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
10525
10630
  input,
10526
10631
  selectedBodyStartRow: sourceShape.selectedBodyStartRow,
10527
10632
  selectedHeaderRow: sourceShape.selectedHeaderRow,
10633
+ selectedNoHeader: sourceShape.selectedNoHeader,
10528
10634
  selectedRange: sourceShape.selectedRange,
10529
10635
  selectedSource
10530
10636
  });
@@ -10538,6 +10644,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
10538
10644
  headerMappings: reviewedHeaders.headerMappings,
10539
10645
  selectedBodyStartRow: sourceShape.selectedBodyStartRow,
10540
10646
  selectedHeaderRow: sourceShape.selectedHeaderRow,
10647
+ selectedNoHeader: sourceShape.selectedNoHeader,
10541
10648
  selectedRange: sourceShape.selectedRange,
10542
10649
  selectedSource
10543
10650
  });
@@ -10550,6 +10657,7 @@ async function runInteractiveDataQuery(runtime, pathPromptContext) {
10550
10657
  headerMappings: reviewedHeaders.headerMappings,
10551
10658
  selectedBodyStartRow: sourceShape.selectedBodyStartRow,
10552
10659
  selectedHeaderRow: sourceShape.selectedHeaderRow,
10660
+ selectedNoHeader: sourceShape.selectedNoHeader,
10553
10661
  selectedRange: sourceShape.selectedRange,
10554
10662
  selectedSource
10555
10663
  });
@@ -10653,6 +10761,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
10653
10761
  });
10654
10762
  const inputPath = resolveFromCwd(runtime, input);
10655
10763
  const format = await promptInteractiveInputFormat(runtime, inputPath);
10764
+ const noHeader = await promptDelimitedHeaderMode(format);
10656
10765
  let connection;
10657
10766
  try {
10658
10767
  connection = await createDuckDbConnection$1();
@@ -10660,6 +10769,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
10660
10769
  const { introspection, sourceShape } = await collectInteractiveIntrospection({
10661
10770
  connection,
10662
10771
  format,
10772
+ initialNoHeader: noHeader,
10663
10773
  inputPath,
10664
10774
  labels: EXTRACT_CONTINUATION_LABELS,
10665
10775
  runtime,
@@ -10674,6 +10784,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
10674
10784
  runtime,
10675
10785
  selectedBodyStartRow: sourceShape.selectedBodyStartRow,
10676
10786
  selectedHeaderRow: sourceShape.selectedHeaderRow,
10787
+ selectedNoHeader: sourceShape.selectedNoHeader,
10677
10788
  selectedRange: sourceShape.selectedRange,
10678
10789
  selectedSource
10679
10790
  });
@@ -10690,6 +10801,7 @@ async function runInteractiveDataExtract(runtime, pathPromptContext) {
10690
10801
  ...reviewedHeaders.headerMappings ? { headerMappings: reviewedHeaders.headerMappings } : {},
10691
10802
  input,
10692
10803
  inputFormat: format,
10804
+ ...sourceShape.selectedNoHeader ? { noHeader: true } : {},
10693
10805
  output: outputOptions.output,
10694
10806
  overwrite: outputOptions.overwrite,
10695
10807
  ...sourceShape.selectedBodyStartRow !== void 0 ? { bodyStartRow: sourceShape.selectedBodyStartRow } : {},
@@ -12362,7 +12474,7 @@ function registerDataDuckDbCommands(dataCommand, runtime) {
12362
12474
  //#endregion
12363
12475
  //#region src/cli/commands/data/extract.ts
12364
12476
  function registerDataExtractCommand(dataCommand, runtime) {
12365
- dataCommand.command("extract").description("Materialize one shaped table from one input file").argument("<input>", "Input data file").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--source-shape <path>", "Reuse an accepted JSON source-shape artifact").option("--codex-suggest-shape", "Ask Codex to suggest an explicit Excel source shape and stop after writing the review artifact", false).option("--write-source-shape <path>", "Write the suggested source-shape artifact to an explicit path").option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("-o, --output <path>", "Write the shaped table to a .csv, .tsv, or .json file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
12477
+ dataCommand.command("extract").description("Materialize one shaped table from one input file").argument("<input>", "Input data file").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--no-header", "Treat CSV or TSV input as headerless and generate column_n names").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--source-shape <path>", "Reuse an accepted JSON source-shape artifact").option("--codex-suggest-shape", "Ask Codex to suggest an explicit Excel source shape and stop after writing the review artifact", false).option("--write-source-shape <path>", "Write the suggested source-shape artifact to an explicit path").option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("-o, --output <path>", "Write the shaped table to a .csv, .tsv, or .json file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
12366
12478
  await actionDataExtract(runtime, {
12367
12479
  bodyStartRow: options.bodyStartRow,
12368
12480
  codexSuggestShape: options.codexSuggestShape,
@@ -12371,6 +12483,7 @@ function registerDataExtractCommand(dataCommand, runtime) {
12371
12483
  headerRow: options.headerRow,
12372
12484
  input,
12373
12485
  inputFormat: options.inputFormat,
12486
+ noHeader: options.noHeader ?? options.header === false,
12374
12487
  output: options.output,
12375
12488
  overwrite: options.overwrite,
12376
12489
  range: options.range,
@@ -12406,7 +12519,7 @@ function registerDataPreviewCommands(dataCommand, runtime) {
12406
12519
  //#endregion
12407
12520
  //#region src/cli/commands/data/query.ts
12408
12521
  function registerDataQueryCommands(dataCommand, runtime) {
12409
- dataCommand.command("query").description("Run a DuckDB-backed SQL query against one input file").argument("<input>", "Input data file").option("--sql <query>", "SQL query to execute against logical table `file`").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("--install-missing-extension", "Attempt one DuckDB extension install-and-retry for sqlite/excel inputs", false).option("--rows <value>", "Number of rows to show in bounded table output", (value) => parsePositiveIntegerOption(value, "--rows")).option("--json", "Write full query results as JSON to stdout", false).option("--pretty", "Pretty-print JSON stdout or .json file output", false).option("-o, --output <path>", "Write full query results to a .json or .csv file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
12522
+ dataCommand.command("query").description("Run a DuckDB-backed SQL query against one input file").argument("<input>", "Input data file").option("--sql <query>", "SQL query to execute against logical table `file`").option("--input-format <format>", `Override detected input format (${DATA_QUERY_INPUT_FORMAT_VALUES.join(", ")})`, parseDataQueryInputFormatOption).option("--source <name>", "Source object name for SQLite tables/views or Excel sheets").option("--range <A1:Z99>", "Excel cell range within the selected sheet").option("--source-shape <path>", "Reuse an accepted JSON source-shape artifact for Excel query replay").option("--no-header", "Treat CSV or TSV input as headerless and generate column_n names").option("--body-start-row <value>", "Excel worksheet row number where logical body rows begin", (value) => parsePositiveIntegerOption(value, "--body-start-row")).option("--header-row <value>", "Excel worksheet row number to treat as the header row", (value) => parsePositiveIntegerOption(value, "--header-row")).option("--header-mapping <path>", "Reuse an accepted JSON header-mapping artifact").option("--codex-suggest-headers", "Ask Codex to suggest semantic header mappings and stop after writing the review artifact", false).option("--write-header-mapping <path>", "Write the suggested header-mapping artifact to an explicit path").option("--install-missing-extension", "Attempt one DuckDB extension install-and-retry for sqlite/excel inputs", false).option("--rows <value>", "Number of rows to show in bounded table output", (value) => parsePositiveIntegerOption(value, "--rows")).option("--json", "Write full query results as JSON to stdout", false).option("--pretty", "Pretty-print JSON stdout or .json file output", false).option("-o, --output <path>", "Write full query results to a .json or .csv file").option("--overwrite", "Overwrite output file if it already exists", false).action(async (input, options) => {
12410
12523
  await actionDataQuery(runtime, {
12411
12524
  bodyStartRow: options.bodyStartRow,
12412
12525
  codexSuggestHeaders: options.codexSuggestHeaders,
@@ -12416,11 +12529,13 @@ function registerDataQueryCommands(dataCommand, runtime) {
12416
12529
  inputFormat: options.inputFormat,
12417
12530
  installMissingExtension: options.installMissingExtension,
12418
12531
  json: options.json,
12532
+ noHeader: options.noHeader ?? options.header === false,
12419
12533
  output: options.output,
12420
12534
  overwrite: options.overwrite,
12421
12535
  pretty: options.pretty,
12422
12536
  range: options.range,
12423
12537
  rows: options.rows,
12538
+ sourceShape: options.sourceShape,
12424
12539
  source: options.source,
12425
12540
  sql: options.sql,
12426
12541
  writeHeaderMapping: options.writeHeaderMapping
@@ -12587,7 +12702,7 @@ function registerCliCommands(program, runtime) {
12587
12702
  }
12588
12703
  //#endregion
12589
12704
  //#region src/cli/program/version-embedded.ts
12590
- const EMBEDDED_PACKAGE_VERSION = "0.0.8";
12705
+ const EMBEDDED_PACKAGE_VERSION = "0.0.9-canary.2";
12591
12706
  //#endregion
12592
12707
  //#region src/cli/program/version.ts
12593
12708
  function* candidateSearchRoots() {
@@ -12620,7 +12735,7 @@ function normalizeVersion(value) {
12620
12735
  return trimmed;
12621
12736
  }
12622
12737
  function resolvePackageVersion(options = {}) {
12623
- const embeddedVersion = normalizeVersion(options.embeddedVersion ?? "0.0.8");
12738
+ const embeddedVersion = normalizeVersion(options.embeddedVersion ?? "0.0.9-canary.2");
12624
12739
  if (embeddedVersion) return embeddedVersion;
12625
12740
  const maxLevels = options.maxLevels ?? 8;
12626
12741
  const resolveFromPath = options.resolveFromPath ?? resolveVersionFromPath;