Skip to content

ft sync lacks --media-limit <n> flag that ft fetch-media --limit already supports #151

@RealADemin

Description

@RealADemin

ft sync runs runMediaFetchWithProgress automatically after the bookmark sync completes (unless --no-media is passed). The standalone ft fetch-media command accepts --limit <n> for capping how many pending bookmarks' media gets fetched in one run — but ft sync doesn't surface the equivalent, so ft sync always fetches all pending media in one shot.

For users with large media backlogs (e.g., after a --rebuild, or a first sync against a corpus with thousands of un-downloaded items), this either blocks for a long time or runs into rate limits. The workaround is ft sync --no-media && ft fetch-media --limit <n> as two commands; surfacing the flag on sync directly would match the existing ft fetch-media --limit contract and let downstream tools (CLI users, third-party wrappers) cap a single ft sync invocation.

The plumbing already exists

The helper runMediaFetchWithProgress at src/cli.ts:207 already accepts the limit parameter:

async function runMediaFetchWithProgress(
  options: { limit?: number; maxBytes?: number; skipProfileImages?: boolean } = {}
): Promise<MediaFetchManifest>

ft fetch-media invokes it WITH limit (src/cli.ts:1515-1521):

await runMediaFetchWithProgress({
  limit: typeof options.limit === 'number' && !Number.isNaN(options.limit) ? options.limit : undefined,
  maxBytes: ...,
  skipProfileImages: ...,
});

ft sync invokes it WITHOUT limit (src/cli.ts:800):

const postSyncMediaFetch = async (): Promise<void> => {
  if (!downloadMedia) return;
  await runMediaFetchWithProgress({
    maxBytes: mediaMaxBytes,
    skipProfileImages: Boolean(options.skipProfileImages),
  });
  console.log('');
};

No limit field passed → runMediaFetchWithProgress defaults to unlimited.

ft sync's current flag list (around src/cli.ts:740-742) has --no-media, --media-max-bytes, --skip-profile-images — but no media-limit equivalent.

Suggested fix

Two changes in src/cli.ts:

  1. Add the option to the ft sync command definition, mirroring the existing --media-max-bytes shape:
.option('--media-limit <n>', 'Cap on pending bookmarks whose media gets fetched after sync (default: all)', (v: string) => Number(v))
  1. Pass it through at line 800:
await runMediaFetchWithProgress({
  limit: typeof options.mediaLimit === 'number' && !Number.isNaN(options.mediaLimit) ? options.mediaLimit : undefined,
  maxBytes: mediaMaxBytes,
  skipProfileImages: Boolean(options.skipProfileImages),
});

That's the full change — the helper already does the right thing with limit: undefined (unlimited) vs a number (cap). No new logic, no schema, no migration.

Naming nit

--media-limit mirrors the existing --media-max-bytes (both media- prefixed on the sync command, distinguishing them from bookmark-pagination flags like --max-pages). Could also be --media-batch <n> or --fetch-limit <n> — maintainer's call.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions