diff --git a/skills/baoyu-url-to-markdown/SKILL.md b/skills/baoyu-url-to-markdown/SKILL.md index 86eaf59..c8c929d 100644 --- a/skills/baoyu-url-to-markdown/SKILL.md +++ b/skills/baoyu-url-to-markdown/SKILL.md @@ -82,8 +82,14 @@ Full reference: [references/config/first-time-setup.md](references/config/first- | `download_media` | `ask` | `ask` / `1` / `0` | `ask` = prompt each time, `1` = always download, `0` = never | | `default_output_dir` | empty | path or empty | Default output directory (empty = `./url-to-markdown/`) | +**EXTEND.md → CLI mapping**: +| EXTEND.md key | CLI argument | Notes | +|---------------|-------------|-------| +| `download_media: 1` | `--download-media` | | +| `default_output_dir: ./posts/` | `--output-dir ./posts/` | Directory path. Do NOT pass to `-o` (which expects a file path) | + **Value priority**: -1. CLI arguments (`--download-media`, `-o`) +1. CLI arguments (`--download-media`, `-o`, `--output-dir`) 2. EXTEND.md 3. Skill defaults @@ -107,6 +113,9 @@ ${BUN_X} ${SKILL_DIR}/scripts/main.ts --wait # Save to specific file ${BUN_X} ${SKILL_DIR}/scripts/main.ts -o output.md +# Save to a custom output directory (auto-generates filename) +${BUN_X} ${SKILL_DIR}/scripts/main.ts --output-dir ./posts/ + # Download images and videos to local directories ${BUN_X} ${SKILL_DIR}/scripts/main.ts --download-media ``` @@ -116,7 +125,8 @@ ${BUN_X} ${SKILL_DIR}/scripts/main.ts --download-media | Option | Description | |--------|-------------| | `` | URL to fetch | -| `-o ` | Output file path (default: auto-generated) | +| `-o ` | Output file path — must be a **file** path, not directory (default: auto-generated) | +| `--output-dir ` | Base output directory — auto-generates `{dir}/{domain}/{slug}.md` (default: `./url-to-markdown/`) | | `--wait` | Wait for user signal before capturing | | `--timeout ` | Page load timeout (default: 30000) | | `--download-media` | Download image/video assets to local `imgs/` and `videos/`, and rewrite markdown links to local relative paths | @@ -139,9 +149,8 @@ YAML front matter with `url`, `title`, `description`, `author`, `published`, `ca ## Output Directory -``` -url-to-markdown//.md -``` +Default: `url-to-markdown//.md` +With `--output-dir ./posts/`: `./posts//.md` - ``: From page title or URL path (kebab-case, 2-6 words) - Conflict resolution: Append timestamp `-YYYYMMDD-HHMMSS.md` diff --git a/skills/baoyu-url-to-markdown/scripts/main.ts b/skills/baoyu-url-to-markdown/scripts/main.ts index 3bd5b32..c48a6b9 100644 --- a/skills/baoyu-url-to-markdown/scripts/main.ts +++ b/skills/baoyu-url-to-markdown/scripts/main.ts @@ -25,6 +25,7 @@ async function fileExists(filePath: string): Promise { interface Args { url: string; output?: string; + outputDir?: string; wait: boolean; timeout: number; downloadMedia: boolean; @@ -40,6 +41,8 @@ function parseArgs(argv: string[]): Args { args.output = argv[++i]; } else if (arg === "--timeout" || arg === "-t") { args.timeout = parseInt(argv[++i], 10) || DEFAULT_TIMEOUT_MS; + } else if (arg === "--output-dir") { + args.outputDir = argv[++i]; } else if (arg === "--download-media") { args.downloadMedia = true; } else if (!arg.startsWith("-") && !args.url) { @@ -66,10 +69,10 @@ function formatTimestamp(): string { return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`; } -async function generateOutputPath(url: string, title: string): Promise { +async function generateOutputPath(url: string, title: string, outputDir?: string): Promise { const domain = new URL(url).hostname.replace(/^www\./, ""); const slug = generateSlug(title, url); - const dataDir = resolveUrlToMarkdownDataDir(); + const dataDir = outputDir ? path.resolve(outputDir) : resolveUrlToMarkdownDataDir(); const basePath = path.join(dataDir, domain, `${slug}.md`); if (!(await fileExists(basePath))) { @@ -149,11 +152,19 @@ async function main(): Promise { process.exit(1); } + if (args.output) { + const stat = await import("node:fs").then(fs => fs.statSync(args.output!, { throwIfNoEntry: false })); + if (stat?.isDirectory()) { + console.error(`Error: -o path is a directory, not a file: ${args.output}`); + process.exit(1); + } + } + console.log(`Fetching: ${args.url}`); console.log(`Mode: ${args.wait ? "wait" : "auto"}`); const result = await captureUrl(args); - const outputPath = args.output || await generateOutputPath(args.url, result.metadata.title); + const outputPath = args.output || await generateOutputPath(args.url, result.metadata.title, args.outputDir); const outputDir = path.dirname(outputPath); await mkdir(outputDir, { recursive: true });