Backend no longer emits the 'break' state (see web-backend
de8adae). Remove the matching entry from STATE_COLORS and the
.ao-card-dot.break CSS rule. Safe because AgentCard's unknown-state
fallback (DEFAULT_STATE_COLOR) handles any stray legacy value.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Old code assumed result_data was a JSON string and ran JSON.parse on it,
falling back to returning the value verbatim on parse error. When the
backend ships result_data as a dict (e.g. compose tasks return
{music_task_id, tracks}), JSON.parse threw, the catch returned the raw
object, and React threw error #31 'Objects are not valid as a React
child' the moment the user expanded the task row.
Extract formatResultData helper: object → JSON.stringify, JSON string
→ parse then pretty-print, plain string → as-is.
Regression tests cover all three input shapes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Backend returns {"tasks": [...]} and {"logs": [...]} but TaskTab and
LogTab stored the raw object and called .map on it, throwing
'l.map is not a function' the moment a user opened the Tasks or
Logs tab. Unwrap via Array.isArray check (also covers theoretical
bare-array responses).
Regression test for TaskTab covers all three response shapes:
wrapped object, bare array, and empty.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace fixed 3s reconnect with exponential backoff
(1s/2s/4s/8s/16s/30s, capped). Reduces console noise when
upstream WebSocket is blocked (e.g. DSM reverse proxy without
WS upgrade headers).
- ws.onerror swallowed (onclose still schedules reconnect) so the
browser stops printing an unhandled-error pair per attempt.
- Expose reconnectAttempt in hook; TopBar shows 'Connecting…'
pre-first-attempt and 'Disconnected · 재연결 시도 #N' after.
Root cause of WS failure is upstream (curl proves the endpoint
itself is fine — see DSM reverse proxy WebSocket headers).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ffmpeg libwebp quality=85 compression_level=6.
Total: 11.8MB → 875KB (~11MB saved). Visually indistinguishable on
the card grid at the 9:16 image aspect.
PNG removals were already staged in the previous CommandTab commit;
this commit adds the 6 .webp replacements and points constants.js
imports at .webp.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously connect's onclose handler referenced connect itself before
the useCallback declaration, triggering react-hooks/immutability. Hold
the latest connect in a ref (updated in useEffect) and call through it
on reconnect. Same runtime behavior, lint-clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Was hardcoded #22c55e (green) regardless of actual state, making
error/break states look healthy. Switch to muted #94a3b8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Approval card gated on 'waiting_approval' (was 'waiting'), matching
the state useAgentManager emits — previously the approval UI was
silently suppressed and pendingTask buttons unreachable
- QUICK_ACTIONS/PARAM_ACTIONS: drop blog (agent removed),
add insta (extract / collect_trends / render)
- Regression test covers the three approval-card branches
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
문제:
- 페이지 1~10 미리보기가 가로 overflow인데 시각 affordance 없어서 page 2~10 못 봄
- 슬레이트 목록(.ic-slates-grid)이 모바일에서 어색 + 카드 자체가 viewport 밖으로 밀림
수정:
- PagesStrip 컴포넌트 신설: 좌/우 chevron + page 인디케이터(3/10) + 양옆 fade gradient
+ 키보드 ←/→ + scroll-snap + 클릭 페이지 이동 + 활성 카드 핑크 테두리/scale
- .ic-page-img width를 clamp(140px, 42vw, 220px)로 viewport 비례
- .ic-slates-grid 모바일 2칸 강제, 640px+ 부터 auto-fill
- .ic-detail에 min-width: 0 + max-width: 100% (자식이 부모 안 밀게)
- .ic-layout grid-template-columns에 minmax(0, 1fr) — 자식 overflow 시 부모 안정
- .ic 모바일 좌우 padding 12px (768px+ 16px)
- Card image aspect-ratio 1/1 → 941/1672 (real image ratio, no crop)
- object-fit cover → contain (defensive against rounding)
- Drop card aspect-ratio so it grows from natural image+name height
- Drop grid max-width 720px so grid fills the viewport width
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 PNGs for 5 active agents + 1 shared placeholder. Required by
constants.js imports; without these the build resolves them from
local disk but a clean clone or NAS deploy would 404.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds two tests verifying that working state adds the pulse class and
idle state does not. Pulse animation is part of the design spec §5
but was not covered by the original 8 tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- state→color mapping via STATE_COLORS
- notification badge with 9+ overflow
- active prop for selected card border
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eliminates dual-write drift risk between ACTIVE_AGENT_IDS list
and GRID_SLOTS slot ordering. Single source of truth is now
GRID_SLOTS; ACTIVE_AGENT_IDS is computed from it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 5 active agents (stock/music/insta/realestate/lotto) + 4 placeholders
- AGENT_META, GRID_SLOTS, STATE_COLORS in single constants module
- blog removed (replaced by insta)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trends 탭의 🎴 버튼 클릭이 silent로 끝나 사용자에게 무동작처럼 보이던
이슈 fix. handleCreateSlate를 3초 간격 폴링으로 확장 (최대 8분):
- 시작/진행/성공/실패 상단 배너로 시각화
- 카드 생성 완료 시 자동으로 Cards 탭 전환 + 새 슬레이트 자동 선택
→ SlateDetail이 카피·이미지 미리보기 즉시 표시
- 실패 시 에러 메시지 + 클릭으로 dismiss
- "Claude 카피 추론 + Playwright 카드 10장 생성 중 (3~7분)" 안내 문구
Single big task (Task 1) for atomic mv + load_dotenv update +
new CLAUDE.md/start.bat + verification. Task 2 = user manual
push + 30-min runtime verification.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lab 네이밍 정책 (feedback_lab_naming.md) 에 따라 정식 서비스 graduation.
디렉토리/컨테이너/환경변수 갱신, API URL/Python import/DB 파일명은 그대로.
Confidence Signal Pipeline V2 Phase 1 작업 시작 전 선행.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
확신의 신호 파이프라인 V2. 4 서비스 분담:
- stock-lab: 가치 발굴 (8 노드 + ATR)
- web-ai (Windows GPU): 시점 분석 (LSTM + KIS 분봉/NXT + 분봉 모멘텀)
- agent-office: Claude 2차 검증 + 이중 텔레그램 (본인 풀 / 아내 간소화)
- web-ui: 캔버스 settings 편집
6 핵심 결정: pull 채널, KIS 직접, Claude context augmentation, 매수+매도,
양쪽 메시지 단일 콜 생성, 시간대별 폴링.
Phase 1-7 분해 (총 10-12주), backlog, 위험 매트릭스, NOT 범위 명시.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
기존 articles 테이블 재사용 + 종목명 substring 매핑. Naver 차단/중복
인프라 해소, LLM 입력에 summary 포함. weight=0 유지 (검증 전 차단),
news_sentiment.source 컬럼 추가 (Phase 2 비교 baseline).
선행 review (adversarial)에서 가장 강한 비판: "이미 매일 수집 중인
articles 테이블을 무시하고 Naver를 100번 더 긁는 중복" → 해소.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>