🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

@tutorialkit/cli

Package Overview
Dependencies
Maintainers
5
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tutorialkit/cli - npm Package Compare versions

Comparing version

to
1.4.0

354

dist/index.js
#!/usr/bin/env node
// src/index.ts
import chalk7 from "chalk";
import chalk8 from "chalk";
import yargs2 from "yargs-parser";
// src/commands/create/index.ts
import fs6 from "node:fs";
import path6 from "node:path";
import * as prompts6 from "@clack/prompts";
import chalk5 from "chalk";
import fs7 from "node:fs";
import path7 from "node:path";
import * as prompts7 from "@clack/prompts";
import chalk6 from "chalk";
import { execa } from "execa";

@@ -18,3 +18,3 @@ import "yargs-parser";

name: "@tutorialkit/cli",
version: "1.3.1",
version: "1.4.0",
description: "Interactive tutorials powered by WebContainer API",

@@ -72,3 +72,3 @@ author: "StackBlitz Inc.",

tempy: "^3.1.0",
vitest: "^2.1.1"
vitest: "^3.0.5"
},

@@ -439,5 +439,5 @@ engines: {

visit(ast, {
ImportDeclaration(path8) {
if (path8.node.source.value === integrationImport) {
const defaultImport = path8.node.specifiers.find((specifier) => specifier.type === "ImportDefaultSpecifier");
ImportDeclaration(path9) {
if (path9.node.source.value === integrationImport) {
const defaultImport = path9.node.specifiers.find((specifier) => specifier.type === "ImportDefaultSpecifier");
if (defaultImport) {

@@ -453,7 +453,7 @@ integrationId = defaultImport.local;

visit(ast, {
ExportDefaultDeclaration(path8) {
if (!t.isCallExpression(path8.node.declaration)) {
ExportDefaultDeclaration(path9) {
if (!t.isCallExpression(path9.node.declaration)) {
return;
}
const configObject = path8.node.declaration.arguments[0];
const configObject = path9.node.declaration.arguments[0];
if (!t.isObjectExpression(configObject)) {

@@ -587,3 +587,3 @@ throw new Error("TutorialKit is not part of the exported config");

// src/commands/create/git.ts
// src/commands/create/generate-hosting-config.ts
import fs3 from "node:fs";

@@ -594,2 +594,118 @@ import path3 from "node:path";

// src/commands/create/hosting-config/_headers.txt?raw
var headers_default = "/*\n Cross-Origin-Embedder-Policy: require-corp\n Cross-Origin-Opener-Policy: same-origin\n";
// src/commands/create/hosting-config/netlify_toml.txt?raw
var netlify_toml_default = '[[headers]]\n for = "/*"\n [headers.values]\n Cross-Origin-Embedder-Policy = "require-corp"\n Cross-Origin-Opener-Policy = "same-origin"\n';
// src/commands/create/hosting-config/vercel.json?raw
var vercel_default = {
headers: [
{
source: "/(.*)",
headers: [
{
key: "Cross-Origin-Embedder-Policy",
value: "require-crop"
},
{
key: "Cross-Origin-Embedder-Policy",
value: "same-origin"
}
]
}
]
};
// src/commands/create/options.ts
import path2 from "node:path";
import { fileURLToPath } from "node:url";
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
var templatePath = path2.resolve(__dirname, "../template");
var DEFAULT_VALUES = {
git: !process.env.CI,
install: true,
start: true,
dryRun: false,
force: false,
packageManager: "npm",
provider: "skip"
};
function readFlag(flags, flag) {
let value = flags[flag];
if (flags.defaults) {
value ??= DEFAULT_VALUES[flag];
}
return value;
}
// src/commands/create/generate-hosting-config.ts
async function generateHostingConfig(dest, flags) {
let provider = readFlag(flags, "provider");
if (provider === void 0) {
provider = await prompts2.select({
message: "Select hosting providers for automatic configuration:",
options: [
{ value: "Vercel", label: "Vercel" },
{ value: "Netlify", label: "Netlify" },
{ value: "Cloudflare", label: "Cloudflare" },
{ value: "skip", label: "Skip hosting configuration" }
],
initialValue: DEFAULT_VALUES.provider
});
}
if (typeof provider !== "string") {
provider = "skip";
}
if (!provider || provider === "skip") {
prompts2.log.message(
`${chalk3.blue("hosting provider config [skip]")} You can configure hosting provider settings manually later.`
);
return provider;
}
prompts2.log.info(`${chalk3.blue("Hosting Configuration")} Setting up configuration for ${provider}`);
const resolvedDest = path3.resolve(dest);
if (!fs3.existsSync(resolvedDest)) {
fs3.mkdirSync(resolvedDest, { recursive: true });
}
let config;
let filename;
switch (provider.toLowerCase()) {
case "vercel": {
config = typeof vercel_default === "string" ? vercel_default : JSON.stringify(vercel_default, null, 2);
filename = "vercel.json";
break;
}
case "netlify": {
config = netlify_toml_default;
filename = "netlify.toml";
break;
}
case "cloudflare": {
config = headers_default;
filename = "_headers";
break;
}
}
if (config && filename) {
await runTask({
title: `Create hosting files for ${provider}`,
dryRun: flags.dryRun,
dryRunMessage: `${warnLabel("DRY RUN")} Skipped hosting provider config creation`,
task: async () => {
const filepath = path3.join(resolvedDest, filename);
fs3.writeFileSync(filepath, config);
return `Added ${filepath}`;
}
});
}
return provider;
}
// src/commands/create/git.ts
import fs4 from "node:fs";
import path4 from "node:path";
import * as prompts3 from "@clack/prompts";
import chalk4 from "chalk";
// src/utils/shell.ts

@@ -635,23 +751,2 @@ import { spawn } from "node:child_process";

// src/commands/create/options.ts
import path2 from "node:path";
import { fileURLToPath } from "node:url";
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
var templatePath = path2.resolve(__dirname, "../template");
var DEFAULT_VALUES = {
git: !process.env.CI,
install: true,
start: true,
dryRun: false,
force: false,
packageManager: "npm"
};
function readFlag(flags, flag) {
let value = flags[flag];
if (flags.defaults) {
value ??= DEFAULT_VALUES[flag];
}
return value;
}
// src/commands/create/git.ts

@@ -661,3 +756,3 @@ async function initGitRepo(cwd, flags) {

if (shouldInitGitRepo === void 0) {
const answer = await prompts2.confirm({
const answer = await prompts3.confirm({
message: "Initialize a new git repository?",

@@ -680,8 +775,8 @@ initialValue: DEFAULT_VALUES.git

} else {
prompts2.log.message(`${chalk3.blue("git [skip]")} You can always run ${chalk3.yellow("git init")} manually.`);
prompts3.log.message(`${chalk4.blue("git [skip]")} You can always run ${chalk4.yellow("git init")} manually.`);
}
}
async function _initGitRepo(cwd) {
if (fs3.existsSync(path3.join(cwd, ".git"))) {
return `${chalk3.cyan("Nice!")} Git has already been initialized`;
if (fs4.existsSync(path4.join(cwd, ".git"))) {
return `${chalk4.cyan("Nice!")} Git has already been initialized`;
}

@@ -706,3 +801,3 @@ try {

// src/commands/create/install-start.ts
import * as prompts3 from "@clack/prompts";
import * as prompts4 from "@clack/prompts";
async function installAndStart(flags) {

@@ -721,3 +816,3 @@ const installDeps = readFlag(flags, "install");

} else {
const answer2 = await prompts3.confirm({
const answer2 = await prompts4.confirm({
message: "Start project?",

@@ -730,3 +825,3 @@ initialValue: DEFAULT_VALUES.install

}
const answer = await prompts3.confirm({
const answer = await prompts4.confirm({
message: "Install dependencies and start project?",

@@ -740,6 +835,6 @@ initialValue: DEFAULT_VALUES.install

// src/commands/create/package-manager.ts
import fs4 from "node:fs";
import path4 from "node:path";
import * as prompts4 from "@clack/prompts";
import chalk4 from "chalk";
import fs5 from "node:fs";
import path5 from "node:path";
import * as prompts5 from "@clack/prompts";
import chalk5 from "chalk";
import { lookpath } from "lookpath";

@@ -755,3 +850,3 @@ var LOCK_FILES = /* @__PURE__ */ new Map([

if (pkgManager !== packageManager) {
fs4.rmSync(path4.join(cwd, lockFile), { force: true });
fs5.rmSync(path5.join(cwd, lockFile), { force: true });
}

@@ -766,4 +861,4 @@ }

}
prompts4.log.warn(
`The specified package manager '${chalk4.yellow(flags.packageManager)}' doesn't seem to be installed!`
prompts5.log.warn(
`The specified package manager '${chalk5.yellow(flags.packageManager)}' doesn't seem to be installed!`
);

@@ -782,3 +877,3 @@ }

}
const answer = await prompts4.select({
const answer = await prompts5.select({
message: "What package manager should we use?",

@@ -810,10 +905,10 @@ initialValue,

// src/commands/create/template.ts
import fs5 from "node:fs";
import fs6 from "node:fs";
import fsPromises from "node:fs/promises";
import path5 from "node:path";
import * as prompts5 from "@clack/prompts";
import path6 from "node:path";
import * as prompts6 from "@clack/prompts";
import ignore from "ignore";
async function copyTemplate(dest, flags) {
if (flags.dryRun) {
prompts5.log.warn(`${warnLabel("DRY RUN")} Skipped copying template`);
prompts6.log.warn(`${warnLabel("DRY RUN")} Skipped copying template`);
return;

@@ -831,5 +926,5 @@ }

for (const fileName of toCopy) {
const sourceFilePath = path5.join(templatePath, fileName);
const sourceFilePath = path6.join(templatePath, fileName);
const destFileName = fileName === ".npmignore" ? ".gitignore" : fileName;
const destFilePath = path5.join(dest, destFileName);
const destFilePath = path6.join(dest, destFileName);
const stats = await fsPromises.stat(sourceFilePath);

@@ -845,5 +940,5 @@ if (stats.isDirectory()) {

try {
return fs5.readFileSync(path5.resolve(templatePath, ".npmignore"), "utf8");
return fs6.readFileSync(path6.resolve(templatePath, ".npmignore"), "utf8");
} catch {
return fs5.readFileSync(path5.resolve(templatePath, ".gitignore"), "utf8");
return fs6.readFileSync(path6.resolve(templatePath, ".gitignore"), "utf8");
}

@@ -862,17 +957,21 @@ }

["--dir, -d", "The folder in which the tutorial gets created"],
["--install, --no-install", `Install dependencies (default ${chalk5.yellow(DEFAULT_VALUES.install)})`],
["--start, --no-start", `Start project (default ${chalk5.yellow(DEFAULT_VALUES.start)})`],
["--git, --no-git", `Initialize a local git repository (default ${chalk5.yellow(DEFAULT_VALUES.git)})`],
["--dry-run", `Walk through steps without executing (default ${chalk5.yellow(DEFAULT_VALUES.dryRun)})`],
["--install, --no-install", `Install dependencies (default ${chalk6.yellow(DEFAULT_VALUES.install)})`],
["--start, --no-start", `Start project (default ${chalk6.yellow(DEFAULT_VALUES.start)})`],
["--git, --no-git", `Initialize a local git repository (default ${chalk6.yellow(DEFAULT_VALUES.git)})`],
[
"--provider <name>, --no-provider",
`Select a hosting provider (default ${chalk6.yellow(DEFAULT_VALUES.provider)})`
],
["--dry-run", `Walk through steps without executing (default ${chalk6.yellow(DEFAULT_VALUES.dryRun)})`],
[
"--package-manager <name>, -p <name>",
`The package used to install dependencies (default ${chalk5.yellow(DEFAULT_VALUES.packageManager)})`
`The package used to install dependencies (default ${chalk6.yellow(DEFAULT_VALUES.packageManager)})`
],
[
"--enterprise <origin>, -e <origin>",
`The origin of your StackBlitz Enterprise instance (if not provided authentication is not turned on and your project will use ${chalk5.yellow("https://stackblitz.com")})`
`The origin of your StackBlitz Enterprise instance (if not provided authentication is not turned on and your project will use ${chalk6.yellow("https://stackblitz.com")})`
],
[
"--force",
`Overwrite existing files in the target directory without prompting (default ${chalk5.yellow(DEFAULT_VALUES.force)})`
`Overwrite existing files in the target directory without prompting (default ${chalk6.yellow(DEFAULT_VALUES.force)})`
],

@@ -904,3 +1003,3 @@ ["--defaults", "Skip all prompts and initialize the tutorial using the defaults"]

async function _createTutorial(flags) {
prompts6.intro(primaryLabel(package_default.name));
prompts7.intro(primaryLabel(package_default.name));
let tutorialName = flags._[1] !== void 0 ? String(flags._[1]) : void 0;

@@ -912,3 +1011,3 @@ if (tutorialName === void 0) {

} else {
const answer = await prompts6.text({
const answer = await prompts7.text({
message: `What's the name of your tutorial?`,

@@ -927,7 +1026,7 @@ placeholder: randomName,

}
prompts6.log.info(`We'll call your tutorial ${chalk5.blue(tutorialName)}`);
prompts7.log.info(`We'll call your tutorial ${chalk6.blue(tutorialName)}`);
const dest = await getTutorialDirectory(tutorialName, flags);
const resolvedDest = path6.resolve(process.cwd(), dest);
prompts6.log.info(`Scaffolding tutorial in ${chalk5.blue(resolvedDest)}`);
if (fs6.existsSync(resolvedDest) && !flags.force) {
const resolvedDest = path7.resolve(process.cwd(), dest);
prompts7.log.info(`Scaffolding tutorial in ${chalk6.blue(resolvedDest)}`);
if (fs7.existsSync(resolvedDest) && !flags.force) {
if (flags.defaults) {

@@ -939,4 +1038,4 @@ console.error(`

let answer;
if (fs6.readdirSync(resolvedDest).length > 0) {
answer = await prompts6.confirm({
if (fs7.readdirSync(resolvedDest).length > 0) {
answer = await prompts7.confirm({
message: `Directory is not empty. Continuing may overwrite existing files. Do you want to continue?`,

@@ -946,3 +1045,3 @@ initialValue: false

} else {
answer = await prompts6.confirm({
answer = await prompts7.confirm({
message: `Directory already exists. Continuing may overwrite existing files. Do you want to continue?`,

@@ -958,7 +1057,8 @@ initialValue: false

if (!flags.dryRun) {
fs6.mkdirSync(resolvedDest, { recursive: true });
fs7.mkdirSync(resolvedDest, { recursive: true });
}
}
await copyTemplate(resolvedDest, flags);
updatePackageJson(resolvedDest, tutorialName, flags);
const provider = await generateHostingConfig(resolvedDest, flags);
updatePackageJson(resolvedDest, tutorialName, flags, provider);
const selectedPackageManager = await selectPackageManager(resolvedDest, flags);

@@ -969,3 +1069,3 @@ updateReadme(resolvedDest, selectedPackageManager, flags);

const { install, start } = await installAndStart(flags);
prompts6.log.success(chalk5.green("Tutorial successfully created!"));
prompts7.log.success(chalk6.green("Tutorial successfully created!"));
if (install || start) {

@@ -977,7 +1077,7 @@ let message = "Please wait while we install the dependencies and start your project...";

}
prompts6.outro(message);
prompts7.outro(message);
await startProject(resolvedDest, selectedPackageManager, flags, start);
} else {
printNextSteps(dest, selectedPackageManager, false);
prompts6.outro(`You're all set!`);
prompts7.outro(`You're all set!`);
console.log("Until next time \u{1F44B}");

@@ -1005,3 +1105,3 @@ }

}
const promptResult = await prompts6.text({
const promptResult = await prompts7.text({
message: "Where should we create your new tutorial?",

@@ -1011,3 +1111,3 @@ initialValue: `./${tutorialName}`,

validate(value) {
if (!path6.isAbsolute(value) && !value.startsWith("./")) {
if (!path7.isAbsolute(value) && !value.startsWith("./")) {
return "Please provide an absolute or relative path!";

@@ -1023,3 +1123,3 @@ }

let i = 0;
prompts6.log.message(chalk5.bold.underline("Next Steps"));
prompts7.log.message(chalk6.bold.underline("Next Steps"));
const steps = [

@@ -1029,3 +1129,3 @@ [`cd ${dest}`, "Navigate to project"],

[`${packageManager} run dev`, "Start development server"],
[, `Head over to ${chalk5.underline("http://localhost:4321")}`]
[, `Head over to ${chalk6.underline("http://localhost:4321")}`]
];

@@ -1037,18 +1137,22 @@ for (const [command, text2, render] of steps) {

i++;
prompts6.log.step(`${i}. ${command ? `${chalk5.blue(command)} - ` : ""}${text2}`);
prompts7.log.step(`${i}. ${command ? `${chalk6.blue(command)} - ` : ""}${text2}`);
}
}
function updatePackageJson(dest, projectName, flags) {
function updatePackageJson(dest, projectName, flags, provider) {
if (flags.dryRun) {
return;
}
const pkgPath = path6.resolve(dest, "package.json");
const pkgJson = JSON.parse(fs6.readFileSync(pkgPath, "utf8"));
const pkgPath = path7.resolve(dest, "package.json");
const pkgJson = JSON.parse(fs7.readFileSync(pkgPath, "utf8"));
pkgJson.name = projectName;
updateWorkspaceVersions(pkgJson.dependencies, TUTORIALKIT_VERSION);
updateWorkspaceVersions(pkgJson.devDependencies, TUTORIALKIT_VERSION);
fs6.writeFileSync(pkgPath, JSON.stringify(pkgJson, void 0, 2));
if (provider.toLowerCase() === "cloudflare") {
pkgJson.scripts = pkgJson.scripts || {};
pkgJson.scripts.postbuild = "cp _headers ./dist/";
}
fs7.writeFileSync(pkgPath, JSON.stringify(pkgJson, null, 2));
try {
const pkgLockPath = path6.resolve(dest, "package-lock.json");
const pkgLockJson = JSON.parse(fs6.readFileSync(pkgLockPath, "utf8"));
const pkgLockPath = path7.resolve(dest, "package-lock.json");
const pkgLockJson = JSON.parse(fs7.readFileSync(pkgLockPath, "utf8"));
const defaultPackage = pkgLockJson.packages[""];

@@ -1059,3 +1163,3 @@ pkgLockJson.name = projectName;

}
fs6.writeFileSync(pkgLockPath, JSON.stringify(pkgLockJson, void 0, 2));
fs7.writeFileSync(pkgLockPath, JSON.stringify(pkgLockJson, null, 2));
} catch {

@@ -1068,9 +1172,9 @@ }

}
const readmePath = path6.resolve(dest, "README.md");
let readme = fs6.readFileSync(readmePath, "utf8");
const readmePath = path7.resolve(dest, "README.md");
let readme = fs7.readFileSync(readmePath, "utf8");
readme = readme.replaceAll("<% pkgManager %>", packageManager ?? DEFAULT_VALUES.packageManager);
fs6.writeFileSync(readmePath, readme);
fs7.writeFileSync(readmePath, readme);
}
function exitEarly(exitCode = 0) {
prompts6.outro("Until next time!");
prompts7.outro("Until next time!");
process.exit(exitCode);

@@ -1096,6 +1200,6 @@ }

// src/commands/eject/index.ts
import fs7 from "node:fs";
import path7 from "node:path";
import * as prompts7 from "@clack/prompts";
import chalk6 from "chalk";
import fs8 from "node:fs";
import path8 from "node:path";
import * as prompts8 from "@clack/prompts";
import chalk7 from "chalk";
import detectIndent from "detect-indent";

@@ -1131,3 +1235,3 @@ import { execa as execa2 } from "execa";

"--force",
`Overwrite existing files in the target directory without prompting (default ${chalk6.yellow(DEFAULT_VALUES2.force)})`
`Overwrite existing files in the target directory without prompting (default ${chalk7.yellow(DEFAULT_VALUES2.force)})`
],

@@ -1156,3 +1260,3 @@ ["--defaults", "Skip all the prompts and eject the routes using the defaults"]

} else {
folderPath = path7.resolve(process.cwd(), folderPath);
folderPath = path8.resolve(process.cwd(), folderPath);
}

@@ -1165,9 +1269,9 @@ const { astroConfigPath, srcPath, pkgJsonPath, astroIntegrationPath, srcDestPath } = validateDestination(

replaceArgs({ defaultRoutes: false }, astroConfig);
fs7.writeFileSync(astroConfigPath, generateAstroConfig(astroConfig));
fs7.cpSync(srcPath, srcDestPath, { recursive: true });
const pkgJsonContent = fs7.readFileSync(pkgJsonPath, "utf-8");
fs8.writeFileSync(astroConfigPath, generateAstroConfig(astroConfig));
fs8.cpSync(srcPath, srcDestPath, { recursive: true });
const pkgJsonContent = fs8.readFileSync(pkgJsonPath, "utf-8");
const indent = detectIndent(pkgJsonContent).indent || " ";
const pkgJson = JSON.parse(pkgJsonContent);
const astroIntegrationPkgJson = JSON.parse(
fs7.readFileSync(path7.join(astroIntegrationPath, "package.json"), "utf-8")
fs8.readFileSync(path8.join(astroIntegrationPath, "package.json"), "utf-8")
);

@@ -1187,3 +1291,3 @@ const newDependencies = [];

if (newDependencies.length > 0) {
fs7.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, void 0, indent), { encoding: "utf-8" });
fs8.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, void 0, indent), { encoding: "utf-8" });
console.log(

@@ -1194,5 +1298,5 @@ primaryLabel("INFO"),

if (!flags.defaults) {
const packageManager = (await whichpm(path7.dirname(pkgJsonPath))).name;
const answer = await prompts7.confirm({
message: `Do you want to install those dependencies now using ${chalk6.blue(packageManager)}?`
const packageManager = (await whichpm(path8.dirname(pkgJsonPath))).name;
const answer = await prompts8.confirm({
message: `Do you want to install those dependencies now using ${chalk7.blue(packageManager)}?`
});

@@ -1208,13 +1312,13 @@ if (answer === true) {

assertExists(folder);
const pkgJsonPath = assertExists(path7.join(folder, "package.json"));
const astroConfigPath = assertExists(path7.join(folder, "astro.config.ts"));
const srcDestPath = assertExists(path7.join(folder, "src"));
const astroIntegrationPath = assertExists(path7.resolve(folder, "node_modules", "@tutorialkit", "astro"));
const srcPath = path7.join(astroIntegrationPath, "dist", "default");
const pkgJsonPath = assertExists(path8.join(folder, "package.json"));
const astroConfigPath = assertExists(path8.join(folder, "astro.config.ts"));
const srcDestPath = assertExists(path8.join(folder, "src"));
const astroIntegrationPath = assertExists(path8.resolve(folder, "node_modules", "@tutorialkit", "astro"));
const srcPath = path8.join(astroIntegrationPath, "dist", "default");
if (!force) {
walk(srcPath, (relativePath) => {
const destination = path7.join(srcDestPath, relativePath);
if (fs7.existsSync(destination)) {
const destination = path8.join(srcDestPath, relativePath);
if (fs8.existsSync(destination)) {
throw new Error(
`Eject aborted because '${destination}' would be overwritten by this command. Use ${chalk6.yellow("--force")} to ignore this error.`
`Eject aborted because '${destination}' would be overwritten by this command. Use ${chalk7.yellow("--force")} to ignore this error.`
);

@@ -1233,3 +1337,3 @@ }

function assertExists(filePath) {
if (!fs7.existsSync(filePath)) {
if (!fs8.existsSync(filePath)) {
throw new Error(`${filePath} does not exists!`);

@@ -1241,6 +1345,6 @@ }

function traverse2(folder, pathPrefix) {
for (const filename of fs7.readdirSync(folder)) {
const filePath = path7.join(folder, filename);
const stat = fs7.statSync(filePath);
const relativeFilePath = path7.join(pathPrefix, filename);
for (const filename of fs8.readdirSync(folder)) {
const filePath = path8.join(folder, filename);
const stat = fs8.statSync(filePath);
const relativeFilePath = path8.join(pathPrefix, filename);
if (stat.isDirectory()) {

@@ -1274,3 +1378,3 @@ traverse2(filePath, relativeFilePath);

case "version": {
console.log(`${primaryLabel(package_default.name)} ${chalk7.green(`v${package_default.version}`)}`);
console.log(`${primaryLabel(package_default.name)} ${chalk8.green(`v${package_default.version}`)}`);
return;

@@ -1281,3 +1385,3 @@ }

commandName: package_default.name,
prolog: `${primaryLabel(package_default.name)} ${chalk7.green(`v${package_default.version}`)} Create tutorial apps powered by WebContainer API`,
prolog: `${primaryLabel(package_default.name)} ${chalk8.green(`v${package_default.version}`)} Create tutorial apps powered by WebContainer API`,
usage: ["[command] [...options]", "[ -h | --help | -v | --version ]"],

@@ -1304,3 +1408,3 @@ tables: {

default: {
console.error(`${errorLabel()} Unknown command ${chalk7.red(cmd)}`);
console.error(`${errorLabel()} Unknown command ${chalk8.red(cmd)}`);
return 1;

@@ -1307,0 +1411,0 @@ }

{
"name": "@tutorialkit/cli",
"version": "1.3.1",
"version": "1.4.0",
"description": "Interactive tutorials powered by WebContainer API",

@@ -51,3 +51,3 @@ "author": "StackBlitz Inc.",

"tempy": "^3.1.0",
"vitest": "^2.1.1"
"vitest": "^3.0.5"
},

@@ -54,0 +54,0 @@ "engines": {

@@ -14,3 +14,3 @@ {

"dependencies": {
"@tutorialkit/react": "1.3.1",
"@tutorialkit/react": "1.4.0",
"react": "^18.3.1",

@@ -22,5 +22,5 @@ "react-dom": "^18.3.1"

"@astrojs/react": "^3.6.0",
"@tutorialkit/astro": "1.3.1",
"@tutorialkit/theme": "1.3.1",
"@tutorialkit/types": "1.3.1",
"@tutorialkit/astro": "1.4.0",
"@tutorialkit/theme": "1.4.0",
"@tutorialkit/types": "1.4.0",
"@types/node": "^20.14.6",

@@ -27,0 +27,0 @@ "@types/react": "^18.3.3",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet