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

@hasna/identities

v0.5.14

Published

Open identity records for humans and AI agents

Readme

@hasna/identities

Open identity records for humans and AI agents.

open-identities treats an identity as more than an ID. An identity can carry a human or agent name, a durable unique identifier, verified email addresses, phone numbers, integration sync references, and narrative documents such as PROMPT.md, SOUL.md, PERSONALITY.md, and ETHOS.md.

License

Install

npm install -g @hasna/identities

CLI

identities --help
identities create --kind agent --name "Ava Example" --identifier agent:ava-example --email [email protected] --phone +15555550123
identities list
identities show agent:ava-example
identities show agent:ava-example --verbose
identities update agent:ava-example --identifier agent:ava-renamed
identities link-email agent:ava-example [email protected] --verified --mailery-id mailery-address-id
identities link-phone agent:ava-example +15555550199
identities machine assign agent:ava-example machine-a --purpose browserplan --slot profile-01 --json
identities browserplan reserve agent:ava-example --machine machine-a --slot profile-01 --json
identities browserplan coverage --target 8 --json
identities doc set agent:ava-example ethos "Protect user intent and identity data."
identities doc get agent:ava-example ethos --json
identities doc export agent:ava-example --dir ./ava-documents --json
identities instructions set global --kind global-rules --title "Global Safety" --content "Never expose secrets." --rule-id safety:no-secrets --provider codewith --non-overridable --json
identities instructions list --json
identities instructions validate --json
identities instructions export ./instructions.json --json
identities instructions sources --canonical --provider codewith --json
identities agent manifest agent:ava-example --json
identities agent seed-roster --roster ./team.roster.json --docs-dir ./agents --json
identities eve export agent:ava-example --out ./ava-agent
identities status --json
identities media doctor --json
identities media generate-voice agent:ava-example --dry-run --json
identities media generate-profile-image agent:ava-example --dry-run --json
identities media generate-roster --voices --profile-images --dry-run --json
identities validate --json
identities status --json

update <target> --identifier scheme:value renames the durable unique identifier. The previous identifier is kept as a secondary identifier so existing references keep resolving, renames onto an identifier held by another identity fail without changes, and a rename-identifier audit event is recorded.

Local data is stored in SQLite at ~/.hasna/identities/identities.json by default. Use OPEN_IDENTITIES_STORE=/path/to/identities.sqlite or --store <path> for isolated scripts and tests. When --store <path> is used, the CLI writes audit events to <path>.audit.jsonl unless --audit <path> is provided. Generated media assets are stored in ~/.hasna/identities/assets by default. Use OPEN_IDENTITIES_ASSETS_DIR or --out-dir <dir> to place generated audio and profile images somewhere else.

CLI human output is compact by default so agent terminals do not ingest full identity records, document bodies, manifests, media objects, or coverage JSON unless explicitly requested. Use:

  • --json for stable machine-readable contracts and full exported objects
  • --verbose for full human-side object details
  • --limit <n> for longer human tables such as list, machine list, browserplan list, media status, and asset list
  • detail commands such as show <id> --verbose, doc get <id> <key> --verbose, and agent manifest <id> --json when a full record is actually needed

Plain doc get writes the complete document body byte-for-byte for shell consumers. Structured --json and --verbose reads include { key, value }. Full agent manifests include the same canonical document bodies; compact human manifest output continues to omit them.

doc export writes each populated canonical Markdown document slot plus .identities-documents.json. The manifest uses the versioned hasna.identities.documents/v1 contract and records the package version, export time, source identity update time, populated count, byte length, and SHA-256 of every body. Consumers can reject unsupported contract versions, compare source.identityUpdatedAt with the current identity, and verify hashes instead of treating an unversioned directory as current. Empty and whitespace-only slots have manifest entries but no Markdown file; a later export removes any stale canonical file for a slot that became empty. The old manifest is removed before files are refreshed and the new one is written last, so a failed partial refresh cannot leave stale metadata certifying mixed files.

identities status --json is the public-safe machine contract for fleet integrations. It reports store path, audit path, environment override state, identity/contact/document/media counts, document key names, and safety flags. It does not include contact values, document bodies, media asset paths, credential values, or sensitive identifiers.

identities status --json emits a metadata-only reference contract for fleet consumers. It reports package version, redacted store paths, env override names, roster and role counts, aggregate contact/document counts, and opaque identity refs. It does not include names, email addresses, phone numbers, identifier values, document bodies, credentials, private keys, GitHub App private data, or raw env values.

