TypeScript/Node.js SDK for the KitOps CLI. Provides a type-safe functional API for packing, pushing, pulling, and inspecting ModelKits — without having to shell out manually.
Similar to pykitops but for TypeScript/JavaScript.
- Node.js >= 23
- KitOps CLI installed and available in
PATH(or setKITOPS_CLI_PATHto the full path of the binary)
npm install @kitops/kitops-ts
# or
pnpm add @kitops/kitops-tsimport { login, pack, push } from '@kitops/kitops-ts';
await login('registry.example.com', process.env.REGISTRY_USER!, process.env.REGISTRY_PASS!);
await pack('.', { tag: 'registry.example.com/org/my-model:v1.0.0' });
await push('registry.example.com/org/my-model:v1.0.0');Scans a directory for ML artifacts and generates a Kitfile. Automatically detects models, datasets, code, and docs by file extension.
const result = await init('./my-model', {
name: 'my-model',
desc: 'Sentiment analysis model',
author: 'ML Team',
force: true, // overwrite existing Kitfile
});
console.log(result.kitfilePath); // absolute path to the generated KitfileReturns the parsed Kitfile for a ModelKit. The result also carries a non-enumerable _raw property with the original YAML string.
const kitfile = await info('registry.example.com/org/my-model', 'v1.0.0');
console.log(kitfile.package?.name);
console.log(kitfile.model?.path);Returns the full OCI manifest and parsed Kitfile. Use flags.remote to inspect directly from a registry without pulling first.
const result = await inspect('registry.example.com/org/my-model', 'v1.0.0', { remote: true });
console.log(result.digest);
console.log(result.manifest.layers);Packages a directory containing a Kitfile into a ModelKit.
await pack('.', {
tag: 'registry.example.com/org/my-model:v1.0.0',
compression: 'zstd',
});Extracts a ModelKit into a directory. Use flags.filter to pull out specific layers or paths.
// Extract everything
await unpack('./output');
// Model layer only
await unpack('./output', { filter: 'model' });
// A specific dataset and the full docs layer
await unpack('./output', { filter: 'datasets:validation,docs' });
// Don't fail if files already exist
await unpack('./output', { ignoreExisting: true });Lists ModelKits. Omit the argument to list local storage; pass a registry/repository to list remote tags.
const local = await list();
const remote = await list('registry.example.com/org/my-model');
for (const kit of local) {
console.log(kit.repository, kit.tag, kit.size, kit.digest);
}Pushes a ModelKit to a registry. Supply destination to push under a different reference (e.g. promote from staging to production).
await push('registry.example.com/org/my-model:v1.0.0');
// Push to a different registry under a different tag
await push('staging.example.com/my-model:rc1', 'registry.example.com/org/my-model:v1.0.0');Pulls a ModelKit from a registry into local storage.
await pull('registry.example.com/org/my-model:v1.0.0');Authenticates with a registry. The password is passed as a CLI argument and will be visible in the process list — use login instead for production.
await loginUnsafe('registry.example.com', 'user', 'pass');Same as login but passes the password via stdin, keeping it out of the process list. Preferred for CI and automated workflows.
await login(
'registry.example.com',
process.env.REGISTRY_USER!,
process.env.REGISTRY_PASS!,
);await logout('registry.example.com');Assigns a new tag to an existing local ModelKit without re-packing. Use push afterward to publish it.
await tag('registry.example.com/org/my-model:rc1', 'registry.example.com/org/my-model:v1.0.0');Removes a ModelKit from local storage or a remote registry.
// Remove a specific tag
await remove('registry.example.com', 'org/my-model', 'v0.9.0');
// Remove all locally cached ModelKits
await remove('', '', '', { all: true });
// Force-remove from the remote registry
await remove('registry.example.com', 'org/my-model', 'v0.9.0', { force: true, remote: true });Returns version information for the installed kit binary.
const { version, commit, built, goVersion } = await version();
console.log(`kit ${version} (${commit})`);Low-level escape hatch for running any kit subcommand directly, useful when the higher-level wrappers don't expose a flag you need.
const result = await kit('pack', ['.', '--tag', 'my-model:latest'], { cwd: '/path/to/project' });
console.log(result.stdout);All functions reject with a string message that includes the exit code and stderr output from the CLI. Wrap calls in try/catch to handle failures:
try {
await push('registry.example.com/org/my-model:v1.0.0');
} catch (err) {
console.error(err); // "Kit command failed with exit code 1: ..."
process.exit(1);
}| Variable | Description |
|---|---|
KITOPS_CLI_PATH |
Full path to the kit binary. Defaults to kit (resolved via PATH). |
See the examples/ directory for runnable scripts covering common workflows:
- Build a Kitfile programmatically
- CI/CD pipeline
- Tag and promote a release
- LLM fine-tuning dataset packaging
pnpm install
pnpm build # compile TypeScript
pnpm dev # watch mode
pnpm test # run tests
pnpm typecheck # type-check without emitting