fluncle 0.35.0 → 0.36.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 +56 -2
  2. package/package.json +1 -1
package/bin/fluncle.mjs CHANGED
@@ -3789,7 +3789,7 @@ function parseVersion(version) {
3789
3789
  var currentVersion, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
3790
3790
  var init_version = __esm(() => {
3791
3791
  init_output();
3792
- currentVersion = "0.35.0".trim() ? "0.35.0".trim() : "0.1.0";
3792
+ currentVersion = "0.36.0".trim() ? "0.36.0".trim() : "0.1.0";
3793
3793
  });
3794
3794
 
3795
3795
  // src/commands/track.ts
@@ -3799,6 +3799,7 @@ __export(exports_track, {
3799
3799
  trackUpdateCommand: () => trackUpdateCommand,
3800
3800
  trackSocialUpdateCommand: () => trackSocialUpdateCommand,
3801
3801
  trackSocialShowCommand: () => trackSocialShowCommand,
3802
+ trackObserveCommand: () => trackObserveCommand,
3802
3803
  trackGetCommand: () => trackGetCommand,
3803
3804
  trackDraftCommand: () => trackDraftCommand
3804
3805
  });
@@ -3892,6 +3893,25 @@ async function trackUpdateCommand(trackId, options) {
3892
3893
  }
3893
3894
  return adminApiPatch(`/api/admin/tracks/${encodeURIComponent(trackId)}`, body);
3894
3895
  }
3896
+ async function trackObserveCommand(idOrLogId, options) {
3897
+ const body = { script: options.script };
3898
+ if (options.voiceId !== undefined) {
3899
+ body.voiceId = options.voiceId;
3900
+ }
3901
+ if (options.model !== undefined) {
3902
+ body.model = options.model;
3903
+ }
3904
+ if (options.durationMs !== undefined) {
3905
+ body.durationMs = options.durationMs;
3906
+ }
3907
+ if (options.durationTargetSec !== undefined) {
3908
+ body.durationTargetSec = options.durationTargetSec;
3909
+ }
3910
+ if (options.contextNote !== undefined) {
3911
+ body.contextNote = options.contextNote;
3912
+ }
3913
+ return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/observe`, body);
3914
+ }
3895
3915
  var DEFAULT_VIDEO_MODEL = "anthropic/claude-opus-4-8", DEFAULT_VIDEO_REASONING = "high", FOUND_BASE = "https://found.fluncle.com", VIDEO_FIELDS;
3896
3916
  var init_track = __esm(() => {
3897
3917
  init_api();
@@ -4929,7 +4949,7 @@ function trackDetailLines(track) {
4929
4949
  var COORD_FALLBACK2 = "—";
4930
4950
 
4931
4951
  // src/cli.ts
4932
- import { existsSync as existsSync2 } from "fs";
4952
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
4933
4953
  import path from "path";
4934
4954
 
4935
4955
  // ../../node_modules/.bun/commander@14.0.3/node_modules/commander/esm.mjs
@@ -5155,6 +5175,10 @@ function addAdminCommands(program2) {
5155
5175
  const { previewArchiveUploadCommand: previewArchiveUploadCommand2 } = await Promise.resolve().then(() => (init_preview_archive(), exports_preview_archive));
5156
5176
  await runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCommand2);
5157
5177
  });
5178
+ adminTrack.command("observe").description("Render Fluncle's spoken field observation for a track (ElevenLabs, Worker-side)").argument("[idOrLogId]").option("--script <text>", "The voice-gated observation script (the spoken text)").option("--script-file <file>", "Read the observation script from a file (e.g. observation.txt)").option("--voice-id <id>", "Override the configured ElevenLabs voice id").option("--model <model>", "TTS model (eleven_multilingual_v2 | eleven_v3)").option("--duration-ms <ms>", "Probed audio duration in ms (the agent runs ffprobe)").option("--duration-target-sec <sec>", "Target observation length in seconds (20\u201345)").option("--context-note <text>", "Pre-fetched factual context (else the Worker firecrawls)").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
5179
+ const { trackObserveCommand: trackObserveCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
5180
+ await runTrackObserve(idOrLogId, options, trackObserveCommand2);
5181
+ });
5158
5182
  const adminMixtapes = configureCommand(admin.command("mixtapes").description("Mixtape admin commands"));
5159
5183
  adminMixtapes.action(() => {
5160
5184
  adminMixtapes.outputHelp();
@@ -5265,6 +5289,36 @@ async function runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCo
5265
5289
  console.log(` source: ${result.source}`);
5266
5290
  console.log(` mime: ${result.mime}`);
5267
5291
  }
5292
+ async function runTrackObserve(idOrLogId, options, trackObserveCommand2) {
5293
+ const script = options.scriptFile ? readFileSync2(options.scriptFile, "utf8") : options.script;
5294
+ if (!idOrLogId || !script || !script.trim()) {
5295
+ 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]");
5296
+ }
5297
+ const durationMs = options.durationMs === undefined ? undefined : Number.parseInt(options.durationMs, 10);
5298
+ if (durationMs !== undefined && (!Number.isInteger(durationMs) || durationMs < 1)) {
5299
+ throw new Error("--duration-ms must be a positive integer");
5300
+ }
5301
+ const durationTargetSec = options.durationTargetSec === undefined ? undefined : Number.parseInt(options.durationTargetSec, 10);
5302
+ if (durationTargetSec !== undefined && (!Number.isInteger(durationTargetSec) || durationTargetSec < 1)) {
5303
+ throw new Error("--duration-target-sec must be a positive integer");
5304
+ }
5305
+ const result = await trackObserveCommand2(idOrLogId, {
5306
+ contextNote: options.contextNote,
5307
+ durationMs,
5308
+ durationTargetSec,
5309
+ model: options.model,
5310
+ script: script.trim(),
5311
+ voiceId: options.voiceId
5312
+ });
5313
+ if (options.json) {
5314
+ printJson(result);
5315
+ return;
5316
+ }
5317
+ console.log(`Recorded observation for ${result.logId}`);
5318
+ console.log(` audio: ${result.audioUrl}`);
5319
+ console.log(` length: ${Math.round(result.durationMs / 1000)}s`);
5320
+ console.log(` voice: ${result.voiceId}`);
5321
+ }
5268
5322
  async function runPreviewArchiveBackfill(options, previewArchiveBackfillCommand2) {
5269
5323
  const limit = options.limit === undefined ? undefined : Number.parseInt(options.limit, 10);
5270
5324
  if (limit !== undefined && (!Number.isInteger(limit) || limit < 1)) {
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.35.0"
34
+ "version": "0.36.0"
35
35
  }