Skip to content

Repository files navigation

sb3-toolchain

日本語

A Node.js toolchain for managing Scratch 3 and TurboWarp .sb3 projects as Git-diffable expanded sources and rebuilding bit-for-bit identical SB3 files from the same input.

Features

  • Safely expand an SB3 into formatted project.source.json, assets, and embedded extensions
  • Validate asset references, MD5 hashes, ZIP entries, and embedded extension mappings
  • Manage embedded extensions from pinned GitHub commits or exact installed npm package versions and verify their SHA-256 hashes offline
  • Optionally compare versioned extension API manifests before replacing embedded JavaScript
  • Statically bundle multiple extensions into one permission unit without deleting their original JavaScript, then restore them from either the expanded source or the bundled SB3
  • Produce deterministic builds with fixed ZIP entry order, timestamps, and compression settings
  • Add sprites, backdrops, costumes, and sounds from an optional JSON or YAML build manifest without modifying the expanded base source
  • Optionally lay out every target's scripts in a deterministic TurboWarp-style cleaned arrangement
  • Protect uncommitted Git changes when importing
  • Protect existing output through transactional replacement and rollback
  • Provide both a CLI and a JavaScript API

Requirements

  • Node.js 22.12.0 or later
  • pnpm 11

Installation

Pin the verified npm version for reproducible installation.

pnpm add --save-dev --save-exact @kubohiroya/sb3-toolchain@0.10.0

Quick start

Expand an SB3 saved by TurboWarp, validate it, and rebuild it.

sb3-toolchain import tmp/project.sb3 --output app
sb3-toolchain check app
sb3-toolchain build app --output dist/project.sb3

See docs/workflows.md for the recommended source-of-truth, re-import, replacement protection, extension update, and CI workflows for a project repository.

JavaScript API

import {readFile} from 'node:fs/promises';

import {
  buildSb3,
  bundleExtensions,
  createDeterministicSb3,
  extensionIntegrity,
  extensionStatus,
  importSb3,
  migrateExtensionId,
  planExtensionIdMigration,
  syncExtensions,
  unbundleSb3,
  unbundleExtensions,
  updateExtensions,
  validateSb3Source,
} from '@kubohiroya/sb3-toolchain';

await importSb3({
  inputPath: 'tmp/project.sb3',
  outputDirectory: 'app',
});

await validateSb3Source('app');

await buildSb3({
  sourceDirectory: 'app',
  outputPath: 'dist/project.sb3',
  // Opt in to cleaned block coordinates in the generated SB3 only:
  cleanUpBlocks: true,
});

const {archive} = await createDeterministicSb3('app', {cleanUpBlocks: true});

const integrity = extensionIntegrity(await readFile('app/extensions/example.js'));

const statuses = await extensionStatus('app');
const migration = await planExtensionIdMigration({
  sourceDirectory: 'app',
  fromId: 'oldId',
  toId: 'newid',
});
await migrateExtensionId({
  sourceDirectory: 'app',
  fromId: 'oldId',
  toId: 'newid',
  yes: true,
});
await syncExtensions({sourceDirectory: 'app', yes: true});
await updateExtensions({
  sourceDirectory: 'app',
  extensionId: 'oldId',
  migrateToId: 'newid',
  sourceArtifact: 'dist/newid.js',
  apiManifestArtifact: 'dist/newid.manifest.json',
  yes: true,
});
// After reviewing a reported breaking API change, opt in explicitly:
await updateExtensions({sourceDirectory: 'app', allowBreakingApi: true, yes: true});
await bundleExtensions({
  sourceDirectory: 'app',
  bundleId: 'projectbundle',
  bundleName: 'Project Extension Bundle',
  extensionIds: ['extensionone', 'extensiontwo'],
  yes: true,
});
await unbundleExtensions({
  sourceDirectory: 'app',
  bundleId: 'projectbundle',
  yes: true,
});
await unbundleSb3({
  inputPath: 'dist/project.sb3',
  outputPath: 'dist/project.unbundled.sb3',
  bundleId: 'projectbundle',
  yes: true,
});

Documentation

Development

corepack enable
pnpm install --frozen-lockfile
pnpm run check

License

SPDX-License-Identifier: MPL-2.0

This implementation extracts the general SB3 source-management mechanism developed for kubohiroya/tm-kamishibai from the TurboWarp TM application layer.

About

A Node.js toolchain for managing Scratch 3 and TurboWarp .sb3 projects as Git-diffable expanded sources and rebuilding bit-for-bit identical SB3 files from the same input.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages