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

@fml-inc/fml

v0.8.11

Published

FML CLI and agent tools

Readme

FML CLI

@fml-inc/fml is the single published FML command-line package. It provides the fml command, account and organization authentication, agent MCP integration, cloud-backed product commands, and raw artifact sync.

Panopticon is an internal workspace engine under packages/panopticon. Its raw-sync implementation is bundled into this package at build time; users do not install or run a second Panopticon package.

Install

Node.js 22.19 or newer and npm are required.

On macOS, Linux, and compatible Bash environments, install with:

curl -fsSL https://fml.inc/install.sh | bash

For Windows or manual installation, run:

npm install --global @fml-inc/fml
fml setup

For a customer-hosted deployment, pass the address you use to open FML in the browser to setup instead. The CLI asks that app for its backend (Convex HTTP actions) origin, signs in against it, and only then saves both as the active custom environment and restarts the observer, so later CLI and observer traffic uses the same deployment and a failed login never switches environments:

fml setup https://fml.example.com
# Sign in again later, or headless:
fml login https://fml.example.com
fml login https://fml.example.com --device

The backend origin itself (for example https://actions.fml.example.com) is also accepted. Either URL must be an HTTPS origin with no path, query, credentials, or fragment. Plain HTTP is accepted only for loopback development servers.

Run fml update to check for and install a newer global package with npm. It reports the version installed and refreshes FML setup automatically. Stable releases stay on npm's latest channel; prerelease versions stay on next.

Installing the package does not change agent configuration. Run fml install to register the FML Claude Code plugin, install the agent-native FML skill, configure the FML MCP server, register capture-only lifecycle hooks for supported agents, and install the FML extension for Pi. fml setup performs this installation, signs in when needed, and restarts the observer. Invoke the skill as /fml review in Claude, Gemini, or Grok, and as $fml review in Codex. Review runs inside the agent from the packaged skill; it is not an fml review CLI command. Start a new agent session after installing so it picks up the integration. FML pre-approves only the isolated command hooks it installs for Codex; use /hooks to review or disable them.

The Claude plugin is MCP-only. FML installs the workflow through each host's native skill directory so it keeps the bare fml name without a second, plugin-namespaced skill.

For a coding agent operating in a sandbox, use the agent installation guide.

mini-swe-agent v2

FML supports native v2 DefaultAgent/InteractiveAgent with LocalEnvironment. Install mini and its dependencies yourself (Python >=3.10, Pydantic >=2), activate that environment, and retain your native model credentials:

fml install
mini -t "Your task" -o ./mini-run.traj.json

Successful Mini setup uses the shared installation summary; Mini-specific output is reserved for warnings.

Native mini-swe-agent and python -m minisweagent entrypoints also work. No wrapper, PYTHONPATH export, or adapter flag is required. Installation probes package metadata without importing mini or loading its .env; activation needs writable site-packages. An absent Mini installation or unrelated executable named mini is optional, not a warning. An existing activation is retained when Mini is unavailable. Recognized Mini prerequisite failures and activation conflicts still warn without blocking general FML setup.

An ASCII-only owned .pth loads a guarded bootstrap bound to the selected Python prefix, including paths with non-ASCII characters. Hook delivery uses owned absolute Node and hook-handler paths recorded at installation; it does not resolve fml or Node from the runtime PATH. Automatic capture leaves ordinary Python commands and other environments native, including environments inheriting that site-packages directory. Native YAML, .env, model/mode/limit/output settings, and configuration edits remain authoritative. fml doctor silently checks prerequisites, activation, and ownership of the managed adapter and hook-command assets. It shows a Mini-specific warning only when a recognized installation needs attention; missing or modified assets warn without changing files. Installation does not guarantee capture for custom configurations.

Explicit -c/--config (including short-option clusters such as -yc) and --agent-class opt out unless they select an FML adapter. Supplying -c replaces mini's default config list: include the native base first, such as -c mini.yaml -c local-overlay.yaml. CLI class selection wins over YAML. To capture an explicit configuration, select --agent-class fml_mini_agent.FmlInteractiveAgent or --agent-class fml_mini_agent.FmlDefaultAgent. Native -o overrides YAML agent.output_path, including its default when omitted. Custom agents, remote environments, mini v1, and batch/SWE-bench are unsupported.

The adapter preserves native confirmation, human/yolo modes, interruptions, completion, and exceptions. FML requests run through bash using the CLI-only workflow; there is no native /fml, $fml, MCP client, or fml review command. The bundled workflow is model-visible without being printed as a user message in the interactive terminal. Capture-only interruptions after execution preserve the native result or pending exception, including during observation snapshots, before interrupting further native work. Capture interruptions before native execution discard the pending execution record, so the final snapshot does not report a command that never ran.

Each run() receives a UUID; interactive continuation keeps it. Native output is unchanged. Atomic snapshots retain the complete native trajectory plus FML identity, actual execution, context, cwd, and message-observation metadata under <FML data directory>/mini-swe-agent/trajectories/<UUID>.traj.json. Managed snapshots omit native info.config.model.model_kwargs and info.config.environment.env; native configuration and output retain both. Messages and tool output remain raw, not generally credential-redacted. Sync replaces the session projection as this full JSON snapshot changes, rather than appending JSONL. Rejected proposals are not executed bash calls, and injected context is not a human prompt. Usage views count reasoning/cache tokens once, including native OpenRouter cache-write details; unknown usage remains unknown. Native cumulative costs are scoped to each run.

Snapshots require fml.human_message_indices, recorded at native input boundaries and tied to retained message objects. Blank interruption and mode-switch feedback do not create human turns; genuine comments and human commands still do, even when their text matches generated feedback. Projection does not infer provenance from message text or accept snapshots missing this metadata. Provenance is recorded before interruptible hook delivery, so accepted native input keeps its human role if capture is interrupted. Human-mode shell commands retain their raw whitespace, including mode-like text that native Mini treats as a command. Confirmation and interruption responses follow their native caller's input decision instead of a global trim heuristic.

Capture uses the bounded, fail-open hook inbox and authenticated destination binding. Dynamic server context is supported, but disabled for mini by default. Admins can opt an organization in through the existing dynamic-context policy with the Convex-safe override {"harnesses":{"miniSweAgent":true}}; organization override lookup failures leave mini disabled. Other harness defaults are unchanged, and the public target/source remains mini-swe-agent.

The hook's JSON transport uses explicit UTF-8 encoding, independent of Python's locale, so Unicode context is preserved at the native model boundary.

The initial native task and actual interactive human prompts arm a BeforeModel request immediately before the next provider call. Native slash/mode controls, generated feedback, and tool continuations do not rearm it. Returned context is inserted quietly into native messages without printing a user message; snapshots record its position in fml.context_message_indices, so it is not classified as human input. Both requests and insertion honor pause state, including a pause while a request is in flight. Deferred capture interruptions are delivered before the next provider call or tool execution, without replacing completed native results or exceptions.

fml stop pauses hooks, context, and snapshots, not native history; resuming publishes the complete cumulative run, including its paused interval. Reinstall repairs a missing owned .pth after environment revalidation. When Mini resolves to a different interpreter, reinstall moves the unchanged owned activation to that environment; no prior uninstall is required. Modified hooks and destination conflicts are preserved with a warning. Updates retain activation if mini is unavailable. Uninstall removes unchanged owned files without editing native YAML or .env; modified/conflicting files retain their dependencies with a warning. Trajectories remain unless --purge is explicit, and unrelated or modified files are preserved even during purge. Resolve reported ownership conflicts manually.

Upgrading from standalone Panopticon

Earlier releases shipped as a separate @fml-inc/panopticon package that installed its own Claude plugin, agent hooks, MCP server, OpenTelemetry settings, and shell environment. fml install does not migrate that install. Retire it first, from the machine that has it, before installing FML:

panopticon uninstall --purge

panopticon uninstall --purge stops the standalone daemon and removes its plugin, hooks, MCP registrations, shell block, and generated data directory. Then follow the Install steps above for a clean setup. If the old panopticon command is already gone, reinstall @fml-inc/panopticon just to run its uninstall, or clean up by hand: remove the # >>> panopticon >>> block from your shell profile, delete the data directory (macOS: ~/Library/Application Support/panopticon; Linux: ~/.local/share/panopticon; Windows: %APPDATA%\panopticon), and remove any leftover panopticon entries from the Claude plugin registration (~/.claude/settings.json and ~/.claude/plugins/), agent hook configs (~/.codex/config.toml, ~/.codex/hooks.json, ~/.gemini/settings.json, ~/.grok/hooks/), and MCP server registrations in those same agent config files. Also remove the legacy Pi extension at ~/.pi/agent/extensions/panopticon.js.

Raw artifact sync

Sync uploads original, file-backed agent artifacts to FML. It does not parse them into local session, message, tool-call, or scanner tables. Server-side scanners own parsing and projections.

Discovery covers supported local stores across Claude Code, Codex, Gemini, Grok, Cursor, Pi, mini-swe-agent, Copilot CLI, and Factory Droid, including archived Codex sessions and managed mini full-trajectory snapshots. Availability depends on which harnesses have written artifacts on the machine.

Sync has one persistent setting: enabled or disabled. It defaults to enabled. The backend environment, login, and selected organization determine the upload destination; there is no user-configurable sync-target list.

fml sync                 # Discover and drain pending raw artifacts
fml sync --dry-run       # Show what would be discovered without changing the queue
fml sync status          # Show enabled state, queue counts, and byte watermarks
fml sync disable         # Stop discovery and upload
fml sync enable          # Allow discovery and upload again
fml sync reset           # Clear watermarks and replay every local artifact from byte zero
fml start                # Start the observer and continuously run enabled raw sync
fml restart              # Stop and start the observer
fml stop                 # Stop the observer and disable raw sync

fml sync reset preserves the enabled/disabled setting and source files. It clears local upload progress and gives tracked artifacts fresh generations, so the next enabled fml sync performs a full replay. Reset refuses to race an active sync.

For automation, the sync commands support --json. fml start enables raw sync and launches a detached observer with a loopback-only HTTP endpoint. The observer runs sync immediately, retries in the background, and follows later fml env and fml org changes. fml sync disable pauses only raw discovery and upload. Capture-only hooks continue writing to their durable local outbox and uploading in the background. fml stop disables raw sync, records an explicit hook-capture pause, and stops the complete observer runtime. Either fml start or fml sync enable clears that pause. A crash or reboot does not pause capture: handler inbox files remain durable until the observer returns.

The observer keeps a SQLite database for runtime bookkeeping and the durable hook outbox. It is operational state, not a local copy of session, message, scanner, or analytics tables. Hermes discovery and sync remain deferred.

The database is panopticon.db under FML's platform-native operational-state root:

| Platform | Account/configuration (FML_DATA_DIR) | Operational database | | -------- | -------------------------------------- | ----------------------------------------------------- | | macOS | ~/Library/Application Support/fml | ~/Library/Application Support/fml/panopticon.db | | Linux | ${XDG_DATA_HOME:-~/.local/share}/fml | ${XDG_STATE_HOME:-~/.local/state}/fml/panopticon.db | | Windows | %APPDATA%\fml | %LOCALAPPDATA%\fml\panopticon.db |

The cutover is forward-only: the observer starts with a clean database at the new path and does not migrate or delete the former ~/.fml/panopticon/observer.db. fml start reports that retained path whenever the file still exists; when replacing a live legacy observer, it also reports the old observer's pending row count. The PID state, lease/lock, endpoint, auth-token files, hook inbox, and raw-sync watermarks remain under the separately configurable observer directory.

Use FML_STATE_DIR to relocate the operational database and FML_DATA_DIR to relocate account and environment configuration. For compatibility, an explicit FML_DATA_DIR also relocates the database when FML_STATE_DIR is absent. It does not relocate logs or observer coordination state: those retain their platform defaults unless FML_LOG_DIR or an observer override is set. FML_OBSERVER_DIR directly relocates observer coordination state; PANOPTICON_HOME is a legacy alias for that directory and FML_HOME is a legacy parent whose panopticon child is used. These observer-only aliases do not relocate the database or account configuration. Because that pattern used to isolate the pre-cutover database as well, fml start and the observer warn at startup when an observer-only alias is set without FML_STATE_DIR or FML_DATA_DIR; set one of those to choose the database root explicitly.

Every explicit FML directory override must be absolute; relative values are rejected so processes launched from different working directories cannot silently select different state. Relative XDG and Windows shell-directory variables are ignored in favor of the platform fallback.

The filesystems containing FML_STATE_DIR and FML_OBSERVER_DIR must support same-directory hard links. FML uses that atomic primitive to publish complete observer lease records without exposing a partially written database lock; standard APFS, ext4, and NTFS volumes support it.

For multiple fully isolated FML instances, configure absolute, dedicated FML_DATA_DIR, FML_LOG_DIR, and FML_OBSERVER_DIR roots per instance. FML_DATA_DIR also isolates the database unless a separate FML_STATE_DIR is set. Configuring a distinct FML_OBSERVER_PORT is also recommended. A database-scoped runtime lease rejects a second observer that resolves to the same panopticon.db; give that instance a different data or state root and start it again.

Hook capture

FML installs capture-only hooks for Claude Code, Codex, Gemini CLI, and Grok CLI. It also configures direct MCP entries for Codex, Gemini, Grok, and Claude Desktop. The hook handler reads the agent's JSON event, first commits an owner-only per-delivery file, then sends it only to the authenticated loopback observer, and always returns an empty JSON object. It does not make permission decisions, inject context, or contact FML directly.

The observer commits each event to SQLite before removing its handler-side delivery file. Files left by a stopped, restarting, busy, or unavailable observer are replayed with the same sync ID, so a timeout cannot create a duplicate or silently drop the event. A separate uploader sends stable, idempotent batches through /v2/sync to the selected FML environment and account, then removes local rows only after the server acknowledges them. Repository authorization is evaluated per row across every organization the account can access; hook delivery does not depend on the currently selected organization. fml status reports both the handler inbox and SQLite outbox.

Each capture with known login state is durably bound to its exact FML URL, and stable account identity; switching environments or accounts cannot upload or acknowledge another destination's rows. Captures made while logged out remain unbound until the first authenticated destination atomically claims that backlog.

The handler-side inbox is a short-lived durability bridge for times when the observer is stopped or unavailable. It is bounded independently from the SQLite spool: by default it accepts at most 512 MiB or 262,144 delivery files, whichever is reached first; the entry cap is derived from the byte budget at 2 KiB per event, so bytes are the effective bound for any realistic event. Raising FML_HOOK_INBOX_MAX_BYTES alone re-derives the entry cap. At a limit it preserves older committed files, refuses the newest inbox write, and still fails open for the invoking agent; a running observer can still accept that event directly. fml status reports the active limits, cumulative capacity refusals, and the subset of refusals that no observer took either, which is real loss; fml start warns about any such loss recorded since the last start.

To keep the bridge short, a hook that finds the observer's recorded endpoint no longer answering relaunches the observer in the background, at most once every ten minutes. An explicit fml stop pauses capture entirely and is never undone by a hook; a crash, reboot, or upgrade is. A machine where fml start never ran has no recorded endpoint and gets no daemon.

Set FML_HOOK_INBOX_MAX_BYTES and FML_HOOK_INBOX_MAX_ENTRIES in the coding agent's environment to change these limits. Bytes accept the same B, KiB, MiB, and GiB suffixes described below; entries are positive integers. An explicit unbounded opts out of either limit. These settings affect only the per-delivery file inbox and do not change normal SQLite spool retention.

The hook spool is unbounded by default. To bound it, set FML_HOOK_SPOOL_MAX_BYTES when starting the observer:

FML_HOOK_SPOOL_MAX_BYTES=512MiB fml start

The value is a positive integer in bytes with an optional B, KiB, MiB, or GiB suffix. Unset it, or set it to unbounded, to retain the full spool without a size limit. Invalid values (including 0) stop observer startup instead of silently disabling the limit. Restart a running observer after changing the setting.

This is a logical-content limit: it counts the UTF-8 bytes retained in hook fields and their destination or rejection metadata across pending and quarantined rows, not SQLite page, index, or WAL overhead. When the limit is exceeded, the observer evicts the oldest quarantined rows first and then the oldest pending rows. It never fails a hook invocation merely because the spool is full. fml status reports current logical bytes, the configured maximum, cumulative eviction counts and bytes, and the last eviction time.

Terminally rejected rows are retained for 30 days by default, independently of the pending spool's unbounded default. Set FML_HOOK_QUARANTINE_MAX_AGE_DAYS to a positive integer to change that window, or to unbounded to retain quarantine rows until the byte bound evicts them. Expired quarantine rows contribute to the same persisted eviction counters. Retryable pending rows are never removed by this age policy.

The spool retains complete hook payloads and extracted fields, which can include prompts, commands, file paths, plans, and tool output. FML-created directories request owner-only permissions, and the SQLite database and sidecars are tightened to owner-only modes on platforms that support POSIX modes. An existing caller-supplied state directory retains its directory mode.

Automatic updates

While the observer is running it checks npm for a newer FML release about once a day (with jitter). A session-start hook also requests a check, limited to one session-start check per hour. When a newer release exists, the observer applies it by running fml update in the background: npm install --global followed by fml setup, which restarts the observer onto the new version. Output from that background update is written to update.log in the FML log directory.

Auto-update is on by default. To disable it, set FML_AUTO_UPDATE=off and restart the observer so it picks up the change:

FML_AUTO_UPDATE=off fml restart

The variable is read from the observer's environment at startup, so exporting it in a shell has no effect until the observer is relaunched. Development builds and non-release versions never auto-update.

MCP tools

The MCP server exposes FML tools for session analytics, cost tracking, integrations, team workflows, and account context, including:

| Tool | Description | | ----------------------------- | ----------------------------------------------------------- | | get_engineering_activity | Activity summary across sessions, prompts, tools, and costs | | list_engineering_sessions | List recent sessions with stats | | search_engineering_sessions | Search across sessions | | get_session_timeline | Messages and tool calls for a session | | get_session_turns | Per-turn token usage for a session | | get_ai_spending | Token usage and cost breakdowns | | whoami | Current auth and organization status | | fml_list_integrations | Connected integrations | | fml_query_* | Query connected integrations | | fml_list_messages | Conversation messages | | fml_search_analysis | Search codebase analysis results | | fml_run_analysis_workflow | Run analysis workflows | | fml_list_skills | Browse and load skills | | list_repo_configs | Team configuration snapshots |

For backend tools not yet exposed as dedicated MCP tools, use the dynamic catalog:

fml tools list --json
fml tools describe <tool-name> --json
fml tools call <tool-name> --args '{"key":"value"}'

CLI overview

fml setup [backend-url]  Install integrations, sign in if needed, and start FML
fml install              Register FML agent integrations and the MCP server
fml uninstall            Remove agent integration; add --purge to remove local state
fml update               Update @fml-inc/fml with npm (stable: latest; prerelease: next)

fml start                Start the local observer and continuous raw sync
fml restart              Stop and start the local observer
fml stop                 Stop the local observer and disable raw sync

fml login [backend-url]  Sign in to hosted FML or a customer-hosted backend
fml logout               Clear stored credentials
fml org [slug]           Show or select an organization
fml env [name-or-url]    Show or select a backend environment
fml status               Show auth, environment, and raw-sync status
fml doctor               Check auth, environment, organization, raw sync, and API access
fml open                 Open the FML dashboard

fml sync                 Upload raw local artifacts
fml sync enable          Enable raw artifact sync
fml sync disable         Disable raw artifact sync
fml sync status          Show queue counts and byte watermarks
fml sync reset           Replay all raw artifacts from byte zero

fml tools                Browse and invoke backend tools
fml activity             Show an activity summary
fml sessions             List recent sessions
fml timeline <id>        Show events for a session
fml spending             Show token usage and cost breakdowns
fml search <query>       Search sessions

Run fml --help or fml commands for the complete command inventory.

Development

Run from the repository root:

pnpm install
pnpm --filter @fml-inc/fml type-check
pnpm --filter @fml-inc/fml test
pnpm --filter @fml-inc/fml build

Build, pack, and install the same artifact that will be published:

pnpm --filter @fml-inc/fml pack:local
pnpm add --global ./apps/cli/fml-inc-fml-*.tgz
fml --version
fml install

The packed manifest must not contain runtime dependencies on @fml/panopticon or @fml/agent-targets; both private workspace packages are bundled into the CLI.

Release

The FML CLI release workflow publishes the exact package that passes the packed-install smoke test. Create a tag named fml-v<semver> on a commit reachable from main, then push the tag:

git tag -a fml-v0.8.0 -m "Release FML CLI 0.8.0"
git push origin fml-v0.8.0

Stable versions use npm's default latest tag. SemVer prereleases such as fml-v0.9.0-beta.1 publish under next. Each release must advance the version currently assigned to its npm channel; the workflow rejects stable versions that do not advance latest and prereleases that do not advance next. Release tags may not contain SemVer build metadata. Keep apps/cli/package.json at 0.0.0-dev on main; the workflow stamps the release version before building.

The @fml-inc/fml package must have one npm trusted publisher configured with these exact values:

  • Provider: GitHub Actions
  • Organization: fml-inc
  • Repository: fml
  • Workflow: publish-fml-cli.yml
  • Environment: npm
  • Allowed action: npm publish

The GitHub npm environment should allow only fml-v* tags and may require a reviewer. The publish job has no npm token, source checkout, dependency installation, or build step; it receives only the smoke-tested tarball and its checksum. npm provenance is disabled because the source repository is private, while OIDC trusted publishing remains enabled.

License

Proprietary — see LICENSE.