Compare commits

..

2 Commits

Author SHA1 Message Date
cfdaily 792e27e757 Revert "[moz] fix(api): flake8 lint 修复 — 移除未使用 import"
CI / lint (pull_request) Failing after 8s
CI / test (pull_request) Has been skipped
CI / notify-on-failure (pull_request) Successful in 2s
This reverts commit c08b891c42.
2026-06-14 15:20:03 +08:00
cfdaily 1c5415490b [moz] feat(frontend): 新增工具链 Tab — 列表+详情+搜索栏 2026-06-14 15:20:03 +08:00
8 changed files with 21 additions and 34 deletions
+3 -23
View File
@@ -62,30 +62,12 @@ jobs:
(echo '=== RETRY WITH VERBOSE ===' && \
PYTHONPATH=$(pwd) /tmp/ci-venv-test/bin/pytest tests/ -m "not e2e" -x -v 2>&1 | tail -30)
# ── Job 3: Frontend Build ───────────────────────────
frontend:
runs-on: macos-arm64
needs: lint
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install & Build
run: |
cd src/frontend
npm ci || npm install
npm run build
# ── Job 4: CI 失败通知 ───────────────────────────────
# ── Job 3: CI 失败通知 ───────────────────────────────
# 使用 needs.<job>.result 直接判断,不查询 commit status API
# 根因:notify 自身的 pending status 会污染 commit status 查询结果(竞态条件)
notify-on-failure:
runs-on: macos-arm64
needs: [lint, test, frontend]
needs: [lint, test]
if: always()
steps:
- name: Check results and notify
@@ -93,13 +75,12 @@ jobs:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
LINT_RESULT: ${{ needs.lint.result }}
TEST_RESULT: ${{ needs.test.result }}
FRONTEND_RESULT: ${{ needs.frontend.result }}
run: |
echo "Lint result: $LINT_RESULT"
echo "Test result: $TEST_RESULT"
# 只有 lint 或 test 明确失败时才发通知
if [ "$LINT_RESULT" = "failure" ] || [ "$TEST_RESULT" = "failure" ] || [ "$FRONTEND_RESULT" = "failure" ]; then
if [ "$LINT_RESULT" = "failure" ] || [ "$TEST_RESULT" = "failure" ]; then
echo "CI has failures, sending notification..."
# 如果是 PR 事件,写评论通知
@@ -109,7 +90,6 @@ jobs:
FAILED_JOBS=""
[ "$LINT_RESULT" = "failure" ] && FAILED_JOBS="${FAILED_JOBS}lint "
[ "$TEST_RESULT" = "failure" ] && FAILED_JOBS="${FAILED_JOBS}test "
[ "$FRONTEND_RESULT" = "failure" ] && FAILED_JOBS="${FAILED_JOBS}frontend "
curl -sf -X POST \
-H "Authorization: token $GITEA_TOKEN" \
+9 -1
View File
@@ -110,7 +110,15 @@ jobs:
PR_AUTHOR=$(curl --max-time 5 -sf \
-H "Authorization: token $GITEA_TOKEN" \
"$API_URL/repos/$REPO/pulls?state=closed&sort=updated&order=desc&limit=10" | \
python3 -c "import json,sys; sha='$COMMIT_SHA'; matches=[pr['user']['login'] for pr in json.load(sys.stdin) if (pr.get('merge_commit_sha','') or '').startswith(sha) or sha.startswith(pr.get('merge_commit_sha','') or '')]; print(matches[0] if matches else '')" 2>/dev/null || echo "")
python3 -c "
import json, sys
sha = '$COMMIT_SHA'
for pr in json.load(sys.stdin):
merge_sha = pr.get('merge_commit_sha', '') or ''
if merge_sha.startswith(sha) or sha.startswith(merge_sha):
print(pr['user']['login'])
break
" 2>/dev/null || echo "")
# 确定通知对象
if [ -n "$PR_AUTHOR" ]; then
+2 -2
View File
@@ -1,5 +1,6 @@
"""共享 helper 和常量"""
from pathlib import Path
from typing import Any, Dict
from fastapi import HTTPException
@@ -55,8 +56,7 @@ def _init_agent_ids():
if _KNOWN_AGENT_IDS:
return
try:
import yaml
import os
import yaml, os
cfg_path = os.path.join(os.path.dirname(__file__), "..", "..", "config", "default.yaml")
with open(cfg_path) as f:
cfg = yaml.safe_load(f)
+1
View File
@@ -19,6 +19,7 @@ from src.api.shared import (
_bb,
_q,
_task_to_dict,
_validate_project,
_extract_mentions,
)
+1 -1
View File
@@ -208,7 +208,7 @@ class Blackboard:
params.append(parent_task)
if conditions:
query += " WHERE " + " AND ".join(conditions)
query += " ORDER BY priority ASC, created_at DESC"
query += " ORDER BY priority ASC, created_at ASC"
rows = conn.execute(query, params).fetchall()
return [Task.from_row(r) for r in rows]
finally:
+2
View File
@@ -17,6 +17,7 @@ import CourtCeremony from './components/CourtCeremony';
import CourtDiscussion from './components/CourtDiscussion';
import UsagePanel from './components/UsagePanel';
import SettingsPanel from './components/SettingsPanel';
import ToolchainPanel from './components/ToolchainPanel';
import GlobalSearch from './components/GlobalSearch';
import NotificationCenter from './components/NotificationCenter';
@@ -100,6 +101,7 @@ export default function App() {
usage: <UsagePanel />,
morning: <MorningPanel />,
settings: <SettingsPanel />,
toolchain: <ToolchainPanel />,
};
return (
@@ -5,7 +5,6 @@
import { useState, useCallback } from 'react';
import { api, AgentsStatusData } from '../api';
import ToolchainPanel from './ToolchainPanel';
interface ServiceCheckResult {
name: string;
@@ -16,7 +15,7 @@ interface ServiceCheckResult {
}
export default function SettingsPanel() {
const [tab, setTab] = useState<'connections' | 'security' | 'version' | 'logs' | 'toolchain'>('connections');
const [tab, setTab] = useState<'connections' | 'security' | 'version' | 'logs'>('connections');
// 接线状态巡检
const [checking, setChecking] = useState(false);
@@ -96,7 +95,6 @@ export default function SettingsPanel() {
{ key: 'security' as const, label: '🛡️ 安全防务' },
{ key: 'version' as const, label: '📦 版本更新' },
{ key: 'logs' as const, label: '📋 城防日志' },
{ key: 'toolchain' as const, label: '⛓️ 工具链' },
].map((t) => (
<button key={t.key} className={`btn ${tab === t.key ? 'btn-primary' : ''}`} onClick={() => setTab(t.key)}>
{t.label}
@@ -290,9 +288,6 @@ export default function SettingsPanel() {
</div>
</div>
)}
{/* ========== 工具链 ========== */}
{tab === 'toolchain' && <ToolchainPanel />}
</div>
);
}
+2 -1
View File
@@ -120,7 +120,7 @@ export function isArchived(t: Task): boolean {
export type TabKey =
| 'tasks' | 'court' | 'monitor' | 'agents'
| 'models' | 'skills' | 'sessions' | 'archives' | 'templates'
| 'usage' | 'settings' | 'officials' | 'morning' | 'mail';
| 'usage' | 'settings' | 'officials' | 'morning' | 'mail' | 'toolchain';
export const TAB_DEFS: { key: TabKey; label: string; icon: string }[] = [
{ key: 'tasks', label: '任务看板', icon: '📜' },
@@ -135,6 +135,7 @@ export const TAB_DEFS: { key: TabKey; label: string; icon: string }[] = [
{ key: 'archives', label: '奏折阁', icon: '📜' },
{ key: 'morning', label: '早朝简报', icon: '🌅' },
{ key: 'templates', label: '任务模板', icon: '📋' },
{ key: 'toolchain', label: '工具链', icon: '⛓️' },
{ key: 'settings', label: '系统设置', icon: '⚙️' },
];