VFS now loads on first has()/getMtime() call rather than requiring
explicit initialization in sync/index.mjs. This ensures it works
regardless of entry point (sync:download, splatnet:quick, etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No major calendar client renders these inline binary attachments.
The ATTACH URL is kept, which links to the publicly hosted image.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
exists() and olderThan() now check the local filesystem first and only
consult the VFS as a fallback. This means freshly written files are
found naturally without callers needing to register them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses S3 ListObjectsV2 to build an in-memory file listing at startup,
allowing exists() and olderThan() to resolve from the listing instead
of requiring files on disk. sync:download now skips assets/splatnet/,
data/xrank/, data/festivals.ranking.*, and status-screenshots/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dotenv v17: Added quiet option to suppress new default logging.
p-limit v7 and p-queue v9: No code changes needed (only dropped older Node).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cron v4: No code changes needed (positional constructor args still supported).
ical-generator v10: Removed `new` keyword (now a factory function) and
switched from `attachments` property to `createAttachment()` method.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jsonpath v1.2.1 (published Feb 2025) fixed the security vulnerability
that prompted the switch to jsonpath-plus. Reverting to the original
package simplifies the code by removing the jsonpathQuery/jsonpathApply
wrapper functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added mkdirp() helper to app/common/fs.mjs that wraps
fs.mkdir(dir, { recursive: true }). Updated all call sites to use it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace silent error handling with descriptive messages: log
HTTP status in i18n locale loading, log response details in
data store fetch, and warn on unexpected localization file
read errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Deduplicate identical _calculateCacheExpiry methods from
SplatNet3Client and NsoClient into a shared calculateCacheExpiry
function in util.mjs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use strict equality in TricolorBox, add async keyword to
CoopUpdater/GearUpdater getData() for consistency, and add
missing HMR accept for useCoopGearStore.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wrap send() methods in try-catch with descriptive error messages
and add early return when media is missing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Guard against accessing undefined media arrays in FileWriter,
ImageWriter, and protect against findIndex returning -1 in
SplatfestResultsBox.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>