fluncle 0.227.0 → 0.229.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 +43 -8
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -612,7 +612,7 @@ function parseVersion(version) {
|
|
|
612
612
|
var currentVersion;
|
|
613
613
|
var init_version = __esm(() => {
|
|
614
614
|
init_output();
|
|
615
|
-
currentVersion = "0.
|
|
615
|
+
currentVersion = "0.229.0".trim() ? "0.229.0".trim() : "0.1.0";
|
|
616
616
|
});
|
|
617
617
|
|
|
618
618
|
// src/update-notifier.ts
|
|
@@ -2362,7 +2362,10 @@ var init_about = __esm(() => {
|
|
|
2362
2362
|
heading: "The mothership",
|
|
2363
2363
|
links: [
|
|
2364
2364
|
{ label: "Web: the archive", url: "https://www.fluncle.com" },
|
|
2365
|
-
{
|
|
2365
|
+
{
|
|
2366
|
+
label: "Newsletter",
|
|
2367
|
+
url: "Fresh bangers, every Friday, from Fluncle. Board it at www.fluncle.com"
|
|
2368
|
+
},
|
|
2366
2369
|
{ label: "RSS: the feed", url: "https://www.fluncle.com/rss.xml" }
|
|
2367
2370
|
]
|
|
2368
2371
|
},
|
|
@@ -2454,7 +2457,7 @@ function parseVersion2(version) {
|
|
|
2454
2457
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2455
2458
|
var init_version2 = __esm(() => {
|
|
2456
2459
|
init_output();
|
|
2457
|
-
currentVersion2 = "0.
|
|
2460
|
+
currentVersion2 = "0.229.0".trim() ? "0.229.0".trim() : "0.1.0";
|
|
2458
2461
|
});
|
|
2459
2462
|
|
|
2460
2463
|
// ../../packages/registry/src/index.ts
|
|
@@ -2468,7 +2471,9 @@ var init_src = __esm(() => {
|
|
|
2468
2471
|
MINUTE_MS = 60 * 1000;
|
|
2469
2472
|
SURFACES = [
|
|
2470
2473
|
{
|
|
2471
|
-
exposedContent: [
|
|
2474
|
+
exposedContent: [
|
|
2475
|
+
"the front door — search with real example queries, one edited lead finding, the newest findings, what just came out, and the four routes into the wider archive"
|
|
2476
|
+
],
|
|
2472
2477
|
kind: "web_route",
|
|
2473
2478
|
name: "web.home",
|
|
2474
2479
|
operatorNotes: "The Worker root. galaxy./radio. rewrite their root to /galaxy and /radio.",
|
|
@@ -2477,6 +2482,16 @@ var init_src = __esm(() => {
|
|
|
2477
2482
|
url: `${SITE}/`,
|
|
2478
2483
|
weights: { web: "primary" }
|
|
2479
2484
|
},
|
|
2485
|
+
{
|
|
2486
|
+
exposedContent: ["the archive — every certified finding, newest first, cover-led"],
|
|
2487
|
+
kind: "web_route",
|
|
2488
|
+
name: "web.findings",
|
|
2489
|
+
operatorNotes: "The cover-led archive page the root used to be. Carries the Stories viewer (?story=<logId>, masked to /log/<id>); /?story= 301s to /log/<id>.",
|
|
2490
|
+
probeConfig: { cadenceMs: PROBE_CADENCE_MS, kind: "http", timeoutMs: PROBE_TIMEOUT_MS },
|
|
2491
|
+
route: "/findings",
|
|
2492
|
+
url: `${SITE}/findings`,
|
|
2493
|
+
weights: { web: "primary" }
|
|
2494
|
+
},
|
|
2480
2495
|
{
|
|
2481
2496
|
exposedContent: [
|
|
2482
2497
|
"the log index — every finding's coordinate page",
|
|
@@ -2657,11 +2672,26 @@ var init_src = __esm(() => {
|
|
|
2657
2672
|
{
|
|
2658
2673
|
discoveryUrl: `${SITE}/llms.txt`,
|
|
2659
2674
|
exposedContent: [
|
|
2660
|
-
"/
|
|
2675
|
+
"/search — the persistent, linkable search surface: one `?q=` carries a coordinate, an entity name, a natural-language filter, or a sonic reference, and the answer is server-rendered from the URL",
|
|
2676
|
+
"/search?q=<query> — a shareable, reload-safe result set over the whole archive (findings and the wider catalogue)"
|
|
2677
|
+
],
|
|
2678
|
+
kind: "web_route",
|
|
2679
|
+
name: "web.search",
|
|
2680
|
+
operatorNotes: "The PERSISTENT half of search — the addressable counterpart to the ⌘K palette, which stays the accelerator and hands off here (components/search/search-command.tsx). It calls the SAME primitive, `searchArchive` (lib/server/search.ts), through a serverFn, so all four resolution tiers, the certified-first ranking, the catalogue rule, and the degradation contract are the ones docs/search.md already specifies; nothing is re-resolved. THE WHOLE QUERY STATE IS ONE PARAM, because the resolver takes one string — a coordinate, a name, a sentence, and a sonic reference all arrive as `q`. A coordinate/entity `redirect` is deliberately NOT followed here (the palette may; a persistent URL that bounced would be un-shareable and a back-button trap): the resolved row is rendered as the first result instead. The field commits on SUBMIT, never per keystroke, so history holds one entry per real query. It is a real `<form method=get action=/search>`, so search works with no JS. The BARE surface is indexable, in the sitemap, and carries the WebSite SearchAction; ANY `?q=` view is noindex, follow with its canonical collapsed onto the bare page (the /tracks filtered-view rule, and the standard posture for an internal results page). The INDEX is always-200, so it is HTTP-probeable.",
|
|
2681
|
+
probeConfig: { cadenceMs: PROBE_CADENCE_MS, kind: "http", timeoutMs: PROBE_TIMEOUT_MS },
|
|
2682
|
+
route: "/search",
|
|
2683
|
+
url: `${SITE}/search`,
|
|
2684
|
+
weights: { web: "primary" }
|
|
2685
|
+
},
|
|
2686
|
+
{
|
|
2687
|
+
discoveryUrl: `${SITE}/llms.txt`,
|
|
2688
|
+
exposedContent: [
|
|
2689
|
+
"/tracks — the whole list: every track Fluncle holds (certified findings + the wider catalogue), newest release first, filterable by release year, tempo, key, label, and galaxy",
|
|
2690
|
+
"/track/:trackId — one archive recording: its artists, record, imprint, release date, tempo and key, a bounded preview, every service that carries it, and what sits close to it in sound"
|
|
2661
2691
|
],
|
|
2662
2692
|
kind: "web_route",
|
|
2663
2693
|
name: "web.tracks",
|
|
2664
|
-
operatorNotes: "The top-level track index — the whole archive as one browse list, findings in full voice and the catalogue rows in the unlit register (DESIGN.md). Ordered by tracks.release_date (what came out), never findings.added_at (the Found Rule), numbered-paginated (?page=N) over the tracks_release_date_track_id_idx btree with a quiet YEAR fast lane, so a crawler with no JS walks the whole list (lib/server/tracks-hub.ts). The filter params MIRROR the search vocabulary verbatim (yearMin/yearMax, bpmMin/bpmMax, key, label; galaxy is the one extension). The bare HUB is always indexable + in the sitemap, each page self-canonical; ANY filter param present flips it to noindex, and paged bare URLs stay out of the sitemap. The INDEX is always-200, so it is HTTP-probeable.",
|
|
2694
|
+
operatorNotes: "The top-level track index — the whole archive as one browse list, findings in full voice and the catalogue rows in the unlit register (DESIGN.md). Ordered by tracks.release_date (what came out), never findings.added_at (the Found Rule), numbered-paginated (?page=N) over the tracks_release_date_track_id_idx btree with a quiet YEAR fast lane, so a crawler with no JS walks the whole list (lib/server/tracks-hub.ts). The filter params MIRROR the search vocabulary verbatim (yearMin/yearMax, bpmMin/bpmMax, key, label; galaxy is the one extension). The bare HUB is always indexable + in the sitemap, each page self-canonical; ANY filter param present flips it to noindex, and paged bare URLs stay out of the sitemap. The INDEX is always-200, so it is HTTP-probeable. The DETAIL page /track/:trackId is the archive recording's own destination, keyed on the row's permanent primary key; a CERTIFIED track 301s to /log/<coordinate> (that URL and its meaning are unchanged) and a stamped duplicate 301s to its principal. It carries its own EVIDENCE gate: one SQL expression (TRACK_PAGE_INDEXABLE_WHERE) drives both the page's robots directive and its sitemap membership, so a low-evidence page serves 200 + noindex,follow and stays out of the tracks sitemap child by construction. See docs/track-destination.md.",
|
|
2665
2695
|
probeConfig: { cadenceMs: PROBE_CADENCE_MS, kind: "http", timeoutMs: PROBE_TIMEOUT_MS },
|
|
2666
2696
|
route: "/tracks",
|
|
2667
2697
|
url: `${SITE}/tracks`,
|
|
@@ -4240,7 +4270,7 @@ function checkBundleCompleteness(files) {
|
|
|
4240
4270
|
uploadingFootage
|
|
4241
4271
|
};
|
|
4242
4272
|
}
|
|
4243
|
-
|
|
4273
|
+
function validateBundleCompleteness(files, onProgress, options) {
|
|
4244
4274
|
const completeness = checkBundleCompleteness(files);
|
|
4245
4275
|
if (completeness.uploadingFootage && completeness.missingContract.length > 0 && !options.allowPartial) {
|
|
4246
4276
|
throw new CliError2("bundle_incomplete", `Refusing to upload a PARTIAL bundle: footage is being uploaded but the re-render contract is missing ${completeness.missingContract.join(", ")}. ` + `A footage-only upload leaves composition.tsx/props.json/render.json stale on R2 and desyncs the render.json from the DB ledger. ` + `Ship the complete bundle (re-run \`ship\` and upload with --dir), or pass --allow-partial for a deliberate partial refresh (e.g. poster-only).`);
|
|
@@ -4256,6 +4286,9 @@ async function trackVideoCommand(idOrLogId, files, onProgress, options = {}) {
|
|
|
4256
4286
|
for (const warning of completeness.plateWarnings) {
|
|
4257
4287
|
onProgress?.(`warning: ${warning}`);
|
|
4258
4288
|
}
|
|
4289
|
+
}
|
|
4290
|
+
async function trackVideoCommand(idOrLogId, files, onProgress, options = {}) {
|
|
4291
|
+
validateBundleCompleteness(files, onProgress, options);
|
|
4259
4292
|
const present = VIDEO_FIELDS.map((spec) => ({
|
|
4260
4293
|
field: spec.field,
|
|
4261
4294
|
path: files[spec.option]
|
|
@@ -12799,7 +12832,9 @@ var init__shared = __esm(() => {
|
|
|
12799
12832
|
logId: string2().optional(),
|
|
12800
12833
|
releaseDate: string2().optional(),
|
|
12801
12834
|
spotifyUrl: string2().optional(),
|
|
12802
|
-
title: string2()
|
|
12835
|
+
title: string2(),
|
|
12836
|
+
trackId: string2(),
|
|
12837
|
+
url: string2().optional()
|
|
12803
12838
|
}).meta({ id: "CatalogueTrackListItem" });
|
|
12804
12839
|
FreshAlbumSchema = object({
|
|
12805
12840
|
artists: array(string2()),
|
package/package.json
CHANGED