Hasna Company Agent Roster

A roster is a JSON file the operator supplies. It names the agents, the organization they belong to, the domain their mailboxes live on, and any identifiers a previous roster version created that should now be pruned.

Rosters are data, not source. This repository ships exactly one — the synthetic three-agent example in rosters/example.roster.json, on the RFC 2606 reserved domain example.com — so the feature is demonstrable and testable from a clean checkout. Keep a real roster outside this repository and point the CLI at it.

identities agent seed-roster --roster ./team.roster.json --docs-dir ./agents --json

Resolution order for the roster file is --roster <file>, then IDENTITIES_ROSTER_FILE, then the bundled example. The command prints which one it used, and says so plainly when it fell back to the example. A deployment that carries no rosters/ directory is fine: an explicit --roster never touches the bundled example.

identities status takes the same --roster <file> flag and resolves it the same way, so its roster counters describe the roster you actually seeded. When no roster resolves it reports unresolvedReason rather than a zero, and identities seeded from some other roster are counted under seededOtherRoster rather than disappearing.

The seed command upserts the roster into the selected identity store, prunes the roster's deprecatedIdentifiers by default, and optionally exports per-agent markdown. Each agent gets exactly one mailbox, <slug>@<emailDomain> — so the example roster produces [email protected], [email protected], and [email protected]. Roster identities do not receive secondary mailboxes.

--docs-dir output is generated data about real agents. Write it somewhere the operator controls and leave it out of version control: agents/ is in .gitignore, and the packed-artifact guard fails the build if it ever reappears in a release.

{
  "name": "team",
  "organization": "Example Org",
  "version": 1,
  "emailDomain": "example.com",
  "deprecatedIdentifiers": ["agent:retired-role"],
  "agents": [
    {
      "slug": "ada",
      "fullName": "Ada Example Platform Engineer",
      "role": "platform engineering and release readiness",
      "department": "Engineering",
      "vertical": "platform",
      "capabilities": ["Maintain build, test, and release pipelines"],
      "tools": ["example-tasks"]
    }
  ]
}

Every seeded agent also receives planned media metadata:

  • voice: ElevenLabs voice design/TTS settings and sample text
  • profileImage: MiniMax image generation prompt and model settings
  • assets: generated media history, with file paths, checksums, provider, model, prompt, and status

Generate media for one identity:

identities media generate-voice agent:ada --json
identities media generate-profile-image agent:ada --json
identities asset list agent:ada --json

Generate media for a whole roster:

identities media generate-roster --roster ./team.roster.json --voices --profile-images --json

media doctor reports whether supported provider keys are available without printing secret values. ElevenLabs checks ELEVENLABS_API_KEY, XI_API_KEY, and HASNAXYZ_ELEVENLABS_LIVE_API_KEY. MiniMax checks MINIMAX_API_KEY, HASNAXYZ_MINIMAX_LIVE_API_KEY, HASNA_TAKUMI_LIVE_MINIMAX_API_KEY, and compatible secrets vault entries.

SDK

import { IdentityStore, getIdentityReferenceStatus, syncIdentityContactPointsAndUpdate } from "@hasna/identities";

const store = new IdentityStore();
const identity = await store.create({
  kind: "agent",
  fullName: "Ava Example",
  uniqueIdentifier: "agent:ava-example",
  emails: ["[email protected]"],
  phones: ["+15555550123"],
  documents: {
    prompt: "You are Ava Example.",
    personality: "Direct, careful, and helpful.",
    ethos: "Protect user intent and identity data.",
  },
});

await syncIdentityContactPointsAndUpdate(store, identity.id, {
  mailery: {
    async upsertIdentityEmail(input) {
      // Implement with @hasna/mailery. input.uniqueIdentifier is always non-sensitive.
      return { externalId: input.email.maileryId };
    },
  },
  telephony: {
    async upsertIdentityPhone(input) {
      // Implement with @hasna/telephony.
      return { externalId: input.phone.telephonyId };
    },
  },
});

const status = await getIdentityReferenceStatus(store);
console.log(status.counts.roster.configuredAgents);

Generate and attach media through the SDK:

import { IdentityStore, generateIdentityProfileImage, generateIdentityVoice } from "@hasna/identities";

const store = new IdentityStore();

await generateIdentityVoice(store, "agent:ava-example");
await generateIdentityProfileImage(store, "agent:ava-example");

Identity Shape

