Forge Your Own Reality
Extend the Spellcraft engine by scaffolding custom modules. Define arcane logic in JavaScript and expose it via high-level Jsonnet abstractions.
Core Principles
Guided by three fundamental principles to ensure your configuration remains stable, contextual, and universal.
Portability
Write once, manifest anywhere. SpellCraft modules are self-contained logical units that run consistently across CI/CD, local, and cloud environments.
Awareness
Contextual intelligence. The engine is designed to be fully aware of its surroundings, sourcing data from envs, secure stores, and third-party APIs.
Idempotency
Stable transmutations. Every evaluation is deterministic, ensuring that reaching the same manifest reality is consistent, regardless of frequency.
Mana Flow
Magic is omniscient. Your spells source knowledge from anywhere, transmuting it as you see fit.
Arcane Architecture
The sacred geometry of a SpellCraft module. Every file serves a specific purpose in the transmutation process.
module.js
The heart of your module. Contains the native JavaScript exports and
_spellcraft_metadata that drive your module's logic.
module.libsonnet
The declarative shell. High-level wrapper functions that expose your JS logic as easy-to-use Jsonnet abstractions.
test.jsonnet
The demonstration of power. Both a comprehensive test case and a living example of how to manifest your module's capabilities.
package.json
Standard NPM metadata with a "spellcraft": true flag, informing
the engine to treat this package as a valid module.
Components of a SpellCraft Module
requires
Declares dependency on other SpellCraft modules. Ensures they are loaded and available in the execution environment.
fileTypeHandlers
Regex-based content transmutations. Register custom handlers to automatically parse and transform specific file extensions.
functionContext
Injects properties into the shared this context. Allows multiple native functions
to access common utilities.
cliExtensions
Extends the spellcraft CLI via Yargs. Graft custom sub-commands and flags directly
onto the engine.
init Hook
The primary initialization ritual. An async hook executed during the engine's boot sequence to prepare whatever context you need.
Native Exports
Public exports outside of metadata. These are automatically transformed into namespaced native functions accessible within your Jsonnet spells.
Module Dependencies
The requires array ensures that dependent modules are always loaded into the
SpellFrame first. This guarantees that any required function context, native utilities, or
initialization prerequisites from those modules are present and active before your own module
manifests.
exports._spellcraft_metadata = {
requires: [
"@c6fc/spellcraft-aws-auth",
"@c6fc/spellcraft-k8s-utils"
]
};
File Type Handlers
Register custom transmutations for specific file extensions. When the Spellcraft engine encounters a file matching your regex, it passes the raw content through these handlers, allowing you to parse complex formats into native objects that Jsonnet can consume.
exports._spellcraft_metadata = {
fileTypeHandlers: {
// Transform .foo files into formatted JSON strings
'.*?\.foo': (content) => JSON.stringify(content, null, 4)
}
};
Shared Function Context
Define properties that should be grafted onto the this context for your native
functions. This is ideal for sharing heavy utility objects, configuration constants, or SDK
instances across multiple exports without polluting the global scope.
const utils = require('./utils');
exports._spellcraft_metadata = {
functionContext: {
helpers: utils,
apiVersion: "v1.4.2"
}
};
// Accessible via `this` in native functions:
exports.myFunc = [function() {
return this.helpers.format(this.apiVersion);
}];
CLI Extensions
Inject custom commands and flags directly into the spellcraft terminal interface.
By utilizing the provided yargs and spellframe instances, you can
build specialized sub-rituals that interact with the engine's core rendering pipeline.
exports._spellcraft_metadata = {
cliExtensions: (yargs, spellframe) => {
yargs.command("echo " , "Print a message",
(yargs) => yargs.positional('msg', { describe: 'The message' }),
async (argv) => {
await spellframe.init();
console.log(argv.msg);
}
);
}
};
To test your new command, use the cli script provided in your module's
package.json. This allows you to invoke the local engine with your module
pre-loaded, verifying that your sub-command is registered and functional.
Initialization Ritual
The primary lifecycle anchor for your module. The init hook is an asynchronous
function called during the engine's boot sequence. Use this space to establish network
connections or prepare stateful contexts needed by your functions.
exports._spellcraft_metadata = {
init: async () => {
// Setup environment for the engine
process.env.ARCANE_DEBUG = "true";
await someArcaneProvider.connect();
}
};
The Three-Step Transmutation
Native power follows a sacred path from JavaScript to your Jsonnet spells. Any export from
module.js is registered by the engine as a native function named
<package>:<export_name>.
// Register a native function with the engine
exports.shout = [
(text) => text.toUpperCase() + "!!!",
"text" // Argument metadata
];
// Wrap the namespaced native call for consumers
{
shout(text): std.native('my-package:shout')(text)
}
local myMod = import 'my-package/module.libsonnet';
{
message: myMod.shout("hello world")
}
// Result: { "message": "HELLO WORLD!!!" }
The Alchemist's Workflow
Initialize the Circle
Use npm init spellcraft-module to generate the
mandatory structure, including module.js and the test frame.
Simulate Terminal Invocations
Test your CLI extensions with npm run cli -- -h to
verify your custom sub-commands and flags.
Perform the Sacrifice
Validate your module with npm run test. The test
frame manifests test.jsonnet in-memory to ensure correctness.