HAL AI 채팅룸 도입(0.3.0): 운영자 콘솔 오른쪽 패널에 통합 방(첫 탭 고정) + 모델별 개별 방, 모델 연결(로그인·OAuth PKCE·API 키, 비밀은 Vault), 모델별 고유 정보(이름·역할·특성), HAL 제어·감시 스킬 문서·도구 29종(읽기 즉시 / 쓰기·고위험은 제안 → 운영자 승인(재인증·3단계 확인)), 통합 방 규칙(@이름 지정, 모델→모델 자동 1회 전달), MCP stdio 서버(읽기 전용), 개발 지시 v0.3.0(Oz), docs/HAL-AI.md, VERSION_HISTORY 0.3.0 — test/hal-ai.test.mjs RED 0/11 → GREEN 11/11, 전체 26파일 182건 통과

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Claude Fable 5.1
2026-10-28 17:41:50 +00:00
parent 6bfde82c5e
commit ba3c5cb2f8
23 changed files with 1494 additions and 11 deletions
+14
View File
@@ -25,3 +25,17 @@ table{width:100%;border-collapse:collapse;background:#fff;border:1px solid var(-
body.login{display:grid;place-items:center;min-height:100vh}.login-box{background:#fff;border:1px solid var(--line);border-radius:12px;padding:24px;width:min(420px,94vw)}
@media (max-width:760px){.menu-btn{display:block}.side{position:fixed;left:-230px;top:48px;bottom:0;transition:left .2s;z-index:30;overflow:auto}.side.open{left:0}.main{padding:10px 12px}.top-right .muted{display:none}
table.r{display:block;border:0;background:none}table.r thead{display:none}table.r tr{display:block;background:#fff;border:1px solid var(--line);border-radius:var(--rad);margin-bottom:8px;padding:6px 10px}table.r td{display:flex;justify-content:space-between;gap:8px;border:0;padding:5px 0;flex-wrap:wrap}table.r td::before{content:attr(data-l);color:var(--mut);font-size:12px;min-width:70px}.kv{grid-template-columns:1fr}}
/* 0.3.0 AI 채팅룸 패널: 본문 오른쪽 고정, 너비 조절, 접기. 1100px 이하에서는 본문 아래 전체 너비. 상태는 글자+배지로 구분 */
.ai-panel{width:var(--ai-w,400px);min-width:280px;max-width:60vw;flex:0 0 auto;border-left:1px solid var(--line);background:#fff;display:flex;flex-direction:column;position:sticky;top:48px;height:calc(100vh - 48px);min-height:0}
.ai-panel.closed{display:none}.ai-resize{position:absolute;left:0;top:0;bottom:0;width:6px;cursor:col-resize;z-index:2}.ai-panel{position:sticky}.ai-panel>.ai-resize{position:absolute}.ai-panel{isolation:isolate}
.ai-head{border-bottom:1px solid var(--line);padding:6px 6px 0 10px}.ai-tabs{display:flex;flex-wrap:wrap;gap:2px}
.ai-tab{border:1px solid transparent;border-bottom:0;background:none;padding:6px 10px;border-radius:8px 8px 0 0;cursor:pointer;font-size:13px;color:var(--fg);text-decoration:none}.ai-tab.on{background:#e6edfb;color:var(--pri);font-weight:600;border-color:var(--line)}.ai-tab.fixed{font-weight:600}.ai-tab.off{color:var(--mut)}.ai-tab.add{color:var(--mut)}.ai-dot{color:var(--warn)}
.ai-status{padding:4px 10px;border-bottom:1px solid var(--line);font-size:12px;min-height:22px}
.ai-log{flex:1;overflow:auto;padding:8px 10px;display:flex;flex-direction:column;gap:8px;min-height:0}
.ai-msg{border:1px solid var(--line);border-radius:10px;padding:8px 10px;background:#fff;font-size:13px}.ai-msg header{margin-bottom:4px}.ai-msg.user{background:#e8effc;border-color:#b9cdf2}.ai-msg.assistant{background:#fff}.ai-msg.tool{background:#f7f9fc}.ai-msg.system{background:#fff7e6;border-color:#f0c36d}.ai-msg.failed{border-color:var(--bad)}.ai-msg.relay{border-style:dashed}
.ai-text{white-space:pre-wrap;word-break:break-word}.ai-tool{margin:4px 0;font-size:12px}.ai-result summary{cursor:pointer;font-size:12px}.ai-result .pre{max-height:200px}
.ai-proposal{border:1px solid var(--warn);background:#fff7e6;border-radius:8px;padding:8px;margin-top:6px}.ai-proposal.executed{border-color:var(--ok);background:#eef8f1}.ai-proposal.rejected,.ai-proposal.cancelled{border-color:var(--line);background:#f7f9fc}.ai-proposal.failed{border-color:var(--bad);background:#fdecea}
.ai-compose{border-top:1px solid var(--line);padding:8px 10px;display:flex;flex-direction:column;gap:6px}.ai-compose textarea{max-width:none;resize:vertical}.ai-compose-row{display:flex;gap:8px;align-items:center;justify-content:flex-end;flex-wrap:wrap}.ai-compose-row label{margin-right:auto;font-weight:400}
.badge.neutral{border-color:var(--line);color:var(--mut)}
@media (max-width:1100px){.shell{flex-wrap:wrap}.ai-panel{position:static;width:100%!important;max-width:none;height:60vh;border-left:0;border-top:1px solid var(--line)}.ai-resize{display:none}}