fluncle 0.80.0 → 0.82.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 +79 -6
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -558,7 +558,7 @@ function parseVersion(version) {
558
558
  var currentVersion;
559
559
  var init_version = __esm(() => {
560
560
  init_output();
561
- currentVersion = "0.80.0".trim() ? "0.80.0".trim() : "0.1.0";
561
+ currentVersion = "0.82.0".trim() ? "0.82.0".trim() : "0.1.0";
562
562
  });
563
563
 
564
564
  // src/update-notifier.ts
@@ -2466,7 +2466,7 @@ function parseVersion2(version) {
2466
2466
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
2467
2467
  var init_version2 = __esm(() => {
2468
2468
  init_output();
2469
- currentVersion2 = "0.80.0".trim() ? "0.80.0".trim() : "0.1.0";
2469
+ currentVersion2 = "0.82.0".trim() ? "0.82.0".trim() : "0.1.0";
2470
2470
  });
2471
2471
 
2472
2472
  // ../../packages/registry/src/index.ts
@@ -3338,12 +3338,17 @@ var init_track = __esm(() => {
3338
3338
  VIDEO_FIELDS = [
3339
3339
  { field: "footage", option: "footage" },
3340
3340
  { field: "footage-social", option: "footageSocial" },
3341
+ { field: "footage-notext", option: "footageNotext" },
3342
+ { field: "footage-landscape", option: "footageLandscape" },
3343
+ { field: "footage-landscape-social", option: "footageLandscapeSocial" },
3341
3344
  { field: "poster", option: "poster" },
3342
3345
  { field: "cover", option: "cover" },
3343
3346
  { field: "note", option: "note" },
3344
3347
  { field: "composition", option: "composition" },
3345
3348
  { field: "props", option: "props" },
3346
- { field: "render", option: "render" }
3349
+ { field: "render", option: "render" },
3350
+ { field: "intent", option: "intent" },
3351
+ { field: "metrics", option: "metrics" }
3347
3352
  ];
3348
3353
  });
3349
3354
 
@@ -3380,13 +3385,24 @@ __export(exports_admin_tracks, {
3380
3385
  queueCommand: () => queueCommand,
3381
3386
  observeQueueCommand: () => observeQueueCommand,
3382
3387
  noteQueueCommand: () => noteQueueCommand,
3388
+ listCommand: () => listCommand,
3383
3389
  enrichQueueCommand: () => enrichQueueCommand,
3384
3390
  contextQueueCommand: () => contextQueueCommand,
3385
3391
  backfillLastfmCommand: () => backfillLastfmCommand,
3386
3392
  backfillDiscogsCommand: () => backfillDiscogsCommand
3387
3393
  });
3388
3394
  async function fetchAdminTracks(options) {
3389
- const { hasContext, hasNote, hasObservation, hasVideo, max, order, retryEmptyContext, status } = options;
3395
+ const {
3396
+ hasContext,
3397
+ hasKey,
3398
+ hasNote,
3399
+ hasObservation,
3400
+ hasVideo,
3401
+ max,
3402
+ order,
3403
+ retryEmptyContext,
3404
+ status
3405
+ } = options;
3390
3406
  const results = [];
3391
3407
  let cursor;
3392
3408
  do {
@@ -3394,6 +3410,9 @@ async function fetchAdminTracks(options) {
3394
3410
  if (hasVideo !== undefined) {
3395
3411
  params.set("hasVideo", String(hasVideo));
3396
3412
  }
3413
+ if (hasKey !== undefined) {
3414
+ params.set("hasKey", String(hasKey));
3415
+ }
3397
3416
  if (hasContext !== undefined) {
3398
3417
  params.set("hasContext", String(hasContext));
3399
3418
  }
@@ -3427,6 +3446,13 @@ async function fetchAdminTracks(options) {
3427
3446
  } while (cursor);
3428
3447
  return results;
3429
3448
  }
3449
+ async function listCommand(options) {
3450
+ return fetchAdminTracks({
3451
+ hasKey: options.hasKey,
3452
+ max: options.limit,
3453
+ order: options.order
3454
+ });
3455
+ }
3430
3456
  async function queueCommand(limit, filters = {}) {
3431
3457
  return fetchAdminTracks({
3432
3458
  hasContext: true,
@@ -7607,6 +7633,10 @@ function addAdminCommands(program2) {
7607
7633
  const { queueCommand: queueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
7608
7634
  await runAdminQueue(options, queueCommand2);
7609
7635
  });
7636
+ adminTracks.command("list").description("List findings, filterable by musical-key presence (--no-key / --has-key)").option("--limit <limit>", "Number of findings to show", "50").option("--no-key", "Only findings with NO stored musical key (the key-backfill backlog)").option("--has-key <bool>", "Filter by key presence: true (has key) or false (missing)").option("--order <order>", "Sort: asc (oldest first) or desc (newest first)", "desc").option("--json", "Print JSON", false).action(async (options) => {
7637
+ const { listCommand: listCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
7638
+ await runAdminTracksList(options, listCommand2);
7639
+ });
7610
7640
  adminTracks.command("enrich").description("Enrichment worklist (pending, failed, or stuck processing) \u2014 use --queue").option("--queue", "Show the enrichment worklist, oldest first", false).option("--limit <limit>", "Number of findings to show with --queue", "10").option("--json", "Print JSON", false).action(async (options) => {
7611
7641
  if (!options.queue) {
7612
7642
  console.error("`tracks enrich` is a worklist view \u2014 enrichment runs on the on-box `fluncle-enrich` cron.\nUse `tracks enrich --queue` to see findings needing (re-)enrichment.");
@@ -7625,7 +7655,7 @@ function addAdminCommands(program2) {
7625
7655
  const { trackUpdateCommand: trackUpdateCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
7626
7656
  await runTrackUpdate(trackId, options, trackUpdateCommand2);
7627
7657
  });
7628
- adminTrack.command("video").description("Upload a track's video bundle to R2 and link it").argument("[idOrLogId]").option("--composition <file>", "Composition source file").option("--cover <file>", "Cover image").option("--dir <dir>", "Bundle directory").option("--footage <file>", "Video footage (square crop source)").option("--footage-social <file>", "Portrait social cut (baked text)").option("--json", "Print JSON", false).option("--model <model>", "Authoring AI model (<provider>/<model>)").option("--note <file>", "Note file").option("--poster <file>", "Poster image").option("--props <file>", "Render props JSON").option("--reasoning <level>", "Authoring model reasoning effort (e.g. high)").option("--render <file>", "Render metadata JSON").allowExcessArguments().action(async (idOrLogId, options) => {
7658
+ adminTrack.command("video").description("Upload a track's video bundle to R2 and link it").argument("[idOrLogId]").option("--composition <file>", "Composition source file").option("--cover <file>", "Cover image").option("--dir <dir>", "Bundle directory").option("--footage <file>", "Video footage (square crop source)").option("--footage-landscape <file>", "Clean landscape cut (optional escape hatch)").option("--footage-landscape-social <file>", "Landscape cut with baked text (optional)").option("--footage-notext <file>", "Portrait cut without the type layer (optional)").option("--footage-social <file>", "Portrait social cut (baked text)").option("--intent <file>", "Render-intent JSON (optional)").option("--json", "Print JSON", false).option("--metrics <file>", "Gate metrics JSON (optional)").option("--model <model>", "Authoring AI model (<provider>/<model>)").option("--note <file>", "Note file").option("--poster <file>", "Poster image").option("--props <file>", "Render props JSON").option("--reasoning <level>", "Authoring model reasoning effort (e.g. high)").option("--render <file>", "Render metadata JSON").allowExcessArguments().action(async (idOrLogId, options) => {
7629
7659
  const { trackVideoCommand: trackVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
7630
7660
  await runTrackVideo(idOrLogId, options, trackVideoCommand2);
7631
7661
  });
@@ -8062,7 +8092,7 @@ async function runBackfillDiscogs(options, backfillDiscogsCommand2) {
8062
8092
  }
8063
8093
  async function runTrackVideo(idOrLogId, options, trackVideoCommand2) {
8064
8094
  if (!idOrLogId) {
8065
- throw new Error("Missing id. Usage: fluncle admin tracks video <track_id|log_id> (--dir <dir> | --footage <file> [--footage-social <file>] [--poster <file>] [--cover <file>] [--note <file>] [--composition <file>] [--props <file>] [--render <file>])");
8095
+ throw new Error("Missing id. Usage: fluncle admin tracks video <track_id|log_id> (--dir <dir> | --footage <file> [--footage-social <file>] [--footage-notext <file>] [--footage-landscape <file>] [--footage-landscape-social <file>] [--poster <file>] [--cover <file>] [--note <file>] [--composition <file>] [--props <file>] [--render <file>] [--intent <file>] [--metrics <file>])");
8066
8096
  }
8067
8097
  const dir = options.dir ? path2.resolve(process.cwd(), options.dir) : undefined;
8068
8098
  const fromDir = (name) => {
@@ -8082,7 +8112,12 @@ async function runTrackVideo(idOrLogId, options, trackVideoCommand2) {
8082
8112
  composition: resolveFile(options.composition, "composition.tsx"),
8083
8113
  cover: resolveFile(options.cover, "cover.jpg"),
8084
8114
  footage: resolveFile(options.footage, "footage.mp4"),
8115
+ footageLandscape: resolveFile(options.footageLandscape, "footage.landscape.mp4"),
8116
+ footageLandscapeSocial: resolveFile(options.footageLandscapeSocial, "footage.landscape.social.mp4"),
8117
+ footageNotext: resolveFile(options.footageNotext, "footage.notext.mp4"),
8085
8118
  footageSocial: resolveFile(options.footageSocial, "footage.social.mp4"),
8119
+ intent: resolveFile(options.intent, "intent.json"),
8120
+ metrics: resolveFile(options.metrics, "metrics.json"),
8086
8121
  model: options.model,
8087
8122
  note: resolveFile(options.note, "note.txt"),
8088
8123
  poster: resolveFile(options.poster, "poster.jpg"),
@@ -8556,6 +8591,39 @@ function parseListLimit(value) {
8556
8591
  }
8557
8592
  return limit;
8558
8593
  }
8594
+ function resolveHasKey(options) {
8595
+ if (options.key === false) {
8596
+ return false;
8597
+ }
8598
+ if (options.hasKey === "false") {
8599
+ return false;
8600
+ }
8601
+ if (options.hasKey === "true") {
8602
+ return true;
8603
+ }
8604
+ return;
8605
+ }
8606
+ async function runAdminTracksList(options, listCommand2) {
8607
+ const limit = parseListLimit(options.limit);
8608
+ const order = options.order === "asc" ? "asc" : "desc";
8609
+ const hasKey = resolveHasKey(options);
8610
+ const tracks = await listCommand2({ hasKey, limit, order });
8611
+ if (options.json) {
8612
+ printJson({ ok: true, tracks });
8613
+ return;
8614
+ }
8615
+ if (tracks.length === 0) {
8616
+ const scope2 = hasKey === false ? " missing a key" : hasKey === true ? " with a key" : "";
8617
+ console.log(`No findings${scope2}.`);
8618
+ return;
8619
+ }
8620
+ const { trackRows: trackRows2 } = await Promise.resolve().then(() => (init_format2(), exports_format));
8621
+ const scope = hasKey === false ? " missing a musical key" : hasKey === true ? " with a musical key" : "";
8622
+ const noun = tracks.length === 1 ? "finding" : "findings";
8623
+ console.log(`${tracks.length} ${noun}${scope}:`);
8624
+ console.log(trackRows2(tracks).join(`
8625
+ `));
8626
+ }
8559
8627
  async function runAdminQueue(options, queueCommand2) {
8560
8628
  const limit = parseListLimit(options.limit);
8561
8629
  const tracks = await queueCommand2(limit, {
@@ -8892,10 +8960,15 @@ var stringOptions = new Set([
8892
8960
  "--features",
8893
8961
  "--file",
8894
8962
  "--footage",
8963
+ "--footage-landscape",
8964
+ "--footage-landscape-social",
8965
+ "--footage-notext",
8895
8966
  "--footage-social",
8896
8967
  "--from",
8968
+ "--intent",
8897
8969
  "--key",
8898
8970
  "--limit",
8971
+ "--metrics",
8899
8972
  "--mime",
8900
8973
  "--note",
8901
8974
  "--platform",
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.80.0"
34
+ "version": "0.82.0"
35
35
  }