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

tag-plugin

v0.1.28

Published

Privacy-minimal local coding-agent usage plugin for The Artificial Games

Readme

TAG Plugin

TAG Plugin is a small, inspectable Node.js program that turns usage records already present on a user's coding machine into privacy-minimal events for The Artificial Games. One installation covers every provider selected during The Artificial Games onboarding; it is not installed once per provider or once per coding agent.

Official builds are published only as versioned, checksummed, attested GitHub release assets. A source checkout is a development copy; install only an exact release artifact after verifying its tag, commit, SHA-256, and GitHub attestation as described in INSTALL.md.

The initial confirmed installation explicitly authorizes future verified stable updates. After a successful signed heartbeat, TAG may accept only a newer release offer pinned to the official GitHub repository, exact tag, full commit, archive name, and SHA-256. It independently verifies those release facts, safely validates the package contract, adds an immutable versions/<version> directory, and atomically changes a stable local launcher pointer. A verification or download failure is fail-open for the completed heartbeat: it does not invalidate that sync, replace the active release, or discard pairing, state, or pending outbox data. This updater does not perform local GitHub-attestation verification or use an offline release-envelope signature. Existing v0.1.9 installations require one explicit install of the first updater-capable release before this heartbeat path exists.

v0.1.20 endpoint migration

v0.1.20 moves existing paired installations from the retired the-artificial-games-dev.theo-lupescu.workers.dev Worker origin to app.theartificialgames.workers.dev. It preserves the existing device key and signed request chain. The migration is deliberately limited to that one exact retired origin; any other endpoint change still requires an explicit re-pair.

v0.1.22 quiet Windows scheduler

v0.1.22 has Windows Task Scheduler call a small local WScript wrapper instead of launching Node directly. The wrapper starts the same current-user heartbeat hidden, waits for it to finish, and returns its exit code to Task Scheduler. New Windows installations no longer flash a terminal window for hourly heartbeats.

v0.1.23 Kimi turn-scope correction

v0.1.23 fixes the Kimi Code adapter so it counts only per-turn usage.record rows. Kimi's wire.jsonl also emits session-scoped rows that are cumulative running totals; the earlier adapter counted every usage.record, which double-counted usage on a real journal. The parser now excludes any explicit non-turn (cumulative) scope while still counting a row that omits the scope, so a documented per-turn increment is never dropped and a running total is never re-added. This aligns the adapter with Moonshot's documented v0.28 wire format. Kimi collection stays opt-in and pending live client validation.

v0.1.24 local provider detection