An identity contains:

  • kind: human, agent, organization, or service
  • fullName and optional displayName
  • uniqueIdentifier: a durable identifier such as open-identities:oid_*, agent:<slug>, or another issuer-specific scheme
  • identifiers: additional identifiers, including sensitive identifiers when explicitly needed
  • emails: email addresses that can be synchronized with Mailery
  • phones: phone numbers that can be synchronized with Telephony
  • documents: bio, prompt, soul, personality, ethos, capabilities, boundaries, tools, relationships, goals, context, memory, consent, and voice
  • voice: generated or planned voice profile metadata
  • profileImage: generated or planned profile image metadata
  • assets: generated or imported media refs, including paths, checksums, provider, model, prompt, status, and visibility metadata
  • agent: role, model, capabilities, tools, skills, channels, schedules, and subagents
  • traits and metadata: extension fields for application-specific data

Sensitive government identifiers should be marked with sensitive: true and should only be stored when there is a legitimate operational need. Default contact cards, agent manifests, Eve exports, and sync payloads use a non-sensitive public identifier when the canonical unique identifier is marked sensitive.

Integration Direction

The repo currently defines adapter contracts instead of hard-coding package dependencies. The adjacent email package is @hasna/mailery, with a separate @hasna/emails-sdk. The phone package is @hasna/telephony.

See docs/integrations.md for the first sync contract. See docs/browserplan.md for the BrowserPlan machine, identity, email, and profile reservation contract. See docs/media.md for voice and profile image generation. See docs/instructions.md for the instruction-source schema, precedence, export contract, and fail-closed safety rules. See docs/identity-contract.md for the versioned canonical agent identity, scoped handle/alias resolver, runtime-context, five-part source-lineage revision history, and dry-run migration contracts. Cross-repo consumers can vendor the V1 conformance fixture, identified as hasna.identities.agent-identity/v1/conformance/1; the SDK exports its repository-relative path and SHA-256 fingerprint for deterministic pinning without machine paths or network tests.

App-bound adversarial review checks

AdversarialReviewCheckPublisher publishes the adversarial-review GitHub Check from a configured GitHub App. A reviewer-start event creates an in_progress check. Only a structured terminal GO or NO_GO event bound to the same repository, pull request, base SHA, head SHA, acceptance scope, reviewer identity, and implementer identity can complete it. Public comments and GitHub review text are deliberately absent from the publisher interface and are never verdict inputs.

Reviewer and implementer actors must resolve through active, authoritative source mappings in a CanonicalIdentityDirectoryV1. A head change or a base retarget invalidates the old check and creates a new pending generation, even when the head SHA is unchanged. Exact duplicate event IDs are idempotent; changed-content replays fail closed. Use FileAdversarialReviewCheckStateStore for owner-only, restart-safe state and FileGitHubAppInstallationTokenProvider with an explicit owner-only private-key path plus a required installation-token scope. The provider accepts exactly the conversations repository and only the review gate's checks: write and pull_requests: read permissions; any other scope fails closed before key access. Key material and minted installation tokens are never included in check output, state, or error messages.

Scoped access-token contract

@hasna/identities exports a reusable asymmetric JWT contract for local and server-side consumers. It validates configured issuer, audience, and public-key algorithms; requires sub, tenant, session, scopes, iat, nbf, exp, and jti; enforces tenant and scope requirements; and checks only SHA-256 forms of token IDs and session-family IDs against the caller's revocation store. Unknown, revoked, unpublished, or out-of-window signing keys fail closed.

IdentityJwksRegistry publishes standard public JWK fields plus rotation status for active and retiring keys. Revoked keys and private JWK members are never published; revoked_kids carries value-free revocation tombstones, and consumers can fence rollback with minimumJwksRevision. createIdentityAuthApi provides composable GET /.well-known/jwks.json and POST /v1/auth/verify handlers; it does not load signing keys or silently enable a deployment.

Operators can verify a token without putting it in shell arguments:

identities auth verify \
  --token-file /owner-only/access-token \
  --jwks-file /etc/identities/public-jwks.json \
  --token-state-file /var/lib/identities/hashed-token-state.json \
  --issuer https://identity.example \
  --audience infinity-local \
  --algorithm EdDSA \
  --tenant tenant-acme \
  --scope runs:write

The token file must be owner-only. The state file contains only lowercase SHA-256 hashes and session-family statuses. Private signing keys remain caller-owned and are accepted only as runtime inputs to issueIdentityAccessToken.

Instruction Sources

