feat: Add OurDigital custom skills package (10 skills)

Complete implementation of OurDigital skills with dual-platform support
(Claude Desktop + Claude Code) following standardized structure.

Skills created:
- 01-ourdigital-brand-guide: Brand reference & style guidelines
- 02-ourdigital-blog: Korean blog drafts (blog.ourdigital.org)
- 03-ourdigital-journal: English essays (journal.ourdigital.org)
- 04-ourdigital-research: Research prompts & workflows
- 05-ourdigital-document: Notion-to-presentation pipeline
- 06-ourdigital-designer: Visual/image prompt generation
- 07-ourdigital-ad-manager: Ad copywriting & keyword research
- 08-ourdigital-trainer: Training materials & workshop planning
- 09-ourdigital-backoffice: Quotes, proposals, cost analysis
- 10-ourdigital-skill-creator: Meta skill for creating new skills

Features:
- YAML frontmatter with "ourdigital" or "our" prefix triggers
- Standardized directory structure (code/, desktop/, shared/, docs/)
- Shared environment setup (_ourdigital-shared/)
- Comprehensive reference documentation
- Cross-skill integration support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 16:50:17 +07:00
parent 7d20abe811
commit 0bc24d00b9
169 changed files with 9970 additions and 741 deletions

View File

@@ -0,0 +1,211 @@
#!/usr/bin/env python3
"""
OurDigital Visual Storytelling Prompt Generator
Generates sophisticated image prompts for blog featured images
"""
import argparse
from typing import Dict, Tuple
import json
class VisualPromptGenerator:
def __init__(self):
self.style_base = (
"sophisticated featured image, minimalist contemporary design, "
"clean vector illustration with subtle texture overlays, "
"1200x630px, suitable for blog header"
)
self.moods = {
"contemplative": "contemplative and introspective atmosphere, zen-like calm",
"critical": "analytical precision with underlying urgency, sharp clarity",
"hopeful": "dawn breaking through uncertainty, warm optimism",
"anxious": "subtle tension and uncertainty, digital unease",
"philosophical": "deep meditation quality, timeless wisdom"
}
self.color_palettes = {
"contemplative": "monochrome palette with single accent color",
"critical": "cool blue-gray with sharp red accents",
"hopeful": "warm amber gradients with sky blue highlights",
"anxious": "desaturated colors with digital green touches",
"philosophical": "near black and off-white with muted gold"
}
self.metaphor_types = {
"technology": "organic-digital hybrid forms, natural systems becoming circuits",
"identity": "layered masks, fragmented mirrors, dissolving boundaries",
"network": "root systems, neural pathways, constellation patterns",
"transformation": "metamorphosis states, particle dissolution, phase transitions",
"knowledge": "light sources, growing trees, prismatic refractions"
}
def generate_prompt(
self,
topic: str,
mood: str = "contemplative",
metaphor: str = None,
cultural_fusion: float = 0.6,
abstract_level: float = 0.8
) -> str:
"""
Generate a sophisticated image prompt for OurDigital blog
Args:
topic: Main subject of the blog post
mood: Emotional tone (contemplative/critical/hopeful/anxious/philosophical)
metaphor: Visual metaphor to use
cultural_fusion: Balance of Korean-Western aesthetics (0-1)
abstract_level: Level of abstraction (0=literal, 1=highly abstract)
"""
# Build core prompt
prompt_parts = [
f"Create a {self.style_base} for blog post about {topic}.",
""
]
# Add visual concept
if metaphor:
prompt_parts.append(f"Visual concept: {metaphor}.")
else:
prompt_parts.append(f"Visual concept: Abstract representation of {topic}.")
prompt_parts.append("")
# Add mood and atmosphere
mood_desc = self.moods.get(mood, self.moods["contemplative"])
prompt_parts.append(f"Atmosphere: {mood_desc}.")
# Add color palette
colors = self.color_palettes.get(mood, self.color_palettes["contemplative"])
prompt_parts.append(f"Colors: {colors}.")
# Add composition guidelines
prompt_parts.extend([
"",
"Composition:",
f"- {'Highly abstract' if abstract_level > 0.7 else 'Semi-abstract'} interpretation",
f"- Minimum 20% negative space for contemplative breathing room",
f"- Asymmetrical balance with {'strong' if abstract_level > 0.5 else 'subtle'} geometric structure"
])
# Add cultural elements if needed
if cultural_fusion > 0.3:
fusion_level = "subtle" if cultural_fusion < 0.6 else "balanced"
prompt_parts.append(
f"- {fusion_level} integration of Korean minimalist aesthetics with Western modernism"
)
# Add quality notes
prompt_parts.extend([
"",
"Technical notes:",
"- Ensure clarity at thumbnail size (200px)",
"- Avoid tech clichés (circuits, binary codes)",
"- No stock photo aesthetics or literal interpretations",
"- Timeless design that won't date quickly"
])
# Add reference
prompt_parts.extend([
"",
"Aesthetic reference: Combine Bauhaus principles with Agnes Martin's contemplative minimalism."
])
return "\n".join(prompt_parts)
def generate_variations(self, topic: str, count: int = 3) -> list:
"""Generate multiple prompt variations for the same topic"""
variations = []
moods = ["contemplative", "critical", "philosophical"]
for i in range(min(count, len(moods))):
prompt = self.generate_prompt(
topic=topic,
mood=moods[i],
abstract_level=0.7 + (i * 0.1)
)
variations.append({
"variation": i + 1,
"mood": moods[i],
"prompt": prompt
})
return variations
def main():
parser = argparse.ArgumentParser(
description="Generate visual prompts for OurDigital blog featured images"
)
parser.add_argument(
"--topic",
required=True,
help="Main topic/subject of the blog post"
)
parser.add_argument(
"--mood",
choices=["contemplative", "critical", "hopeful", "anxious", "philosophical"],
default="contemplative",
help="Emotional tone of the image"
)
parser.add_argument(
"--metaphor",
help="Specific visual metaphor to use"
)
parser.add_argument(
"--cultural-fusion",
type=float,
default=0.6,
help="Korean-Western aesthetic balance (0-1)"
)
parser.add_argument(
"--abstract",
type=float,
default=0.8,
help="Level of abstraction (0-1)"
)
parser.add_argument(
"--variations",
type=int,
help="Generate N variations of the prompt"
)
parser.add_argument(
"--json",
action="store_true",
help="Output as JSON"
)
args = parser.parse_args()
generator = VisualPromptGenerator()
if args.variations:
results = generator.generate_variations(args.topic, args.variations)
if args.json:
print(json.dumps(results, indent=2, ensure_ascii=False))
else:
for var in results:
print(f"\n--- Variation {var['variation']} ({var['mood']}) ---")
print(var['prompt'])
else:
prompt = generator.generate_prompt(
topic=args.topic,
mood=args.mood,
metaphor=args.metaphor,
cultural_fusion=args.cultural_fusion,
abstract_level=args.abstract
)
if args.json:
result = {
"topic": args.topic,
"mood": args.mood,
"prompt": prompt
}
print(json.dumps(result, indent=2, ensure_ascii=False))
else:
print(prompt)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,251 @@
#!/usr/bin/env python3
"""
OurDigital Mood Calibrator
Fine-tune emotional and stylistic parameters for visual prompts
"""
import json
from typing import Dict, Any
import argparse
class MoodCalibrator:
def __init__(self):
self.presets = {
"default": {
"contemplative_depth": 0.8,
"cultural_fusion": 0.6,
"technical_precision": 0.7,
"emotional_weight": 0.5,
"innovation_index": 0.7
},
"philosophical_essay": {
"contemplative_depth": 0.95,
"cultural_fusion": 0.7,
"technical_precision": 0.6,
"emotional_weight": 0.3,
"innovation_index": 0.8
},
"technical_analysis": {
"contemplative_depth": 0.6,
"cultural_fusion": 0.4,
"technical_precision": 0.9,
"emotional_weight": 0.3,
"innovation_index": 0.6
},
"social_commentary": {
"contemplative_depth": 0.7,
"cultural_fusion": 0.6,
"technical_precision": 0.5,
"emotional_weight": 0.7,
"innovation_index": 0.7
},
"cultural_exploration": {
"contemplative_depth": 0.8,
"cultural_fusion": 0.9,
"technical_precision": 0.4,
"emotional_weight": 0.6,
"innovation_index": 0.8
}
}
self.parameter_descriptions = {
"contemplative_depth": "Level of abstraction (0=literal, 1=highly abstract)",
"cultural_fusion": "Balance of Korean-Western aesthetics (0=Western only, 1=Korean dominant)",
"technical_precision": "Clean geometric vs organic forms (0=organic, 1=geometric)",
"emotional_weight": "Mood intensity (0=neutral, 1=heavy atmosphere)",
"innovation_index": "Traditional vs experimental approach (0=traditional, 1=experimental)"
}
def calibrate(self, preset: str = "default", **overrides) -> Dict[str, float]:
"""
Get calibrated mood parameters
Args:
preset: Base preset to use
**overrides: Specific parameter overrides
Returns:
Dictionary of calibrated parameters
"""
params = self.presets.get(preset, self.presets["default"]).copy()
# Apply overrides
for key, value in overrides.items():
if key in params:
params[key] = max(0, min(1, value)) # Clamp to 0-1
return params
def generate_modifier_text(self, params: Dict[str, float]) -> str:
"""
Generate text modifiers based on parameters
Args:
params: Dictionary of mood parameters
Returns:
Text description for prompt modification
"""
modifiers = []
# Contemplative depth
if params["contemplative_depth"] > 0.8:
modifiers.append("highly abstract and philosophical")
elif params["contemplative_depth"] > 0.6:
modifiers.append("semi-abstract with symbolic elements")
else:
modifiers.append("grounded with recognizable forms")
# Cultural fusion
if params["cultural_fusion"] > 0.7:
modifiers.append("strong Korean aesthetic influence")
elif params["cultural_fusion"] > 0.4:
modifiers.append("balanced East-West aesthetic fusion")
else:
modifiers.append("Western minimalist approach")
# Technical precision
if params["technical_precision"] > 0.7:
modifiers.append("precise geometric construction")
elif params["technical_precision"] > 0.4:
modifiers.append("blend of geometric and organic")
else:
modifiers.append("flowing organic forms")
# Emotional weight
if params["emotional_weight"] > 0.7:
modifiers.append("heavy, contemplative atmosphere")
elif params["emotional_weight"] > 0.4:
modifiers.append("balanced emotional tone")
else:
modifiers.append("light, open feeling")
# Innovation index
if params["innovation_index"] > 0.7:
modifiers.append("experimental and avant-garde")
elif params["innovation_index"] > 0.4:
modifiers.append("contemporary with classic elements")
else:
modifiers.append("timeless and traditional")
return ", ".join(modifiers)
def suggest_color_temperature(self, params: Dict[str, float]) -> str:
"""
Suggest color temperature based on parameters
Args:
params: Dictionary of mood parameters
Returns:
Color temperature suggestion
"""
emotional = params.get("emotional_weight", 0.5)
technical = params.get("technical_precision", 0.7)
if emotional > 0.6:
if technical > 0.6:
return "Cool palette with strategic warm accents"
else:
return "Warm, earthy tones with depth"
else:
if technical > 0.6:
return "Neutral grays with single accent color"
else:
return "Soft, desaturated natural colors"
def export_for_prompt(self, params: Dict[str, float]) -> Dict[str, Any]:
"""
Export parameters in a format ready for prompt generation
Args:
params: Dictionary of mood parameters
Returns:
Formatted export for prompt generation
"""
return {
"parameters": params,
"modifiers": self.generate_modifier_text(params),
"color_temperature": self.suggest_color_temperature(params),
"abstraction_level": params["contemplative_depth"],
"cultural_balance": params["cultural_fusion"]
}
def main():
parser = argparse.ArgumentParser(
description="Calibrate mood parameters for OurDigital visual prompts"
)
parser.add_argument(
"--preset",
choices=["default", "philosophical_essay", "technical_analysis",
"social_commentary", "cultural_exploration"],
default="default",
help="Base preset to use"
)
parser.add_argument(
"--contemplative-depth",
type=float,
help="Override contemplative depth (0-1)"
)
parser.add_argument(
"--cultural-fusion",
type=float,
help="Override cultural fusion (0-1)"
)
parser.add_argument(
"--technical-precision",
type=float,
help="Override technical precision (0-1)"
)
parser.add_argument(
"--emotional-weight",
type=float,
help="Override emotional weight (0-1)"
)
parser.add_argument(
"--innovation-index",
type=float,
help="Override innovation index (0-1)"
)
parser.add_argument(
"--export",
action="store_true",
help="Export full configuration for prompt generation"
)
args = parser.parse_args()
calibrator = MoodCalibrator()
# Build overrides
overrides = {}
if args.contemplative_depth is not None:
overrides["contemplative_depth"] = args.contemplative_depth
if args.cultural_fusion is not None:
overrides["cultural_fusion"] = args.cultural_fusion
if args.technical_precision is not None:
overrides["technical_precision"] = args.technical_precision
if args.emotional_weight is not None:
overrides["emotional_weight"] = args.emotional_weight
if args.innovation_index is not None:
overrides["innovation_index"] = args.innovation_index
# Calibrate
params = calibrator.calibrate(args.preset, **overrides)
if args.export:
export = calibrator.export_for_prompt(params)
print(json.dumps(export, indent=2, ensure_ascii=False))
else:
print(f"Calibrated Parameters for '{args.preset}':")
print("-" * 50)
for key, value in params.items():
desc = calibrator.parameter_descriptions[key]
print(f"{key}: {value:.2f} - {desc}")
print("-" * 50)
print(f"Modifiers: {calibrator.generate_modifier_text(params)}")
print(f"Color Temperature: {calibrator.suggest_color_temperature(params)}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,5 @@
# 30-ourdigital-designer dependencies
openai>=1.0.0
python-dotenv>=1.0.0
rich>=13.7.0
typer>=0.9.0