v0.1.24 adds content-free local detection so one installation can recognize which supported providers are present on the machine instead of being told at pairing. Each scan (and the new refresh-detection command) checks only whether each provider's data directory exists — it never opens, lists, or reads a file inside — and records the result in local state, visible in status. Detection is always safe and on by default; it does not start tracking anything. Reading a provider's usage stays an explicit choice, unless the new autoTrack standing consent is enabled, which promotes a detected, already-authorized journal provider to tracked (it never widens the account's authorization, and version-pinned providers stay manual). Provider identity, detection, and consent now derive from a single src/providers/registry.mjs descriptor list, so a future provider is added as one descriptor plus its adapter rather than edits across the collector, state, and config.

The signed heartbeat can carry the content-free detection snapshot (which supported providers are present — presence booleans only, never paths, file contents, versions, or timestamps) so the account can surface recognized providers. This send is off by default and guarded by reportDetection: a connector never sends the field until the operator enables it with refresh-detection --enable-detection-report, after the deployed server is known to accept it. Because the server validates the heartbeat body against a strict key allowlist, this ordering (server accepts first, connector sends second) is what prevents a rejected heartbeat from stalling the signed request chain. Provider-agnostic authorization and the Connections UI for these controls land in a later release.

What is supported

| Provider | Preferred source | Model-level source | Current status | | --- | --- | --- | --- | | Codex | Official codex app-server aggregate plus account/read and rate-limit observations | Rollout JSONL token_count records | The aggregate remains a provider-backed checkpoint. The native account PlanType distinguishes prolite (Pro 5x) from pro (Pro 20x); quota-window observations do not provide model or speed detail. | | Claude Code | First-party account status plus the exact allowlisted rate_limit_tier in Claude Desktop's cached account bootstrap | Project JSONL terminal assistant usage snapshots | Exact Max 5x/20x evidence overrides the CLI's coarse or stale family label only after a current signed-in status succeeds and its organization ID matches the cached account membership. The cache parser checks a work-bounded set of recent provider cache values, deserializes the exact account object shape, and extracts only the allowlisted tier. A same-account non-Max membership, logout, API-key/third-party auth route, or account switch revokes the old Max claim; a transient same-account cache miss does not. It never retains, hashes, logs, or uploads other account/conversation fields and never opens Claude tokens or cookies. Journal detail remains opt-in; partial rows without message.stop_reason are withheld. | | Kimi Code | A future content-free aggregate API | Version-sensitive local session records under research | Planned / unavailable. The internal adapter remains test-only until it passes live validation against the current official client. | | Antigravity desktop 2.3.1 | Version-pinned read-only conversation SQLite metadata plus the live local account-status service | Completed-step token metadata and a bounded native effective-quota code | Available only for the pinned desktop version. TAG reads steps.idx, steps.status, and steps.metadata from completed steps; it does not read prompt, transcript, payload, or render fields. On heartbeat it compares the same-user loopback GetUserStatus.userTier with GetLoadCodeAssist.paidTier, maps Starter to Free, reports an unregistered tier as unknown:<normalized-native-tier>, and discards the local CSRF token, account fields, endpoint, and full responses. Legacy planInfo is ignored. Unregistered models or modes remain raw-only. | | Grok Build | Local session summaries | None | Planned / unavailable. No standalone device authorization is issued. | | DeepSeek | Explicit API evidence only | None | A hosted DeepSeek model can be attributed to DeepSeek for a known model event, but it never creates a DeepSeek API plan. |

The Codex, Claude, and Kimi journals can contain sensitive text. The connector opens only the journals authorized by the website installation prompt, prefilters unrelated lines, extracts an allowlisted usage subset, and never uploads, stores, hashes, or logs prompt/response/tool content. Raw journal paths never upload or enter logs. A keyed alias derived from each path is persisted locally so byte cursors can resume without retaining the raw path. Codex/Kimi resumes verify file metadata plus a rolling digest made only from previously allowlisted usage/model/mode fields; prompt and tool text never enter that digest. Antigravity desktop 2.3.1 token collection is metadata-only: it queries only the three allowlisted completed-step columns and never reads prompt, transcript, payload, or render fields. Its separate plan detector makes two bounded requests to the active same-user loopback account-status service during heartbeat and keeps only a bounded normalized native effective-quota code. Its CLI status-line wrapper remains an explicitly consented prospective fallback that writes only a sanitized capture and forwards input to the saved prior command. If either model or speed cannot be attributed, the usage uploads immediately with the atomic attribution: raw_only, modelId: unknown, serviceMode: unknown sentinel. It remains visible as Raw Tokens but is structurally ineligible for Kleos. The raw source-model token never uploads.

The first journal import covers all retained history that can be discovered and parsed safely; the server independently decides which observations are eligible for weekly Kleos. Every usage event keeps two separate identities: provider is the actual model vendor used for model validation and Kleos, while serviceProviderId is the authorized coding service that hosted the usage and owns plan, reset, checkpoint, Raw-total, and provider-filter boundaries. This prevents a DeepSeek model used through Codex, for example, from inventing a DeepSeek subscription or being counted twice beside a Codex account total. Eligible raw records are deduplicated by account-scoped source ID, then reduced into stable aggregates keyed by host provider, source session, UTC hour, raw source-model token, raw mode token, and coding surface. Uncached input, cache-read input, and cache-write input remain separate canonical counters. Parser/accounting generation, collector provenance, and canonical model classification are not part of logical aggregate identity. A corrected canonical observation therefore keeps the same event ID and arrives as a payload revision instead of minting separately scoreable usage; raw-only and attributed projections likewise share the logical ID. Stable session-hour aggregates are not sharded, so server anomaly and quarantine rules see their full volume. Each enabled provider advances its own settled-through watermark after discovery and bounded parsing reach the range boundary; a disabled, unavailable, truncated, or event-limited provider retains its prior watermark. Malformed or oversized records are irreversible parse losses in this release: coverage remains explicitly partial with a privacy-safe count and the repair/backfill remains pending, while the watermark may still advance so later valid usage is not pinned behind an old unreadable line. Raw history is described as retained history, never as a guaranteed complete provider lifetime ledger.

Commands

node src/cli.mjs preview
node src/cli.mjs pair --endpoint https://YOUR_ARTIFICIAL_GAMES_HOST --code ABCD-EFGH
node src/cli.mjs sync
node src/cli.mjs heartbeat
node src/cli.mjs status
node src/cli.mjs doctor
node src/cli.mjs install --dry-run
node src/cli.mjs install --confirm-install
node src/cli.mjs pause
node src/cli.mjs resume
node src/cli.mjs uninstall --dry-run
node src/cli.mjs uninstall --confirm-uninstall

preview makes no upload to The Artificial Games, but it can invoke the official local Codex app-server to obtain provider-backed account usage; that subprocess controls whether it refreshes its own data. status, doctor, pause, resume, and dry runs make no network requests. pair, sync, and heartbeat are the only plugin commands that send data to The Artificial Games. Scheduler mutation requires the exact --confirm-install or --confirm-uninstall flag.

Journal adapters remain off unless pairing both authorizes that provider and includes an explicit flag such as:

--allow-journal-fallbacks codex,claude,kimi

Antigravity desktop collection is enabled only when Gemini/Antigravity is authorized and the local desktop matches the pinned 2.3.1 adapter. It reads retained completed-step metadata only and never changes Antigravity settings. During heartbeat, the plan detector validates the installed version, same-user process, executable path, loopback listener, and pinned local TLS certificate before comparing userTier with paidTier. The local Starter family maps to Free. Mismatched native evidence remains ambiguous; a future tier remains unverified but retains its bounded normalized value as unknown:<native-tier>, and a missing or temporarily unavailable response cannot replace the last successful observation. An explicit logout revokes it. The optional CLI status-line fallback needs separate explicit antigravityStatuslineConsent (the CLI flag is --enable-antigravity-statusline). Only then may TAG save and forward a prior statusLine, and restore it on removal when TAG still owns the entry. Any observed CLI quota reset is recorded only after its reset boundary advances; a changed percentage alone is not a reset. Grok Build is never a token source, and DeepSeek api_payg is never inferred from a hosted-model record.

Security model

  • A fresh Ed25519 keypair and fixed exchange request are persisted before pairing traffic. A lost response resumes the same key and request instead of consuming a code with an unrecoverable key.
  • Every request signs the exact request body, route, timestamp, request ID, and monotonic sequence.
  • Every authenticated body carries the prior accepted request digest. Replays, gaps, rollback, and divergent chains are server-detectable.
  • Raw source identities are account-scoped HMACs: Claude uses its message ID, Codex uses the first owner session plus lineage epoch and cumulative endpoint, and Kimi uses a provider record ID when present or stable journal plus timestamp occurrence ordinal. They deduplicate raw records locally. Codex and Claude logical aggregates retain the released v4 identity domain and Kimi retains v3. Aggregate identity binds provider, stable source-session scope, UTC hour, raw source-model token, raw mode token, and coding surface independently of source-ID set, parser/accounting generation, collector provenance, canonical model mapping, and raw-versus-attributed classification. Neither raw source IDs nor the identity inputs upload as separate fields; changed canonical observation fields are request-digested as a revision under the same event ID.
  • Local file aliases use a separate installation-only HMAC key. Raw paths never enter an outbound body, state file, or safe log.
  • Event and checkpoint requests are disjoint and capped at three events or two checkpoints. Before every eligible Codex checkpoint plan, a signed heartbeat hydrates the account's active snapshot head so reinstalls and multiple devices extend the current parent rather than guessing. Codex provider evidence uses a parent-linked snapshot generation: only changed daily values are tagged daily_delta, followed by one lifetime commit marker containing the generation ID, parent generation ID, canonical full-snapshot digest, and delta count. The connector persists its submitted generation, digest, lifetime value, and daily-value map only after the backend explicitly confirms every checkpoint's exact digest and confirms that the submitted commit generation is active. An identical snapshot sends nothing; a correction with the same lifetime sends only its changed dates and marker; returning from A to B to A creates a new child generation even though A's snapshot digest repeats. Every Codex checkpoint carries sourceScope: codex_subscription_account. If another device wins a parent race, the connector hydrates that active head, retires only the stale checkpoint generation, and keeps draining the same durable event pages before committing their source cursors; checkpoint evidence is replanned from the hydrated parent on the next sync. Event catch-up is ordered newest hour first and divided into private pages of at most 5,000 events. The active page is embedded in state.json; future content-free pages live under sync-pages/<batch-id>/ and every page is bound to the state's event-count and digest manifest. A missing, oversized, malformed, or digest-mismatched page fails closed. No collection cursors or provider watermarks commit until the final page completes, after which the private batch directory is removed. Requests are paced 550 ms apart and honor bounded HTTP Retry-After; an interactive sync processes at most 100 ingest requests, while scheduled runs process at most 1,000, interleave a signed heartbeat every 50 requests, and send a final heartbeat even when backlog remains. Permanent invalid same-type chunks are bisected, but an isolated item remains blocked rather than advancing its cursor without proof. Every submitted event requires exactly one matching response with submittedRevisionActive: true, or submittedObservationCanonical: true when the backend proves an exact content duplicate is canonical under another logical event. A raw-only event additionally requires rawPreserved: true; aggregate counts and status labels alone never authorize cursor commit.
  • An upgraded v0.1.6 install has no local checkpoint generation. An already-persisted signed legacy outbox drains unchanged and its checkpoints remain audit evidence without activating the new projection. The signed hydration response explicitly reports no modern active snapshot before the first fresh v0.1.7 snapshot uses the all-zero genesis parent and sends every currently observed daily value. The backend accepts that takeover only once when the active generation is explicitly legacy; a reinstall with a modern active generation hydrates it instead. Normal parent equality is mandatory thereafter. The connector neither discards pending signed work nor treats the retired v0.1.6 checkpoint hash as a generation ID.
  • Installation copies the verified release into a stable current-user version directory, writes a stable launcher and atomic current/previous release pointer, and targets that launcher from the hourly scheduler with an explicit connector home. The scheduled run can check the disclosed verified stable-update offer after its successful signed heartbeat, while an update uses a separate lock/state. It runs one sync and one signed heartbeat on install and uses no elevation or system account.
  • Every state-changing command holds an owner-token lock whose filesystem lease renews every one quarter of the stale window. Stale takeover is atomic, refuses to replace a live owner PID, and release removes only its own lock.
  • Runtime JSON uses exclusive-create temporary files followed by one atomic rename. If Windows transiently refuses replacement with EEXIST or EPERM, the connector retries that same atomic primitive five times with bounded delay; exhaustion fails closed without unlinking the prior committed JSON and removes only its new temp. A later state-changing startup can reclaim a crash-stranded temp only after the 15-minute lease window, while it owns the canonical overlap lock, when the filename exactly names a known runtime JSON target, the encoded writer PID is no longer live, and the unchanged committed counterpart still exists as a regular file. A temp that is the sole recovery copy is preserved. Cleanup scans only connector-home root and direct exact sync-pages/<batch-id> children with fixed entry limits; it does not glob or recurse.
  • Windows pairing first restricts the connector directory so a new credential inherits user-only access, then verifies the pending secret before network traffic and the final secret before commit; installation re-verifies the current-user ACL before scheduling. POSIX secret files use mode 0600.
  • Logs are allowlisted and rotate at 256 KiB with one retained backup.

This is tamper evidence, not proof of honest usage. A user who controls an open-source client controls its inputs. Provider-backed checkpoints and future provider APIs create stronger cross-checks; connector-reported journal events must remain labeled as connector-reported.

See INSTALL.md, PRIVACY.md, SECURITY.md, and THREAT_MODEL.md.

Local verification

Requires Node.js 22 or newer and no third-party packages:

npm test
npm run check
npm run pack:dry-run