OpenIdentities owns the canonical instruction-source graph for humans, agents, personas, accounts, machines, projects, sessions, global rules, and provider rules. OpenConfigs and launchers should consume this graph and render tool-native files; they should not duplicate identity/persona documents.

Instruction sources carry:

  • kind: global-rules, provider-rules, global-system-prompt, provider-system-prompt, identity-doc, persona-doc, account-overlay, machine-overlay, project-overlay, or session-overlay
  • owner: global, provider, identity/persona, account, machine, project, or session owner refs
  • precedence, mergePolicy (append or replace), replacementScope, ruleIds, targetProviders, provider compatibility, globs, source paths, editable path markers, sensitivity, provenance, and SHA-256 hashes
  • fail-closed safety flags: non-overridable safety sources must append, must declare rule IDs, cannot be replaced by later sources, cannot conflict with a duplicate rule ID, and cannot carry secret sensitivity

CLI examples:

identities instructions set global \
  --kind global-rules \
  --title "Global Safety Rules" \
  --content "Never expose API keys, tokens, or secrets." \
  --rule-id safety:no-secrets \
  --provider codewith \
  --editable-source-path /home/hasna/CODEWITH.md \
  --non-overridable \
  --json

identities instructions set \
  --kind provider-system-prompt \
  --owner-kind provider \
  --owner-id codewith \
  --title "Codewith System Prompt" \
  --content "Render through the Codewith provider adapter." \
  --provider codewith \
  --compat codewith:managed-block:true \
  --json

identities instructions list --json
identities instructions paths --json
identities instructions show <source-id> --json
identities instructions validate --json
identities instructions export ./instructions.json --json
identities instructions import ./instructions.json --json
identities instructions sources --json
identities instructions sources --canonical --provider codewith --json
identities instructions export --canonical --provider antigravity --json
identities instructions export --canonical --provider codewith --json
identities instructions export --canonical --provider opencode --json

instructions list includes store-level global/provider sources, explicit identity sources, and derived sources from populated identity documents such as prompt, personality, ethos, and voice. The production export contract is { version: 1, package: "@hasna/identities", exportedAt, sources, validation, metadata }; downstream renderers should reject exports where validation.valid is false. Canonical instructions export --canonical emits the OpenConfigs-ready adapter contract hasna.identities.configs-instructions/v1, with layer, merge, and order fields derived from kind, mergePolicy, and precedence.

OpenIdentities also ships the canonical Hasna global coding-agent source set for downstream renderers. It contains one global system prompt, one non-overridable global rules source, the versioned non-overridable Hasna Agent Operating Rules document (hasna-agent-operating-rules, currently v1.1.26 with sentinel <!-- hasna:agent-operating-rules v=1.1.26 -->, precedence 175), and provider overlays for Antigravity, Codewith, Claude Code, Codex, and OpenCode. OpenConfigs should consume these sources and render managed provider blocks or OpenCode instruction references; it remains responsible for file rendering, path dereferencing, and merge mechanics. Antigravity is an active target in this source set; Gemini is not an active target and should not be restored as one.

