(() => { 'use strict'; const $ = (selector) => document.querySelector(selector); const openButton = $('#gitea-workflow-open'); const panel = $('#gitea-workflow-panel'); const root = $('#gitea-workflow-root'); const status = $('#gitea-workflow-status'); const refreshButton = $('#gitea-workflow-refresh'); const closeButton = $('#gitea-workflow-close'); if (!openButton || !panel || !root) return; const SYSTEM_AUDIT_ACTOR = 'system'; const SYSTEM_AUDIT_REASON = 'cc-web 管理页自动操作'; let overview = null; let loading = false; function escapeHtml(value) { return String(value == null ? '' : value) .replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>') .replaceAll('"', '"').replaceAll("'", '''); } function token() { return localStorage.getItem('cc-web-token') || ''; } function api(path, init = {}) { const headers = { ...(init.body ? { 'Content-Type': 'application/json' } : {}), ...(init.headers || {}) }; if (token()) headers.Authorization = `Bearer ${token()}`; return fetch(path, { ...init, headers }).then(async (response) => { const data = await response.json().catch(() => ({})); if (!response.ok) throw Object.assign(new Error(data.message || data.code || `HTTP ${response.status}`), { response, data }); return data; }); } function stateLabel(task) { return task.stateLabel || ({ queued: '排队中', preparing: '准备中', running: '运行中', waiting_user: '等待用户', verifying_reply: '核验回帖', retry_wait: '等待重试', blocked_workspace: '工作区阻塞', aborting: '中止中', succeeded: '已完成', succeeded_with_rest_fallback: '已完成(REST 兜底)', failed: '失败', failed_reply: '回帖失败', cancelled: '已取消', aborted: '已中止' }[task.state] || task.state); } function date(value) { if (!value) return '—'; const parsed = new Date(value); return Number.isNaN(parsed.getTime()) ? escapeHtml(value) : escapeHtml(parsed.toLocaleString()); } function actionLabel(value) { const labels = { 'admin.pause': '暂停工作流', 'admin.resume': '恢复工作流', 'admin.enable': '启用仓库', 'admin.disable': '停用仓库', 'admin.cancel': '取消排队', 'admin.abort': '中止 Turn', 'admin.configuration_updated': '更新配置', }; return labels[value] || String(value || '工作流操作').replace(/^admin\./, ''); } function systemAuditFields(requestId = '') { const payload = { actor: SYSTEM_AUDIT_ACTOR, reason: SYSTEM_AUDIT_REASON, }; if (requestId) payload.requestId = requestId; return payload; } function actionButtonLabel(paused) { return paused ? '恢复全局' : '暂停全局'; } function render() { const data = overview || { summary: {}, control: {}, repositories: [], tasks: [], audits: [], logs: [] }; const control = data.control || {}; const summary = data.summary || {}; const paused = !!control.globalPaused; const repositories = Array.isArray(data.repositories) ? data.repositories : []; const tasks = Array.isArray(data.tasks) ? data.tasks : []; const audits = Array.isArray(data.audits) ? data.audits : []; const logs = Array.isArray(data.logs) ? data.logs : []; const settings = data.settings || {}; root.innerHTML = `
${!data.available ? '| 仓库 | 状态 | 工作区 | 脏目录原因 | 队列 | 操作 |
|---|---|---|---|---|---|
| ${escapeHtml(repo.owner ? `${repo.owner}/${repo.name}` : repo.repoKey)} ${escapeHtml(repo.repoKey)} | ${repo.enabled ? '启用' : '停用'} | ${escapeHtml(repo.workspacePath || '—')} | ${repo.dirty ? escapeHtml(repo.dirtyReason || '检测到未提交修改或冲突') : '—'} | ${Number(repo.queuedCount || 0)} | |
| 暂无仓库记录 | |||||
| 任务 / 资源 | 状态 | Turn | 脏目录原因 | 更新时间 | 操作 |
|---|---|---|---|---|---|
| ${escapeHtml(task.taskId || '—')} ${escapeHtml(task.resourceKey || task.repoKey || '—')} | ${escapeHtml(stateLabel(task))}${task.errorMessage ? ` ${escapeHtml(task.errorMessage)}` : ''} | ${escapeHtml(task.turnId || '—')} ${escapeHtml(task.turnState || '—')} | ${escapeHtml(task.dirtyReason || '—')} | ${date(task.updatedAt || task.turnUpdatedAt || task.createdAt)} | ${task.state === 'queued' || task.state === 'waiting_user' ? `` : ''}${task.state === 'running' || task.state === 'preparing' || task.state === 'aborting' ? `` : ''} |
| 暂无任务记录 | |||||
| 时间 | 动作 | 任务 / 仓库 |
|---|---|---|
| ${date(entry.timestamp)} | ${escapeHtml(actionLabel(entry.action))} | ${escapeHtml(entry.taskId || entry.repoKey || '—')} |
| 暂无记录 | ||