TypeScript / Node SDK
Files:
sdk/typescript/shire-sdk.js— runtime (CommonJS, no dependencies).sdk/typescript/shire-sdk.d.ts— TypeScript declarations.
The CLI init --lang typescript copies both and generates a main.ts plus a
tsconfig.json that outputs to out/.
Connect
import { Plugin } from './shire-sdk';
async function main(): Promise<void> {
const plugin = await Plugin.create(); // reads SHIRE_PLUGIN_*
// or: const plugin = new Plugin(); await plugin.ready;
console.log(await plugin.playerPosition());
plugin.run();
}
void main();
Calls
await plugin.log('hello');
await plugin.notify('Title', 'Body', 0);
await plugin.scene();
await plugin.entities(64);
await plugin.markers(128);
await plugin.teleport(1, 2, 3, 0);
await plugin.storageSet('key', { n: 1 });
const value = await plugin.storageGet('key');
await plugin.subscribe('player.position', 'scene.changed');
UI
await plugin.setUi([
plugin.text('Player', 'title'),
plugin.section('Controls'),
plugin.toggle('enabled', 'Enabled', true),
plugin.slider('speed', 'Speed', 5, 0, 10),
plugin.input('name', 'Name', ''),
plugin.select('mode', 'Mode', ['A', 'B'], 'A'),
plugin.progress('Progress', 0.5),
plugin.button('refresh', 'Refresh'),
]);
await plugin.updateUi('speed', { value: 7 });
Events
plugin.onEvent('player.position', (data) => console.log(data.x, data.z));
plugin.onUiEvent((component, type, value) => {
void plugin.notify('UI', `${component}: ${value}`);
});
plugin.run(); // keeps the process alive; close with plugin.close()
Build and manifest
npx --yes -p typescript tsc -p .
The generated main.ts compiles to out/main.js; the CLI also copies
shire-sdk.js into out/. The manifest:
{
"language": "typescript",
"entrypoint": "out/main.js",
"permissions": ["notifications.show", "ui.create"]
}
The Host runs node out/main.js. For a plain JavaScript plugin, use
language: "node" and entrypoint: "main.js"; copy shire-sdk.js beside it.
The SDK is asynchronous; there is no blocking reader on the pipe.