Type Augmentation
Plugins may augment stable runtime/config interfaces with normal TypeScript module augmentation. Generated pika() authoring types use the Engine-owned Typegen manager instead of a global autocomplete augmentation pool.
EngineConfig
EngineConfig is the supported plugin-configuration augmentation anchor:
declare module '@pikacss/core' {
interface EngineConfig {
myPlugin?: {
enabled?: boolean
theme?: 'light' | 'dark'
}
}
}Consumers configure it inside the project entry's engine field:
import { defineConfig } from '@pikacss/unplugin-pikacss'
export default defineConfig({
engine: {
plugins: [myPlugin()],
myPlugin: {
enabled: true,
theme: 'dark',
},
},
})Inside the plugin, prefer configureRawConfig to lower plugin-owned options into existing Core semantic domains. This keeps runtime behavior and generated Typegen under one owner:
defineEnginePlugin({
name: 'my-plugin',
configureRawConfig(config) {
if (!config.myPlugin?.enabled)
return
config.selectors = {
definitions: [
...(config.selectors?.definitions ?? []),
{ name: '@my-theme', value: 'html[data-theme] $' },
],
}
},
})Engine
A plugin that intentionally exposes a runtime/tooling capability may augment Engine:
declare module '@pikacss/core' {
interface Engine {
getTheme: () => string
}
}configureEngine receives an EngineConfigurator; mutate the underlying runtime through engine.runtime:
defineEnginePlugin({
name: 'my-plugin',
configureEngine(engine) {
engine.runtime.getTheme = () => 'dark'
},
})Keep this for genuine runtime/tooling APIs. Semantic selector/shortcut/variable/keyframe producers should be lowered through config rather than exposing another mutable producer ingress.
Generated authoring types
The old global Autocomplete / DefineAutocomplete / appendAutocomplete() architecture is removed. PikaAugment still exists only as transitional generated-file plumbing; it is not a plugin authoring API.
There are two supported patterns.
Prefer an existing semantic subsystem
If your feature is a selector, shortcut, variable, keyframe, token constraint, etc., lower definitions in configureRawConfig. The owning Core subsystem then generates the appropriate Typegen and runtime semantics together.
For dynamic selectors/shortcuts, put the accepted raw TypeScript family in inputType and deterministic concrete completions in autocomplete:
config.shortcuts = {
definitions: [
...(config.shortcuts?.definitions ?? []),
{
pattern: /^my-gap-(.+)$/,
inputType: '`my-gap-${string}`',
resolve: ([, value]) => ({ gap: value }),
autocomplete: ['my-gap-1rem', 'my-gap-2rem'],
},
],
}Register plugin-owned Typegen during configureEngine
For a genuinely new authoring surface, use the owner-bound engine.typegen capability. Registration is initialization-only and closes when that plugin's configureEngine invocation settles:
defineEnginePlugin({
name: 'my-plugin',
configureEngine(engine) {
engine.typegen.add({
id: 'my-plugin:authoring',
declarations: 'interface __MyPluginTheme { current: "dark" | "light" }',
pika: {
theme: '__MyPluginTheme',
},
})
},
})If the same first-level Pika root has runtime semantics, the same plugin must own both sides. Register its static implementation with engine.pika.extendStatic(...) in the same configureEngine lifecycle:
configureEngine(engine) {
engine.pika.extendStatic('theme', { current: 'dark' })
engine.typegen.add({
id: 'my-plugin:theme',
declarations: 'interface __MyPluginTheme { current: "dark" | "light" }',
pika: { theme: '__MyPluginTheme' },
})
}Static extensions are compile-time authoring helpers valid only inside the bounded-static argument tree of the base pika(...) call. They are not general runtime macros.
Direct createEngine() tests
An Engine's typegen.snapshot is always finalized as part of Engine creation, even without a bundler. Integration/hosts later render one or more snapshots into <stateDir>/pika.gen.ts. Tests can therefore assert semantic Typegen contributions directly without inventing a manual PikaAugment declaration.