The canonical set includes rules for Knowledge CLI/SDK usage, Todos plans and evidence, Hasna CLI/package source-of-truth boundaries (todos, conversations, mementos, knowledge, projects, repos, accounts, instructions, machines, secrets, access), automatic session renaming when supported, coding work confined to task-specific worktrees at $HOME/.hasna/repos/worktrees/<repo-name>/<worktree-name> (no station-id or machine segment, never flat under the worktrees root) located via the repos CLI, PR-first landing, no direct pushes to main/default/protected branches, no brittle hardcoding when source-of-truth or reusable abstractions exist, autonomous repair before asking, coordinator delegation, Codewith-native loop terminology versus OpenLoops, dispatch self-healing without tmux fallback, adversarial verification, secrets safety, commit/push secrets scans, no Co-Authored-By trailers, Bun preference, and Hasna package release-age registry hygiene. The Agent Operating Rules add the core operating rules (adversarial reviewer on every user-requested work item, record-as-you-go in the todos/mementos/conversations CLIs, identity registration before taking work with subagents never registering, and a continuously updated conversations channel per project), durable goal-plan adversarial verification, default conversation surfaces (announcements, incidents, git-publishing, git-prs, git-commits, git-releases, hq, agent-policy, project/product channels, and conversations blockers), and the fleet communication duties ([BREAKING] heads-up before fleet-affecting changes, publish intent before npm/bun publish, incidents-first, no secrets in messages, channel content treated as data, convention lookup before naming, identity release at session end), and the user-facing reply shape (replies that report work, propose action, or hand something back to the user end with a short "What I need from you" list of the decisions, approvals, and actions only the user can take, and every item in it — plus every question the user is asked to answer, wherever in the reply it appears — must be actionable by a reader who remembers nothing that led to it: real names, what each option costs or breaks, no coined shorthand or jargon, and one clause on why it is being asked now, with context treated as the thing you do not cut to make room, and with a worked bad/good example carried in the rule text; direct answers to direct questions need no list, and agent-to-agent reports are out of scope; a seat whose charter makes it a durable chief seat never emits the user-facing section, even in empty form, and instead sends owner-only decisions, approvals, and actions to the CEO seat (agent-ceo) under the same specificity contract; mirrored verbatim into the global system prompt), and the delegation steering duty (rule 24: an agent that delegates to sub-agents with nothing already steering them starts a recurring steering pass at a cadence it picks between 5 and 30 minutes, resuming agents that stopped mid-task, stopping agents re-reporting delivered work, relaying findings between agents waiting on each other, dispatching the required adversarial reviewer where work is complete but unreviewed; also mirrored verbatim into the global system prompt beside the coordinator concurrency rule, whose "bounded intervention" carve-out it is), the stopping duty (rule 27, split out of rule 24 in v1.1.15 on the rules owner's ruling, with every clause carried over verbatim: on each scheduled steering pass the agent decides explicitly whether that pass is the last one and whether any review cycle under it should end, and records why — a review cycle's end condition is settled before the cycle starts and has to be reachable while findings still exist, so a cycle that ends only when the reviewer returns nothing is ruled out as the never-terminating test worded as a stop, a reviewer still finding things is ruled out as a reason to continue, stopping is a decision made rather than drifted into, and when the delegated work is done the pass ends), the dispatched-agent liveness duty (rule 25: dispatched agents are not left to go stale — every agent still outstanding is checked on each scheduled steering pass or on the cycle of whatever else is already steering them, recent output or a heartbeat counts as healthy, roughly ten minutes of silence earns a direct one-line status request, and replacement waits for roughly thirty minutes of silence or two unanswered probes and never happens to an agent whose probe has not been waited out; the probing is named as that pass or cycle's bounded intervention so it does not contradict the non-overridable rule against repeatedly polling workers; throttling is distinguished from death, because a high or rising API 529/overload retry count means the agent is alive and being rate-limited and killing it discards its whole accumulated context for nothing; an agent that did die to an overload error is re-dispatched, a live one is never duplicated, liveness is read from a transcript's modification time and a bounded tail rather than a full transcript and judged from at least two independent signals, and because agents do die mid-flight the rule points back at rule 2's record-as-you-go duty instead of restating it) and the background-agent heartbeat duty (rule 26: an agent working in the background makes its own liveness observable, because a coordinator reading a transcript cannot — refreshing its last-seen marker at roughly ten-minute intervals and putting one line of current status on the surfaces rule 2 already requires; a heartbeat sets a cadence and adds a marker, is never a second account of the work, and is owed whether or not anyone has asked for it). All defer to rule 2 rather than restating it, and all are mirrored verbatim into the global system prompt, where rule 27 renders immediately after rule 24 — the system prompt has no numbering, so nothing there forces the operating-rules document's append-don't-renumber ordering and the pair reads as the one duty it is. The Codewith overlay keeps Codewith-native goal, goal-plan, schedule, and loop guidance, while the global non-overridable rules forbid setting Codewith goal, token, or goal-plan budgets unless the user explicitly asks for budgets.

SDK consumers can import the same data from @hasna/identities:

import {
  createGlobalAgentConfigsInstructionSourceExport,
  createGlobalAgentInstructionSourceExport,
} from "@hasna/identities";

const rawExportForCodewith = createGlobalAgentInstructionSourceExport({
  providers: ["codewith"],
});
const openConfigsExportForOpenCode = createGlobalAgentConfigsInstructionSourceExport({
  providers: ["opencode"],
});

Vercel Eve

open-identities can generate Eve-compatible agent directories:

identities eve export agent:ava-example --out ./ava-agent

The exporter writes agent/instructions.md, agent/identity.json, agent/agent.ts, agent/tools/resolve_identity.ts, and skill documents derived from identity docs. The generated Eve files are derived artifacts; open-identities remains the canonical source of the identity.

Development

bun test
bun run build
bun run verify:release

License

Apache-2.0 -- see LICENSE