import { useEffect, useState } from 'react'; import { fetchRoomSkillSettings, fetchRuntimeInventory, updateRoomSkillSetting, type RuntimeAgentInventory, type RuntimeInventorySnapshot, type RuntimePathSnapshot, type RuntimeSkillDirSnapshot, type RoomSkillCatalogItem, type RoomSkillSettingUpdateInput, type RoomSkillSettingsSnapshot, } from './api'; import { SettingsSectionHeading } from './SettingsPanelChrome'; import './RuntimeInventorySettings.css'; function ExistsBadge({ exists }: { exists: boolean }) { return ( {exists ? '감지됨' : '없음'} ); } function PathRow({ item }: { item: RuntimePathSnapshot }) { return (
  • {item.label} {item.path}
  • ); } function SkillDirCard({ dir }: { dir: RuntimeSkillDirSnapshot }) { const preview = dir.skills.slice(0, 6); return (
    {dir.label} {dir.path}
    {dir.count} skills
    {preview.length === 0 ? (

    표시할 SKILL.md 없음

    ) : ( )} {dir.count > preview.length ? ( 외 {dir.count - preview.length}개 더 있음 ) : null}
    ); } function AgentInventoryCard({ title, inventory, }: { title: string; inventory: RuntimeAgentInventory; }) { return (

    {title}

    MCP {inventory.mcp.ejclawConfigured ? '연결' : '미감지'}

    MCP servers {inventory.mcp.serverCount}개 · EJClaw section{' '} {inventory.mcp.ejclawConfigured ? '있음' : '없음'}

    {inventory.skillDirs.map((dir) => ( ))}
    ); } function agentLabel(agentType: 'claude-code' | 'codex') { return agentType === 'codex' ? 'Codex' : 'Claude Code'; } function RoomSkillPolicyCard({ onToggle, savingKey, snapshot, }: { onToggle: (input: RoomSkillSettingUpdateInput) => void; savingKey: string | null; snapshot: RoomSkillSettingsSnapshot | null; }) { if (!snapshot) { return (

    방별 스킬 정책

    방별 스킬 정책을 불러오는 중…

    ); } const catalogById = new Map( snapshot.catalog.map((skill) => [skill.id, skill]), ); const roomPreview = snapshot.rooms.slice(0, 8); return (

    방별 스킬 정책

    전역 설정은 읽기 전용입니다. 이 목록은 다음 토글 PR에서 방 단위 enable/disable 대상으로 쓰입니다.

    {snapshot.catalog.length} skills · {snapshot.rooms.length} rooms
    {roomPreview.length === 0 ? (

    등록된 방이 없습니다.

    ) : (
    {roomPreview.map((room) => (
    {room.name} {room.folder}
    {room.jid}
    {room.agents.map((agent) => { const disabledNames = agent.disabledSkillIds .map((id) => catalogById.get(id)?.displayName ?? id) .slice(0, 3); const enabledIds = new Set(agent.effectiveEnabledSkillIds); return (
    {agentLabel(agent.agentType)} {agent.mode === 'all-enabled' ? '기본 전체 ON' : `${agent.disabledSkillIds.length}개 OFF`} 사용 {agent.effectiveEnabledSkillIds.length} / 가능{' '} {agent.availableSkillIds.length} {disabledNames.length > 0 ? ( OFF: {disabledNames.join(', ')} ) : null}
    {agent.availableSkillIds.map((skillId) => { const skill = catalogById.get(skillId); const key = `${room.jid}:${agent.agentType}:${skillId}`; return ( ); })}
    ); })}
    ))}
    )} {snapshot.rooms.length > roomPreview.length ? ( 외 {snapshot.rooms.length - roomPreview.length}개 방 더 있음 ) : null}
    ); } export function RuntimeInventorySettings() { const [snapshot, setSnapshot] = useState( null, ); const [roomSkillSnapshot, setRoomSkillSnapshot] = useState(null); const [error, setError] = useState(null); const [roomSkillError, setRoomSkillError] = useState(null); const [savingRoomSkillKey, setSavingRoomSkillKey] = useState( null, ); useEffect(() => { let cancelled = false; Promise.all([fetchRuntimeInventory(), fetchRoomSkillSettings()]) .then(([value, roomSkills]) => { if (cancelled) return; setSnapshot(value); setRoomSkillSnapshot(roomSkills); setError(null); }) .catch((err) => { if (cancelled) return; setError(err instanceof Error ? err.message : String(err)); }); return () => { cancelled = true; }; }, []); async function handleRoomSkillToggle(input: RoomSkillSettingUpdateInput) { const key = `${input.roomJid}:${input.agentType}:${input.skillId}`; setSavingRoomSkillKey(key); setRoomSkillError(null); try { const next = await updateRoomSkillSetting(input); setRoomSkillSnapshot(next); } catch (err) { setRoomSkillError(err instanceof Error ? err.message : String(err)); } finally { setSavingRoomSkillKey(null); } } return (
    {error ?

    {error}

    : null} {!snapshot ? (

    런타임 정보를 불러오는 중…

    ) : (
    Current service {snapshot.service.id} {snapshot.service.agentType} · session{' '} {snapshot.service.sessionScope}
    Project {snapshot.projectRoot} data {snapshot.dataDir}
    {roomSkillError ? (

    {roomSkillError}

    ) : null} { void handleRoomSkillToggle(input); }} savingKey={savingRoomSkillKey} snapshot={roomSkillSnapshot} />

    EJClaw bridge

    )}
    ); }