You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constprompt=`You are analyzing an inbound sponsorship inquiry for CodingCat.dev, a developer education platform with YouTube videos, podcasts, blog posts, and newsletters.
Copy file name to clipboardExpand all lines: sanity/schemas/singletons/contentConfig.ts
+6Lines changed: 6 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,7 @@ export default defineType({
10
10
name: "rssFeeds",
11
11
title: "RSS Feeds",
12
12
type: "array",
13
+
description: "RSS/Atom feeds to monitor for trending topics. The ingest cron checks these daily for new content ideas",
13
14
of: [
14
15
{
15
16
type: "object",
@@ -42,6 +43,7 @@ export default defineType({
42
43
name: "trendSourcesEnabled",
43
44
title: "Trend Sources Enabled",
44
45
type: "object",
46
+
description: "Toggle individual trend discovery sources on/off. Disabling a source skips it during the daily ingest scan",
45
47
fields: [
46
48
defineField({
47
49
name: "hn",
@@ -79,24 +81,28 @@ export default defineType({
79
81
name: "systemInstruction",
80
82
title: "System Instruction",
81
83
type: "text",
84
+
description: "The AI system prompt used for script generation. Defines the writing style, tone, and format for all generated video scripts",
82
85
initialValue: "You are a content strategist and scriptwriter for CodingCat.dev, a web development education channel run by Alex Patterson.\n\nYour style is inspired by Cleo Abram's \"Huge If True\" — you make complex technical topics feel exciting, accessible, and important. Key principles:\n- Start with a BOLD claim or surprising fact that makes people stop scrolling\n- Use analogies and real-world comparisons to explain technical concepts\n- Build tension: \"Here's the problem... here's why it matters... here's the breakthrough\"\n- Keep energy HIGH — short sentences, active voice, conversational tone\n- End with a clear takeaway that makes the viewer feel smarter\n- Target audience: developers who want to stay current but don't have time to read everything\n\nScript format: 60-90 second explainer videos. Think TikTok/YouTube Shorts energy with real educational depth.\n\nCodingCat.dev covers: React, Next.js, TypeScript, Svelte, web APIs, CSS, Node.js, cloud services, AI/ML for developers, and web platform updates.",
83
86
}),
84
87
defineField({
85
88
name: "targetVideoDurationSec",
86
89
title: "Target Video Duration (sec)",
87
90
type: "number",
91
+
description: "Target duration for generated videos in seconds. Scripts are calibrated to this length",
88
92
initialValue: 90,
89
93
}),
90
94
defineField({
91
95
name: "sceneCountMin",
92
96
title: "Scene Count Min",
93
97
type: "number",
98
+
description: "Minimum number of scenes per video. The AI generates at least this many visual segments",
94
99
initialValue: 3,
95
100
}),
96
101
defineField({
97
102
name: "sceneCountMax",
98
103
title: "Scene Count Max",
99
104
type: "number",
105
+
description: "Maximum number of scenes per video. Keeps videos focused and within duration targets",
Copy file name to clipboardExpand all lines: sanity/schemas/singletons/pipelineConfig.ts
+8Lines changed: 8 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -10,18 +10,21 @@ export default defineType({
10
10
name: "geminiModel",
11
11
title: "Gemini Model",
12
12
type: "string",
13
+
description: "The Google Gemini model used for script generation and content analysis (e.g., gemini-2.0-flash, gemini-2.5-pro)",
13
14
initialValue: "gemini-2.0-flash",
14
15
}),
15
16
defineField({
16
17
name: "elevenLabsVoiceId",
17
18
title: "ElevenLabs Voice ID",
18
19
type: "string",
20
+
description: "ElevenLabs voice ID for text-to-speech narration. Find voice IDs at elevenlabs.io/voice-library",
19
21
initialValue: "pNInz6obpgDQGcFmaJgB",
20
22
}),
21
23
defineField({
22
24
name: "youtubeUploadVisibility",
23
25
title: "YouTube Upload Visibility",
24
26
type: "string",
27
+
description: "Default visibility for uploaded YouTube videos. Use 'private' for testing, 'unlisted' for review, 'public' for production",
25
28
initialValue: "private",
26
29
options: {
27
30
list: ["private","unlisted","public"],
@@ -31,32 +34,37 @@ export default defineType({
31
34
name: "youtubeChannelId",
32
35
title: "YouTube Channel ID",
33
36
type: "string",
37
+
description: "Your YouTube channel ID \u2014 used for analytics and upload targeting",
34
38
initialValue: "",
35
39
}),
36
40
defineField({
37
41
name: "enableNotebookLmResearch",
38
42
title: "Enable NotebookLM Research",
39
43
type: "boolean",
44
+
description: "When enabled, the ingest cron creates a NotebookLM notebook for deep research before script generation. Requires NOTEBOOKLM_AUTH_JSON env var",
40
45
initialValue: false,
41
46
}),
42
47
defineField({
43
48
name: "qualityThreshold",
44
49
title: "Quality Threshold",
45
50
type: "number",
51
+
description: "Minimum quality score (0-100) from the AI critic. Videos scoring below this are flagged for manual review instead of auto-publishing",
46
52
initialValue: 50,
47
53
validation: (rule)=>rule.min(0).max(100),
48
54
}),
49
55
defineField({
50
56
name: "stuckTimeoutMinutes",
51
57
title: "Stuck Timeout Minutes",
52
58
type: "number",
59
+
description: "Minutes before a pipeline document is considered stuck and auto-flagged. Sub-statuses use proportional timeouts (infographics: 50%, enriching: 33%)",
53
60
initialValue: 30,
54
61
validation: (rule)=>rule.min(5).max(120),
55
62
}),
56
63
defineField({
57
64
name: "maxIdeasPerRun",
58
65
title: "Max Ideas Per Run",
59
66
type: "number",
67
+
description: "Maximum number of content ideas to process per ingest cron run. Keep low (1-3) to stay within serverless time limits",
0 commit comments