package.schema.json field reference#
Purpose#
This Schema describes one version of one package. It stores metadata only: no binary is included, and Agent Forge does not verify sources, compatibility, checksums, signatures, facets, or installation commands. bundle is special: it may omit distributions because installers select distributions for each member.
Top-level fields#
| Field | Type / values | Purpose |
|---|---|---|
schemaVersion | 2 | Contract version. |
id | string | Stable logical package ID across versions, Agents, and projections. |
name | string | Human-readable name or source-local slug. |
displayName | string | Presentation name. |
version | string | Original upstream version; never rewritten. |
versionScheme | enum | Comparison hint only. |
description | string | Package description. |
releaseNotes | string | Notes for this version. |
license | string or string[] | Upstream license declaration. |
media | object | Optional icon and ordered static previews; unverified image references. |
links | object | repository, homepage, readme, license, documentation, changelog, issues URLs. |
keywords | string[] | Free-text search terms. |
maintainers | object[] | Maintainer identity and role. |
platform | object | OS, architecture, libc, and runtime hints. |
type | mcp/plugin/skill/general/bundle | First-class Agent Forge category. |
subtype | string or null | One administrator-controlled subtype. |
mcpDetails | object | MCP-specific registry and transport details. |
pluginDetails | object | Plugin manifest and entrypoint details. |
skillDetails | object | Skill path and allowed-tool details. |
generalDetails | object | Requires toolType and agentUse; no kind or typeRef.type. |
bundleDetails | object | Members, effective targets, and facet union. |
targets | object[] | Agent compatibility and target metadata. |
distributions | object[] | Git, Release, Archive, Registry, OCI, or other artifact candidates. Required for non-Bundles. |
dependencies/conflicts/provides/replaces | object[] | Shared relationship declarations for every type. |
facets | object | Controlled administrator vocabulary. |
customFacets | object | User vocabulary kept separate and unverified. |
lifecycle | object | Active, deprecated, archived, yanked, or experimental state. |
createdAt/updatedAt/publishedAt | date-time | Lifecycle timestamps. |
_meta | namespaced object | Preserved extension data with no Agent Forge interpretation. |
Reusable definitions#
identifier, packageName, url, timestamp, stringOrArray, and stringList provide shared primitive constraints. agentTarget requires agentId and compatibilityStatus; known targets require a range, while unknown targets require a null range and note. distribution requires id, type, and url, with optional Agent filters, refs, regions, checksum, signature, and install hints. bundleMember uses memberType (package or bundle) and memberId; cycles are rejected by semantic validation.
The optional distribution name is a human-readable label, such as github repository or npm package. Consumers should display name when available and fall back to type. Known sources use specific type values: github-repo retains repository/ref semantics, and npm-pkg retains registry/version semantics with registry=npm. Plugin sourceType also supports these values. Generic git and registry remain valid for other and legacy sources. Consumers must support the new type values before using migrated records; dispatch based only on the old enum is insufficient.
Other specific sources are pypi-pkg, nuget-pkg, crates-pkg, ghcr-image, dockerhub-image, quay-image, gcp-artifact-image, oci-image, github-mcpb, gitlab-mcpb, mcpb-pkg, and mcp-endpoint. Image sources retain OCI semantics, MCPB sources are files, and MCP endpoints are remote services.
Package names and index keys preserve original Unicode text. Identifiers accept Unicode or UTF-8 percent escapes, with controls, whitespace, and literal backslashes forbidden. New imported identities use reversible percent encoding; established ids remain unchanged. JSON Unicode escapes serialize the same decoded value rather than creating an identity alias. Filesystem and URL encoding are separate from package names.
Commented TypeScript-style example#
The example fills every co-existing top-level field and distribution field. The five type-specific detail objects are intentionally mutually exclusive, so no valid instance can contain all five at once; the remaining four detail branches are covered by the field reference and the branch note below.
const record = {
schemaVersion: 2, // Public contract version.
id: "dsh.example-skin", // Stable logical ID.
name: "example-skin", // Source-local package name.
displayName: "Example Skin", // Display label.
version: "1.4.0", // Original upstream version.
versionScheme: "semver", // Comparison hint only.
description: "A GUI skin plugin for DSH.", // Human-readable description.
releaseNotes: "Adds compact navigation icons.", // Version notes.
license: "MIT", // Recorded declaration, not legal verification.
links: { // URLs are indexed, not copied or reviewed.
repository: "https://github.com/example/example-skin", // Source repository.
homepage: "https://example.com/example-skin", // Homepage.
readme: "https://github.com/example/example-skin#readme", // README.
license: "https://github.com/example/example-skin/blob/v1.4.0/LICENSE", // LICENSE.
documentation: "https://example.com/example-skin/docs", // Documentation.
changelog: "https://github.com/example/example-skin/blob/v1.4.0/CHANGELOG.md", // Changelog.
issues: "https://github.com/example/example-skin/issues", // Issue tracker.
},
keywords: ["gui", "skin", "desktop"], // Search terms.
maintainers: [{ name: "Example Maintainer", url: "https://github.com/example", email: "[email protected]", role: "maintainer" }], // Maintainer.
platform: { os: ["linux", "windows"], arch: ["x86_64", "arm64"], libc: ["glibc"], runtime: ["nodejs>=20"] }, // Platform hints.
type: "plugin", // First-class category.
subtype: "skin", // Administrator-controlled subtype.
pluginDetails: { manifestPath: ".dsh/plugin.json", sourceType: "github-repo", marketplaceUrl: "https://example.com/marketplace/example-skin", entrypoint: "dist/index.js", permissions: ["filesystem.workspace-read"] }, // Plugin details.
targets: [{ agentId: "dsh", agentVersionRange: "^0.2.0", versionScheme: "semver", compatibilityStatus: "known", targetMetadata: { desktop: true }, installMetadata: { mode: "plugin" }, status: "active" }, { agentId: "future-agent", agentVersionRange: null, versionScheme: "unknown", compatibilityStatus: "unknown", compatibilityNote: "Upstream did not publish a parseable range.", targetMetadata: {}, installMetadata: {}, status: "experimental" }], // Known and unknown targets.
distributions: [{ id: "github-release", type: "release", url: "https://github.com/example/example-skin/releases/download/v1.4.0/example-skin.zip", agentIds: ["dsh"], version: "1.4.0", ref: "v1.4.0", registry: "github", priority: 10, regions: ["global"], checksum: { sha256: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, signature: { url: "https://example.com/example-skin.sig", type: "sigstore", keyId: "example-key", keyUrl: "https://example.com/keys/example.asc" }, install: { type: "url", url: "https://example.com/example-skin.zip", command: "dsh plugin install example-skin", scriptIntegrity: "sha256-BASE64-VALUE", requires: ["dsh>=0.2.0"], notes: "Review upstream instructions." }, notes: "Primary distribution." }], // Artifact candidates, not catalog mirrors.
dependencies: [{ id: "dsh.ui-runtime", versionRange: "^0.2.0", versionScheme: "semver", agentId: "dsh", optional: false, reason: "Provides the extension host." }], // Dependencies.
conflicts: [{ id: "dsh.legacy-theme", versionRange: "<2.0.0", versionScheme: "semver", agentId: "dsh", optional: false, reason: "Same theme slot." }], // Conflicts.
provides: [{ id: "dsh.gui.skin", versionRange: "1.4.0", versionScheme: "semver", agentId: "dsh", optional: false, reason: "Skin capability." }], // Provided capability.
replaces: [{ id: "dsh.example-skin-old", versionRange: "*", versionScheme: "custom", agentId: "dsh", optional: false, reason: "Successor package." }], // Replacement.
facets: { capabilities: ["gui.modify"], effects: ["user-config.modify"], dataPractices: ["public:read"], permissions: ["filesystem.workspace-read"], runtime: ["interactive.required"], integrations: ["agent-ui"] }, // Core facets.
customFacets: { capabilities: ["theme.preview"], effects: ["desktop.appearance.modify"], dataPractices: ["telemetry:unknown"], permissions: [], runtime: ["gpu.optional"], integrations: ["community-dashboard"], other: ["community-entered"] }, // User facets.
lifecycle: { status: "active", reason: "Maintained upstream.", replacementId: "dsh.example-skin-next", since: "2026-09-30T16:00:00Z" }, // Lifecycle.
createdAt: "2026-09-01T00:00:00Z", // Creation time.
updatedAt: "2026-09-30T15:00:00Z", // Last update.
publishedAt: "2026-09-30T16:00:00Z", // Public time.
_meta: { "org.example/review": { importedBy: "community" } }, // Namespaced extension.
} as const;
Use mcpDetails, skillDetails, generalDetails, or bundleDetails only when the corresponding top-level type is selected. generalDetails.toolType describes a General tool without introducing another first-class category. Bundle members use memberType, expose the intersection of member Agent sets, and keep core facetUnion separate from customFacetUnion.
Display media#
Optional media.icon requires an absolute credential-free HTTPS url (at most 4096 characters) and nonblank alt (1–500 characters). Optional media.previews is an ordered array of 1–12 images with the same required fields and optional theme=light|dark|system. The first image is the default preview. A media object must contain at least one of these fields; unknown fields are rejected. These are static references, not interactive skin code, verified assets, or compatibility claims. No image is fetched, cached or proxied by catalog tools. Skins remain plugin + subtype=skin.
Indexes carry only the icon and at most the first preview in packageEntry.media; fetch the selected record for the gallery. Pages requests external images only after session-local consent, using no-referrer, lazy loading and fixed failure placeholders. Accepted imported references retain source/revision evidence in _meta["org.agentforge/media-provenance"].sources.
This is a v2 optional extension, not forward compatibility with old closed validators: upgrade package/index validators and strict consumers before publishing media-bearing records. Backfill planning, hash guards and the release gate are described in the repository's docs/MEDIA-MIGRATION.zh-CN.md.