fluncle 0.101.0 → 0.102.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 +50 -2
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -557,7 +557,7 @@ function parseVersion(version) {
557
557
  var currentVersion;
558
558
  var init_version = __esm(() => {
559
559
  init_output();
560
- currentVersion = "0.101.0".trim() ? "0.101.0".trim() : "0.1.0";
560
+ currentVersion = "0.102.0".trim() ? "0.102.0".trim() : "0.1.0";
561
561
  });
562
562
 
563
563
  // src/update-notifier.ts
@@ -2205,7 +2205,7 @@ function parseVersion2(version) {
2205
2205
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
2206
2206
  var init_version2 = __esm(() => {
2207
2207
  init_output();
2208
- currentVersion2 = "0.101.0".trim() ? "0.101.0".trim() : "0.1.0";
2208
+ currentVersion2 = "0.102.0".trim() ? "0.102.0".trim() : "0.1.0";
2209
2209
  });
2210
2210
 
2211
2211
  // ../../packages/registry/src/index.ts
@@ -2799,6 +2799,17 @@ var init_src = __esm(() => {
2799
2799
  probeConfig: { cadenceMs: 5 * MINUTE_MS, cronName: "fluncle-embed", kind: "cron" },
2800
2800
  weights: { status: "hidden" }
2801
2801
  },
2802
+ {
2803
+ command: "fluncle admin tracks capture-audio --queue",
2804
+ exposedContent: [
2805
+ "capture each finding's full song once → private R2 (yt-dlp via a residential proxy)"
2806
+ ],
2807
+ kind: "cron",
2808
+ name: "cron.capture",
2809
+ operatorNotes: "every 5m, run by a rave-02 HOST systemd timer (docs/agents/hermes/capture-timer/) — NOT a gateway cron: a proxied yt-dlp fetch has an unbounded tail that would starve the 5-min enrich/context/note sweeps on the shared serial runner. A NON-BLOCKING side-channel (never gates enrich/embed). Runs yt-dlp through a residential proxy on a per-track sticky session, duration-guards the match, stores the full song in the PRIVATE fluncle-source-audio bucket (S3-direct), and writes back via the agent-tier update_track (with per-finding backoff). yt-dlp + ffprobe are a box deploy prereq. Newest-first so a fresh add jumps the backfill. Source: docs/agents/hermes/scripts/capture-sweep.*. See docs/full-audio-rfc.md § Unit 1.",
2810
+ probeConfig: { cadenceMs: 5 * MINUTE_MS, cronName: "fluncle-capture", kind: "cron" },
2811
+ weights: { status: "hidden" }
2812
+ },
2802
2813
  {
2803
2814
  command: "fluncle admin tracks context --queue",
2804
2815
  exposedContent: [
@@ -3529,11 +3540,13 @@ __export(exports_admin_tracks, {
3529
3540
  enrichQueueCommand: () => enrichQueueCommand,
3530
3541
  embedQueueCommand: () => embedQueueCommand,
3531
3542
  contextQueueCommand: () => contextQueueCommand,
3543
+ captureQueueCommand: () => captureQueueCommand,
3532
3544
  backfillLastfmCommand: () => backfillLastfmCommand,
3533
3545
  backfillDiscogsCommand: () => backfillDiscogsCommand
3534
3546
  });
3535
3547
  async function fetchAdminTracks(options) {
3536
3548
  const {
3549
+ captureQueue,
3537
3550
  hasContext,
3538
3551
  hasEmbedding,
3539
3552
  hasKey,
@@ -3558,6 +3571,9 @@ async function fetchAdminTracks(options) {
3558
3571
  if (hasEmbedding !== undefined) {
3559
3572
  params.set("hasEmbedding", String(hasEmbedding));
3560
3573
  }
3574
+ if (captureQueue) {
3575
+ params.set("captureQueue", "true");
3576
+ }
3561
3577
  if (hasContext !== undefined) {
3562
3578
  params.set("hasContext", String(hasContext));
3563
3579
  }
@@ -3613,6 +3629,9 @@ async function enrichQueueCommand(limit) {
3613
3629
  async function embedQueueCommand(limit) {
3614
3630
  return fetchAdminTracks({ hasEmbedding: false, max: limit, order: "asc" });
3615
3631
  }
3632
+ async function captureQueueCommand(limit) {
3633
+ return fetchAdminTracks({ captureQueue: true, max: limit, order: "desc" });
3634
+ }
3616
3635
  async function contextQueueCommand(limit, retryEmptyContext = false) {
3617
3636
  return fetchAdminTracks({ hasContext: false, max: limit, order: "asc", retryEmptyContext });
3618
3637
  }
@@ -7787,6 +7806,15 @@ function addAdminCommands(program2) {
7787
7806
  const { embedQueueCommand: embedQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
7788
7807
  await runAdminEmbedQueue(options, embedQueueCommand2);
7789
7808
  });
7809
+ adminTracks.command("capture-audio").description("Full-song capture worklist (findings with no source audio yet) \u2014 use --queue").option("--queue", "Show the capture worklist, newest first", false).option("--limit <limit>", "Number of findings to show with --queue", "10").option("--json", "Print JSON", false).action(async (options) => {
7810
+ if (!options.queue) {
7811
+ console.error("`tracks capture-audio` is a worklist view \u2014 capture runs on the on-box `fluncle-capture` cron.\nUse `tracks capture-audio --queue` to see findings needing a full-song capture.");
7812
+ process.exitCode = 1;
7813
+ return;
7814
+ }
7815
+ const { captureQueueCommand: captureQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
7816
+ await runAdminCaptureQueue(options, captureQueueCommand2);
7817
+ });
7790
7818
  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) => {
7791
7819
  const { vehiclesCommand: vehiclesCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
7792
7820
  await runAdminVehicles(options, vehiclesCommand2);
@@ -9091,6 +9119,26 @@ async function runAdminEmbedQueue(options, embedQueueCommand2) {
9091
9119
  console.log(trackRows2(tracks).join(`
9092
9120
  `));
9093
9121
  }
9122
+ async function runAdminCaptureQueue(options, captureQueueCommand2) {
9123
+ const limit = parseListLimit(options.limit);
9124
+ const tracks = await captureQueueCommand2(limit);
9125
+ if (options.json) {
9126
+ printJson({
9127
+ ok: true,
9128
+ tracks
9129
+ });
9130
+ return;
9131
+ }
9132
+ if (tracks.length === 0) {
9133
+ console.log("Nothing awaiting a capture. Every finding has its full song.");
9134
+ return;
9135
+ }
9136
+ const { trackRows: trackRows2 } = await Promise.resolve().then(() => (init_format2(), exports_format));
9137
+ const noun = tracks.length === 1 ? "finding" : "findings";
9138
+ console.log(`${tracks.length} ${noun} needing a full-song capture, newest first:`);
9139
+ console.log(trackRows2(tracks).join(`
9140
+ `));
9141
+ }
9094
9142
  async function runAdminVehicles(options, vehiclesCommand2) {
9095
9143
  const limit = parseListLimit(options.limit);
9096
9144
  const vehicles = await vehiclesCommand2(limit);
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.101.0"
34
+ "version": "0.102.0"
35
35
  }