refactor: reorganize skill numbering, remove obsolete skills, rename shared libs
- Rename: 00→80 claude-settings-optimizer, 88→79 dintel-skill-update, 92→81 mac-optimizer, 93→82 tui-design-template - Rename: dintel-shared → _dintel-shared (consistent with _ourdigital-shared) - Remove: 61-gtm-manager, 62-gtm-guardian (obsolete), 99_archive - Update all dintel-* skill refs (114 occurrences across 31 files) - Sync README.md, CLAUDE.md, AGENTS.md with new structure Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
3
custom-skills/_dintel-shared/src/dintel/__init__.py
Normal file
3
custom-skills/_dintel-shared/src/dintel/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""D.intelligence Agent Corps — shared utilities."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
132
custom-skills/_dintel-shared/src/dintel/brand.py
Normal file
132
custom-skills/_dintel-shared/src/dintel/brand.py
Normal file
@@ -0,0 +1,132 @@
|
||||
"""Brand constants and identity for D.intelligence."""
|
||||
|
||||
# ── Brand Core ──────────────────────────────────────────────────
|
||||
BRAND_NAME = "D.intelligence"
|
||||
BRAND_CONCEPT = "SMART Marketing Clinic"
|
||||
TAGLINE = "Analysis, Treatment & Growth"
|
||||
MOTTO = "Think Forward"
|
||||
MISSION = "데이터 기반 의사결정으로 기업의 지속가능한 성장을 실현하는 전문 파트너"
|
||||
WEBSITE = "https://dintelligence.co.kr"
|
||||
|
||||
CORE_VALUES = {
|
||||
"Scientific": "과학적 방법론, 검증, 데이터 기반 판단",
|
||||
"Practical": "실행 가능하고 현실적인 해법",
|
||||
"Outcome": "측정 가능한 성과 중심",
|
||||
"Insights": "복잡한 문제를 분명한 인사이트로 전환",
|
||||
}
|
||||
|
||||
# ── Brand Colors — 2025 Design System ───────────────────────────
|
||||
# Source: D.intelligence_Design_System_2025.pdf
|
||||
|
||||
# Primary palette (RGB)
|
||||
COLOR_D_BEIGE = (229, 225, 210) # #E5E1D2 — Cover/Section BG (NEW primary BG)
|
||||
COLOR_D_OLIVE = (206, 220, 0) # #CEDC00 — Accent only (demoted from 2022 BG)
|
||||
COLOR_D_BROWN = (35, 24, 21) # #231815 — Primary text / Dark BG
|
||||
COLOR_D_BLACK = (0, 0, 0) # #000000 — Dark BG / Text
|
||||
|
||||
# Secondary palette (RGB)
|
||||
COLOR_D_GRAY = (114, 113, 113) # #727171 — Secondary text
|
||||
COLOR_D_LIGHT_GRAY = (242, 242, 242) # #F2F2F2 — Card / BG
|
||||
COLOR_D_BLUE = (0, 117, 192) # #0075C0 — Digital accent (diagrams, data viz)
|
||||
COLOR_D_BORDER = (191, 191, 191) # #BFBFBF — Border 0.5pt
|
||||
COLOR_D_WARM_GRAY = (200, 196, 184) # #C8C4B8 — Header bar, vertical line accent
|
||||
|
||||
COLOR_WHITE = (255, 255, 255)
|
||||
|
||||
# Hex versions
|
||||
HEX_D_BEIGE = "#E5E1D2"
|
||||
HEX_D_OLIVE = "#CEDC00"
|
||||
HEX_D_BROWN = "#231815"
|
||||
HEX_D_BLACK = "#000000"
|
||||
HEX_D_GRAY = "#727171"
|
||||
HEX_D_LIGHT_GRAY = "#F2F2F2"
|
||||
HEX_D_BLUE = "#0075C0"
|
||||
HEX_D_BORDER = "#BFBFBF"
|
||||
HEX_D_WARM_GRAY = "#C8C4B8"
|
||||
|
||||
# Semantic aliases (for backward compatibility)
|
||||
COLOR_PRIMARY = COLOR_D_BROWN # Primary text color
|
||||
COLOR_ACCENT = COLOR_D_OLIVE # Accent (sparingly)
|
||||
COLOR_TEXT = COLOR_D_BROWN # Body text
|
||||
COLOR_BG = COLOR_D_BEIGE # Cover/section background
|
||||
COLOR_SECONDARY = COLOR_D_GRAY # Secondary text
|
||||
HEX_PRIMARY = HEX_D_BROWN
|
||||
HEX_ACCENT = HEX_D_OLIVE
|
||||
HEX_TEXT = HEX_D_BROWN
|
||||
HEX_BG = HEX_D_BEIGE
|
||||
HEX_SECONDARY = HEX_D_GRAY
|
||||
|
||||
# ── Typography — 2025 Design System ─────────────────────────────
|
||||
FONT_KR = "Apple SD Gothic Neo"
|
||||
FONT_EN = "DM Sans"
|
||||
FONT_FALLBACK_KR = "Apple SD Gothic Neo"
|
||||
FONT_FALLBACK_EN = "DM Sans"
|
||||
|
||||
# Type Scale
|
||||
TYPE_SCALE = {
|
||||
"display_title": {"size_pt": (54, 72), "weight": "Bold", "color": "D_BROWN"},
|
||||
"slide_title": {"size_pt": (28, 36), "weight": "Bold", "color": "D_BROWN"},
|
||||
"subtitle": {"size_pt": (14, 16), "weight": "Regular", "color": "D_GRAY"},
|
||||
"body": {"size_pt": (11, 14), "weight": "Regular", "color": "D_BROWN"},
|
||||
"footnote": {"size_pt": (8, 10), "weight": "Regular", "color": "D_GRAY"},
|
||||
"header_bar": {"size_pt": (10, 10), "weight": "Regular", "color": "WARM_GRAY"},
|
||||
}
|
||||
|
||||
# ── Layout Motifs — 2025 Design System ──────────────────────────
|
||||
LAYOUT = {
|
||||
"vertical_line_accent": {"color": "WARM_GRAY", "note": "Thin vertical line on left of section dividers"},
|
||||
"three_dot_motif": {"symbol": "• • •", "position": "upper-right corner of cover/featured slides"},
|
||||
"footer_tagline": "Analysis, Treatment & Growth",
|
||||
"min_margin": "0.5 inches",
|
||||
"border_weight": "0.5pt",
|
||||
}
|
||||
|
||||
# ── Service Architecture ────────────────────────────────────────
|
||||
SERVICE_PHASES = {
|
||||
"Analysis": {"kr": "진단", "modules": ["A1", "A2", "A3", "A4", "A5", "A6"]},
|
||||
"Treatment": {"kr": "처방", "modules": ["T1", "T2", "T3", "T4", "T5", "T6", "T7"]},
|
||||
"Growth": {"kr": "성장", "modules": ["G1", "G2", "G3", "G4"]},
|
||||
}
|
||||
|
||||
SERVICE_MODULES = {
|
||||
"A1": "비즈니스·브랜드 진단",
|
||||
"A2": "고객·소비자 분석",
|
||||
"A3": "데이터 분석 — 웹·앱",
|
||||
"A4": "디지털 마케팅 진단",
|
||||
"A5": "퍼포먼스 마케팅 진단",
|
||||
"A6": "운영·관리 진단",
|
||||
"T1": "브랜드 스토리텔링 & 가이드",
|
||||
"T2": "고객 접점 경험 최적화",
|
||||
"T3": "디지털 자산 통합관리",
|
||||
"T4": "콘텐츠 마케팅",
|
||||
"T5": "광고·전환 최적화",
|
||||
"T6": "Brand Visibility Treatment",
|
||||
"T7": "운영 시스템·자동화",
|
||||
"G1": "퍼포먼스 마케팅",
|
||||
"G2": "콘텐츠 마케팅 대행",
|
||||
"G3": "모니터링·이슈관리",
|
||||
"G4": "연간 계약·운영",
|
||||
}
|
||||
|
||||
SERVICE_CATEGORIES = {
|
||||
"DI": "Data Intelligence",
|
||||
"MD": "Measurement Design",
|
||||
"MPO": "Marketing Performance Optimization",
|
||||
"BVT": "Brand Visibility Treatment",
|
||||
}
|
||||
|
||||
# ── Client Codes ────────────────────────────────────────────────
|
||||
CLIENT_CODES = {
|
||||
"JHR": "조선호텔앤리조트",
|
||||
"JAM": "제이미성형외과",
|
||||
"SLA": "신라호텔",
|
||||
"SHR": "SHR",
|
||||
"OurDigital": "OurDigital",
|
||||
}
|
||||
|
||||
# ── Prohibited Expressions ──────────────────────────────────────
|
||||
PROHIBITED_WORDS = [
|
||||
"획기적", "혁신적", "놀라운", "독보적", "최고의",
|
||||
"반드시", "확실히", "무조건", "100%", "보장",
|
||||
"대행사", "에이전시", "바이럴",
|
||||
]
|
||||
91
custom-skills/_dintel-shared/src/dintel/document.py
Normal file
91
custom-skills/_dintel-shared/src/dintel/document.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""Document generation utilities for D.intelligence branded outputs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from docx import Document
|
||||
from docx.shared import Inches, Pt, RGBColor
|
||||
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||||
|
||||
from dintel.brand import (
|
||||
BRAND_NAME,
|
||||
COLOR_PRIMARY,
|
||||
COLOR_SECONDARY,
|
||||
COLOR_TEXT,
|
||||
FONT_FALLBACK_EN,
|
||||
FONT_FALLBACK_KR,
|
||||
TAGLINE,
|
||||
)
|
||||
|
||||
|
||||
def create_branded_doc(
|
||||
title: str,
|
||||
subtitle: str = "",
|
||||
author: str = "D.intelligence",
|
||||
) -> Document:
|
||||
"""Create a new DOCX document with D.intelligence branding."""
|
||||
doc = Document()
|
||||
|
||||
# Core properties
|
||||
doc.core_properties.author = author
|
||||
doc.core_properties.title = title
|
||||
doc.core_properties.created = datetime.datetime.now()
|
||||
|
||||
# Default style
|
||||
style = doc.styles["Normal"]
|
||||
font = style.font
|
||||
font.name = FONT_FALLBACK_EN
|
||||
font.size = Pt(10)
|
||||
font.color.rgb = RGBColor(*COLOR_TEXT)
|
||||
|
||||
# Title
|
||||
heading = doc.add_heading(title, level=0)
|
||||
for run in heading.runs:
|
||||
run.font.color.rgb = RGBColor(*COLOR_PRIMARY)
|
||||
|
||||
if subtitle:
|
||||
p = doc.add_paragraph(subtitle)
|
||||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
for run in p.runs:
|
||||
run.font.color.rgb = RGBColor(*COLOR_SECONDARY)
|
||||
run.font.size = Pt(12)
|
||||
|
||||
# Tagline footer
|
||||
p = doc.add_paragraph(f"{BRAND_NAME} — {TAGLINE}")
|
||||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
for run in p.runs:
|
||||
run.font.size = Pt(8)
|
||||
run.font.color.rgb = RGBColor(*COLOR_SECONDARY)
|
||||
|
||||
doc.add_paragraph("") # spacer
|
||||
return doc
|
||||
|
||||
|
||||
def add_section_heading(doc: Document, text: str, level: int = 1) -> None:
|
||||
"""Add a branded section heading."""
|
||||
heading = doc.add_heading(text, level=level)
|
||||
for run in heading.runs:
|
||||
run.font.color.rgb = RGBColor(*COLOR_PRIMARY)
|
||||
|
||||
|
||||
def add_bilingual_heading(
|
||||
doc: Document, en_text: str, kr_text: str, level: int = 2
|
||||
) -> None:
|
||||
"""Add a bilingual heading (English + Korean subtitle)."""
|
||||
heading = doc.add_heading(en_text, level=level)
|
||||
for run in heading.runs:
|
||||
run.font.color.rgb = RGBColor(*COLOR_PRIMARY)
|
||||
p = doc.add_paragraph(kr_text)
|
||||
for run in p.runs:
|
||||
run.font.color.rgb = RGBColor(*COLOR_SECONDARY)
|
||||
run.font.size = Pt(10)
|
||||
|
||||
|
||||
def save_doc(doc: Document, output_path: str | Path) -> Path:
|
||||
"""Save document and return the path."""
|
||||
output_path = Path(output_path)
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
doc.save(str(output_path))
|
||||
return output_path
|
||||
71
custom-skills/_dintel-shared/src/dintel/excel.py
Normal file
71
custom-skills/_dintel-shared/src/dintel/excel.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""Excel utilities for D.intelligence branded spreadsheets."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||
|
||||
from dintel.brand import (
|
||||
BRAND_NAME,
|
||||
HEX_PRIMARY,
|
||||
HEX_SECONDARY,
|
||||
HEX_ACCENT,
|
||||
HEX_TEXT,
|
||||
)
|
||||
|
||||
# ── Style Constants ─────────────────────────────────────────────
|
||||
HEADER_FILL = PatternFill(start_color=HEX_PRIMARY.lstrip("#"), end_color=HEX_PRIMARY.lstrip("#"), fill_type="solid")
|
||||
HEADER_FONT = Font(name="Arial", size=10, bold=True, color="FFFFFF")
|
||||
SUBHEADER_FILL = PatternFill(start_color=HEX_SECONDARY.lstrip("#"), end_color=HEX_SECONDARY.lstrip("#"), fill_type="solid")
|
||||
SUBHEADER_FONT = Font(name="Arial", size=10, bold=True, color="FFFFFF")
|
||||
ACCENT_FONT = Font(name="Arial", size=10, bold=True, color=HEX_ACCENT.lstrip("#"))
|
||||
BODY_FONT = Font(name="Arial", size=10, color=HEX_TEXT.lstrip("#"))
|
||||
THIN_BORDER = Border(
|
||||
left=Side(style="thin"),
|
||||
right=Side(style="thin"),
|
||||
top=Side(style="thin"),
|
||||
bottom=Side(style="thin"),
|
||||
)
|
||||
CENTER_ALIGN = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
LEFT_ALIGN = Alignment(horizontal="left", vertical="center", wrap_text=True)
|
||||
RIGHT_ALIGN = Alignment(horizontal="right", vertical="center")
|
||||
|
||||
|
||||
def create_branded_workbook(title: str = "D.intelligence") -> Workbook:
|
||||
"""Create an openpyxl Workbook with brand defaults."""
|
||||
wb = Workbook()
|
||||
wb.properties.title = title
|
||||
wb.properties.creator = BRAND_NAME
|
||||
return wb
|
||||
|
||||
|
||||
def style_header_row(ws, row: int = 1, col_start: int = 1, col_end: int = 10) -> None:
|
||||
"""Apply header styling to a row."""
|
||||
for col in range(col_start, col_end + 1):
|
||||
cell = ws.cell(row=row, column=col)
|
||||
cell.fill = HEADER_FILL
|
||||
cell.font = HEADER_FONT
|
||||
cell.alignment = CENTER_ALIGN
|
||||
cell.border = THIN_BORDER
|
||||
|
||||
|
||||
def style_body_cell(cell, align: str = "left") -> None:
|
||||
"""Apply body styling to a cell."""
|
||||
cell.font = BODY_FONT
|
||||
cell.border = THIN_BORDER
|
||||
if align == "center":
|
||||
cell.alignment = CENTER_ALIGN
|
||||
elif align == "right":
|
||||
cell.alignment = RIGHT_ALIGN
|
||||
else:
|
||||
cell.alignment = LEFT_ALIGN
|
||||
|
||||
|
||||
def save_workbook(wb: Workbook, output_path: str | Path) -> Path:
|
||||
"""Save workbook and return the path."""
|
||||
output_path = Path(output_path)
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
wb.save(str(output_path))
|
||||
return output_path
|
||||
50
custom-skills/_dintel-shared/src/dintel/notion.py
Normal file
50
custom-skills/_dintel-shared/src/dintel/notion.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""Notion database IDs and helper constants for D.intelligence."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
# ── Database IDs ────────────────────────────────────────────────
|
||||
DB_TASKS_DASHBOARD = "2c0581e58a1e816d9948c3f3591c372c"
|
||||
DB_CLIENT_REFERENCE = "f0508d67b26042c1a0c7f2283f87eab4"
|
||||
DB_JHR = "529587363fe04a8da588337e8eb1aa0b"
|
||||
DB_SLA = "1e0581e58a1e80e28802d19bf8d468c7"
|
||||
DB_JAM = "4d76fb5bb4134e81883c21a8c4aa80c1"
|
||||
|
||||
# ── Collection IDs ──────────────────────────────────────────────
|
||||
COLLECTION_TASKS = "2c0581e5-8a1e-8178-aa9a-000b44537e0a"
|
||||
COLLECTION_CLIENT_REF = "b8ddab91-d3a7-4b84-86d7-35e46711598c"
|
||||
COLLECTION_JHR = "931a663c-4b76-4903-858c-f801b973a1aa"
|
||||
COLLECTION_SLA = "1e0581e5-8a1e-8070-96b0-000bd2aacc88"
|
||||
COLLECTION_JAM = "9f183ecb-9364-410e-91a7-a41a20455272"
|
||||
|
||||
# ── Related Collections ─────────────────────────────────────────
|
||||
COLLECTION_CLIENT_DB = "ac212daf-4eda-4a99-8c97-89699c846331"
|
||||
COLLECTION_DAILY_WORK = "2ef581e5-8a1e-80b9-81cb-000b121910d3"
|
||||
COLLECTION_GDRIVE_FILES = "2d0581e5-8a1e-8096-8577-000b5152a9f2"
|
||||
|
||||
# ── Task Status Options ─────────────────────────────────────────
|
||||
TASK_STATUSES = [
|
||||
"Not Started", "Planning", "In Progress", "In Review",
|
||||
"Waiting", "Done", "On Hold", "Archived",
|
||||
]
|
||||
|
||||
# ── Priority Codes ──────────────────────────────────────────────
|
||||
PRIORITY_CODES = [
|
||||
"A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3",
|
||||
]
|
||||
|
||||
# ── Client Codes for Notion ─────────────────────────────────────
|
||||
NOTION_CLIENT_CODES = ["JHR", "JAM", "SLA", "SHR", "OurDigital"]
|
||||
|
||||
# ── Service Lines ───────────────────────────────────────────────
|
||||
SERVICE_LINES = [
|
||||
"SEO", "Local SEO", "Digital Ads", "Content Marketing",
|
||||
"Growth Package", "AI Literacy", "Data Literacy",
|
||||
"Data Analytics", "GTM/Tagging", "Web Dev",
|
||||
]
|
||||
|
||||
# ── DB Mapping (client code → database ID) ──────────────────────
|
||||
CLIENT_DB_MAP = {
|
||||
"JHR": DB_JHR,
|
||||
"JAM": DB_JAM,
|
||||
"SLA": DB_SLA,
|
||||
}
|
||||
Reference in New Issue
Block a user