@openagentid/oas-did
v1.0.2
Published
DID parsing, entity kinds, and namespace validation for the Open Agent Specification
Readme
@openagentid/oas-did
DID parsing, entity kind taxonomy, and namespace validation for the Open Agent Specification (OAS).
This is the foundational package in the OAS TypeScript SDK. It parses and validates did:oas:<namespace>:<kind>:<identifier> strings, classifies entity kinds, and enforces the namespace and identifier rules from the OAS specification.
Installation
npm i @openagentid/oas-didRequirements: Node.js >= 20, ESM-only.
Usage
Parse a DID
import { OasDid, EntityKind, isRootKind } from '@openagentid/oas-did';
const did = OasDid.parse('did:oas:l1fe:agent:analyzer');
console.log(did.namespace); // 'l1fe'
console.log(did.kind); // 'agent'
console.log(did.identifier); // 'analyzer'
console.log(did.isRoot); // false
console.log(did.toString()); // 'did:oas:l1fe:agent:analyzer'Create a DID from components
import { OasDid, EntityKind } from '@openagentid/oas-did';
const did = OasDid.create('l1fe', EntityKind.Agent, 'my-bot');
console.log(did.toString()); // 'did:oas:l1fe:agent:my-bot'Parse compound kinds
import { OasDid } from '@openagentid/oas-did';
const did = OasDid.parse('did:oas:l1fe:agent:instance:bot-7');
console.log(did.kind); // 'agent:instance'
console.log(did.identifier); // 'bot-7'Validate namespaces and identifiers
import { validateNamespace, validateIdentifier, isReservedNamespace } from '@openagentid/oas-did';
validateNamespace('l1fe'); // OK
validateNamespace('my-org'); // OK
validateNamespace('L1FE'); // throws DidError (uppercase)
validateIdentifier('alice'); // OK
validateIdentifier('my-agent_v2.0'); // OK
validateIdentifier(''); // throws DidError (empty)
isReservedNamespace('test'); // true
isReservedNamespace('l1fe'); // falseCheck entity kinds
import { EntityKind, isRootKind, entityKindFromString } from '@openagentid/oas-did';
isRootKind(EntityKind.Hmr); // true
isRootKind(EntityKind.Agent); // false
const kind = entityKindFromString('agent:instance');
console.log(kind === EntityKind.AgentInstance); // true
const unknown = entityKindFromString('unknown');
console.log(unknown); // undefinedError handling
import { OasDid, DidError, DidErrorCode } from '@openagentid/oas-did';
try {
OasDid.parse('not-a-did');
} catch (e) {
if (e instanceof DidError) {
console.log(e.code); // 'INVALID_PREFIX'
console.log(e.message); // human-readable description
}
}API Reference
OasDid (class)
Immutable, frozen value object representing a parsed and validated did:oas identifier. Constructed via parse() or create() -- never via new.
class OasDid {
/** The namespace component (e.g., "l1fe"). */
readonly namespace: string;
/** The entity kind (e.g., "agent", "agent:instance"). */
readonly kind: EntityKind;
/** The identifier component (e.g., "analyzer"). */
readonly identifier: string;
/**
* Creates a new OasDid from validated components.
* @param namespace - 1-63 chars, lowercase alphanumeric + hyphens.
* @param kind - The entity kind.
* @param identifier - 1-128 chars, [a-zA-Z0-9._-].
* @returns A frozen OasDid instance.
* @throws DidError if any component fails validation.
*/
static create(namespace: string, kind: EntityKind, identifier: string): OasDid;
/**
* Parses a DID string into an OasDid.
* @param input - The DID string (e.g., "did:oas:l1fe:agent:analyzer").
* @returns A frozen OasDid instance.
* @throws DidError if parsing or validation fails.
*/
static parse(input: string): OasDid;
/** Returns true if this DID represents a root entity (HMR, MHR, or ENR). */
get isRoot(): boolean;
/** Returns the number of colon-separated components in the kind (1 or 2). */
get kindComponentCount(): number;
/** Returns the canonical DID string. */
toString(): string;
/** Returns the canonical DID string for JSON serialization. */
toJSON(): string;
/** Compares two OasDid instances for equality. */
equals(other: OasDid): boolean;
}EntityKind
All recognized OAS entity kinds as a const object with a companion type.
const EntityKind = {
Hmr: 'hmr', // Human Root -- trust anchor
Mhr: 'mhr', // Multi-Human Root -- trust anchor
Enr: 'enr', // Entity Name Record -- MHR-governed trust anchor
Ao: 'ao', // Autonomous Organization
Agent: 'agent', // Autonomous software agent
AgentInstance: 'agent:instance', // Runtime instance of an agent
Tool: 'tool', // Callable capability
Skill: 'skill', // Composable behavior module
Workflow: 'workflow', // Multi-step orchestration
Model: 'model', // Machine learning model
Dataset: 'dataset', // Structured data source
Service: 'service', // Infrastructure service endpoint
} as const;
type EntityKind = (typeof EntityKind)[keyof typeof EntityKind];Functions
/**
* Parses a string into an EntityKind.
* Returns undefined if the string is not recognized.
*/
function entityKindFromString(s: string): EntityKind | undefined;
/**
* Returns the string representation of an entity kind.
*/
function entityKindToString(kind: EntityKind): string;
/**
* Returns true if the entity kind is a root kind (HMR, MHR, or ENR).
*/
function isRootKind(kind: EntityKind): boolean;
/**
* Returns the number of colon-separated components in the kind string.
* Simple kinds return 1; compound kinds (agent:instance) return 2.
*/
function entityKindComponentCount(kind: EntityKind): number;
/**
* Validates a namespace string against OAS Spec rules.
* Valid: 1-63 chars, lowercase alphanumeric + hyphens, no leading/trailing hyphen.
* @throws DidError with code INVALID_NAMESPACE on failure.
*/
function validateNamespace(namespace: string): void;
/**
* Returns true if the namespace is reserved (oas, test, example).
*/
function isReservedNamespace(namespace: string): boolean;
/**
* Validates an identifier string against OAS Spec rules.
* Valid: 1-128 chars, [a-zA-Z0-9._-].
* @throws DidError with code INVALID_IDENTIFIER on failure.
*/
function validateIdentifier(identifier: string): void;Constants
/** Reserved namespaces: ['oas', 'test', 'example'] */
const RESERVED_NAMESPACES: ReadonlyArray<string>;Error classes
class DidError extends Error {
/** Machine-readable error code for programmatic matching. */
readonly code: DidErrorCode;
constructor(code: DidErrorCode, message: string);
}
const DidErrorCode = {
Empty: 'EMPTY',
InvalidPrefix: 'INVALID_PREFIX',
TooFewComponents: 'TOO_FEW_COMPONENTS',
InvalidNamespace: 'INVALID_NAMESPACE',
UnknownEntityKind: 'UNKNOWN_ENTITY_KIND',
InvalidIdentifier: 'INVALID_IDENTIFIER',
} as const;
type DidErrorCode = (typeof DidErrorCode)[keyof typeof DidErrorCode];Dependencies
None. This package has zero runtime dependencies.
License
Copyright © 2026 L1fe Labs, Inc.
Licensed under either of Apache License 2.0 or MIT license, at your option.
