GalCraft plugin SDK
The galcraft-plugin development CLI supports Node.js 22.12.0 or later. Use the latest Node.js 24 LTS patch for an independent plugin project; source development and CI use Node.js 24.21.0 with pnpm 12.3.4. Generated Node service and native entries target Node.js 22.12; browser entries retain their browser target. The contracts and optional DSL parser exports also serve browser consumers and do not require a Node runtime in those consumers. Plugin authors install exact SDK versions from npm: npm install @galcraft/[email protected] @galcraft/[email protected]. Parser consumers also install @galcraft/[email protected].
The SDK exports plugin contracts at @galcraft/plugins/contracts, the host-shared React instance at @galcraft/plugins/react, the host-shared Pixi namespace at @galcraft/plugins/pixi, and authoring tools at @galcraft/plugins/development. Plugins use these public exports; host assembly uses @galcraft/plugins/host and @galcraft/plugins/registry.
galcraft-plugin create <directory> <pluginId> <template> creates an independent TypeScript project. Templates are author-tool, game-system, resource-stage, service-provider, and complete. Install contracts and plugins with npm install @galcraft/[email protected] @galcraft/[email protected], then run npm run typecheck, npm run build, npm run check, and npm run pack. The package directory supports Studio development loading; .galplugin files support the ordinary installer.
Manifest v1 remains supported. Manifest v2 requires a DOM-free definition entry and supports separate editor, Node services, and runtime entries plus environment dependencies. The host checks SDK major 0 together with the declared engine range. Engine, plugin and SDK package versions stay at 0.1.0 for current local development; example plugins declare ^0.1.0. Ordinary installation can refresh the same package version, and active leases retain a complete graph outside the replaceable package directory until release. An exact project Lock remains authoritative for package versions, including missing-version diagnostics. Plugin state uses one system contribution per plugin.
Package versions do not replace manifest versions, contractVersion: 1, or independent type, operation and state data versions. Existing document, asset-index, snapshot, task, candidate, draft and recipe envelopes remain at schemaVersion 1. Older records keep their original read mapping; opening them does not write extension fields or submit generation requests.
Manifest name and description contain the author's source text. Optional localizations maps locale keys to complete { name, description } translations, for example localizations.en and localizations.ja. Studio resolves display text using the current interface locale, then its language, then the source text. pluginDisplayMetadata(manifest, locale) exposes this rule through @galcraft/plugins/contracts. Display text does not change package IDs, versions or project locks.
The SDK distribution consists of the contracts and plugins package artifacts, plus the optional DSL parser artifact for authoring plugins that read GalCraft statements through @galcraft/dsl/parser. The distribution command builds and packs these artifacts; ordinary plugins install contracts/plugins, while parser consumers also install the matching DSL artifact. Builds bundle ordinary dependencies, preserve the host-shared React entry, and validate the ESM graph for each execution environment. Before measuring manifest file sizes, the build removes trailing spaces and tabs from generated JavaScript syntax in every environment, including native entries. Literal contents and files copied through include retain their original bytes. Services may use node: imports. Definition entries contain synchronous data callbacks and stay independent of UI and service execution.
See the repository developer guide at docs/reference/plugins.md for lifecycle, document mapping, services, and acceptance boundaries. GalCraft SDK code uses MPL-2.0. Distributed SDK tarballs carry the license and a source-availability notice under dist/licenses/project/. The development builder collects a plugin project's own LICENSE, COPYING, NOTICE and licenses/ files plus bundled dependency license reports; it preserves the author's declared license. New projects start with UNLICENSED until their author chooses terms. Read LICENSING.md in the source tree for the project material scope.
Asset UI extensions use AssetEditorContribution, AssetPreviewContribution, and AssetThumbnailContribution from the contracts export. A type descriptor associates editorKey, previewKey, and thumbnailKey with matching manifest declarations and editor contributions. Editor targets distinguish asset metadata, command fields, and stage instances; submit only through the context callback. The context also exposes the selected resource/version and a read-only flag.
Preview contexts identify an indexed asset or an unadopted candidate, carry its exact variant/typeData and read-only resource collection, and provide signal plus onDispose. Mounts may return a synchronous cleanup or a promise for cleanup. Register resources acquired before an awaited operation with onDispose; check signal before appending asynchronous results. Studio isolates each mount and releases old ranges on switching, deactivation, reload, and close. The external custom-asset example demonstrates real vertices/color editing, static previews, thumbnails, formal references, and an exact scalar filterFields declaration.
Typed production operations declare their fields and media ports in a DOM-free definition. The host provides generic controls for each port's type, MIME, required and multiple rules, including selection, replacement and individual removal while preserving other ports. A public fieldEditor is optional; its commit callback updates the personal M10 draft, checks its revision and invalidates the previous send plan. It does not submit an M02 work edit. See plugins/development-examples/video-generation/README.md for the local video protocol example and its verification limits.