fluncle 0.131.0 → 0.132.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 +59 -5
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -561,7 +561,7 @@ function parseVersion(version) {
561
561
  var currentVersion;
562
562
  var init_version = __esm(() => {
563
563
  init_output();
564
- currentVersion = "0.131.0".trim() ? "0.131.0".trim() : "0.1.0";
564
+ currentVersion = "0.132.0".trim() ? "0.132.0".trim() : "0.1.0";
565
565
  });
566
566
 
567
567
  // src/update-notifier.ts
@@ -2189,7 +2189,7 @@ function parseVersion2(version) {
2189
2189
  var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
2190
2190
  var init_version2 = __esm(() => {
2191
2191
  init_output();
2192
- currentVersion2 = "0.131.0".trim() ? "0.131.0".trim() : "0.1.0";
2192
+ currentVersion2 = "0.132.0".trim() ? "0.132.0".trim() : "0.1.0";
2193
2193
  });
2194
2194
 
2195
2195
  // ../../packages/registry/src/index.ts
@@ -2836,6 +2836,15 @@ var init_src = __esm(() => {
2836
2836
  name: "cli.tracks-get",
2837
2837
  weights: { cli: "tertiary" }
2838
2838
  },
2839
+ {
2840
+ command: "fluncle tracks similar",
2841
+ exposedContent: [
2842
+ "the findings that sound nearest to one (the sonic neighbourhood, off the MuQ audio embedding), each with its note"
2843
+ ],
2844
+ kind: "cli",
2845
+ name: "cli.tracks-similar",
2846
+ weights: { cli: "tertiary" }
2847
+ },
2839
2848
  {
2840
2849
  command: "fluncle about",
2841
2850
  exposedContent: ["Fluncle, and where to find him"],
@@ -3221,6 +3230,7 @@ __export(exports_track, {
3221
3230
  trackSocialUpdateCommand: () => trackSocialUpdateCommand,
3222
3231
  trackSocialShowCommand: () => trackSocialShowCommand,
3223
3232
  trackSocialCaptureCommand: () => trackSocialCaptureCommand,
3233
+ trackSimilarCommand: () => trackSimilarCommand,
3224
3234
  trackRequeueVideoCommand: () => trackRequeueVideoCommand,
3225
3235
  trackPurgeVideoCommand: () => trackPurgeVideoCommand,
3226
3236
  trackObserveCommand: () => trackObserveCommand,
@@ -3235,6 +3245,10 @@ __export(exports_track, {
3235
3245
  async function trackGetCommand(idOrLogId) {
3236
3246
  return publicApiGet(`/api/tracks/${encodeURIComponent(idOrLogId)}`);
3237
3247
  }
3248
+ async function trackSimilarCommand(idOrLogId, limit) {
3249
+ const query = limit === undefined ? "" : `?limit=${encodeURIComponent(String(limit))}`;
3250
+ return publicApiGet(`/api/tracks/${encodeURIComponent(idOrLogId)}/similar${query}`);
3251
+ }
3238
3252
  async function trackGetAdminCommand(idOrLogId) {
3239
3253
  return adminApiGet(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}`);
3240
3254
  }
@@ -3438,6 +3452,9 @@ async function trackContextCommand(idOrLogId, options = {}) {
3438
3452
  }
3439
3453
  async function trackNoteCommand(idOrLogId, options) {
3440
3454
  const body = { note: options.note };
3455
+ if (options.dryRun) {
3456
+ body.dryRun = true;
3457
+ }
3441
3458
  return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/note`, body);
3442
3459
  }
3443
3460
  var DEFAULT_VIDEO_MODEL = "anthropic/claude-opus-4-8", DEFAULT_VIDEO_REASONING = "high", FOUND_BASE = "https://found.fluncle.com", VIDEO_FIELDS, RERENDER_CONTRACT_FIELDS, RERENDER_ADVISORY_FIELDS, FOOTAGE_FIELDS, PLATE_FIELDS, NON_FILE_OPTIONS;
@@ -8019,6 +8036,10 @@ function addTrackCommands(program2) {
8019
8036
  const { trackGetCommand: trackGetCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
8020
8037
  await runTrackGet(idOrLogId, options, trackGetCommand2);
8021
8038
  });
8039
+ tracks.command("similar").description("The findings that sound nearest to one (the sonic neighbourhood)").argument("[idOrLogId]").option("--limit <limit>", "Number of neighbours to show", "6").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
8040
+ const { trackSimilarCommand: trackSimilarCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
8041
+ await runTrackSimilar(idOrLogId, options, trackSimilarCommand2);
8042
+ });
8022
8043
  }
8023
8044
  function addAdminCommands(program2) {
8024
8045
  const admin = configureCommand(program2.command("admin", { hidden: true }).description("Operator commands"));
@@ -8147,7 +8168,7 @@ function addAdminCommands(program2) {
8147
8168
  const { trackContextCommand: trackContextCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
8148
8169
  await runTrackContext(idOrLogId, options, trackContextCommand2);
8149
8170
  });
8150
- adminTrack.command("note").description("Author the editorial note for a finding (fills an empty note only)").argument("[idOrLogId]").option("--queue", "Show the note worklist (context'd findings with no note yet), oldest first", false).option("--limit <limit>", "Number of findings to show with --queue", "10").option("--script <text>", "The voice-gated editorial note").option("--script-file <file>", "Read the editorial note from a file").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
8171
+ adminTrack.command("note").description("Author the editorial note for a finding (fills an empty note only)").argument("[idOrLogId]").option("--queue", "Show the note worklist (context'd findings with no note yet), oldest first", false).option("--limit <limit>", "Number of findings to show with --queue", "10").option("--script <text>", "The voice-gated editorial note").option("--script-file <file>", "Read the editorial note from a file").option("--dry-run", "Run the voice + echo gates and report the verdict without storing anything", false).option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
8151
8172
  if (options.queue) {
8152
8173
  const { noteQueueCommand: noteQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
8153
8174
  await runAdminNoteQueue(options, noteQueueCommand2);
@@ -8509,9 +8530,12 @@ async function runTrackContext(idOrLogId, options, trackContextCommand2) {
8509
8530
  async function runTrackNote(idOrLogId, options, trackNoteCommand2) {
8510
8531
  const note = options.scriptFile ? readFileSync6(options.scriptFile, "utf8") : options.script;
8511
8532
  if (!idOrLogId || !note || !note.trim()) {
8512
- throw new Error("Usage: fluncle admin tracks note <track_id|log_id> (--script <text> | --script-file <file>) [--json]");
8533
+ throw new Error("Usage: fluncle admin tracks note <track_id|log_id> (--script <text> | --script-file <file>) [--dry-run] [--json]");
8513
8534
  }
8514
- const result = await trackNoteCommand2(idOrLogId, { note: note.trim() });
8535
+ const result = await trackNoteCommand2(idOrLogId, {
8536
+ dryRun: options.dryRun,
8537
+ note: note.trim()
8538
+ });
8515
8539
  if (options.json) {
8516
8540
  printJson(result);
8517
8541
  return;
@@ -8520,9 +8544,39 @@ async function runTrackNote(idOrLogId, options, trackNoteCommand2) {
8520
8544
  console.log(`A note is already on file for ${result.logId}. The operator's note stands.`);
8521
8545
  return;
8522
8546
  }
8547
+ if (result.dryRun) {
8548
+ console.log(`Both gates passed for ${result.logId}. Nothing was stored (dry run).`);
8549
+ console.log(` ${result.note}`);
8550
+ if (result.echo?.logId) {
8551
+ const reading = result.echo.phrase ? `lifts "${result.echo.phrase}" from ${result.echo.logId}` : `${Math.round(result.echo.overlap * 100)}% word overlap with ${result.echo.logId}`;
8552
+ console.log(` echo: ${reading}`);
8553
+ }
8554
+ return;
8555
+ }
8523
8556
  console.log(`Authored the note for ${result.logId}:`);
8524
8557
  console.log(` ${result.note}`);
8525
8558
  }
8559
+ async function runTrackSimilar(idOrLogId, options, trackSimilarCommand2) {
8560
+ if (!idOrLogId) {
8561
+ throw new Error("Missing id. Usage: fluncle tracks similar <track_id|log_id> [--limit <n>] [--json]");
8562
+ }
8563
+ const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
8564
+ const result = await trackSimilarCommand2(idOrLogId, limit !== undefined && Number.isFinite(limit) ? limit : undefined);
8565
+ if (options.json) {
8566
+ printJson(result);
8567
+ return;
8568
+ }
8569
+ if (result.findings.length === 0) {
8570
+ console.log("Nothing sounds near this one yet. It may still be waiting on its embedding.");
8571
+ return;
8572
+ }
8573
+ for (const finding of result.findings) {
8574
+ console.log(`${finding.logId ?? "\u2014"} ${finding.artists.join(", ")} \u2014 ${finding.title}`);
8575
+ if (finding.note) {
8576
+ console.log(` ${finding.note}`);
8577
+ }
8578
+ }
8579
+ }
8526
8580
  function printSweepJson(payload, failedCount) {
8527
8581
  printJson({ ...payload, failedCount, ok: failedCount === 0 });
8528
8582
  if (failedCount > 0) {
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.131.0"
34
+ "version": "0.132.0"
35
35
  }