@sutraa/kalpa-semantic
v0.1.1
Published
Framework-neutral semantic manifest schema and graph utilities for Kalpa experiences.
Maintainers
Readme
@sutraa/kalpa-semantic
@sutraa/kalpa-semantic defines Kalpa schema 0.1 and creates a relationship-indexed semantic graph. Use it when your application needs a framework-neutral manifest contract, TypeScript types inferred from that contract, or entity/relationship lookup indexes.
npm install @sutraa/kalpa-semanticExports
| Export | Purpose |
| --- | --- |
| experienceManifestSchema | Zod schema for a complete canonical manifest. |
| capabilitySchema, entitySchema, relationshipSchema, behaviorSchema, representationSchema | Zod schemas for individual manifest collections. |
| createExperienceGraph(manifest) | Builds entity, incoming-relationship, and outgoing-relationship indexes. |
| ExperienceManifest and related inferred types | TypeScript types for canonical semantic data. |
| RuntimeCommand, RuntimeEvent, RuntimeState, RuntimeDiagnostic | Shared runtime contract types. |
Create and validate a manifest
Every canonical manifest uses schemaVersion: "0.1". Entity IDs and relationship IDs use lower-case letters, numbers, and hyphens. The following is the smallest useful manifest with one selectable and inspectable entity.
import {
experienceManifestSchema,
type ExperienceManifest,
} from "@sutraa/kalpa-semantic";
const manifest: ExperienceManifest = {
schemaVersion: "0.1",
experience: {
id: "pump-inspection",
name: "Pump inspection",
purpose: "Inspect a single equipment component.",
defaultRepresentation: "dom",
},
entities: [{
id: "pump",
kind: "equipment",
name: "Transfer pump",
purpose: "Moves fluid through the system.",
capabilities: ["selectable", "inspectable"],
behaviorIds: ["select-pump", "inspect-pump"],
representationIds: ["dom"],
accessibility: {
label: "Transfer pump",
description: "A selectable and inspectable transfer pump.",
essentialTasks: ["Select the pump", "Inspect pump information"],
},
metadata: { material: "steel" },
}],
relationships: [],
capabilities: [
{
id: "selectable",
label: "Selectable",
commandTypes: ["select-entity"],
representationRequirements: ["dom"],
accessibility: { keyboardAction: "Enter or Space", essential: true },
},
{
id: "inspectable",
label: "Inspectable",
commandTypes: ["inspect-entity"],
representationRequirements: ["dom"],
accessibility: { keyboardAction: "Enter or Space", essential: true },
},
],
behaviors: [
{ id: "select-pump", commandType: "select-entity", targetCapability: "selectable", effect: "Selects the pump." },
{ id: "inspect-pump", commandType: "inspect-entity", targetCapability: "inspectable", effect: "Opens pump inspection." },
],
representations: [{
id: "dom",
label: "Accessible DOM",
status: "complete",
supportsCapabilities: ["selectable", "inspectable"],
rationale: "Complete keyboard and semantic baseline.",
}],
};
const checked = experienceManifestSchema.safeParse(manifest);
if (!checked.success) console.error(checked.error.issues);Build a graph index
createExperienceGraph preserves the manifest collections in snapshot and adds lookup maps. It throws when a relationship references an unknown entity, so validate user input with experienceManifestSchema or @sutraa/kalpa-compiler before graph creation when input is untrusted.
import { createExperienceGraph } from "@sutraa/kalpa-semantic";
const graph = createExperienceGraph(manifest);
const pump = graph.entityById.get("pump");
const outgoing = graph.outgoingByEntityId.get("pump") ?? [];
const incoming = graph.incomingByEntityId.get("pump") ?? [];Vocabulary and limits
| Collection | Required meaning in 0.1 | Supported values / rule |
| --- | --- | --- |
| Capability | named interaction contract | command type is select-entity or inspect-entity |
| Behavior | description of a capability command outcome | effect is descriptive text, not executable code |
| Relationship | directed semantic connection | contains, part-of, or feeds-data-to |
| Representation | declared projection capability | ID is dom or canvas; status is complete or degraded |
| Accessibility | task and keyboard intent | every entity needs one or more essential tasks |
This package does not define arbitrary commands, arbitrary relationship types, typed metadata values, visual rendering, or state transitions beyond the shared runtime types. Use the compiler package to enforce cross-collection reference and behavior-capability rules.
License
MIT. Requires Node.js 18 or later.
