fluncle 0.57.0 → 0.59.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 +47 -62
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -423,7 +423,7 @@ function parseVersion(version) {
423
423
  var currentVersion;
424
424
  var init_version = __esm(() => {
425
425
  init_output();
426
- currentVersion = "0.57.0".trim() ? "0.57.0".trim() : "0.1.0";
426
+ currentVersion = "0.59.0".trim() ? "0.59.0".trim() : "0.1.0";
427
427
  });
428
428
 
429
429
  // src/update-notifier.ts
@@ -782,6 +782,7 @@ function mapTrack(track) {
782
782
  title: track.title,
783
783
  trackId: track.trackId,
784
784
  type: "finding",
785
+ videoGrain: track.videoGrain,
785
786
  videoModel: track.videoModel,
786
787
  videoModelReasoning: track.videoModelReasoning,
787
788
  videoUrl: track.videoUrl,
@@ -1531,6 +1532,7 @@ function mapTrack2(track) {
1531
1532
  title: track.title,
1532
1533
  trackId: track.trackId,
1533
1534
  type: "finding",
1535
+ videoGrain: track.videoGrain,
1534
1536
  videoModel: track.videoModel,
1535
1537
  videoModelReasoning: track.videoModelReasoning,
1536
1538
  videoUrl: track.videoUrl,
@@ -1912,7 +1914,7 @@ function parseVersion2(version) {
1912
1914
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
1913
1915
  var init_version2 = __esm(() => {
1914
1916
  init_output();
1915
- currentVersion2 = "0.57.0".trim() ? "0.57.0".trim() : "0.1.0";
1917
+ currentVersion2 = "0.59.0".trim() ? "0.59.0".trim() : "0.1.0";
1916
1918
  });
1917
1919
 
1918
1920
  // src/commands/track.ts
@@ -1922,6 +1924,8 @@ __export(exports_track, {
1922
1924
  trackUpdateCommand: () => trackUpdateCommand,
1923
1925
  trackSocialUpdateCommand: () => trackSocialUpdateCommand,
1924
1926
  trackSocialShowCommand: () => trackSocialShowCommand,
1927
+ trackRequeueVideoCommand: () => trackRequeueVideoCommand,
1928
+ trackPurgeVideoCommand: () => trackPurgeVideoCommand,
1925
1929
  trackObserveCommand: () => trackObserveCommand,
1926
1930
  trackNoteCommand: () => trackNoteCommand,
1927
1931
  trackGetCommand: () => trackGetCommand,
@@ -1964,7 +1968,8 @@ async function trackVideoCommand(idOrLogId, files, onProgress) {
1964
1968
  videoModel,
1965
1969
  videoModelReasoning,
1966
1970
  ...squared ? { squared: true } : {},
1967
- ...manifest.vehicle ? { videoVehicle: manifest.vehicle } : {}
1971
+ ...manifest.vehicle ? { videoVehicle: manifest.vehicle } : {},
1972
+ ...manifest.grain ? { videoGrain: manifest.grain } : {}
1968
1973
  });
1969
1974
  return { logId: finalize.logId, ok: true, trackId: finalize.trackId, urls };
1970
1975
  }
@@ -1972,7 +1977,7 @@ async function readManifestFields(renderPath) {
1972
1977
  try {
1973
1978
  const manifest = await Bun.file(renderPath).json();
1974
1979
  const result = {};
1975
- for (const key of ["vehicle", "model", "reasoning"]) {
1980
+ for (const key of ["vehicle", "grain", "model", "reasoning"]) {
1976
1981
  const value = manifest[key];
1977
1982
  if (typeof value === "string" && value.trim()) {
1978
1983
  result[key] = value.trim().slice(0, 120);
@@ -2020,6 +2025,12 @@ async function trackUpdateCommand(trackId, options) {
2020
2025
  }
2021
2026
  return adminApiPatch(`/api/admin/tracks/${encodeURIComponent(trackId)}`, body);
2022
2027
  }
2028
+ async function trackRequeueVideoCommand(idOrLogId) {
2029
+ return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/video/requeue`);
2030
+ }
2031
+ async function trackPurgeVideoCommand(idOrLogId) {
2032
+ return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/video/purge`);
2033
+ }
2023
2034
  async function trackObserveCommand(idOrLogId, options) {
2024
2035
  const body = { script: options.script };
2025
2036
  if (options.voiceId !== undefined) {
@@ -2106,8 +2117,7 @@ __export(exports_admin_tracks, {
2106
2117
  enrichQueueCommand: () => enrichQueueCommand,
2107
2118
  contextQueueCommand: () => contextQueueCommand,
2108
2119
  backfillLastfmCommand: () => backfillLastfmCommand,
2109
- backfillDiscogsCommand: () => backfillDiscogsCommand,
2110
- backfillAlignmentCommand: () => backfillAlignmentCommand
2120
+ backfillDiscogsCommand: () => backfillDiscogsCommand
2111
2121
  });
2112
2122
  async function fetchAdminTracks(options) {
2113
2123
  const { hasContext, hasNote, hasObservation, hasVideo, max, order, status } = options;
@@ -2193,18 +2203,12 @@ async function backfillDiscogsCommand(limit, dryRun, cursor) {
2193
2203
  }
2194
2204
  return adminApiPost(`/api/admin/backfill/discogs?${params.toString()}`);
2195
2205
  }
2196
- async function backfillAlignmentCommand(limit, dryRun, cursor) {
2197
- const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
2198
- if (cursor) {
2199
- params.set("cursor", cursor);
2200
- }
2201
- return adminApiPost(`/api/admin/backfill/alignment?${params.toString()}`);
2202
- }
2203
2206
  async function vehiclesCommand(limit) {
2204
2207
  const tracks = await fetchAdminTracks({ hasVideo: true, max: limit, order: "desc" });
2205
2208
  return tracks.map((track) => ({
2206
2209
  addedAt: track.addedAt,
2207
2210
  artists: track.artists,
2211
+ grain: track.videoGrain,
2208
2212
  logId: track.logId,
2209
2213
  title: track.title,
2210
2214
  vehicle: track.videoVehicle
@@ -5490,6 +5494,14 @@ function addAdminCommands(program2) {
5490
5494
  const { trackVideoCommand: trackVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5491
5495
  await runTrackVideo(idOrLogId, options, trackVideoCommand2);
5492
5496
  });
5497
+ adminTrack.command("requeue-video").description("Clear a finding's video so it re-enters the render queue (operator)").argument("[idOrLogId]").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
5498
+ const { trackRequeueVideoCommand: trackRequeueVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5499
+ await runTrackRequeueVideo(idOrLogId, options, trackRequeueVideoCommand2);
5500
+ });
5501
+ adminTrack.command("purge-video").description("Purge a finding's stale Cloudflare video renditions from the edge (operator)").argument("[idOrLogId]").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
5502
+ const { trackPurgeVideoCommand: trackPurgeVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5503
+ await runTrackPurgeVideo(idOrLogId, options, trackPurgeVideoCommand2);
5504
+ });
5493
5505
  adminTrack.command("draft").description("Push the video to a platform as a draft").argument("[idOrLogId]").option("--json", "Print JSON", false).option("--platform <platform>", "Publishing platform").allowExcessArguments().action(async (idOrLogId, options) => {
5494
5506
  const { trackDraftCommand: trackDraftCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5495
5507
  await runTrackDraft(idOrLogId, options, trackDraftCommand2);
@@ -5648,10 +5660,6 @@ function addAdminCommands(program2) {
5648
5660
  const { backfillDiscogsCommand: backfillDiscogsCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5649
5661
  await runBackfillDiscogs(options, backfillDiscogsCommand2);
5650
5662
  });
5651
- backfill.command("alignment").description("Back-fill word-level caption timings for observations rendered before timestamps (no re-render)").option("--dry-run", "Report the eligible set but align nothing", false).option("--limit <limit>", "Max observations to align", "50").option("--json", "Print JSON", false).action(async (options) => {
5652
- const { backfillAlignmentCommand: backfillAlignmentCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
5653
- await runBackfillAlignment(options, backfillAlignmentCommand2);
5654
- });
5655
5663
  }
5656
5664
  async function runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCommand2) {
5657
5665
  if (!idOrLogId || !options.file || !options.source || !options.mime) {
@@ -5852,51 +5860,6 @@ async function runBackfillDiscogs(options, backfillDiscogsCommand2) {
5852
5860
  console.log(` ${item.logId}: release ${item.releaseId}${master}`);
5853
5861
  }
5854
5862
  }
5855
- async function runBackfillAlignment(options, backfillAlignmentCommand2) {
5856
- const limit = parseListLimit(options.limit);
5857
- const aligned = [];
5858
- const empty = [];
5859
- const failed = [];
5860
- let cursor;
5861
- let dryRun = options.dryRun;
5862
- while (aligned.length + empty.length + failed.length < limit) {
5863
- const remaining = limit - (aligned.length + empty.length + failed.length);
5864
- const result = await backfillAlignmentCommand2(remaining, options.dryRun, cursor);
5865
- dryRun = result.dryRun;
5866
- aligned.push(...result.aligned);
5867
- empty.push(...result.empty);
5868
- failed.push(...result.failed);
5869
- if (!options.json) {
5870
- const verb2 = result.dryRun ? "would align" : "aligned";
5871
- console.log(` \u2026${verb2} ${result.alignedCount}; ${result.emptyCount} empty; ${result.failedCount} failed`);
5872
- }
5873
- if (result.nextCursor === null) {
5874
- break;
5875
- }
5876
- cursor = result.nextCursor;
5877
- }
5878
- if (options.json) {
5879
- printJson({
5880
- aligned,
5881
- alignedCount: aligned.length,
5882
- dryRun,
5883
- empty,
5884
- emptyCount: empty.length,
5885
- failed,
5886
- failedCount: failed.length,
5887
- ok: true
5888
- });
5889
- return;
5890
- }
5891
- const verb = dryRun ? "Would align" : "Aligned";
5892
- console.log(`${verb} ${aligned.length} observation(s); ${empty.length} empty; ${failed.length} failed.`);
5893
- for (const logId of aligned) {
5894
- console.log(` ${logId}`);
5895
- }
5896
- for (const item of failed) {
5897
- console.log(` ${item.logId}: ${item.error}`);
5898
- }
5899
- }
5900
5863
  async function runTrackVideo(idOrLogId, options, trackVideoCommand2) {
5901
5864
  if (!idOrLogId) {
5902
5865
  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>])");
@@ -6039,6 +6002,28 @@ async function runTrackUpdate(trackId, options, trackUpdateCommand2) {
6039
6002
  }
6040
6003
  console.log(`Updated ${result.trackId}: ${result.fields.join(", ")}`);
6041
6004
  }
6005
+ async function runTrackRequeueVideo(idOrLogId, options, trackRequeueVideoCommand2) {
6006
+ if (!idOrLogId) {
6007
+ throw new Error("Missing id. Usage: fluncle admin tracks requeue-video <track_id|log_id>");
6008
+ }
6009
+ const result = await trackRequeueVideoCommand2(idOrLogId);
6010
+ if (options.json) {
6011
+ printJson(result);
6012
+ return;
6013
+ }
6014
+ console.log(result.alreadyClear ? `${result.logId} already had no video \u2014 nothing to clear.` : `Cleared the video for ${result.logId}. It's back on the render queue (and off radio until re-rendered).`);
6015
+ }
6016
+ async function runTrackPurgeVideo(idOrLogId, options, trackPurgeVideoCommand2) {
6017
+ if (!idOrLogId) {
6018
+ throw new Error("Missing id. Usage: fluncle admin tracks purge-video <track_id|log_id>");
6019
+ }
6020
+ const result = await trackPurgeVideoCommand2(idOrLogId);
6021
+ if (options.json) {
6022
+ printJson(result);
6023
+ return;
6024
+ }
6025
+ console.log(result.noVideo ? `${result.logId} has no video \u2014 nothing to purge.` : `Purging the stale renditions for ${result.logId} from the edge. The next play picks up the fresh render.`);
6026
+ }
6042
6027
  async function runMixtapeCreate(options, mixtapeCreateCommand2) {
6043
6028
  const result = await mixtapeCreateCommand2(options);
6044
6029
  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.57.0"
34
+ "version": "0.59.0"
35
35
  }