fluncle 0.43.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/fluncle.mjs +49 -21
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -2539,7 +2539,7 @@ function parseVersion(version) {
2539
2539
  var currentVersion;
2540
2540
  var init_version = __esm(() => {
2541
2541
  init_output();
2542
- currentVersion = "0.43.0".trim() ? "0.43.0".trim() : "0.1.0";
2542
+ currentVersion = "0.45.0".trim() ? "0.45.0".trim() : "0.1.0";
2543
2543
  });
2544
2544
 
2545
2545
  // src/update-notifier.ts
@@ -4001,7 +4001,7 @@ function parseVersion2(version) {
4001
4001
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
4002
4002
  var init_version2 = __esm(() => {
4003
4003
  init_output();
4004
- currentVersion2 = "0.43.0".trim() ? "0.43.0".trim() : "0.1.0";
4004
+ currentVersion2 = "0.45.0".trim() ? "0.45.0".trim() : "0.1.0";
4005
4005
  });
4006
4006
 
4007
4007
  // src/commands/track.ts
@@ -4216,7 +4216,7 @@ async function enrichQueueCommand(limit) {
4216
4216
  return fetchAdminTracks({ max: limit, order: "asc", status: "queue" });
4217
4217
  }
4218
4218
  async function enrichSweepCommand(limit) {
4219
- return adminApiPost(`/api/admin/enrich-sweep?limit=${limit}`);
4219
+ return adminApiPost(`/api/admin/tracks/enrich?limit=${limit}`);
4220
4220
  }
4221
4221
  async function backfillLastfmCommand(limit, dryRun, cursor) {
4222
4222
  const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
@@ -5383,30 +5383,55 @@ function addAdminCommands(program2) {
5383
5383
  admin.command("help", { hidden: true }).description("display help for command").action(() => {
5384
5384
  admin.outputHelp();
5385
5385
  });
5386
- admin.command("add").description("Publish a Spotify track").argument("[spotifyUrl]").option("--note <text>", "Operator note").option("--dry-run", "Preview without publishing", false).option("--json", "Print JSON", false).allowExcessArguments().action(async (spotifyUrl, options) => {
5386
+ const adminTracks = configureCommand(admin.command("tracks").alias("track").description("Track admin commands"));
5387
+ adminTracks.action(() => {
5388
+ adminTracks.outputHelp();
5389
+ });
5390
+ adminTracks.command("publish").description("Publish a Spotify track").argument("[spotifyUrl]").option("--note <text>", "Operator note").option("--dry-run", "Preview without publishing", false).option("--json", "Print JSON", false).allowExcessArguments().action(async (spotifyUrl, options) => {
5387
5391
  const { addCommand: addCommand3 } = await Promise.resolve().then(() => (init_add(), exports_add));
5388
5392
  await runAdd(spotifyUrl, options, addCommand3);
5389
5393
  });
5390
- admin.command("queue").description("Findings awaiting a video, oldest first (the next to film is first)").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5394
+ admin.command("add", { hidden: true }).description("Publish a Spotify track (alias of `admin tracks publish`)").argument("[spotifyUrl]").option("--note <text>", "Operator note").option("--dry-run", "Preview without publishing", false).option("--json", "Print JSON", false).allowExcessArguments().action(async (spotifyUrl, options) => {
5395
+ const { addCommand: addCommand3 } = await Promise.resolve().then(() => (init_add(), exports_add));
5396
+ await runAdd(spotifyUrl, options, addCommand3);
5397
+ });
5398
+ adminTracks.command("queue").description("Findings awaiting a video, oldest first (the next to film is first)").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5391
5399
  const { queueCommand: queueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5392
5400
  await runAdminQueue(options, queueCommand2);
5393
5401
  });
5394
- admin.command("enrich-queue").description("Findings needing (re-)enrichment: pending, failed, or stuck processing").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5402
+ admin.command("queue", { hidden: true }).description("Render queue (alias of `admin tracks queue`)").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5403
+ const { queueCommand: queueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5404
+ await runAdminQueue(options, queueCommand2);
5405
+ });
5406
+ adminTracks.command("enrich-queue").description("Findings needing (re-)enrichment: pending, failed, or stuck processing").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5395
5407
  const { enrichQueueCommand: enrichQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5396
5408
  await runAdminEnrichQueue(options, enrichQueueCommand2);
5397
5409
  });
5398
- admin.command("enrich-sweep").description("Re-fire enrichment for everything in the enrich-queue (idempotent self-heal)").option("--limit <limit>", "Max findings to re-trigger", "25").option("--json", "Print JSON", false).action(async (options) => {
5410
+ admin.command("enrich-queue", { hidden: true }).description("Enrich queue (alias of `admin tracks enrich-queue`)").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5411
+ const { enrichQueueCommand: enrichQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5412
+ await runAdminEnrichQueue(options, enrichQueueCommand2);
5413
+ });
5414
+ adminTracks.command("enrich").description("Re-fire enrichment for everything in the enrich-queue (--all; idempotent self-heal)").option("--all", "Sweep the whole enrich-queue (required)", false).option("--limit <limit>", "Max findings to re-trigger", "25").option("--json", "Print JSON", false).action(async (options) => {
5415
+ const { enrichSweepCommand: enrichSweepCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5416
+ await runAdminEnrich(options, enrichSweepCommand2);
5417
+ });
5418
+ adminTracks.command("enrich-sweep", { hidden: true }).description("Enrich sweep (alias of `admin tracks enrich --all`)").option("--limit <limit>", "Max findings to re-trigger", "25").option("--json", "Print JSON", false).action(async (options) => {
5419
+ const { enrichSweepCommand: enrichSweepCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5420
+ await runAdminEnrich({ ...options, all: true }, enrichSweepCommand2);
5421
+ });
5422
+ admin.command("enrich-sweep", { hidden: true }).description("Enrich sweep (alias of `admin tracks enrich --all`)").option("--limit <limit>", "Max findings to re-trigger", "25").option("--json", "Print JSON", false).action(async (options) => {
5399
5423
  const { enrichSweepCommand: enrichSweepCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5400
- await runAdminEnrichSweep(options, enrichSweepCommand2);
5424
+ await runAdminEnrich({ ...options, all: true }, enrichSweepCommand2);
5401
5425
  });
5402
- admin.command("vehicles").description("Recent video vehicles, newest first (the style ledger for diversity)").option("--limit <limit>", "Number of vehicles to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5426
+ adminTracks.command("vehicles").description("Recent video vehicles, newest first (the style ledger for diversity)").option("--limit <limit>", "Number of vehicles to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5403
5427
  const { vehiclesCommand: vehiclesCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5404
5428
  await runAdminVehicles(options, vehiclesCommand2);
5405
5429
  });
5406
- const adminTrack = configureCommand(admin.command("track").description("Track admin commands"));
5407
- adminTrack.action(() => {
5408
- adminTrack.outputHelp();
5430
+ admin.command("vehicles", { hidden: true }).description("Video vehicles (alias of `admin tracks vehicles`)").option("--limit <limit>", "Number of vehicles to show", "10").option("--json", "Print JSON", false).action(async (options) => {
5431
+ const { vehiclesCommand: vehiclesCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5432
+ await runAdminVehicles(options, vehiclesCommand2);
5409
5433
  });
5434
+ const adminTrack = adminTracks;
5410
5435
  adminTrack.command("update").description("Certify a track into the archive").argument("[trackId]").option("--bpm <number>", "Track BPM").option("--features <json>", "Audio feature JSON").option("--json", "Print JSON", false).option("--key <key>", "Musical key").option("--note <text>", "Operator note").option("--status <status>", "Enrichment status").option("--video-url <url>", "Rendered video URL").allowExcessArguments().action(async (trackId, options) => {
5411
5436
  const { trackUpdateCommand: trackUpdateCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5412
5437
  await runTrackUpdate(trackId, options, trackUpdateCommand2);
@@ -5423,7 +5448,7 @@ function addAdminCommands(program2) {
5423
5448
  const { trackSocialShowCommand: trackSocialShowCommand2, trackSocialUpdateCommand: trackSocialUpdateCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5424
5449
  await runTrackSocial(idOrLogId, options, trackSocialShowCommand2, trackSocialUpdateCommand2);
5425
5450
  });
5426
- adminTrack.command("preview-archive").description("Store one official preview at the operator-only archive path for analysis").argument("[idOrLogId]").option("--file <file>", "Preview audio file to archive").option("--mime <mime>", "MIME type of the preview audio").option("--source <source>", "Provenance label for the archived preview").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
5451
+ adminTrack.command("preview").alias("preview-archive").description("Store one official preview at the operator-only archive path for analysis").argument("[idOrLogId]").option("--file <file>", "Preview audio file to archive").option("--mime <mime>", "MIME type of the preview audio").option("--source <source>", "Provenance label for the archived preview").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
5427
5452
  const { previewArchiveUploadCommand: previewArchiveUploadCommand2 } = await Promise.resolve().then(() => (init_preview_archive(), exports_preview_archive));
5428
5453
  await runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCommand2);
5429
5454
  });
@@ -5514,7 +5539,7 @@ function addAdminCommands(program2) {
5514
5539
  const { authLastfmCommand: authLastfmCommand2 } = await Promise.resolve().then(() => (init_auth_lastfm(), exports_auth_lastfm));
5515
5540
  await authLastfmCommand2(options);
5516
5541
  });
5517
- const backfill = configureCommand(admin.command("backfill").description("Backfill operator-only archives"));
5542
+ const backfill = configureCommand(admin.command("backfills").alias("backfill").description("Backfill operator-only archives"));
5518
5543
  backfill.action(() => {
5519
5544
  backfill.outputHelp();
5520
5545
  });
@@ -5533,7 +5558,7 @@ function addAdminCommands(program2) {
5533
5558
  }
5534
5559
  async function runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCommand2) {
5535
5560
  if (!idOrLogId || !options.file || !options.source || !options.mime) {
5536
- throw new Error("Usage: fluncle admin track preview-archive <track_id|log_id> --file <file> --source <source> --mime <mime> [--json]");
5561
+ throw new Error("Usage: fluncle admin tracks preview <track_id|log_id> --file <file> --source <source> --mime <mime> [--json]");
5537
5562
  }
5538
5563
  const result = await previewArchiveUploadCommand2(idOrLogId, {
5539
5564
  file: options.file,
@@ -5552,7 +5577,7 @@ async function runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCo
5552
5577
  async function runTrackObserve(idOrLogId, options, trackObserveCommand2) {
5553
5578
  const script = options.scriptFile ? readFileSync2(options.scriptFile, "utf8") : options.script;
5554
5579
  if (!idOrLogId || !script || !script.trim()) {
5555
- throw new Error("Usage: fluncle admin track observe <track_id|log_id> (--script <text> | --script-file <file>) [--voice-id <id>] [--model <model>] [--duration-ms <ms>] [--context-note <text>] [--json]");
5580
+ throw new Error("Usage: fluncle admin tracks observe <track_id|log_id> (--script <text> | --script-file <file>) [--voice-id <id>] [--model <model>] [--duration-ms <ms>] [--context-note <text>] [--json]");
5556
5581
  }
5557
5582
  const durationMs = options.durationMs === undefined ? undefined : Number.parseInt(options.durationMs, 10);
5558
5583
  if (durationMs !== undefined && (!Number.isInteger(durationMs) || durationMs < 1)) {
@@ -5681,7 +5706,7 @@ async function runBackfillDiscogs(options, backfillDiscogsCommand2) {
5681
5706
  }
5682
5707
  async function runTrackVideo(idOrLogId, options, trackVideoCommand2) {
5683
5708
  if (!idOrLogId) {
5684
- throw new Error("Missing id. Usage: fluncle admin track video <track_id|log_id> (--dir <dir> | --footage <file> [--footage-social <file>] [--footage-silent <file>] [--poster <file>] [--cover <file>] [--note <file>] [--composition <file>] [--props <file>] [--render <file>])");
5709
+ throw new Error("Missing id. Usage: fluncle admin tracks video <track_id|log_id> (--dir <dir> | --footage <file> [--footage-social <file>] [--footage-silent <file>] [--poster <file>] [--cover <file>] [--note <file>] [--composition <file>] [--props <file>] [--render <file>])");
5685
5710
  }
5686
5711
  const dir = options.dir ? path.resolve(process.cwd(), options.dir) : undefined;
5687
5712
  const fromDir = (name) => {
@@ -5726,7 +5751,7 @@ async function runTrackVideo(idOrLogId, options, trackVideoCommand2) {
5726
5751
  }
5727
5752
  async function runTrackDraft(idOrLogId, options, trackDraftCommand2) {
5728
5753
  if (!idOrLogId) {
5729
- throw new Error("Missing id. Usage: fluncle admin track draft <track_id|log_id> [--platform tiktok]");
5754
+ throw new Error("Missing id. Usage: fluncle admin tracks draft <track_id|log_id> [--platform tiktok]");
5730
5755
  }
5731
5756
  const platform2 = options.platform ?? "tiktok";
5732
5757
  const result = await trackDraftCommand2(idOrLogId, platform2);
@@ -5738,7 +5763,7 @@ async function runTrackDraft(idOrLogId, options, trackDraftCommand2) {
5738
5763
  }
5739
5764
  async function runTrackSocial(idOrLogId, options, trackSocialShowCommand2, trackSocialUpdateCommand2) {
5740
5765
  if (!idOrLogId) {
5741
- throw new Error("Missing id. Usage: fluncle admin track social <track_id|log_id> [--platform tiktok] [--status scheduled|published [--url <url>]]");
5766
+ throw new Error("Missing id. Usage: fluncle admin tracks social <track_id|log_id> [--platform tiktok] [--status scheduled|published [--url <url>]]");
5742
5767
  }
5743
5768
  if (!options.status) {
5744
5769
  const result2 = await trackSocialShowCommand2(idOrLogId);
@@ -5801,7 +5826,7 @@ async function runTrackGet(idOrLogId, options, trackGetCommand2) {
5801
5826
  }
5802
5827
  async function runTrackUpdate(trackId, options, trackUpdateCommand2) {
5803
5828
  if (!trackId) {
5804
- throw new Error("Missing track id. Usage: fluncle admin track update <track_id>");
5829
+ throw new Error("Missing track id. Usage: fluncle admin tracks update <track_id>");
5805
5830
  }
5806
5831
  const bpm = options.bpm === undefined ? undefined : Number(options.bpm);
5807
5832
  if (bpm !== undefined && !Number.isFinite(bpm)) {
@@ -6068,7 +6093,10 @@ async function runAdminEnrichQueue(options, enrichQueueCommand2) {
6068
6093
  console.log(trackRows2(tracks).join(`
6069
6094
  `));
6070
6095
  }
6071
- async function runAdminEnrichSweep(options, enrichSweepCommand2) {
6096
+ async function runAdminEnrich(options, enrichSweepCommand2) {
6097
+ if (!options.all) {
6098
+ throw new Error("Usage: fluncle admin tracks enrich --all [--limit 25] [--json] (sweeps the whole enrich-queue)");
6099
+ }
6072
6100
  const limit = parseListLimit(options.limit);
6073
6101
  const result = await enrichSweepCommand2(limit);
6074
6102
  if (options.json) {
package/package.json CHANGED
@@ -31,5 +31,5 @@
31
31
  "url": "git+https://github.com/mauricekleine/fluncle.git"
32
32
  },
33
33
  "type": "module",
34
- "version": "0.43.0"
34
+ "version": "0.45.0"
35
35
  }