Separate skills state completely per user

- All skill toggles are now per-user (except multi-agent-orchestrator
  which remains global). Admin toggle without a target username defaults
  to their own per-user state instead of the global file.
- GET /api/skills defaults to the requesting user's own state (previously
  returned global state when no ?username= param was given).
- Add SkillsManager.initUserSkillsState(): creates per-user
  skills_state.json from global defaults if missing — called on user
  creation and on every login as a safety net for existing accounts.
- Create initial per-user skills_state.json for cherry and jasmine.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kim
2026-05-28 17:33:29 +09:00
co-authored by Claude Sonnet 4.6
parent 2d3e33b6b3
commit 22bfc3ac27
5 changed files with 66 additions and 33 deletions
+4 -4
View File
@@ -6917,7 +6917,7 @@ async function loadInstalledSkills() {
const el = document.getElementById('skills-list');
el.innerHTML = '<div style="padding:12px;color:var(--muted);font-size:11px"><span class="spinner"></span> Loading...</div>';
try {
const effectiveUser = skillsTargetUser || (currentUser?.role !== 'admin' ? currentUser?.username : null);
const effectiveUser = skillsTargetUser || currentUser?.username || null;
const url = effectiveUser ? `/api/skills?username=${encodeURIComponent(effectiveUser)}` : '/api/skills';
const data = await api(url);
const skills = data.skills || [];
@@ -6958,13 +6958,13 @@ async function toggleSkill(id) {
addProcessEntry('error', skillMeta.eligibleReason || 'This skill is currently unavailable.');
return;
}
// globalOnly 스킬은 per-user 모드에서 토글 불가
if (skillMeta?.globalOnly && (skillsTargetUser || currentUser?.role !== 'admin')) {
// globalOnly 스킬은 per-user 모드에서 토글 불가 (서버가 전역으로 처리)
if (skillMeta?.globalOnly && skillsTargetUser) {
addProcessEntry('error', `"${skillMeta.name}" 스킬은 글로벌 전용입니다.`);
return;
}
try {
const effectiveUser = skillsTargetUser || (currentUser?.role !== 'admin' ? currentUser?.username : null);
const effectiveUser = skillsTargetUser || currentUser?.username || null;
const body = effectiveUser ? JSON.stringify({ username: effectiveUser }) : undefined;
const res = await api(`/api/skills/${encodeURIComponent(id)}/toggle`, { method: 'POST', body });
if (!res.success) {