npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fieldlyab/translator-cli

v0.12.1

Published

Fieldly Translator developer CLI (ft) — push/pull/status translations between repos and Fieldly Translator.

Readme

ft — Fieldly Translator CLI

A thin command-line transport between your repo's translation files and Fieldly Translator (FT). It does not parse translation formats — it reads raw files at configured paths and POSTs/GETs them; FT's server-side engine handles every format (Rails YAML, ngx-translate/Transloco JSON, Android XML, iOS strings/stringsdict/xcstrings).

Cross-platform (macOS / Windows / Linux) via Node ≥ 18.

Fieldly Translator: ft.fieldly.com

Install

npm install -g @fieldlyab/translator-cli

or run without installing:

npx @fieldlyab/translator-cli login

The binary is exposed as both ft and fieldly-translator.

Requirements

Fieldly Translator is invite-only for now — there is no self-service sign-up yet, so installing this CLI on its own does not grant access. You need an existing Fieldly Translator account that an admin, from Fieldly, has added. If you don't have access, contact your Fieldly Translator administrator.

Run ft from a repo that has a fieldly-translator.yml file at its root.

Commands

ft login   [--token [T]] [--host URL]              sign in via browser SSO, or paste a token
ft push    [--locales L] [--branch B] [--force] [--dry-run]  send new/changed source+authored keys up
ft pull    [--locales L] [--branch B] [--release V] [--force] [--dry-run]  write FT-owned target locales
ft status  [--branch B] [--locales L] [--min-status S]  report completeness; non-zero exit gates CI
ft get     KEY [--locale L] [--namespace N]         fetch a single key
ft set     KEY code="text" [...] [--branch B] [--namespace N] [--status S] [--no-write|--write]  hand-fill locale values on a key
ft create  KEY "Source" [code="text" ...] [--branch B] [--namespace N] [--description D] [--status S] [--no-write|--write] [--wait]  create a key with source + values
ft config  push | check                             apply this repo's locale roles to FT, or report drift
ft init    PROJECT [--force]                        write a fieldly-translator.yml from the project
ft request [--locales L] [--all]                    trigger translations for missing targets

ft --version | -v                                   print the ft version
ft --help    | -h                                   show usage

A flag this list does not name is a usage error (exit 2), never something ft drops on the floor — the closest real flag is suggested. Before 0.12.0 an unrecognised flag was accepted and ignored, so ft pull --brnach x quietly pulled live head and ft pull --dry-runn quietly wrote your locale files. --flag=value works the same as --flag value, and a boolean flag no longer swallows the word after it.

The CLI sends User-Agent: ft/<version> on every request, and the server answers with the oldest version it considers safe. If yours is below it, ft prints a warning to stderr naming what is at risk — once per run, never changing the exit code, and never blocking the command. The floor moves only when an older CLI would corrupt a repo or lose data, not for new features.

Run ft <command> --help for the full option list.

Working on a feature branch

Name your branch and the strings a feature adds stay out of everyone else's way until it ships:

ft push --branch fp-1234-new-quotes     # new keys are STAGED on that branch
ft create checkout.title "Checkout" --branch fp-1234-new-quotes
ft pull --branch fp-1234-new-quotes     # main + branch: your branch's strings included
ft status --branch fp-1234-new-quotes   # gate CI on just this feature's strings

A key born under --branch is staged: stored in FT, translated by AI and reviewed as usual, but absent from ft pull on main, from exports, and from completeness — until someone merges the branch in FT, which promotes it to live. So a delayed feature is just an unmerged branch, and no half-finished wording leaks into production.

ft pull --branch B is the developer's view of that: live head plus B's staged keys, with B's staged edits overriding head values — everything the merge will produce. A plain ft pull stays pure live head. --branch and --release are mutually exclusive: a release is an immutable snapshot.

Naming a branch FT has never heard of does not fail the pull — "main + branch" where the branch contributes nothing is just live head, so ft pull --branch $(git branch --show-current) is safe in a script on a branch that has not staged a key yet. It warns and names the branch you meant, so a typo is still obvious rather than quietly handing you head:

Branch "fp-4048-quotes-calclation" is not in FT — pulling live head only.
  Did you mean "fp-4048-quotes-calculation"?

The match runs server-side across every open branch, so it finds the one you meant however long ago it was pushed. When nothing is close enough to be a typo, no guess is offered and the project's open branches are listed instead.

ft status --branch is stricter and still fails on an unknown branch: its fallback would be a gate over zero keys, which passes CI green for a branch nobody checked. It names the branch you meant too, so the failure tells you what to fix.

Writing a value to a key that already exists on live (ft set --branch, or ft push --branch over unchanged keys) is not staging — the value goes live immediately and the branch is recorded for reporting, so ft status --branch and the GitHub PR check cover it.

Hand-filled target values land as needs_review by default; --status is honored when you're signed in via SSO and have editor rights on the locale. AI fill (ft request) only ever fills missing values, so it never overwrites what you set.

Both commands also update the mapped local files (skip with --no-write): target files are re-exported like a scoped ft pull, while the repo-owned source file gets just the new key spliced in — your unpushed source edits survive. YAML/JSON formats only for now.

How much of that you want is a setting, because the two halves cost very differently — the splice is local and instant, the target re-export is one request per (locale, file block), so a batch of ft creates spends most of its time re-downloading catalogues:

local_write: all        # all (default) | authored | off

authored keeps the splice and leaves target files to your next ft pull; off writes nothing. Per run, --no-write means off and --write means all, whatever the file says.

ft pull (and the target half of the local write) merges rather than overwriting: entries FT cannot store — Rails' date.day_names, number.format. precision, and anything else the import reported as a skipped non-string value — are kept in the file. FT still wins on every key it holds, so a key FT dropped still disappears, and a file with nothing to preserve is written exactly as exported.

Configuration

A single fieldly-translator.yml at the repo root declares the FT project, the locale roles (source / authored / target), and the translation file paths per platform and app.

When a repo's filenames disagree with FT's canonical locale code — Rails writes en_au.yml, FT stores the BCP-47 en-AU — map them per format block:

targets: [en-AU]                   # the CANONICAL code
formats:
  - platform: rails
    format: rails-yaml
    path: config/locales/{locale}.yml
    locale_map:
      en-AU: en_au                 # canonical -> on-disk filename

locale_map changes the filename only, never the file contents. Declaring the on-disk spelling in targets: instead creates a second locale in FT, and the two then split the same language's translations between them.