create-spellcraft-module v0.1.1

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.

$ npm init spellcraft-module @me/my-new-module

Core Principles

Guided by three fundamental principles to ensure your configuration remains stable, contextual, and universal.

rocket_launch
rocket_launch

Portability

Write once, manifest anywhere. SpellCraft modules are self-contained logical units that run consistently across CI/CD, local, and cloud environments.

visibility
visibility

Awareness

Contextual intelligence. The engine is designed to be fully aware of its surroundings, sourcing data from envs, secure stores, and third-party APIs.

sync
sync

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.

Input
psychology Context
Input
database Data Sources
Input
api Third Party APIs
auto_fix_high Spellcraft
Manifest
data_object JSON
Manifest
description YAML
Manifest
settings INI

Arcane Architecture

The sacred geometry of a SpellCraft module. Every file serves a specific purpose in the transmutation process.

folder_open my-new-module/
├── folder utils/
│ ├── cli-test.js
│ └── test.js
├── .gitignore
├── module.js
├── module.libsonnet
├── package.json
├── README.md
└── test.jsonnet

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

01.

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.

metadata.requires TRACE
exports._spellcraft_metadata = {
  requires: [
    "@c6fc/spellcraft-aws-auth",
    "@c6fc/spellcraft-k8s-utils"
  ]
};
02.

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.

metadata.fileTypeHandlers DIRECT
exports._spellcraft_metadata = {
  fileTypeHandlers: {
    // Transform .foo files into formatted JSON strings
    '.*?\.foo': (content) => JSON.stringify(content, null, 4)
  }
};
03.

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.

metadata.functionContext COMPOSE
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); 
}];
04.

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.

metadata.cliExtensions GRAFT
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.

$ npm run cli -- -h
$ npm run cli -- echo "Hello"
05.

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.

metadata.init EVOKE
exports._spellcraft_metadata = {
  init: async () => {
    // Setup environment for the engine
    process.env.ARCANE_DEBUG = "true";
    await someArcaneProvider.connect();
  }
};
06.

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>.

Step 1: module.js EXPORT
// Register a native function with the engine
exports.shout = [
  (text) => text.toUpperCase() + "!!!",
  "text" // Argument metadata
];
Step 2: module.libsonnet REGISTER
// Wrap the namespaced native call for consumers
{
  shout(text): std.native('my-package:shout')(text)
}
Step 3: test.jsonnet INVOKE
local myMod = import 'my-package/module.libsonnet';

{
  message: myMod.shout("hello world") 
} 
// Result: { "message": "HELLO WORLD!!!" }

The Alchemist's Workflow

1

Initialize the Circle

Use npm init spellcraft-module to generate the mandatory structure, including module.js and the test frame.

check_circle Evaluating test.jsonnet...
check_circle Loading module @me/my-new-module
sync Generating artifacts...
2

Simulate Terminal Invocations

Test your CLI extensions with npm run cli -- -h to verify your custom sub-commands and flags.

3

Perform the Sacrifice

Validate your module with npm run test. The test frame manifests test.jsonnet in-memory to ensure correctness.