fluncle 0.50.0 → 0.52.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.
- package/bin/fluncle.mjs +67 -39
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -408,7 +408,7 @@ function compareVersions(left, right) {
|
|
|
408
408
|
const leftParts = parseVersion(left);
|
|
409
409
|
const rightParts = parseVersion(right);
|
|
410
410
|
for (let index = 0;index < 3; index += 1) {
|
|
411
|
-
const difference = leftParts[index] - rightParts[index];
|
|
411
|
+
const difference = (leftParts[index] ?? 0) - (rightParts[index] ?? 0);
|
|
412
412
|
if (difference !== 0) {
|
|
413
413
|
return difference;
|
|
414
414
|
}
|
|
@@ -417,16 +417,13 @@ function compareVersions(left, right) {
|
|
|
417
417
|
}
|
|
418
418
|
function parseVersion(version) {
|
|
419
419
|
const parts = version.split(".").map((part) => Number.parseInt(part, 10));
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
Number.isInteger(parts[1]) ? parts[1] : 0,
|
|
423
|
-
Number.isInteger(parts[2]) ? parts[2] : 0
|
|
424
|
-
];
|
|
420
|
+
const integerOrZero = (value) => value !== undefined && Number.isInteger(value) ? value : 0;
|
|
421
|
+
return [integerOrZero(parts[0]), integerOrZero(parts[1]), integerOrZero(parts[2])];
|
|
425
422
|
}
|
|
426
423
|
var currentVersion;
|
|
427
424
|
var init_version = __esm(() => {
|
|
428
425
|
init_output();
|
|
429
|
-
currentVersion = "0.
|
|
426
|
+
currentVersion = "0.52.0".trim() ? "0.52.0".trim() : "0.1.0";
|
|
430
427
|
});
|
|
431
428
|
|
|
432
429
|
// src/update-notifier.ts
|
|
@@ -483,6 +480,9 @@ function shouldNotify(args) {
|
|
|
483
480
|
function firstPositional(args) {
|
|
484
481
|
for (let index = 0;index < args.length; index += 1) {
|
|
485
482
|
const arg = args[index];
|
|
483
|
+
if (arg === undefined) {
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
486
|
if (arg === "--env") {
|
|
487
487
|
index += 1;
|
|
488
488
|
continue;
|
|
@@ -1237,6 +1237,9 @@ async function mixtapeDistributeCommand(idOrLogId, options, onProgress = () => {
|
|
|
1237
1237
|
}
|
|
1238
1238
|
const results = [];
|
|
1239
1239
|
if (doYoutube) {
|
|
1240
|
+
if (!options.video) {
|
|
1241
|
+
throw new CliError2("missing_video", "YouTube distribution needs --video <mp4>");
|
|
1242
|
+
}
|
|
1240
1243
|
onProgress("YouTube: uploading video…");
|
|
1241
1244
|
const { distributeYoutube: distributeYoutube2 } = await Promise.resolve().then(() => (init_mixtape_youtube(), exports_mixtape_youtube));
|
|
1242
1245
|
const result = await distributeYoutube2(mixtapeId, options.video, onProgress);
|
|
@@ -1244,6 +1247,9 @@ async function mixtapeDistributeCommand(idOrLogId, options, onProgress = () => {
|
|
|
1244
1247
|
onProgress(`YouTube: ${result.url}`);
|
|
1245
1248
|
}
|
|
1246
1249
|
if (doMixcloud) {
|
|
1250
|
+
if (!options.audio) {
|
|
1251
|
+
throw new CliError2("missing_audio", "Mixcloud distribution needs --audio <file>");
|
|
1252
|
+
}
|
|
1247
1253
|
onProgress("Mixcloud: uploading audio…");
|
|
1248
1254
|
const { distributeMixcloud: distributeMixcloud2 } = await Promise.resolve().then(() => (init_mixtape_mixcloud(), exports_mixtape_mixcloud));
|
|
1249
1255
|
const result = await distributeMixcloud2(mixtapeId, options.audio, onProgress, options.unlisted);
|
|
@@ -1327,11 +1333,15 @@ function parseCueSheet(text) {
|
|
|
1327
1333
|
}
|
|
1328
1334
|
const match = trimmed.match(/^(\d{1,2}:\d{2}(?::\d{2})?)\s+(.+)$/);
|
|
1329
1335
|
if (match) {
|
|
1330
|
-
const
|
|
1336
|
+
const [, time, ref] = match;
|
|
1337
|
+
if (time === undefined || ref === undefined) {
|
|
1338
|
+
continue;
|
|
1339
|
+
}
|
|
1340
|
+
const startMs = parseDuration(time);
|
|
1331
1341
|
if (startMs === null) {
|
|
1332
1342
|
continue;
|
|
1333
1343
|
}
|
|
1334
|
-
entries.push({ ref:
|
|
1344
|
+
entries.push({ ref: ref.trim(), startMs });
|
|
1335
1345
|
} else {
|
|
1336
1346
|
entries.push({ ref: trimmed });
|
|
1337
1347
|
}
|
|
@@ -1354,12 +1364,18 @@ function parseDuration(input) {
|
|
|
1354
1364
|
}
|
|
1355
1365
|
if (parts.length === 3) {
|
|
1356
1366
|
const [hours, minutes2, seconds2] = nums;
|
|
1367
|
+
if (hours === undefined || minutes2 === undefined || seconds2 === undefined) {
|
|
1368
|
+
return null;
|
|
1369
|
+
}
|
|
1357
1370
|
if (minutes2 >= 60 || seconds2 >= 60) {
|
|
1358
1371
|
return null;
|
|
1359
1372
|
}
|
|
1360
1373
|
return Math.round((hours * 3600 + minutes2 * 60 + seconds2) * 1000);
|
|
1361
1374
|
}
|
|
1362
1375
|
const [minutes, seconds] = nums;
|
|
1376
|
+
if (minutes === undefined || seconds === undefined) {
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1363
1379
|
if (seconds >= 60) {
|
|
1364
1380
|
return null;
|
|
1365
1381
|
}
|
|
@@ -1881,7 +1897,7 @@ function compareVersions2(left, right) {
|
|
|
1881
1897
|
const leftParts = parseVersion2(left);
|
|
1882
1898
|
const rightParts = parseVersion2(right);
|
|
1883
1899
|
for (let index = 0;index < 3; index += 1) {
|
|
1884
|
-
const difference = leftParts[index] - rightParts[index];
|
|
1900
|
+
const difference = (leftParts[index] ?? 0) - (rightParts[index] ?? 0);
|
|
1885
1901
|
if (difference !== 0) {
|
|
1886
1902
|
return difference;
|
|
1887
1903
|
}
|
|
@@ -1890,16 +1906,13 @@ function compareVersions2(left, right) {
|
|
|
1890
1906
|
}
|
|
1891
1907
|
function parseVersion2(version) {
|
|
1892
1908
|
const parts = version.split(".").map((part) => Number.parseInt(part, 10));
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
Number.isInteger(parts[1]) ? parts[1] : 0,
|
|
1896
|
-
Number.isInteger(parts[2]) ? parts[2] : 0
|
|
1897
|
-
];
|
|
1909
|
+
const integerOrZero = (value) => value !== undefined && Number.isInteger(value) ? value : 0;
|
|
1910
|
+
return [integerOrZero(parts[0]), integerOrZero(parts[1]), integerOrZero(parts[2])];
|
|
1898
1911
|
}
|
|
1899
1912
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
1900
1913
|
var init_version2 = __esm(() => {
|
|
1901
1914
|
init_output();
|
|
1902
|
-
currentVersion2 = "0.
|
|
1915
|
+
currentVersion2 = "0.52.0".trim() ? "0.52.0".trim() : "0.1.0";
|
|
1903
1916
|
});
|
|
1904
1917
|
|
|
1905
1918
|
// src/commands/track.ts
|
|
@@ -2187,7 +2200,7 @@ async function previewArchiveUploadCommand(idOrLogId, options) {
|
|
|
2187
2200
|
form.append("preview", Bun.file(options.file), basename(options.file));
|
|
2188
2201
|
form.append("source", options.source);
|
|
2189
2202
|
form.append("mime", options.mime);
|
|
2190
|
-
return adminApiPostForm(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/preview
|
|
2203
|
+
return adminApiPostForm(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/preview`, form);
|
|
2191
2204
|
}
|
|
2192
2205
|
async function previewArchiveBackfillCommand(options) {
|
|
2193
2206
|
const result = {
|
|
@@ -2207,7 +2220,7 @@ async function previewArchiveBackfillCommand(options) {
|
|
|
2207
2220
|
result.skipped.push({ reason: "no_log_id", trackId: track.trackId });
|
|
2208
2221
|
continue;
|
|
2209
2222
|
}
|
|
2210
|
-
const status = await adminApiGet(`/api/admin/tracks/${encodeURIComponent(track.trackId)}/preview
|
|
2223
|
+
const status = await adminApiGet(`/api/admin/tracks/${encodeURIComponent(track.trackId)}/preview`);
|
|
2211
2224
|
if (status.archived) {
|
|
2212
2225
|
result.skipped.push({ reason: "already_archived", trackId: track.trackId });
|
|
2213
2226
|
continue;
|
|
@@ -2246,7 +2259,7 @@ async function uploadResolvedPreview(trackId, preview) {
|
|
|
2246
2259
|
form.append("preview", new Blob([preview.bytes], { type: preview.mime }), `preview.${extension}`);
|
|
2247
2260
|
form.append("source", preview.source);
|
|
2248
2261
|
form.append("mime", preview.mime);
|
|
2249
|
-
await adminApiPostForm(`/api/admin/tracks/${encodeURIComponent(trackId)}/preview
|
|
2262
|
+
await adminApiPostForm(`/api/admin/tracks/${encodeURIComponent(trackId)}/preview`, form);
|
|
2250
2263
|
}
|
|
2251
2264
|
async function resolvePreview(track) {
|
|
2252
2265
|
const stored = await downloadPreview(track.previewUrl, "deezer:stored");
|
|
@@ -2992,6 +3005,9 @@ async function paginateWithKeyboard(options) {
|
|
|
2992
3005
|
const columns = stdout.columns ?? 80;
|
|
2993
3006
|
const before = pages.slice(0, index).reduce((count, page2) => count + page2.lines.length, 0);
|
|
2994
3007
|
const page = pages[index];
|
|
3008
|
+
if (page === undefined) {
|
|
3009
|
+
return;
|
|
3010
|
+
}
|
|
2995
3011
|
const start = before + 1;
|
|
2996
3012
|
const end = before + page.lines.length;
|
|
2997
3013
|
const loading = busy ? " · loading…" : "";
|
|
@@ -3003,7 +3019,7 @@ async function paginateWithKeyboard(options) {
|
|
|
3003
3019
|
`);
|
|
3004
3020
|
}
|
|
3005
3021
|
function loadNext() {
|
|
3006
|
-
const cursor = pages[index]
|
|
3022
|
+
const cursor = pages[index]?.nextCursor;
|
|
3007
3023
|
if (cursor === undefined) {
|
|
3008
3024
|
return;
|
|
3009
3025
|
}
|
|
@@ -5330,8 +5346,8 @@ function addMetaCommands(program2) {
|
|
|
5330
5346
|
});
|
|
5331
5347
|
}
|
|
5332
5348
|
function addTrackCommands(program2) {
|
|
5333
|
-
const
|
|
5334
|
-
|
|
5349
|
+
const tracks = configureCommand(program2.command("tracks", { hidden: true }).alias("track").description("Public track lookups"));
|
|
5350
|
+
tracks.command("get").description("Look up one finding by id or Log ID").argument("[idOrLogId]").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5335
5351
|
const { trackGetCommand: trackGetCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5336
5352
|
await runTrackGet(idOrLogId, options, trackGetCommand2);
|
|
5337
5353
|
});
|
|
@@ -5364,19 +5380,12 @@ function addAdminCommands(program2) {
|
|
|
5364
5380
|
const { queueCommand: queueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5365
5381
|
await runAdminQueue(options, queueCommand2);
|
|
5366
5382
|
});
|
|
5367
|
-
adminTracks.command("
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
await runAdminObserveQueue(options, observeQueueCommand2);
|
|
5374
|
-
});
|
|
5375
|
-
adminTracks.command("enrich-queue").description("Findings needing (re-)enrichment: pending, failed, or stuck processing").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
|
|
5376
|
-
const { enrichQueueCommand: enrichQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5377
|
-
await runAdminEnrichQueue(options, enrichQueueCommand2);
|
|
5378
|
-
});
|
|
5379
|
-
admin.command("enrich-queue", { hidden: true }).description("Enrich queue (alias of `admin tracks enrich-queue`)").option("--limit <limit>", "Number of findings to show", "10").option("--json", "Print JSON", false).action(async (options) => {
|
|
5383
|
+
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) => {
|
|
5384
|
+
if (!options.queue) {
|
|
5385
|
+
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.");
|
|
5386
|
+
process.exitCode = 1;
|
|
5387
|
+
return;
|
|
5388
|
+
}
|
|
5380
5389
|
const { enrichQueueCommand: enrichQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5381
5390
|
await runAdminEnrichQueue(options, enrichQueueCommand2);
|
|
5382
5391
|
});
|
|
@@ -5405,15 +5414,25 @@ function addAdminCommands(program2) {
|
|
|
5405
5414
|
const { trackSocialShowCommand: trackSocialShowCommand2, trackSocialUpdateCommand: trackSocialUpdateCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5406
5415
|
await runTrackSocial(idOrLogId, options, trackSocialShowCommand2, trackSocialUpdateCommand2);
|
|
5407
5416
|
});
|
|
5408
|
-
adminTrack.command("preview").
|
|
5417
|
+
adminTrack.command("preview").description("Store one official preview at the operator-only archive path for analysis").argument("[idOrLogId]").option("--file <file>", "Preview audio file to archive").option("--mime <mime>", "MIME type of the preview audio").option("--source <source>", "Provenance label for the archived preview").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5409
5418
|
const { previewArchiveUploadCommand: previewArchiveUploadCommand2 } = await Promise.resolve().then(() => (init_preview_archive(), exports_preview_archive));
|
|
5410
5419
|
await runTrackPreviewArchive(idOrLogId, options, previewArchiveUploadCommand2);
|
|
5411
5420
|
});
|
|
5412
|
-
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) => {
|
|
5421
|
+
adminTrack.command("observe").description("Render Fluncle's spoken field observation for a track (ElevenLabs, Worker-side)").argument("[idOrLogId]").option("--queue", "Show the observe worklist (notes but no observation yet), oldest first", false).option("--limit <limit>", "Number of findings to show with --queue", "10").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) => {
|
|
5422
|
+
if (options.queue) {
|
|
5423
|
+
const { observeQueueCommand: observeQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5424
|
+
await runAdminObserveQueue(options, observeQueueCommand2);
|
|
5425
|
+
return;
|
|
5426
|
+
}
|
|
5413
5427
|
const { trackObserveCommand: trackObserveCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5414
5428
|
await runTrackObserve(idOrLogId, options, trackObserveCommand2);
|
|
5415
5429
|
});
|
|
5416
|
-
adminTrack.command("context").description("Gather the field notes for a finding (facts only; observe speaks from them)").argument("[idOrLogId]").option("--query <text>", "Override the fact-search query (else the Worker builds one)").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5430
|
+
adminTrack.command("context").description("Gather the field notes for a finding (facts only; observe speaks from them)").argument("[idOrLogId]").option("--queue", "Show the context worklist (findings missing field notes), oldest first", false).option("--limit <limit>", "Number of findings to show with --queue", "10").option("--query <text>", "Override the fact-search query (else the Worker builds one)").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5431
|
+
if (options.queue) {
|
|
5432
|
+
const { contextQueueCommand: contextQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5433
|
+
await runAdminContextQueue(options, contextQueueCommand2);
|
|
5434
|
+
return;
|
|
5435
|
+
}
|
|
5417
5436
|
const { trackContextCommand: trackContextCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5418
5437
|
await runTrackContext(idOrLogId, options, trackContextCommand2);
|
|
5419
5438
|
});
|
|
@@ -5784,7 +5803,7 @@ async function runTrackSocial(idOrLogId, options, trackSocialShowCommand2, track
|
|
|
5784
5803
|
}
|
|
5785
5804
|
async function runTrackGet(idOrLogId, options, trackGetCommand2) {
|
|
5786
5805
|
if (!idOrLogId) {
|
|
5787
|
-
throw new Error("Missing id. Usage: fluncle
|
|
5806
|
+
throw new Error("Missing id. Usage: fluncle tracks get <track_id|log_id> [--json]");
|
|
5788
5807
|
}
|
|
5789
5808
|
const result = await trackGetCommand2(idOrLogId);
|
|
5790
5809
|
if (options.json) {
|
|
@@ -6224,6 +6243,9 @@ function assertParseArgsCompatibleOptionValues(args) {
|
|
|
6224
6243
|
}
|
|
6225
6244
|
for (let index = 0;index < args.length; index += 1) {
|
|
6226
6245
|
const arg = args[index];
|
|
6246
|
+
if (arg === undefined) {
|
|
6247
|
+
continue;
|
|
6248
|
+
}
|
|
6227
6249
|
if (arg === "--") {
|
|
6228
6250
|
return;
|
|
6229
6251
|
}
|
|
@@ -6253,6 +6275,9 @@ function positionalArgs(args) {
|
|
|
6253
6275
|
const positionals = [];
|
|
6254
6276
|
for (let index = 0;index < args.length; index += 1) {
|
|
6255
6277
|
const arg = args[index];
|
|
6278
|
+
if (arg === undefined) {
|
|
6279
|
+
continue;
|
|
6280
|
+
}
|
|
6256
6281
|
if (arg === "--") {
|
|
6257
6282
|
positionals.push(...args.slice(index + 1));
|
|
6258
6283
|
return positionals;
|
|
@@ -6281,6 +6306,9 @@ function positionalArgs(args) {
|
|
|
6281
6306
|
function topLevelCommand(args) {
|
|
6282
6307
|
for (let index = 0;index < args.length; index += 1) {
|
|
6283
6308
|
const arg = args[index];
|
|
6309
|
+
if (arg === undefined) {
|
|
6310
|
+
continue;
|
|
6311
|
+
}
|
|
6284
6312
|
if (arg === "--env") {
|
|
6285
6313
|
index += 1;
|
|
6286
6314
|
continue;
|
package/package.json
CHANGED