@ncukondo/slide-generation 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +217 -95
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1515,7 +1515,7 @@ var Pipeline = class {
|
|
|
1515
1515
|
};
|
|
1516
1516
|
|
|
1517
1517
|
// src/index.ts
|
|
1518
|
-
var VERSION = "0.2.
|
|
1518
|
+
var VERSION = "0.2.4";
|
|
1519
1519
|
|
|
1520
1520
|
// src/cli/commands/convert.ts
|
|
1521
1521
|
import { Command } from "commander";
|
|
@@ -2947,20 +2947,60 @@ import { Command as Command4 } from "commander";
|
|
|
2947
2947
|
import chalk4 from "chalk";
|
|
2948
2948
|
import * as yaml2 from "yaml";
|
|
2949
2949
|
import { mkdir as mkdir3, writeFile as writeFile3, rm as rm2 } from "fs/promises";
|
|
2950
|
-
import { join as
|
|
2950
|
+
import { join as join10, basename as basename5 } from "path";
|
|
2951
2951
|
import { tmpdir as tmpdir2 } from "os";
|
|
2952
|
-
import { execFileSync as execFileSync2 } from "child_process";
|
|
2953
2952
|
|
|
2954
2953
|
// src/cli/commands/preview.ts
|
|
2955
2954
|
import { Command as Command3 } from "commander";
|
|
2956
2955
|
import { access as access6, unlink as unlink2, readdir as readdir4, mkdir as mkdir2, writeFile as writeFile2, readFile as readFile10, rm } from "fs/promises";
|
|
2957
|
-
import { basename as basename4, dirname as dirname4, join as
|
|
2956
|
+
import { basename as basename4, dirname as dirname4, join as join9, extname as extname2 } from "path";
|
|
2958
2957
|
import * as path6 from "path";
|
|
2959
2958
|
import { tmpdir } from "os";
|
|
2960
|
-
import { spawn, execSync, execFileSync } from "child_process";
|
|
2961
2959
|
import { createServer } from "http";
|
|
2962
2960
|
import chalk3 from "chalk";
|
|
2963
2961
|
import { watch as chokidarWatch } from "chokidar";
|
|
2962
|
+
|
|
2963
|
+
// src/cli/utils/marp-runner.ts
|
|
2964
|
+
import { existsSync } from "fs";
|
|
2965
|
+
import { join as join8 } from "path";
|
|
2966
|
+
import {
|
|
2967
|
+
execFileSync,
|
|
2968
|
+
spawn
|
|
2969
|
+
} from "child_process";
|
|
2970
|
+
function getMarpCommand(projectDir) {
|
|
2971
|
+
const dir = projectDir ?? process.cwd();
|
|
2972
|
+
const localMarp = join8(dir, "node_modules", ".bin", "marp");
|
|
2973
|
+
if (existsSync(localMarp)) {
|
|
2974
|
+
return localMarp;
|
|
2975
|
+
}
|
|
2976
|
+
try {
|
|
2977
|
+
execFileSync("marp", ["--version"], { stdio: "ignore", timeout: 5e3 });
|
|
2978
|
+
return "marp";
|
|
2979
|
+
} catch {
|
|
2980
|
+
return null;
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
function isMarpAvailable(projectDir) {
|
|
2984
|
+
return getMarpCommand(projectDir) !== null;
|
|
2985
|
+
}
|
|
2986
|
+
function runMarp(args, options = {}) {
|
|
2987
|
+
const { projectDir, ...execOptions } = options;
|
|
2988
|
+
const marpCmd = getMarpCommand(projectDir);
|
|
2989
|
+
if (!marpCmd) {
|
|
2990
|
+
throw new Error("Marp CLI not found. Install it with: npm install -D @marp-team/marp-cli");
|
|
2991
|
+
}
|
|
2992
|
+
execFileSync(marpCmd, args, execOptions);
|
|
2993
|
+
}
|
|
2994
|
+
function spawnMarp(args, options = {}) {
|
|
2995
|
+
const { projectDir, ...spawnOptions } = options;
|
|
2996
|
+
const marpCmd = getMarpCommand(projectDir);
|
|
2997
|
+
if (!marpCmd) {
|
|
2998
|
+
throw new Error("Marp CLI not found. Install it with: npm install -D @marp-team/marp-cli");
|
|
2999
|
+
}
|
|
3000
|
+
return spawn(marpCmd, args, spawnOptions);
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
// src/cli/commands/preview.ts
|
|
2964
3004
|
function escapeHtml(str) {
|
|
2965
3005
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2966
3006
|
}
|
|
@@ -3074,7 +3114,7 @@ async function collectSlideInfo(dir, baseName, format) {
|
|
|
3074
3114
|
if (match) {
|
|
3075
3115
|
const index = parseInt(match[1], 10);
|
|
3076
3116
|
slides.push({
|
|
3077
|
-
path:
|
|
3117
|
+
path: join9(dir, file),
|
|
3078
3118
|
title: `Slide ${index}`,
|
|
3079
3119
|
index
|
|
3080
3120
|
});
|
|
@@ -3085,20 +3125,15 @@ async function collectSlideInfo(dir, baseName, format) {
|
|
|
3085
3125
|
return [];
|
|
3086
3126
|
}
|
|
3087
3127
|
}
|
|
3088
|
-
async function checkMarpCliAvailable() {
|
|
3089
|
-
|
|
3090
|
-
execSync("marp --version", { stdio: "ignore", timeout: 5e3 });
|
|
3091
|
-
return true;
|
|
3092
|
-
} catch {
|
|
3093
|
-
return false;
|
|
3094
|
-
}
|
|
3128
|
+
async function checkMarpCliAvailable(projectDir) {
|
|
3129
|
+
return isMarpAvailable(projectDir);
|
|
3095
3130
|
}
|
|
3096
3131
|
function getTempOutputPath(inputPath) {
|
|
3097
3132
|
const base = basename4(inputPath, ".yaml");
|
|
3098
|
-
return
|
|
3133
|
+
return join9(tmpdir(), `slide-gen-preview-${base}-${Date.now()}.md`);
|
|
3099
3134
|
}
|
|
3100
3135
|
function buildMarpCommand(markdownPath, options) {
|
|
3101
|
-
const parts = ["
|
|
3136
|
+
const parts = ["marp", "--preview"];
|
|
3102
3137
|
if (options.port) {
|
|
3103
3138
|
parts.push("-p", String(options.port));
|
|
3104
3139
|
}
|
|
@@ -3153,7 +3188,7 @@ function startStaticServer(baseDir, port, options = {}) {
|
|
|
3153
3188
|
async function executeGalleryPreview(inputPath, options) {
|
|
3154
3189
|
const errors = [];
|
|
3155
3190
|
const port = Number(options.port) || 8080;
|
|
3156
|
-
const galleryDir =
|
|
3191
|
+
const galleryDir = join9(tmpdir(), `slide-gen-gallery-${Date.now()}`);
|
|
3157
3192
|
try {
|
|
3158
3193
|
await access6(inputPath);
|
|
3159
3194
|
} catch {
|
|
@@ -3163,11 +3198,12 @@ async function executeGalleryPreview(inputPath, options) {
|
|
|
3163
3198
|
return { success: false, errors };
|
|
3164
3199
|
}
|
|
3165
3200
|
console.log("Checking for Marp CLI...");
|
|
3166
|
-
const
|
|
3201
|
+
const projectDir = dirname4(inputPath);
|
|
3202
|
+
const marpAvailable = await checkMarpCliAvailable(projectDir);
|
|
3167
3203
|
if (!marpAvailable) {
|
|
3168
3204
|
console.error(
|
|
3169
3205
|
chalk3.red(
|
|
3170
|
-
"Error: Marp CLI not found. Install it with: npm install -
|
|
3206
|
+
"Error: Marp CLI not found. Install it with: npm install -D @marp-team/marp-cli"
|
|
3171
3207
|
)
|
|
3172
3208
|
);
|
|
3173
3209
|
errors.push("Marp CLI not available");
|
|
@@ -3194,7 +3230,7 @@ async function executeGalleryPreview(inputPath, options) {
|
|
|
3194
3230
|
await rm(galleryDir, { recursive: true, force: true });
|
|
3195
3231
|
return { success: false, errors };
|
|
3196
3232
|
}
|
|
3197
|
-
const tempMdPath =
|
|
3233
|
+
const tempMdPath = join9(galleryDir, "slides.md");
|
|
3198
3234
|
console.log(`Converting ${chalk3.cyan(inputPath)}...`);
|
|
3199
3235
|
try {
|
|
3200
3236
|
await pipeline.runWithResult(inputPath, { outputPath: tempMdPath });
|
|
@@ -3209,7 +3245,8 @@ async function executeGalleryPreview(inputPath, options) {
|
|
|
3209
3245
|
}
|
|
3210
3246
|
console.log("Taking screenshots...");
|
|
3211
3247
|
try {
|
|
3212
|
-
|
|
3248
|
+
runMarp(["--images", "png", "-o", galleryDir, tempMdPath], {
|
|
3249
|
+
projectDir,
|
|
3213
3250
|
stdio: options.verbose ? "inherit" : "pipe"
|
|
3214
3251
|
});
|
|
3215
3252
|
console.log(chalk3.green("\u2713") + " Screenshots generated");
|
|
@@ -3234,7 +3271,7 @@ async function executeGalleryPreview(inputPath, options) {
|
|
|
3234
3271
|
path: basename4(s.path)
|
|
3235
3272
|
}));
|
|
3236
3273
|
const galleryHtml = generateGalleryHtml(relativeSlides);
|
|
3237
|
-
await writeFile2(
|
|
3274
|
+
await writeFile2(join9(galleryDir, "index.html"), galleryHtml);
|
|
3238
3275
|
console.log(`
|
|
3239
3276
|
Starting gallery server on port ${chalk3.cyan(port)}...`);
|
|
3240
3277
|
let server;
|
|
@@ -3314,11 +3351,11 @@ async function executePreview(inputPath, options) {
|
|
|
3314
3351
|
return { success: false, errors };
|
|
3315
3352
|
}
|
|
3316
3353
|
console.log("Checking for Marp CLI...");
|
|
3317
|
-
const marpAvailable = await checkMarpCliAvailable();
|
|
3354
|
+
const marpAvailable = await checkMarpCliAvailable(dirname4(inputPath));
|
|
3318
3355
|
if (!marpAvailable) {
|
|
3319
3356
|
console.error(
|
|
3320
3357
|
chalk3.red(
|
|
3321
|
-
"Error: Marp CLI not found. Install it with: npm install -
|
|
3358
|
+
"Error: Marp CLI not found. Install it with: npm install -D @marp-team/marp-cli"
|
|
3322
3359
|
)
|
|
3323
3360
|
);
|
|
3324
3361
|
errors.push("Marp CLI not available");
|
|
@@ -3366,9 +3403,9 @@ Starting preview server on port ${chalk3.cyan(port)}...`);
|
|
|
3366
3403
|
if (verbose) {
|
|
3367
3404
|
console.log(`Running: ${marpCommand}`);
|
|
3368
3405
|
}
|
|
3369
|
-
const marpProcess =
|
|
3370
|
-
|
|
3371
|
-
|
|
3406
|
+
const marpProcess = spawnMarp(["--preview", "-p", String(port), tempMarkdownPath], {
|
|
3407
|
+
projectDir: dirname4(inputPath),
|
|
3408
|
+
stdio: "inherit"
|
|
3372
3409
|
});
|
|
3373
3410
|
let watcher = null;
|
|
3374
3411
|
let debounceTimer = null;
|
|
@@ -3849,7 +3886,7 @@ async function executeTemplatePreview(name, options) {
|
|
|
3849
3886
|
return;
|
|
3850
3887
|
}
|
|
3851
3888
|
const port = Number(options.port) || 8080;
|
|
3852
|
-
const previewDir =
|
|
3889
|
+
const previewDir = join10(tmpdir2(), `slide-gen-template-preview-${Date.now()}`);
|
|
3853
3890
|
console.log("Checking for Marp CLI...");
|
|
3854
3891
|
const marpAvailable = await checkMarpCliAvailable();
|
|
3855
3892
|
if (!marpAvailable) {
|
|
@@ -3902,9 +3939,9 @@ async function executeTemplatePreview(name, options) {
|
|
|
3902
3939
|
for (const template of templates) {
|
|
3903
3940
|
console.log(`Processing template: ${chalk4.cyan(template.name)}...`);
|
|
3904
3941
|
const sampleYaml = generateSampleYaml(template);
|
|
3905
|
-
const yamlPath =
|
|
3942
|
+
const yamlPath = join10(previewDir, `${template.name}.yaml`);
|
|
3906
3943
|
await writeFile3(yamlPath, sampleYaml);
|
|
3907
|
-
const mdPath =
|
|
3944
|
+
const mdPath = join10(previewDir, `${template.name}.md`);
|
|
3908
3945
|
try {
|
|
3909
3946
|
await pipeline.runWithResult(yamlPath, { outputPath: mdPath });
|
|
3910
3947
|
} catch (error) {
|
|
@@ -3913,7 +3950,8 @@ async function executeTemplatePreview(name, options) {
|
|
|
3913
3950
|
continue;
|
|
3914
3951
|
}
|
|
3915
3952
|
try {
|
|
3916
|
-
|
|
3953
|
+
runMarp(["--images", "png", "-o", previewDir, mdPath], {
|
|
3954
|
+
projectDir: process.cwd(),
|
|
3917
3955
|
stdio: "pipe"
|
|
3918
3956
|
});
|
|
3919
3957
|
} catch {
|
|
@@ -3936,7 +3974,7 @@ async function executeTemplatePreview(name, options) {
|
|
|
3936
3974
|
return;
|
|
3937
3975
|
}
|
|
3938
3976
|
const previewHtml = generateTemplatePreviewHtml(templatePreviews);
|
|
3939
|
-
await writeFile3(
|
|
3977
|
+
await writeFile3(join10(previewDir, "index.html"), previewHtml);
|
|
3940
3978
|
console.log(`
|
|
3941
3979
|
Starting preview server on port ${chalk4.cyan(port)}...`);
|
|
3942
3980
|
let server;
|
|
@@ -4769,9 +4807,10 @@ function createIconsCommand() {
|
|
|
4769
4807
|
// src/cli/commands/init.ts
|
|
4770
4808
|
import { Command as Command6 } from "commander";
|
|
4771
4809
|
import { mkdir as mkdir7, writeFile as writeFile7, access as access10, readdir as readdir6, cp } from "fs/promises";
|
|
4772
|
-
import { existsSync } from "fs";
|
|
4773
|
-
import { execSync
|
|
4774
|
-
import {
|
|
4810
|
+
import { existsSync as existsSync2 } from "fs";
|
|
4811
|
+
import { execSync, spawnSync } from "child_process";
|
|
4812
|
+
import { createInterface } from "readline";
|
|
4813
|
+
import { dirname as dirname6, join as join16, resolve as resolve5, sep } from "path";
|
|
4775
4814
|
import { fileURLToPath } from "url";
|
|
4776
4815
|
import chalk6 from "chalk";
|
|
4777
4816
|
import ora3 from "ora";
|
|
@@ -6035,9 +6074,9 @@ function generateSlideThemeCommand() {
|
|
|
6035
6074
|
function getPackageRoot() {
|
|
6036
6075
|
const __dirname = dirname6(fileURLToPath(import.meta.url));
|
|
6037
6076
|
if (__dirname.includes(`${sep}src${sep}`) || __dirname.includes("/src/")) {
|
|
6038
|
-
return
|
|
6077
|
+
return join16(__dirname, "..", "..", "..");
|
|
6039
6078
|
}
|
|
6040
|
-
return
|
|
6079
|
+
return join16(__dirname, "..", "..");
|
|
6041
6080
|
}
|
|
6042
6081
|
function createInitCommand() {
|
|
6043
6082
|
return new Command6("init").description("Initialize a new project").argument("[directory]", "Target directory", ".").option("--template <name>", "Initial template").option("--no-examples", "Do not create sample files").option("--no-ai-config", "Do not create AI assistant config files").option("--no-sources", "Do not create sources directory").option("--from-directory <path>", "Import materials from directory").option("--skip-marp-install", "Skip Marp CLI installation prompt").action(async (directory, options) => {
|
|
@@ -6061,29 +6100,29 @@ async function executeInit(directory, options) {
|
|
|
6061
6100
|
} catch {
|
|
6062
6101
|
}
|
|
6063
6102
|
await mkdir7(targetDir, { recursive: true });
|
|
6064
|
-
await mkdir7(
|
|
6065
|
-
await mkdir7(
|
|
6103
|
+
await mkdir7(join16(targetDir, "themes"), { recursive: true });
|
|
6104
|
+
await mkdir7(join16(targetDir, "icons", "custom"), { recursive: true });
|
|
6066
6105
|
const packageRoot = getPackageRoot();
|
|
6067
|
-
const sourceTemplatesDir =
|
|
6068
|
-
const targetTemplatesDir =
|
|
6106
|
+
const sourceTemplatesDir = join16(packageRoot, "templates");
|
|
6107
|
+
const targetTemplatesDir = join16(targetDir, "templates");
|
|
6069
6108
|
try {
|
|
6070
6109
|
await access10(targetTemplatesDir);
|
|
6071
6110
|
} catch {
|
|
6072
6111
|
await cp(sourceTemplatesDir, targetTemplatesDir, { recursive: true });
|
|
6073
6112
|
}
|
|
6074
|
-
const sourceIconsRegistry =
|
|
6075
|
-
const targetIconsRegistry =
|
|
6113
|
+
const sourceIconsRegistry = join16(packageRoot, "icons", "registry.yaml");
|
|
6114
|
+
const targetIconsRegistry = join16(targetDir, "icons", "registry.yaml");
|
|
6076
6115
|
await copyFileIfNotExists(sourceIconsRegistry, targetIconsRegistry);
|
|
6077
|
-
const sourceDefaultTheme =
|
|
6078
|
-
const targetDefaultTheme =
|
|
6116
|
+
const sourceDefaultTheme = join16(packageRoot, "themes", "default.css");
|
|
6117
|
+
const targetDefaultTheme = join16(targetDir, "themes", "default.css");
|
|
6079
6118
|
await copyFileIfNotExists(sourceDefaultTheme, targetDefaultTheme);
|
|
6080
6119
|
const configContent = generateConfigContent();
|
|
6081
|
-
await writeFileIfNotExists(
|
|
6120
|
+
await writeFileIfNotExists(join16(targetDir, "config.yaml"), configContent);
|
|
6082
6121
|
const customCssContent = generateCustomCssContent();
|
|
6083
|
-
await writeFileIfNotExists(
|
|
6122
|
+
await writeFileIfNotExists(join16(targetDir, "themes", "custom.css"), customCssContent);
|
|
6084
6123
|
if (includeExamples) {
|
|
6085
6124
|
const presentationContent = generatePresentationContent(options.template);
|
|
6086
|
-
await writeFileIfNotExists(
|
|
6125
|
+
await writeFileIfNotExists(join16(targetDir, "presentation.yaml"), presentationContent);
|
|
6087
6126
|
}
|
|
6088
6127
|
if (includeAiConfig) {
|
|
6089
6128
|
await generateAiConfig(targetDir);
|
|
@@ -6138,7 +6177,7 @@ async function executeInit(directory, options) {
|
|
|
6138
6177
|
console.log(` 1. Edit ${chalk6.yellow("presentation.yaml")} to add your slides`);
|
|
6139
6178
|
console.log(` 2. Run ${chalk6.yellow("slide-gen convert presentation.yaml")} to generate markdown`);
|
|
6140
6179
|
if (options.skipMarpInstall !== true) {
|
|
6141
|
-
showMarpCliInfo(targetDir);
|
|
6180
|
+
await showMarpCliInfo(targetDir);
|
|
6142
6181
|
}
|
|
6143
6182
|
} catch (error) {
|
|
6144
6183
|
spinner.fail("Failed to initialize project");
|
|
@@ -6162,53 +6201,139 @@ async function copyFileIfNotExists(source, dest) {
|
|
|
6162
6201
|
await cp(source, dest);
|
|
6163
6202
|
}
|
|
6164
6203
|
}
|
|
6165
|
-
function
|
|
6204
|
+
function isMarpCliInstalledGlobally() {
|
|
6166
6205
|
try {
|
|
6167
|
-
|
|
6206
|
+
execSync("marp --version", { stdio: "pipe", timeout: 5e3 });
|
|
6168
6207
|
return true;
|
|
6169
6208
|
} catch {
|
|
6170
6209
|
return false;
|
|
6171
6210
|
}
|
|
6172
6211
|
}
|
|
6212
|
+
function isMarpCliInstalledLocally(targetDir) {
|
|
6213
|
+
const dir = targetDir ?? process.cwd();
|
|
6214
|
+
const marpBinPath = join16(dir, "node_modules", ".bin", "marp");
|
|
6215
|
+
return existsSync2(marpBinPath);
|
|
6216
|
+
}
|
|
6173
6217
|
function detectPackageManager(targetDir) {
|
|
6174
6218
|
const dir = targetDir ?? process.cwd();
|
|
6175
|
-
if (
|
|
6176
|
-
if (
|
|
6219
|
+
if (existsSync2(join16(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
6220
|
+
if (existsSync2(join16(dir, "yarn.lock"))) return "yarn";
|
|
6177
6221
|
return "npm";
|
|
6178
6222
|
}
|
|
6179
|
-
function
|
|
6180
|
-
|
|
6181
|
-
|
|
6223
|
+
function getMarpInstallCommand(pm) {
|
|
6224
|
+
switch (pm) {
|
|
6225
|
+
case "pnpm":
|
|
6226
|
+
return "pnpm add -D @marp-team/marp-cli";
|
|
6227
|
+
case "yarn":
|
|
6228
|
+
return "yarn add -D @marp-team/marp-cli";
|
|
6229
|
+
default:
|
|
6230
|
+
return "npm install -D @marp-team/marp-cli";
|
|
6231
|
+
}
|
|
6232
|
+
}
|
|
6233
|
+
async function promptYesNo(question, defaultYes = true) {
|
|
6234
|
+
if (!process.stdin.isTTY) {
|
|
6235
|
+
return defaultYes;
|
|
6236
|
+
}
|
|
6237
|
+
const rl = createInterface({
|
|
6238
|
+
input: process.stdin,
|
|
6239
|
+
output: process.stdout
|
|
6240
|
+
});
|
|
6241
|
+
const hint = defaultYes ? "(Y/n)" : "(y/N)";
|
|
6242
|
+
const prompt = `${question} ${hint} `;
|
|
6243
|
+
return new Promise((resolve7) => {
|
|
6244
|
+
rl.question(prompt, (answer) => {
|
|
6245
|
+
rl.close();
|
|
6246
|
+
const normalized = answer.trim().toLowerCase();
|
|
6247
|
+
if (normalized === "") {
|
|
6248
|
+
resolve7(defaultYes);
|
|
6249
|
+
} else {
|
|
6250
|
+
resolve7(normalized === "y" || normalized === "yes");
|
|
6251
|
+
}
|
|
6252
|
+
});
|
|
6253
|
+
});
|
|
6254
|
+
}
|
|
6255
|
+
function installMarpCli(targetDir) {
|
|
6256
|
+
const pm = detectPackageManager(targetDir);
|
|
6257
|
+
const installCmd = getMarpInstallCommand(pm);
|
|
6258
|
+
const spinner = ora3(`Installing Marp CLI with ${pm}...`).start();
|
|
6259
|
+
try {
|
|
6260
|
+
const result = spawnSync(pm, ["add", "-D", "@marp-team/marp-cli"], {
|
|
6261
|
+
cwd: targetDir,
|
|
6262
|
+
stdio: "pipe",
|
|
6263
|
+
shell: true,
|
|
6264
|
+
timeout: 12e4
|
|
6265
|
+
// 2 minutes timeout
|
|
6266
|
+
});
|
|
6267
|
+
if (result.status === 0) {
|
|
6268
|
+
spinner.succeed("Marp CLI installed successfully");
|
|
6269
|
+
return true;
|
|
6270
|
+
} else {
|
|
6271
|
+
const stderr = result.stderr?.toString() || "Unknown error";
|
|
6272
|
+
spinner.fail(`Failed to install Marp CLI: ${stderr}`);
|
|
6273
|
+
console.log(chalk6.dim(`You can install it manually with: ${installCmd}`));
|
|
6274
|
+
return false;
|
|
6275
|
+
}
|
|
6276
|
+
} catch (error) {
|
|
6277
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
6278
|
+
spinner.fail(`Failed to install Marp CLI: ${message}`);
|
|
6279
|
+
console.log(chalk6.dim(`You can install it manually with: ${installCmd}`));
|
|
6280
|
+
return false;
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
async function showMarpCliInfo(targetDir) {
|
|
6284
|
+
if (isMarpCliInstalledGlobally() || isMarpCliInstalledLocally(targetDir)) {
|
|
6285
|
+
console.log("");
|
|
6286
|
+
console.log(chalk6.green("\u2713") + " Marp CLI is available");
|
|
6287
|
+
return true;
|
|
6182
6288
|
}
|
|
6183
6289
|
const pm = detectPackageManager(targetDir);
|
|
6184
|
-
const installCmd = pm
|
|
6290
|
+
const installCmd = getMarpInstallCommand(pm);
|
|
6185
6291
|
console.log("");
|
|
6292
|
+
console.log(chalk6.dim("\u2500".repeat(45)));
|
|
6186
6293
|
console.log(chalk6.yellow("Marp CLI is recommended for full features:"));
|
|
6187
|
-
console.log("
|
|
6188
|
-
console.log("
|
|
6189
|
-
console.log("
|
|
6294
|
+
console.log(" \u2022 Preview slides in browser");
|
|
6295
|
+
console.log(" \u2022 Take screenshots for AI review");
|
|
6296
|
+
console.log(" \u2022 Export to PDF/HTML/PPTX");
|
|
6190
6297
|
console.log("");
|
|
6191
|
-
console.log(chalk6.dim("
|
|
6192
|
-
console.log(
|
|
6298
|
+
console.log(chalk6.dim("Marp CLI is not currently installed."));
|
|
6299
|
+
console.log(chalk6.dim("\u2500".repeat(45)));
|
|
6300
|
+
console.log("");
|
|
6301
|
+
const packageJsonPath = join16(targetDir, "package.json");
|
|
6302
|
+
const hasPackageJson = existsSync2(packageJsonPath);
|
|
6303
|
+
if (!hasPackageJson) {
|
|
6304
|
+
console.log(chalk6.dim("No package.json found. You can install Marp CLI globally:"));
|
|
6305
|
+
console.log(` ${chalk6.cyan("npm install -g @marp-team/marp-cli")}`);
|
|
6306
|
+
return false;
|
|
6307
|
+
}
|
|
6308
|
+
const shouldInstall = await promptYesNo("Install Marp CLI now?", true);
|
|
6309
|
+
if (shouldInstall) {
|
|
6310
|
+
const success = installMarpCli(targetDir);
|
|
6311
|
+
return success;
|
|
6312
|
+
} else {
|
|
6313
|
+
console.log("");
|
|
6314
|
+
console.log(chalk6.dim("You can install it later with:"));
|
|
6315
|
+
console.log(` ${chalk6.cyan(installCmd)}`);
|
|
6316
|
+
return false;
|
|
6317
|
+
}
|
|
6193
6318
|
}
|
|
6194
6319
|
async function generateAiConfig(targetDir) {
|
|
6195
|
-
await mkdir7(
|
|
6196
|
-
await mkdir7(
|
|
6197
|
-
await mkdir7(
|
|
6198
|
-
await mkdir7(
|
|
6320
|
+
await mkdir7(join16(targetDir, ".skills", "slide-assistant", "references"), { recursive: true });
|
|
6321
|
+
await mkdir7(join16(targetDir, ".skills", "slide-assistant", "scripts"), { recursive: true });
|
|
6322
|
+
await mkdir7(join16(targetDir, ".claude", "commands"), { recursive: true });
|
|
6323
|
+
await mkdir7(join16(targetDir, ".opencode", "agent"), { recursive: true });
|
|
6199
6324
|
await writeFileIfNotExists(
|
|
6200
|
-
|
|
6325
|
+
join16(targetDir, ".skills", "slide-assistant", "SKILL.md"),
|
|
6201
6326
|
generateSkillMd()
|
|
6202
6327
|
);
|
|
6203
6328
|
await writeFileIfNotExists(
|
|
6204
|
-
|
|
6329
|
+
join16(targetDir, ".skills", "slide-assistant", "references", "templates.md"),
|
|
6205
6330
|
generateTemplatesRef()
|
|
6206
6331
|
);
|
|
6207
6332
|
await writeFileIfNotExists(
|
|
6208
|
-
|
|
6333
|
+
join16(targetDir, ".skills", "slide-assistant", "references", "workflows.md"),
|
|
6209
6334
|
generateWorkflowsRef()
|
|
6210
6335
|
);
|
|
6211
|
-
await writeFileIfNotExists(
|
|
6336
|
+
await writeFileIfNotExists(join16(targetDir, "CLAUDE.md"), generateClaudeMd());
|
|
6212
6337
|
const commandGenerators = {
|
|
6213
6338
|
"slide-create": generateSlideCreateCommand,
|
|
6214
6339
|
"slide-validate": generateSlideValidateCommand,
|
|
@@ -6218,16 +6343,16 @@ async function generateAiConfig(targetDir) {
|
|
|
6218
6343
|
};
|
|
6219
6344
|
for (const [name, generator] of Object.entries(commandGenerators)) {
|
|
6220
6345
|
await writeFileIfNotExists(
|
|
6221
|
-
|
|
6346
|
+
join16(targetDir, ".claude", "commands", `${name}.md`),
|
|
6222
6347
|
generator()
|
|
6223
6348
|
);
|
|
6224
6349
|
}
|
|
6225
|
-
await writeFileIfNotExists(
|
|
6350
|
+
await writeFileIfNotExists(join16(targetDir, "AGENTS.md"), generateAgentsMd());
|
|
6226
6351
|
await writeFileIfNotExists(
|
|
6227
|
-
|
|
6352
|
+
join16(targetDir, ".opencode", "agent", "slide.md"),
|
|
6228
6353
|
generateOpenCodeAgent()
|
|
6229
6354
|
);
|
|
6230
|
-
await writeFileIfNotExists(
|
|
6355
|
+
await writeFileIfNotExists(join16(targetDir, ".cursorrules"), generateAgentsMd());
|
|
6231
6356
|
}
|
|
6232
6357
|
function generateConfigContent() {
|
|
6233
6358
|
return `# slide-gen configuration
|
|
@@ -6325,7 +6450,7 @@ slides:
|
|
|
6325
6450
|
// src/cli/commands/watch.ts
|
|
6326
6451
|
import { Command as Command7 } from "commander";
|
|
6327
6452
|
import { access as access11 } from "fs/promises";
|
|
6328
|
-
import { basename as basename7, dirname as dirname7, join as
|
|
6453
|
+
import { basename as basename7, dirname as dirname7, join as join17 } from "path";
|
|
6329
6454
|
import chalk7 from "chalk";
|
|
6330
6455
|
import { watch as chokidarWatch2 } from "chokidar";
|
|
6331
6456
|
var WatchState = class {
|
|
@@ -6360,7 +6485,7 @@ var WatchState = class {
|
|
|
6360
6485
|
function getDefaultOutputPath2(inputPath) {
|
|
6361
6486
|
const dir = dirname7(inputPath);
|
|
6362
6487
|
const base = basename7(inputPath, ".yaml");
|
|
6363
|
-
return
|
|
6488
|
+
return join17(dir, `${base}.md`);
|
|
6364
6489
|
}
|
|
6365
6490
|
function formatTime() {
|
|
6366
6491
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -6504,7 +6629,7 @@ async function executeWatch(inputPath, options) {
|
|
|
6504
6629
|
// src/cli/commands/images.ts
|
|
6505
6630
|
import { Command as Command8 } from "commander";
|
|
6506
6631
|
import { readFile as readFile15, stat as stat2, mkdir as mkdir8 } from "fs/promises";
|
|
6507
|
-
import { dirname as dirname8, basename as basename8, join as
|
|
6632
|
+
import { dirname as dirname8, basename as basename8, join as join18 } from "path";
|
|
6508
6633
|
import chalk8 from "chalk";
|
|
6509
6634
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
6510
6635
|
function createImagesCommand() {
|
|
@@ -6792,7 +6917,7 @@ async function executeImagesProcess(inputPath, options) {
|
|
|
6792
6917
|
}
|
|
6793
6918
|
async function processDirectory(dirPath, options) {
|
|
6794
6919
|
if (options.fromMeta) {
|
|
6795
|
-
const outputDir =
|
|
6920
|
+
const outputDir = join18(dirPath, options.output);
|
|
6796
6921
|
const pipeline = new ImageProcessingPipeline(dirPath, { outputDir });
|
|
6797
6922
|
const result = await pipeline.processDirectory();
|
|
6798
6923
|
console.log("");
|
|
@@ -6829,9 +6954,9 @@ async function processSingleFile(filePath, options) {
|
|
|
6829
6954
|
const processor = new ImageProcessor();
|
|
6830
6955
|
const dir = dirname8(filePath);
|
|
6831
6956
|
const filename = basename8(filePath);
|
|
6832
|
-
const outputDir =
|
|
6957
|
+
const outputDir = join18(dir, options.output);
|
|
6833
6958
|
await mkdir8(outputDir, { recursive: true });
|
|
6834
|
-
const outputPath =
|
|
6959
|
+
const outputPath = join18(outputDir, filename);
|
|
6835
6960
|
let success = false;
|
|
6836
6961
|
if (options.crop) {
|
|
6837
6962
|
const edges = parseCropSpec(options.crop);
|
|
@@ -6926,14 +7051,13 @@ function parseBlurSpec(spec) {
|
|
|
6926
7051
|
// src/cli/commands/screenshot.ts
|
|
6927
7052
|
import { Command as Command9 } from "commander";
|
|
6928
7053
|
import { access as access12, mkdir as mkdir9, readdir as readdir7, unlink as unlink3 } from "fs/promises";
|
|
6929
|
-
import { basename as basename9, dirname as dirname9, join as
|
|
6930
|
-
import { execSync as execSync3, execFileSync as execFileSync3 } from "child_process";
|
|
7054
|
+
import { basename as basename9, dirname as dirname9, join as join19 } from "path";
|
|
6931
7055
|
import chalk9 from "chalk";
|
|
6932
7056
|
import ora4 from "ora";
|
|
6933
7057
|
async function filterToSpecificSlide(outputDir, baseName, slideNumber, format) {
|
|
6934
7058
|
const slideStr = slideNumber.toString().padStart(3, "0");
|
|
6935
7059
|
const targetFileName = `${baseName}.${slideStr}.${format}`;
|
|
6936
|
-
const targetPath =
|
|
7060
|
+
const targetPath = join19(outputDir, targetFileName);
|
|
6937
7061
|
try {
|
|
6938
7062
|
await access12(targetPath);
|
|
6939
7063
|
} catch {
|
|
@@ -6948,7 +7072,7 @@ async function filterToSpecificSlide(outputDir, baseName, slideNumber, format) {
|
|
|
6948
7072
|
);
|
|
6949
7073
|
for (const file of slideFiles) {
|
|
6950
7074
|
if (file !== targetFileName) {
|
|
6951
|
-
await unlink3(
|
|
7075
|
+
await unlink3(join19(outputDir, file));
|
|
6952
7076
|
}
|
|
6953
7077
|
}
|
|
6954
7078
|
return {
|
|
@@ -6956,17 +7080,12 @@ async function filterToSpecificSlide(outputDir, baseName, slideNumber, format) {
|
|
|
6956
7080
|
keptFile: targetFileName
|
|
6957
7081
|
};
|
|
6958
7082
|
}
|
|
6959
|
-
function checkMarpCliAvailable2() {
|
|
6960
|
-
|
|
6961
|
-
execSync3("marp --version", { stdio: "ignore", timeout: 5e3 });
|
|
6962
|
-
return true;
|
|
6963
|
-
} catch {
|
|
6964
|
-
return false;
|
|
6965
|
-
}
|
|
7083
|
+
function checkMarpCliAvailable2(projectDir) {
|
|
7084
|
+
return isMarpAvailable(projectDir);
|
|
6966
7085
|
}
|
|
6967
7086
|
function buildMarpCommandArgs(markdownPath, outputDir, options) {
|
|
6968
7087
|
const format = options.format || "png";
|
|
6969
|
-
const args = ["
|
|
7088
|
+
const args = ["--images", format];
|
|
6970
7089
|
if (options.width && options.width !== 1280) {
|
|
6971
7090
|
const scale = options.width / 1280;
|
|
6972
7091
|
args.push("--image-scale", String(scale));
|
|
@@ -7001,9 +7120,9 @@ async function executeScreenshot(inputPath, options) {
|
|
|
7001
7120
|
return { success: false, errors };
|
|
7002
7121
|
}
|
|
7003
7122
|
spinner?.start("Checking for Marp CLI...");
|
|
7004
|
-
if (!checkMarpCliAvailable2()) {
|
|
7123
|
+
if (!checkMarpCliAvailable2(dirname9(inputPath))) {
|
|
7005
7124
|
spinner?.fail("Marp CLI not found");
|
|
7006
|
-
const message = "Marp CLI not found. Install it with: npm install -
|
|
7125
|
+
const message = "Marp CLI not found. Install it with: npm install -D @marp-team/marp-cli";
|
|
7007
7126
|
console.error(chalk9.red(`Error: ${message}`));
|
|
7008
7127
|
errors.push(message);
|
|
7009
7128
|
process.exitCode = ExitCode.GeneralError;
|
|
@@ -7063,10 +7182,13 @@ async function executeScreenshot(inputPath, options) {
|
|
|
7063
7182
|
spinner?.start("Taking screenshots...");
|
|
7064
7183
|
const marpArgs = buildMarpCommandArgs(tempMdPath, outputDir, options);
|
|
7065
7184
|
if (options.verbose) {
|
|
7066
|
-
console.log(`Running:
|
|
7185
|
+
console.log(`Running: marp ${marpArgs.join(" ")}`);
|
|
7067
7186
|
}
|
|
7068
7187
|
try {
|
|
7069
|
-
|
|
7188
|
+
runMarp(marpArgs, {
|
|
7189
|
+
projectDir: dirname9(inputPath),
|
|
7190
|
+
stdio: options.verbose ? "inherit" : "pipe"
|
|
7191
|
+
});
|
|
7070
7192
|
spinner?.succeed(`Screenshots saved to ${outputDir}`);
|
|
7071
7193
|
} catch (error) {
|
|
7072
7194
|
spinner?.fail("Failed to take screenshots");
|