fluncle 0.56.0 → 0.58.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 +119 -8
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -423,7 +423,7 @@ function parseVersion(version) {
|
|
|
423
423
|
var currentVersion;
|
|
424
424
|
var init_version = __esm(() => {
|
|
425
425
|
init_output();
|
|
426
|
-
currentVersion = "0.
|
|
426
|
+
currentVersion = "0.58.0".trim() ? "0.58.0".trim() : "0.1.0";
|
|
427
427
|
});
|
|
428
428
|
|
|
429
429
|
// src/update-notifier.ts
|
|
@@ -782,6 +782,7 @@ function mapTrack(track) {
|
|
|
782
782
|
title: track.title,
|
|
783
783
|
trackId: track.trackId,
|
|
784
784
|
type: "finding",
|
|
785
|
+
videoGrain: track.videoGrain,
|
|
785
786
|
videoModel: track.videoModel,
|
|
786
787
|
videoModelReasoning: track.videoModelReasoning,
|
|
787
788
|
videoUrl: track.videoUrl,
|
|
@@ -1531,6 +1532,7 @@ function mapTrack2(track) {
|
|
|
1531
1532
|
title: track.title,
|
|
1532
1533
|
trackId: track.trackId,
|
|
1533
1534
|
type: "finding",
|
|
1535
|
+
videoGrain: track.videoGrain,
|
|
1534
1536
|
videoModel: track.videoModel,
|
|
1535
1537
|
videoModelReasoning: track.videoModelReasoning,
|
|
1536
1538
|
videoUrl: track.videoUrl,
|
|
@@ -1912,7 +1914,7 @@ function parseVersion2(version) {
|
|
|
1912
1914
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
1913
1915
|
var init_version2 = __esm(() => {
|
|
1914
1916
|
init_output();
|
|
1915
|
-
currentVersion2 = "0.
|
|
1917
|
+
currentVersion2 = "0.58.0".trim() ? "0.58.0".trim() : "0.1.0";
|
|
1916
1918
|
});
|
|
1917
1919
|
|
|
1918
1920
|
// src/commands/track.ts
|
|
@@ -1922,7 +1924,10 @@ __export(exports_track, {
|
|
|
1922
1924
|
trackUpdateCommand: () => trackUpdateCommand,
|
|
1923
1925
|
trackSocialUpdateCommand: () => trackSocialUpdateCommand,
|
|
1924
1926
|
trackSocialShowCommand: () => trackSocialShowCommand,
|
|
1927
|
+
trackRequeueVideoCommand: () => trackRequeueVideoCommand,
|
|
1928
|
+
trackPurgeVideoCommand: () => trackPurgeVideoCommand,
|
|
1925
1929
|
trackObserveCommand: () => trackObserveCommand,
|
|
1930
|
+
trackNoteCommand: () => trackNoteCommand,
|
|
1926
1931
|
trackGetCommand: () => trackGetCommand,
|
|
1927
1932
|
trackDraftCommand: () => trackDraftCommand,
|
|
1928
1933
|
trackContextCommand: () => trackContextCommand
|
|
@@ -1963,7 +1968,8 @@ async function trackVideoCommand(idOrLogId, files, onProgress) {
|
|
|
1963
1968
|
videoModel,
|
|
1964
1969
|
videoModelReasoning,
|
|
1965
1970
|
...squared ? { squared: true } : {},
|
|
1966
|
-
...manifest.vehicle ? { videoVehicle: manifest.vehicle } : {}
|
|
1971
|
+
...manifest.vehicle ? { videoVehicle: manifest.vehicle } : {},
|
|
1972
|
+
...manifest.grain ? { videoGrain: manifest.grain } : {}
|
|
1967
1973
|
});
|
|
1968
1974
|
return { logId: finalize.logId, ok: true, trackId: finalize.trackId, urls };
|
|
1969
1975
|
}
|
|
@@ -1971,7 +1977,7 @@ async function readManifestFields(renderPath) {
|
|
|
1971
1977
|
try {
|
|
1972
1978
|
const manifest = await Bun.file(renderPath).json();
|
|
1973
1979
|
const result = {};
|
|
1974
|
-
for (const key of ["vehicle", "model", "reasoning"]) {
|
|
1980
|
+
for (const key of ["vehicle", "grain", "model", "reasoning"]) {
|
|
1975
1981
|
const value = manifest[key];
|
|
1976
1982
|
if (typeof value === "string" && value.trim()) {
|
|
1977
1983
|
result[key] = value.trim().slice(0, 120);
|
|
@@ -2019,6 +2025,12 @@ async function trackUpdateCommand(trackId, options) {
|
|
|
2019
2025
|
}
|
|
2020
2026
|
return adminApiPatch(`/api/admin/tracks/${encodeURIComponent(trackId)}`, body);
|
|
2021
2027
|
}
|
|
2028
|
+
async function trackRequeueVideoCommand(idOrLogId) {
|
|
2029
|
+
return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/video/requeue`);
|
|
2030
|
+
}
|
|
2031
|
+
async function trackPurgeVideoCommand(idOrLogId) {
|
|
2032
|
+
return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/video/purge`);
|
|
2033
|
+
}
|
|
2022
2034
|
async function trackObserveCommand(idOrLogId, options) {
|
|
2023
2035
|
const body = { script: options.script };
|
|
2024
2036
|
if (options.voiceId !== undefined) {
|
|
@@ -2043,8 +2055,15 @@ async function trackContextCommand(idOrLogId, options = {}) {
|
|
|
2043
2055
|
if (options.query !== undefined) {
|
|
2044
2056
|
body.query = options.query;
|
|
2045
2057
|
}
|
|
2058
|
+
if (options.refresh) {
|
|
2059
|
+
body.refresh = true;
|
|
2060
|
+
}
|
|
2046
2061
|
return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/context`, body);
|
|
2047
2062
|
}
|
|
2063
|
+
async function trackNoteCommand(idOrLogId, options) {
|
|
2064
|
+
const body = { note: options.note };
|
|
2065
|
+
return adminApiPost(`/api/admin/tracks/${encodeURIComponent(idOrLogId)}/note`, body);
|
|
2066
|
+
}
|
|
2048
2067
|
var DEFAULT_VIDEO_MODEL = "anthropic/claude-opus-4-8", DEFAULT_VIDEO_REASONING = "high", FOUND_BASE = "https://found.fluncle.com", VIDEO_FIELDS;
|
|
2049
2068
|
var init_track = __esm(() => {
|
|
2050
2069
|
init_api();
|
|
@@ -2094,6 +2113,7 @@ __export(exports_admin_tracks, {
|
|
|
2094
2113
|
vehiclesCommand: () => vehiclesCommand,
|
|
2095
2114
|
queueCommand: () => queueCommand,
|
|
2096
2115
|
observeQueueCommand: () => observeQueueCommand,
|
|
2116
|
+
noteQueueCommand: () => noteQueueCommand,
|
|
2097
2117
|
enrichQueueCommand: () => enrichQueueCommand,
|
|
2098
2118
|
contextQueueCommand: () => contextQueueCommand,
|
|
2099
2119
|
backfillLastfmCommand: () => backfillLastfmCommand,
|
|
@@ -2101,7 +2121,7 @@ __export(exports_admin_tracks, {
|
|
|
2101
2121
|
backfillAlignmentCommand: () => backfillAlignmentCommand
|
|
2102
2122
|
});
|
|
2103
2123
|
async function fetchAdminTracks(options) {
|
|
2104
|
-
const { hasContext, hasObservation, hasVideo, max, order, status } = options;
|
|
2124
|
+
const { hasContext, hasNote, hasObservation, hasVideo, max, order, status } = options;
|
|
2105
2125
|
const results = [];
|
|
2106
2126
|
let cursor;
|
|
2107
2127
|
do {
|
|
@@ -2112,6 +2132,9 @@ async function fetchAdminTracks(options) {
|
|
|
2112
2132
|
if (hasContext !== undefined) {
|
|
2113
2133
|
params.set("hasContext", String(hasContext));
|
|
2114
2134
|
}
|
|
2135
|
+
if (hasNote !== undefined) {
|
|
2136
|
+
params.set("hasNote", String(hasNote));
|
|
2137
|
+
}
|
|
2115
2138
|
if (hasObservation !== undefined) {
|
|
2116
2139
|
params.set("hasObservation", String(hasObservation));
|
|
2117
2140
|
}
|
|
@@ -2159,6 +2182,14 @@ async function observeQueueCommand(limit) {
|
|
|
2159
2182
|
order: "asc"
|
|
2160
2183
|
});
|
|
2161
2184
|
}
|
|
2185
|
+
async function noteQueueCommand(limit) {
|
|
2186
|
+
return fetchAdminTracks({
|
|
2187
|
+
hasContext: true,
|
|
2188
|
+
hasNote: false,
|
|
2189
|
+
max: limit,
|
|
2190
|
+
order: "asc"
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
2162
2193
|
async function backfillLastfmCommand(limit, dryRun, cursor) {
|
|
2163
2194
|
const params = new URLSearchParams({ dryRun: String(dryRun), limit: String(limit) });
|
|
2164
2195
|
if (cursor) {
|
|
@@ -2185,6 +2216,7 @@ async function vehiclesCommand(limit) {
|
|
|
2185
2216
|
return tracks.map((track) => ({
|
|
2186
2217
|
addedAt: track.addedAt,
|
|
2187
2218
|
artists: track.artists,
|
|
2219
|
+
grain: track.videoGrain,
|
|
2188
2220
|
logId: track.logId,
|
|
2189
2221
|
title: track.title,
|
|
2190
2222
|
vehicle: track.videoVehicle
|
|
@@ -5470,6 +5502,14 @@ function addAdminCommands(program2) {
|
|
|
5470
5502
|
const { trackVideoCommand: trackVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5471
5503
|
await runTrackVideo(idOrLogId, options, trackVideoCommand2);
|
|
5472
5504
|
});
|
|
5505
|
+
adminTrack.command("requeue-video").description("Clear a finding's video so it re-enters the render queue (operator)").argument("[idOrLogId]").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5506
|
+
const { trackRequeueVideoCommand: trackRequeueVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5507
|
+
await runTrackRequeueVideo(idOrLogId, options, trackRequeueVideoCommand2);
|
|
5508
|
+
});
|
|
5509
|
+
adminTrack.command("purge-video").description("Purge a finding's stale Cloudflare video renditions from the edge (operator)").argument("[idOrLogId]").option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5510
|
+
const { trackPurgeVideoCommand: trackPurgeVideoCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5511
|
+
await runTrackPurgeVideo(idOrLogId, options, trackPurgeVideoCommand2);
|
|
5512
|
+
});
|
|
5473
5513
|
adminTrack.command("draft").description("Push the video to a platform as a draft").argument("[idOrLogId]").option("--json", "Print JSON", false).option("--platform <platform>", "Publishing platform").allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5474
5514
|
const { trackDraftCommand: trackDraftCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5475
5515
|
await runTrackDraft(idOrLogId, options, trackDraftCommand2);
|
|
@@ -5491,7 +5531,7 @@ function addAdminCommands(program2) {
|
|
|
5491
5531
|
const { trackObserveCommand: trackObserveCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5492
5532
|
await runTrackObserve(idOrLogId, options, trackObserveCommand2);
|
|
5493
5533
|
});
|
|
5494
|
-
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) => {
|
|
5534
|
+
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("--refresh", "Re-run the fetch even if a note exists (backfill/sharpen)", false).option("--json", "Print JSON", false).allowExcessArguments().action(async (idOrLogId, options) => {
|
|
5495
5535
|
if (options.queue) {
|
|
5496
5536
|
const { contextQueueCommand: contextQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5497
5537
|
await runAdminContextQueue(options, contextQueueCommand2);
|
|
@@ -5500,6 +5540,15 @@ function addAdminCommands(program2) {
|
|
|
5500
5540
|
const { trackContextCommand: trackContextCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5501
5541
|
await runTrackContext(idOrLogId, options, trackContextCommand2);
|
|
5502
5542
|
});
|
|
5543
|
+
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) => {
|
|
5544
|
+
if (options.queue) {
|
|
5545
|
+
const { noteQueueCommand: noteQueueCommand2 } = await Promise.resolve().then(() => (init_admin_tracks(), exports_admin_tracks));
|
|
5546
|
+
await runAdminNoteQueue(options, noteQueueCommand2);
|
|
5547
|
+
return;
|
|
5548
|
+
}
|
|
5549
|
+
const { trackNoteCommand: trackNoteCommand2 } = await Promise.resolve().then(() => (init_track(), exports_track));
|
|
5550
|
+
await runTrackNote(idOrLogId, options, trackNoteCommand2);
|
|
5551
|
+
});
|
|
5503
5552
|
const adminMixtapes = configureCommand(admin.command("mixtapes").description("Mixtape admin commands"));
|
|
5504
5553
|
adminMixtapes.action(() => {
|
|
5505
5554
|
adminMixtapes.outputHelp();
|
|
@@ -5674,9 +5723,12 @@ async function runTrackObserve(idOrLogId, options, trackObserveCommand2) {
|
|
|
5674
5723
|
}
|
|
5675
5724
|
async function runTrackContext(idOrLogId, options, trackContextCommand2) {
|
|
5676
5725
|
if (!idOrLogId) {
|
|
5677
|
-
throw new Error("Usage: fluncle admin tracks context <track_id|log_id> [--query <text>] [--json]");
|
|
5726
|
+
throw new Error("Usage: fluncle admin tracks context <track_id|log_id> [--query <text>] [--refresh] [--json]");
|
|
5678
5727
|
}
|
|
5679
|
-
const result = await trackContextCommand2(idOrLogId, {
|
|
5728
|
+
const result = await trackContextCommand2(idOrLogId, {
|
|
5729
|
+
query: options.query,
|
|
5730
|
+
refresh: options.refresh
|
|
5731
|
+
});
|
|
5680
5732
|
if (options.json) {
|
|
5681
5733
|
printJson(result);
|
|
5682
5734
|
return;
|
|
@@ -5695,6 +5747,23 @@ async function runTrackContext(idOrLogId, options, trackContextCommand2) {
|
|
|
5695
5747
|
console.log(` sources: ${result.sources.join(", ")}`);
|
|
5696
5748
|
}
|
|
5697
5749
|
}
|
|
5750
|
+
async function runTrackNote(idOrLogId, options, trackNoteCommand2) {
|
|
5751
|
+
const note = options.scriptFile ? readFileSync3(options.scriptFile, "utf8") : options.script;
|
|
5752
|
+
if (!idOrLogId || !note || !note.trim()) {
|
|
5753
|
+
throw new Error("Usage: fluncle admin tracks note <track_id|log_id> (--script <text> | --script-file <file>) [--json]");
|
|
5754
|
+
}
|
|
5755
|
+
const result = await trackNoteCommand2(idOrLogId, { note: note.trim() });
|
|
5756
|
+
if (options.json) {
|
|
5757
|
+
printJson(result);
|
|
5758
|
+
return;
|
|
5759
|
+
}
|
|
5760
|
+
if (result.skipped) {
|
|
5761
|
+
console.log(`A note is already on file for ${result.logId}. The operator's note stands.`);
|
|
5762
|
+
return;
|
|
5763
|
+
}
|
|
5764
|
+
console.log(`Authored the note for ${result.logId}:`);
|
|
5765
|
+
console.log(` ${result.note}`);
|
|
5766
|
+
}
|
|
5698
5767
|
async function runPreviewArchiveBackfill(options, previewArchiveBackfillCommand2) {
|
|
5699
5768
|
const limit = options.limit === undefined ? undefined : Number.parseInt(options.limit, 10);
|
|
5700
5769
|
if (limit !== undefined && (!Number.isInteger(limit) || limit < 1)) {
|
|
@@ -5990,6 +6059,28 @@ async function runTrackUpdate(trackId, options, trackUpdateCommand2) {
|
|
|
5990
6059
|
}
|
|
5991
6060
|
console.log(`Updated ${result.trackId}: ${result.fields.join(", ")}`);
|
|
5992
6061
|
}
|
|
6062
|
+
async function runTrackRequeueVideo(idOrLogId, options, trackRequeueVideoCommand2) {
|
|
6063
|
+
if (!idOrLogId) {
|
|
6064
|
+
throw new Error("Missing id. Usage: fluncle admin tracks requeue-video <track_id|log_id>");
|
|
6065
|
+
}
|
|
6066
|
+
const result = await trackRequeueVideoCommand2(idOrLogId);
|
|
6067
|
+
if (options.json) {
|
|
6068
|
+
printJson(result);
|
|
6069
|
+
return;
|
|
6070
|
+
}
|
|
6071
|
+
console.log(result.alreadyClear ? `${result.logId} already had no video \u2014 nothing to clear.` : `Cleared the video for ${result.logId}. It's back on the render queue (and off radio until re-rendered).`);
|
|
6072
|
+
}
|
|
6073
|
+
async function runTrackPurgeVideo(idOrLogId, options, trackPurgeVideoCommand2) {
|
|
6074
|
+
if (!idOrLogId) {
|
|
6075
|
+
throw new Error("Missing id. Usage: fluncle admin tracks purge-video <track_id|log_id>");
|
|
6076
|
+
}
|
|
6077
|
+
const result = await trackPurgeVideoCommand2(idOrLogId);
|
|
6078
|
+
if (options.json) {
|
|
6079
|
+
printJson(result);
|
|
6080
|
+
return;
|
|
6081
|
+
}
|
|
6082
|
+
console.log(result.noVideo ? `${result.logId} has no video \u2014 nothing to purge.` : `Purging the stale renditions for ${result.logId} from the edge. The next play picks up the fresh render.`);
|
|
6083
|
+
}
|
|
5993
6084
|
async function runMixtapeCreate(options, mixtapeCreateCommand2) {
|
|
5994
6085
|
const result = await mixtapeCreateCommand2(options);
|
|
5995
6086
|
if (options.json) {
|
|
@@ -6307,6 +6398,26 @@ async function runAdminObserveQueue(options, observeQueueCommand2) {
|
|
|
6307
6398
|
console.log(trackRows2(tracks).join(`
|
|
6308
6399
|
`));
|
|
6309
6400
|
}
|
|
6401
|
+
async function runAdminNoteQueue(options, noteQueueCommand2) {
|
|
6402
|
+
const limit = parseListLimit(options.limit);
|
|
6403
|
+
const tracks = await noteQueueCommand2(limit);
|
|
6404
|
+
if (options.json) {
|
|
6405
|
+
printJson({
|
|
6406
|
+
ok: true,
|
|
6407
|
+
tracks
|
|
6408
|
+
});
|
|
6409
|
+
return;
|
|
6410
|
+
}
|
|
6411
|
+
if (tracks.length === 0) {
|
|
6412
|
+
console.log("Every context'd finding has a note. Nothing waiting on the uncle's words.");
|
|
6413
|
+
return;
|
|
6414
|
+
}
|
|
6415
|
+
const { trackRows: trackRows2 } = await Promise.resolve().then(() => (init_format2(), exports_format));
|
|
6416
|
+
const noun = tracks.length === 1 ? "finding" : "findings";
|
|
6417
|
+
console.log(`${tracks.length} ${noun} awaiting a note, oldest first:`);
|
|
6418
|
+
console.log(trackRows2(tracks).join(`
|
|
6419
|
+
`));
|
|
6420
|
+
}
|
|
6310
6421
|
async function runAdminEnrichQueue(options, enrichQueueCommand2) {
|
|
6311
6422
|
const limit = parseListLimit(options.limit);
|
|
6312
6423
|
const tracks = await enrichQueueCommand2(limit);
|
package/package.json
CHANGED