@barbapapazes/content-creation
v0.18.9
Published
A CLI tool to streamline multi-platform content creation by generating dated directories with content files for LinkedIn, X (Twitter), YouTube, and Instagram.
Downloads
1,560
Readme
@barbapapazes/content-creation
A CLI tool to streamline multi-platform content creation by generating dated directories with content files for LinkedIn, X (Twitter), YouTube, and Instagram.
Features
- Create dated directory structure (YYYY/MM/DD format)
- Support for multiple content types: LinkedIn, X, YouTube, Instagram
- User-friendly date selection that starts with 7 days and can keep loading more future dates
- Multi-select content types to create multiple files in one run
- Config-driven templates for each content type
- Never overwrites existing files (skip if exists behavior)
- Generate separate index files per content type
- Manage article series with generated README indexes and ordered inserts
- Estimate series article reading time and write it to frontmatter
- List upcoming content from today onward with absolute file paths
- Generate and upload a LinkedIn publication calendar for Google Calendar subscriptions
- Link images to LinkedIn post frontmatter
- Mark a publication as ready by setting
ready: truein frontmatter - Create resource directories (articles, videos, audio)
Installation
npm install -g @barbapapazes/content-creationUsage
Several workflows are now grouped under domain-oriented commands for better discoverability:
content-creation index ...content-creation series ...content-creation linkedin ...content-creation x ...content-creation publication ...content-creation resource ...
Create Content Directory
Create a dated directory with content files for selected platforms:
# Create content directory in current working directory
content-creation
# Prompts you to select: LinkedIn, X, YouTube, and/or Instagram
# Create content directory at a specific path
content-creation --path /path/to/contentThe tool will prompt you to:
- Enter a title (shared across all selected types)
- Select one or more content types
- Answer type-specific questions:
- LinkedIn: Whether to include a video. If not, photos are automatically enabled.
- YouTube/Instagram: Whether to create script and description files
- Choose a date, with the option to keep loading more future dates
Content Files by Type
Each content type creates specific files:
- LinkedIn:
linkedin.mdwithimages: [null]by default, pluslinkedin-script.mdwhen video is planned - X:
x.md - YouTube:
youtube.md,youtube-script.md,youtube-description.md - Instagram:
instagram.md,instagram-script.md,instagram-description.md
All main files (*.md) include frontmatter with at least a title field for indexing.
Important: Files are never overwritten. If a file already exists, it will be skipped.
Create Index Files
Generate index files for each content type found in your dated folders:
# Generate index files in current directory
content-creation index create
# Generate index files at a specific path
content-creation index create --path /path/to/contentThis command scans your YYYY/MM/DD directory structure and creates:
linkedin-posts.md- Index of all LinkedIn postsx-posts.md- Index of all X postsyoutube-videos.md- Index of all YouTube videosinstagram-posts.md- Index of all Instagram posts
Each index file contains:
# LinkedIn Posts
_Generated on 1/31/2026_
Total posts: 15
- [Understanding AI Agents](2026/01/20/linkedin.md) - _January 20, 2026_
- [Deep Dive into RAG](2026/01/15/linkedin.md) - _January 15, 2026_
...List Upcoming Content
List all content scheduled for today or later:
content-creation publication list-upcoming
# List upcoming content at a specific path
content-creation publication list-upcoming --path /path/to/contentThis command scans your YYYY/MM/DD directory structure, reads the content title from frontmatter, and prints each matching content item with its absolute file path so it is easy to click from the terminal.
Example output:
2026-04-18 · LinkedIn · Shipping a better content workflow
/absolute/path/to/content/2026/04/18/linkedin.md
2026-04-20 · X · A tiny automation tip
/absolute/path/to/content/2026/04/20/x.mdManage Series
Work with article series stored under series/<series-slug>/.
Each series directory can contain:
- a
README.mdfile with the editorial context for the series; - numbered markdown files such as
1.introduction.md,2.my-next-article.md, etc.
Generate the series index
Refresh the generated ## Index section in each series README.md based on the numbered article files:
# Generate indexes for all series in the current directory
content-creation series create-index
# Generate the index for a specific series only
content-creation series create-index --series my-series-slug
# Generate series indexes from another base path
content-creation series create-index --path /path/to/contentThe command preserves the existing README.md content and only manages the generated ## Index section.
Introduce a new article in a series
Insert a new article at a specific position in the series:
# Interactive mode
content-creation series introduce
# Fully scripted mode
content-creation series introduce \
--series my-series-slug \
--title "What tool calling really changes" \
--position 6This command will:
- create a new markdown file with frontmatter containing the title;
- rename subsequent numbered files to make room for the new article;
- regenerate the series
README.mdindex automatically.
Generated article files follow the pattern <index>.<slug>.md.
Estimate a series article reading time
Compute the reading duration of a numbered series article and store it in the time frontmatter field.
The estimate ignores frontmatter and HTML comments, assumes 5 characters per word, and uses 100 words per minute by default.
# Interactive mode
content-creation series estimate-time
# Fully scripted mode
content-creation series estimate-time \
--series my-series-slug \
--file 6.what-tool-calling-really-changes.md \
--wpm 120This command will:
- prompt you for the series and the article file when needed;
- estimate the reading time in whole minutes from the markdown body only;
- ignore frontmatter and HTML comments during the calculation;
- write the resulting value into
timein the article frontmatter.
Publish LinkedIn Calendar
Generate a Google Calendar-compatible .ics file for LinkedIn publications, upload it to Cloudflare R2 using Wrangler, and print the subscription URL:
content-creation linkedin publish-calendar
# Publish the LinkedIn calendar from a specific content directory
content-creation linkedin publish-calendar --path /path/to/contentThis command will:
- Scan your
YYYY/MM/DDdirectory structure forlinkedin.mdfiles only - Read the LinkedIn frontmatter and generate all-day calendar events
- Stream the generated calendar directly to Cloudflare R2 using Wrangler
- Upload
content-creation.icsto thecontent-creationR2 bucket - Print the final subscription URL for Google Calendar
Required Configuration: You must set up the following environment variables in a .env file:
CALENDAR_PUBLIC_URL=https://calendar.soubiran.dev
CALENDAR_TOKEN=your-calendar-token-hereSee .env.example for a template. The printed URL uses the format:
https://calendar.soubiran.dev/content-creation.ics?token=<your-calendar-token>Current Scope: This command publishes LinkedIn entries only for now.
Link Images
Scan recent LinkedIn posts and link images to their frontmatter:
content-creation linkedin link-images
# Link images at a specific path
content-creation linkedin link-images --path /path/to/contentCreate Resource
Create a resource directory with article, video, or audio content:
# Preferred grouped command
content-creation resource create
# Create resource at a specific path
content-creation resource create --path /path/to/resourcesSchedule Reminder
Schedule a reminder for X (Twitter) content to be posted at 11:00 AM UTC on the date specified in the folder path:
content-creation x schedule-reminder
# Schedule reminder at a specific path
content-creation x schedule-reminder --path /path/to/contentThe command will:
- Scan your directory for dated folders containing
x.mdfiles - Prompt you to select which content to schedule
- Check if the content is already scheduled (exits early if
scheduled: truein frontmatter) - Extract the tweet content from
x.md - Calculate the scheduled time (11:00 AM UTC based on the folder date: YYYY/MM/DD)
- Send a POST request to your automation endpoint
- Update the frontmatter with
scheduled: true - Display a confirmation message with the scheduled date/time
Required Configuration: You must set up the following environment variables in a .env file:
AUTOMATION_ENDPOINT=https://automation.soubiran.dev/trigger
CF_ACCESS_CLIENT_ID=your-client-id-here
CF_ACCESS_CLIENT_SECRET=your-client-secret-hereSee .env.example for a template.
Mark Publication as Ready
Mark a publication as ready by setting ready: true in the selected markdown file frontmatter:
content-creation publication ready
# Mark a publication as ready from a specific content directory
content-creation publication ready --path /path/to/contentThis command will:
- Scan your
YYYY/MM/DDdirectory structure for publication files - Prompt you to select which publication to update
- Add
ready: trueto the selected file frontmatter
Configuration
You can configure the tool using a configuration file. Create one of the following files:
- Local config:
content-creation.config.{ts,js,mjs,json}in your project root - Global config:
~/.content-creationrc(JSON format)
Configuration Options
export default {
// Array of thematic areas (reserved for future features)
thematic: ['JavaScript', 'TypeScript', 'Node.js'],
// Base directory for external template files (optional)
templatesDir: '~/.config/content-creation/templates',
// Templates configuration per content type
templates: {
linkedin: {
body: '', // Inline template for body content
bodyPath: 'linkedin-body.md', // Or path to template file
footer: '\n\n---\n\nCustom footer text', // Inline footer
footerPath: 'linkedin-footer.md', // Or path to footer file
},
x: {
body: '',
bodyPath: 'x-body.md',
},
youtube: {
body: '',
script: '',
description: '',
// Or use paths: bodyPath, scriptPath, descriptionPath
},
instagram: {
body: '',
script: '',
description: '',
},
},
// Scheduling configuration (optional, can also be set via environment variables)
scheduling: {
automationEndpoint: 'https://automation.soubiran.dev/trigger',
cfAccessClientId: 'your-client-id',
cfAccessClientSecret: 'your-client-secret',
},
// Calendar publishing configuration (optional, can also be set via environment variables)
calendar: {
publicUrl: 'https://calendar.soubiran.dev',
token: 'your-calendar-token',
},
// Reading-time configuration (optional)
reading: {
wordsPerMinute: 100,
},
}Template Resolution
For each template field (body, footer, script, description):
- If
*Pathis specified, it's resolved relative totemplatesDiror the config file location - Otherwise, the inline string value is used
- If neither is specified, defaults are used (LinkedIn has a default footer)
Example: Customizing LinkedIn Footer
Create a content-creation.config.ts file:
import { defineConfig } from '@barbapapazes/content-creation'
export default defineConfig({
templates: {
linkedin: {
footer: '\n\n---\n\nCustom signature here! 🚀',
},
},
})Or store templates in external files:
import { defineConfig } from '@barbapapazes/content-creation'
export default defineConfig({
templatesDir: '~/.config/content-creation/templates',
templates: {
linkedin: {
footerPath: 'linkedin-footer.md',
},
youtube: {
descriptionPath: 'youtube-description.md',
},
},
})Then create ~/.config/content-creation/templates/linkedin-footer.md:
---
Subscribe for more content! 🎯JSON Configuration
For a JSON config file (~/.content-creationrc):
{
"thematic": ["JavaScript", "TypeScript", "Node.js"],
"templates": {
"linkedin": {
"footer": "\n\n---\n\nFollow for more! 🚀"
}
}
}Directory Structure
The CLI creates a nested directory structure organized by date:
base-path/
└── YYYY/ # Year folder
└── MM/ # Month folder
└── DD/ # Day folder
├── linkedin.md
├── linkedin-script.md
├── x.md
├── youtube.md
├── youtube-script.md
├── youtube-description.md
├── instagram.md
├── instagram-script.md
└── instagram-description.mdExample: Running the CLI on January 31, 2026 and selecting all types will create a 2026/01/31/ directory with all the relevant files.
License
MIT
