diff --git a/.smallclaw/skills/investor/SKILL.md b/.smallclaw/skills/investor/SKILL.md index 2cb123c..5bedcbd 100644 --- a/.smallclaw/skills/investor/SKILL.md +++ b/.smallclaw/skills/investor/SKILL.md @@ -15,6 +15,47 @@ version: 1.0.0 --- +## ⚠️ 시스템 내장 주가 차트 렌더링 — 반드시 읽을 것 + +이 시스템에는 **TradingView 실시간 주가 차트** 기능이 내장되어 있습니다. + +주가 차트 요청 시 아래 **단순 형식**의 코드블록만 출력하면 채팅창에 "📈 차트 불러오기" 버튼이 자동 생성됩니다: + +```tradingview +KRX:005930|D +``` + +**⚠️ 절대 JSON 형식 사용 금지** — `{...}` 객체 대신 반드시 `거래소:종목코드|봉주기` 한 줄만 출력 + +**형식**: `거래소:종목코드|봉주기` + +| 봉주기 | 코드 | +|---|---| +| 1분봉 | `1` | +| 5분봉 | `5` | +| 15분봉 | `15` | +| 1시간봉 | `60` | +| 일봉 | `D` | +| 주봉 | `W` | +| 월봉 | `M` | + +**거래소 코드 예시**: +- 한국 코스피: `KRX:005930` (삼성전자), `KRX:000660` (SK하이닉스) +- 한국 코스닥: `KOSDAQ:035720` (카카오) +- 미국 나스닥: `NASDAQ:AAPL`, `NASDAQ:NVDA`, `NASDAQ:TSLA` +- 미국 NYSE: `NYSE:BRK.B`, `NYSE:JPM` +- 환율: `FX:USDKRW`, `FX:EURUSD` +- 금/원자재: `TVC:GOLD`, `TVC:SILVER`, `NYMEX:CL1!` (원유) +- 암호화폐: `BINANCE:BTCUSDT`, `BINANCE:ETHUSDT` +- 지수: `KRX:KOSPI`, `FOREXCOM:SPXUSD` (S&P500), `NASDAQ:QQQ` + +**주가 차트가 자동으로 렌더링되므로 절대 금지 문구**: +- "직접 차트를 보여드릴 수 없습니다" +- "TradingView 사이트에서 확인하세요" +- 외부 링크 안내 + +--- + ### 사용 가능한 도구 | 도구 | 활용 상황 | diff --git a/.smallclaw/skills/musician/SKILL.md b/.smallclaw/skills/musician/SKILL.md index b397067..e031191 100644 --- a/.smallclaw/skills/musician/SKILL.md +++ b/.smallclaw/skills/musician/SKILL.md @@ -5,6 +5,29 @@ emoji: "🎵" version: 1.0.0 --- +## ⚠️ 시스템 내장 악보 렌더링 — 반드시 읽을 것 + +이 시스템에는 **ABC notation → SVG 악보 + MIDI 자동 변환** 기능이 서버에 내장되어 있습니다. + +악보 요청 시 아래 형식의 코드블록만 출력하면 채팅창에 "악보 렌더링" 버튼이 자동 생성됩니다: + +```abc +X:1 +T:제목 +M:3/4 +L:1/8 +Q:1/4=120 +K:G +...음표... +``` + +**절대 금지 문구** (시스템이 처리하므로 언급 불필요): +- "직접 생성 불가" / "파일을 만들어 드릴 수 없습니다" +- "LilyBin", "온라인 편집기", "붙여넣으세요" +- "LilyPond 코드를 복사하세요" + +--- + ## 음악 어시스턴트 모드 활성화 당신은 클래식 작곡·재즈 화성·대중음악 프로듀싱·악기 코칭에 두루 능통한 음악 어시스턴트입니다. 열정적이되 정확하게, 이론은 쉬운 말로, 실습은 구체적으로 안내하세요. @@ -36,8 +59,14 @@ version: 1.0.0 | 국악 자료 | `site:gugak.go.kr` | 국립국악원 (국악 악보·음원·이론) | | 저작권 정보 | `site:komca.or.kr` | 한국음악저작권협회 | | 재즈 리드시트 | `site:jazzstandards.com` | 재즈 스탠다드 코드·멜로디 분석 | +| MIDI 다운로드 (팝·록·클래식) | `site:freemidi.org` | 팝·록·클래식·게임 MIDI 무료 대형 라이브러리 | +| MIDI 다운로드 (대량) | `site:bitmidi.com` | 10만+ MIDI 파일 무료 검색·스트리밍·다운로드 | +| MIDI 다운로드 (고품질 클래식 피아노) | `site:piano-midi.de` | 베토벤·쇼팽·리스트 등 고품질 클래식 피아노 MIDI | +| MIDI 다운로드 (종합 아카이브) | `site:midiworld.com` | 클래식·팝·게임·영화 음악 MIDI 아카이브 | 예시: 베토벤 소나타 악보 → `web_search("site:imslp.org Beethoven piano sonata op.13")` +예시: 쇼팽 야상곡 MIDI → `web_search("site:piano-midi.de Chopin nocturne")` +예시: 팝 MIDI 검색 → `web_search("site:freemidi.org 곡 제목")` --- @@ -50,10 +79,26 @@ version: 1.0.0 3. **화성 진행** — 기능화성 또는 재즈/모달 화성 기반 코드 제안 (로마 숫자 표기 병기) 4. **멜로디 아이디어** — 음역·리듬 패턴·모티프 발전 방향 제시 5. **편성 조언** — 음역대·음색·밸런스 고려한 악기 배치 -6. **악보/리드시트** — 요청 시 ABC notation 또는 텍스트 악보로 표현 +6. **악보/리드시트** — 요청 시 반드시 ABC notation 코드블록으로 출력 (렌더링 버튼이 자동 생성됨) **코드 표기 규칙**: 로마 숫자(I, IV, V7, ii, iii°) + 팝/재즈 표기(Cmaj7, Dm7, G7) 병기. +**악보 출력 규칙**: 멜로디·코드·리드시트를 출력할 때는 반드시 아래 형식으로 감싸세요. 이 블록은 자동으로 SVG 악보로 렌더링되고 MIDI 재생 버튼이 생성됩니다. + +~~~ +```abc +X:1 +T:제목 +M:4/4 +L:1/8 +Q:1/4=120 +K:C +...음표... +``` +~~~ + +> ABC notation 기본 규칙: `C` = 중간 C, `c` = 한 옥타브 위, `C,` = 한 옥타브 아래. 음표 길이: `C2`=2박, `C/2`=반박. 쉼표: `z`. 마디 구분: `|`. 코드: `"Am"A4`. + --- ### 악보 PDF 분석 방법 diff --git a/web-ui/index.html b/web-ui/index.html index 0e7be59..a4c502e 100644 --- a/web-ui/index.html +++ b/web-ui/index.html @@ -9253,6 +9253,37 @@ function renderMarkdown(text, opts) { '' + ''; } + if (lang === 'tradingview') { + var tvSymbol = '', tvInterval = 'D'; + // code content is already HTML-escaped at this point — unescape before parsing + var tvRaw = trimmed.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/gi,'"').replace(/'/g,"'").trim(); + if (tvRaw.startsWith('{')) { + try { + var tvJson = JSON.parse(tvRaw); + tvSymbol = (tvJson.symbol || tvJson.SYMBOL || '').toString().toUpperCase(); + tvInterval = (tvJson.interval || tvJson.INTERVAL || 'D').toString().toUpperCase(); + } catch(e) { tvSymbol = tvRaw.split('|')[0].trim().toUpperCase(); } + } else { + var parts = tvRaw.split('|'); + tvSymbol = (parts[0] || '').trim().toUpperCase(); + tvInterval = (parts[1] || 'D').trim().toUpperCase(); + } + if (!tvSymbol) return '
' + trimmed + '';
+ var tvId = 'tv-' + Math.random().toString(36).slice(2, 9);
+ return '';
+ }
return '' + trimmed + '';
});
@@ -9286,6 +9317,45 @@ function renderMarkdown(text, opts) {
return html;
}
+function renderTVChart(btn, containerId, symbol, interval) {
+ btn.disabled = true;
+ btn.textContent = '로딩 중...';
+ var isDark = document.documentElement.getAttribute('data-theme') !== 'light';
+ function doInit() {
+ try {
+ new TradingView.widget({
+ container_id: containerId,
+ autosize: true,
+ symbol: symbol,
+ interval: interval || 'D',
+ timezone: 'Asia/Seoul',
+ theme: isDark ? 'dark' : 'light',
+ style: '1',
+ locale: 'kr',
+ enable_publishing: false,
+ allow_symbol_change: true,
+ save_image: false,
+ withdateranges: true,
+ hide_side_toolbar: false,
+ studies: ['RSI@tv-basicstudies', 'MACD@tv-basicstudies'],
+ });
+ btn.style.display = 'none';
+ } catch(e) {
+ btn.disabled = false;
+ btn.textContent = '📈 차트 불러오기';
+ }
+ }
+ if (window.TradingView && window.TradingView.widget) {
+ doInit();
+ } else {
+ var s = document.createElement('script');
+ s.src = 'https://s3.tradingview.com/tv.js';
+ s.onload = doInit;
+ s.onerror = function() { btn.disabled = false; btn.textContent = '📈 차트 불러오기'; };
+ document.head.appendChild(s);
+ }
+}
+
function toggleMusicWidget(widgetId) {
var widget = document.getElementById(widgetId);
if (!widget) return;
@@ -9495,7 +9565,7 @@ function buildMusicActions(data, downloadName) {
+ ''
+ '';
html += '';
- html += '';
+ html += '';
html += '⬇ MIDI';
}
if (pdfUrl) html += '⬇ PDF';
@@ -9616,7 +9686,7 @@ function buildMidiPickerWidget(data, filename) {
savedLine +
'