Nexus Agent
dfb0ea2d8f
fix(frontend): 脚本库与推送调度对齐设计文档
...
修复 ScriptsPage 执行契约(script_id/command、历史过滤、长任务/凭据)及 SchedulesPage 缺失能力(target_path、next_run、push/script、cron/once、sync_mode);后端补迁移与 schedule_runner 传参。
2026-06-08 02:39:18 +08:00
Nexus Agent
5ed3c28491
fix(sync): 推送异常时落库 failed,修复订正时区与卡住阈值
...
rsync 抛错时 sync_log 不再永久 running;reconcile 兼容 naive UTC。
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-08 02:14:33 +08:00
Nexus Agent
7ea94a60ab
fix(auth,servers): 修复 refresh 自动登出与服务器状态未知
...
API 返回 status 字段供前端显示在线状态;token_version 为 NULL 时 refresh cookie 含 :None 导致续期 401。
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-07 22:53:29 +08:00
Nexus Agent
05006cb5df
feat(auth): refresh token 先 Redis 后 MySQL 双写
...
登录 30 天会话 hash 持久化到 admin_refresh_tokens;启动从 MySQL 回填 Redis,
Redis 重启后会话仍可 refresh。
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-07 21:56:56 +08:00
Nexus Deploy
4ba45abf38
feat(servers): 凭据轮询登录与连接失败列表
...
- 密码/SSH密钥预设增加用户名;快速添加(IP)轮询全部预设尝试 SSH 登录
- 成功入 servers 列表;失败写入 pending_servers 并支持重试/删除
- 新增 credential_poller、try_ssh_login 与 add-by-ip/pending API
2026-06-06 20:08:48 +08:00
Your Name
78798e3630
feat(push): refactor B0-B6, /ws/sync channel, staging cleanup
...
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-02 08:14:09 +08:00
Your Name
928e3c5fdb
fix: 登录白名单 IP 绕过防暴破锁定
...
白名单内 IP 跳过失败次数锁定;失败仅审计不计数;成功登录清除该用户历史失败记录。
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-02 01:37:22 +08:00
Your Name
832e34fd98
fix: 修复 6 个 MEDIUM 级 Bug (锁定/重试/调度/分页/SSH池/token_version)
...
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-02 01:29:06 +08:00
Your Name
8311821590
fix: 全量修复批量选择、JWT 60min、script-callback 认证与心跳数据流
...
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-01 12:17:47 +08:00
Your Name
32feb1b6db
fix: 全站 ruff 清零 — 77 errors → 0
...
Fixes:
- F821: install.py site_url 未定义(NameError)、sync_v2.py os 未导入、script_jobs.py LOG f-string
- F401: 移除 22 个未使用导入(models/__init__.py、install.py、auth.py 等)
- B904: 20 个 except 块 raise 添加 from e/from None
- S110: 20 个有意的 try-except-pass 添加 noqa 注释(SSH清理/DDL幂等/WS断连)
- B007: 3 个未使用循环变量重命名(dirs→_dirs、server_id→_server_id)
- F541: 3 个无占位符 f-string 修正
- F841: auth.py 未使用 ip_address 变量移除
- S105: auth_service.py Redis key prefix 误报 noqa
- B023: script_execution_flush.py 循环变量绑定修复
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 20:07:45 +08:00
Your Name
84282e87ae
feat: servers list iteration — server-side pagination/search/sort/status filter
...
Backend:
- server_repo.py: get_paginated() adds search/sort_by/sort_order/is_online params
with whitelist-validated sorting and DB-level pagination
- servers.py: list_servers() adds search/sort_by/sort_order/is_online Query params
with Redis post-filter for is_online accuracy
- servers.py: fix all 12 pre-existing ruff errors (unused imports, B904, S110, F541)
- servers.py: fix F821 bug — agent_port undefined in upgrade_agent()
Frontend:
- servers.html: complete rewrite with server-side pagination, debounced search,
clickable column sorting, status filter dropdown, auto-refresh toggle,
keyboard shortcuts (↑↓/jk/Esc//r), CSV export, skeleton loading,
empty state with contextual hints, pagination controls (first/prev/nums/next/last)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 19:45:53 +08:00
Your Name
ad2e7667d3
Merge branch 'claude/condescending-ishizaka-3cff3a'
2026-05-28 21:02:09 +08:00
Your Name
82c297776a
feat: 推送页面 5 项迭代 — WS实时进度 + 分组选择 + 历史增强 + 文件操作 + 推送校验
...
F1: broadcast_sync_progress() + batch_id + 前端WS逐台更新
F2: get_paginated() platform_id/node_id + /categories端点 + 筛选下拉框
F4: _sync_log_to_dict() 补全字段 + diff_summary捕获 + 可展开详情面板
F7: /local-file-ops端点 + 文件管理器删除/重命名
F8: /verify端点 md5sum对比 + 推送后校验UI
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-28 21:01:27 +08:00
Your Name
867e2aa552
Merge branch 'claude/condescending-ishizaka-3cff3a'
...
# Conflicts:
# server/infrastructure/database/setting_repo.py
2026-05-26 21:58:38 +08:00
Your Name
ccb78ed980
feat: SSH key preset system — dropdown + backend auto-resolve
...
- Add SshKeyPreset model + repo (encrypted_private_key, public_key)
- Add ssh_key_preset_id to Server model + schemas
- Add CRUD + reveal API routes (/api/ssh-key-presets/)
- servers.py: auto-resolve ssh_key_preset_id → decrypt → set ssh_key_private
- servers.html: key preset dropdown in key auth section, hides path/textarea on select
- Mirror password preset pattern: zero frontend credential exposure
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2026-05-25 22:49:57 +08:00
Your Name
99201f48fd
fix: MissingGreenlet error — convert all middleware to pure ASGI
...
Root cause: BaseHTTPMiddleware.call_next() runs the endpoint in a
separate async task, which breaks SQLAlchemy's greenlet context.
After session.commit(), the connection is released to the pool.
When session.refresh() tries to acquire a new connection for a
SELECT, it fails with MissingGreenlet because the greenlet spawn
context is not available in the call_next() task.
Fix (two-part):
1. Convert all 4 middleware classes from BaseHTTPMiddleware to pure
ASGI middleware — eliminates call_next() entirely so the entire
request chain runs in the same async context.
2. Set expire_on_commit=False on the session factory — after commit,
objects retain their in-memory values instead of being expired.
This removes the need for session.refresh() entirely.
All session.refresh() calls removed from 11 repository files.
With expire_on_commit=False, post-commit attribute access no longer
triggers lazy loads that would also fail with MissingGreenlet.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2026-05-25 15:24:15 +08:00
Your Name
c72631a293
merge: 安装脚本+PHP移除+宝塔适配 合并到main
...
合并 claude/condescending-ishizaka-3cff3a 分支:
- deploy/install.sh: 一键安装脚本(宝塔/标准模式自适应)
- deploy/upgrade.sh + uninstall.sh
- docs/install-guide.md: 完整中文安装教程
- PHP完全移除: install.php删除, config.php→config.json
- crypto.py: 移除PHP AES-CBC兼容, 纯Fernet
- install.py: 宝塔Supervisor路径自适应, Fernet密钥生成
- install.html: Step 5宝塔/标准模式条件渲染
- 44个冲突文件使用worktree分支版本(全部最新代码)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2026-05-25 08:25:29 +08:00
Your Name
a1276f38ad
feat: 一键安装脚本 + PHP完全移除 + config.php→config.json
...
新增文件:
- deploy/install.sh: 7步一键安装(自动检测宝塔/标准模式)
- deploy/upgrade.sh: git pull + pip install + restart + 健康检查
- deploy/uninstall.sh: 停服务+删配置, 可选--purge删部署目录
- docs/install-guide.md: 完整中文安装教程(宝塔+手动)
核心改动:
- install.py: 宝塔Supervisor路径自适应, init-db返回bt_panel标记,
config.php→config.json, 移除PHP锁文件, 生成Fernet加密密钥
- install.html: Step 5根据btPanel显示不同Supervisor/Nginx/SSL指引
- crypto.py: 移除PHP AES-CBC兼容层, 纯Fernet加密
- 删除 web/install.php (1192行PHP, 功能已完全迁移到Python)
PHP清理:
- Nginx配置: config\.php→config\.json deny规则
- config.py/main.py/migrations.py: install.php注释→install wizard
- CLAUDE.md/AGENTS.md: config.php→config.json, 移除PHP引用
- firefox_server.py: login.php→login.html默认URL
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2026-05-25 08:23:37 +08:00
Your Name
cdd0be328a
fix: 六轮深度扫描 — 47项Bug修复、安全加固、死代码清理
...
Critical runtime bugs:
- terminal.html WebSSH完全不可用(URL前缀/JSON解析/Content-Type三处错误)
- servers.py路由遮蔽:/logs被/{id}拦截,3个前端页面同步日志查询失败
- scripts.html startExecPoll()→startExecPolling(),长任务快速执行崩溃
- agent.py {value!r!s:.50}格式串非法,agent发非数值时ValueError
- alerts.html d.daily.reduce()无null检查,API返回空数据时TypeError
Resource leak / stability:
- websocket.py僵尸连接未关闭TCP,文件描述符泄漏
- websocket.py _last_alert_time字典无限增长(加1小时过期清理)
- asyncssh_pool.py全忙时超过MAX_CONNECTIONS无限增长
- self_monitor.py Telegram告警无冷却,宕机时每30秒刷屏
- schedule_runner.py一次性调度执行超60秒会重复触发
- 限速脚本EXPIRE每次重置窗口可绕过(改用Lua原子脚本)
Security:
- JWT access token加token_version声明,改密码后旧token立失效(零宽限)
- INSTALL_MODE导入时常量→动态函数,安装后JWT认证不再残留禁用
- install.py /lock端点加管理员存在性验证,防止阻断安装
- ServerUpdate schema移除connectivity只读字段,防止伪造连接状态
Frontend fixes:
- doExec()缺r.ok检查、commands.html null检查
- _server_to_dict()补last_checked_at+ssh_key_public
- _field_match()逗号cron表达式修复
- alerts类型显示、SSH会话名称、搜索高亮定位
- 一次性/循环定时任务(run_mode+fire_at+自动禁用)
Dead code removed (400+ lines):
- SyncService batch_push/_push_single等5个方法(零调用者)
- 5个未使用schema(SyncCommands/SyncConfig/SyncSftp/FileDeploy/PaginatedResponse)
- 6个零调用service方法、3个无前端API端点
- 4个未使用import
Schema migrations:
- push_schedules: run_mode + fire_at列,cron_expr改NULL
- servers: 7个新列 + ssh_key_private/public VARCHAR(500)→TEXT
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2026-05-24 16:26:40 +08:00
Your Name
fbf5eadcf2
fix(security): R2+R3 全面代码审计修复 — 3 CRITICAL / 9 HIGH / 15 MEDIUM / 10 LOW
...
CRITICAL:
- C-1: sync_service.py rsync命令shlex.quote防Shell注入回归
- C-2: agent.py exec端点危险命令正则拦截+compare_digest+僵尸进程修复
- C-3: WebSSH JWT token绑定server_id防IDOR
HIGH:
- H-1: 所有PUT/POST端点setattr改为字段白名单防任意字段注入
- H-2: settings/assets/scripts端点添加JWT认证
- H-3: refresh_token invalidate-then-generate防并发重放
- H-4: servers.py Redis pipeline解决N+1查询
- H-7: settings API Key/Secret掩码+禁止修改
- H-8: TOTP暴力破解速率限制(5次/5分钟)
- H-9: get_optional_admin改用request-scoped session
MEDIUM:
- M-2: X-Real-IP优先+X-Forwarded-For取末值防IP伪造
- M-4: asyncssh异常信息脱敏(只含server_id)
- M-5: 分页limit上限(500/200/500/500)
- M-9: API层Redis依赖抽象至dependencies.py
- M-10: WebSocket ConnectionManager多worker Redis聚合
- M-13: login_attempts复合索引
- M-14: ServerRepository.get_by_ids批量查询
- M-15: API错误消息统一中文
R3追加:
- sysctl命令注入防护+regex验证
- $DB_PASS明文存储→masked_command双命令方案
- MYSQL_PWD环境变量替代-p flag
- health端点拆分(公开/需认证)
- repo层**kwargs→字段白名单
- 全局str(e)信息泄露修复(API/Telegram/WebSocket)
- SSRF私有IP拦截
- Nginx HTTPS配置+DB备份脚本
- 前端CDN SRI哈希+XSS修复
- __import__替换为正常import
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-24 10:58:33 +08:00
Your Name
9bba58a529
feat: Telegram test+ChatID, Agent IP allowlist/upgrade, alert history page
...
Telegram:
- POST /api/settings/telegram/test: send test message (checks token+chat_id)
- GET /api/settings/telegram/chats: call getUpdates, return up to 5 chats
- settings.html: test button + detect chat IDs with click-to-fill
Agent IP allowlist (web/agent/agent.py):
- allowed_ips config: list of trusted IPs/CIDRs from config.json
- _ip_allowed(): checks exact IP, CIDR (ipaddress module), hostname
- verify_api_key(): now checks IP allowlist before API key
- /health: also checks IP allowlist
- install.sh: auto-extracts central server IP from --url, adds to allowed_ips
Agent auto-upgrade (server/api/servers.py):
- POST /api/servers/{id}/upgrade-agent: SSH → curl new agent.py → systemctl restart
- servers.html: 升级 Agent button in Agent tab (only when online)
Alert history (new page):
- domain/models: AlertLog table (server_id, type, value, is_recovery, created_at)
- migrations.py: CREATE TABLE IF NOT EXISTS alert_logs
- websocket.py: _save_alert_log() called from broadcast_alert/recovery
- settings.py: GET /api/alert-history/ (paginated, filters), GET /stats
- main.py: register alert_history_router
- alerts.html: new page with stats cards, top-servers bar chart, alert list
- layout.js: 🔔 告警中心 added to sidebar nav
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-05-23 18:27:12 +08:00
Your Name
d414b945e1
feat: audit log time-range filter + script execution schedules
...
Audit log time-range filter:
- audit_log_repo.py: unified query() with action/admin_username/date_from/date_to
filters + total count; _build_filters() helper for date parsing
- settings.py GET /audit/: add date_from, date_to, admin_username query params
- audit.html: date range inputs (YYYY-MM-DD), admin filter input, action filter
expanded with optgroups (服务器/推送/脚本/认证/设置); clear filter button
Script execution schedules:
- domain/models: PushSchedule extended with schedule_type('push'|'script'),
script_id FK, script_content Text, exec_timeout int, long_task bool;
source_path made nullable
- migrations.py: 6 new ALTER TABLE statements (idempotent)
- schedule_runner.py: detect schedule_type; for 'script' type use ScriptService;
for 'push' type keep original SyncEngineV2 sync_files behaviour
- schemas.py: ScheduleCreate/Update add all new fields
- schedules.html: full UI rewrite
- type selector radio: 📁 文件推送 / ⚡ 脚本执行
- script fields: script library dropdown + textarea + timeout + long_task
- schedule list shows type badge + detail preview
- saveSched() validates required fields per type
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-05-23 17:29:16 +08:00
Your Name
d2832567c7
feat: push logs view in commands.html + paginated sync log API
...
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
sync_log_repo.py:
- get_all_paginated(): server_id/status/sync_mode/trigger_type filters +
server name JOIN + total count for pagination
server/api/servers.py GET /servers/logs:
- Add server_id/status/sync_mode/trigger_type/offset/limit query params
- Return {items, total, offset, limit} instead of plain list
web/app/commands.html (renamed title to '操作日志'):
- Third view: '推送日志' with paginated table
- Columns: 状态(dot badge) / 服务器 / 模式 / 触发方式 / 源路径 /
目标路径 / 文件数 / 耗时 / 操作人 / 开始时间
- Filters: 服务器 + 状态(success/failed/running) + 模式 (incremental/full/...)
- Pagination controls with prev/next page (50 per page)
- Error message in row title attribute (hover for details)
web/app/push.html:
- Update loadHistory() to handle new {items, total} response format
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-05-23 17:20:53 +08:00
Your Name
80d73d1b74
fix: WSL startup compatibility + dependency updates
...
- redis/client.py: use BlockingConnectionPool.from_url() (fixes 'url' kwarg error)
- database/engine_compat.py: patch aiomysql do_ping to satisfy pool_pre_ping
- database/session.py: apply engine_compat patch before create_async_engine
- requirements.txt: SQLAlchemy 2.0.49 (fixes aiomysql ping() reconnect signature)
- .env.example: document NEXUS_REDIS_URL format
- scripts/wsl_ensure_venv.sh: create project .venv (PEP 668 safe)
- scripts/wsl_start_dev.sh: use .venv python, validate Redis before start
- scripts/wsl_integration_smoke.sh: code-only verification mode
- scripts/wsl_check_mysql.py / bootstrap_database.py: MySQL setup helpers
- scripts/sync_frontend_vendor.py: vendor asset sync utility
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-05-23 15:27:18 +08:00
Your Name
752a24497c
feat: Phase 2 security audit fixes + script execution platform
...
Security (P0/P1/P2):
- WebSSH: dedicated short-lived token, server_id binding, 4003 close code
- Remove /api/agent/exec from control plane (RCE surface eliminated)
- Global JWT middleware (JwtAuthMiddleware) with install-mode bypass
- decrypt_value: failure returns None, never leaks ciphertext
- Telegram: sanitize_external_message strips sensitive fields
- Agent auth: startup enforces non-empty API key, compare_digest
- Credentials: password_set bool flag, no plaintext in API responses
- audit_log: writes admin_username + ip_address on all CUD ops
- Install lock: all /api/install/* except GET /status return 403 post-install
- WebSocket dedup: publish once, subscribers deliver locally
Script execution platform:
- script_jobs.py / script_job_callback.py: async batching and callback
- script_execution_store.py / script_callback_rate.py: Redis-backed state
- script_execution_flush.py: background flusher to MySQL
- scripts.html / script-executions.html: full execution UI
- agent_url.py: centralised URL builder
Frontend:
- All 13 pages migrated from CDN to /app/vendor/ (no external deps)
- vendor/: alpinejs, tailwindcss-browser, xterm, xterm-addon-*, qrious
- Dashboard WebSocket real-time alerts; 8h JWT session timeout
Tests:
- test_security_unit.py: 15 unit tests (JWT, sanitize, vendor, install 403)
- test_api.py: env-configurable admin credentials
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-05-23 15:26:56 +08:00
Your Name
938d26927f
P1/P2: 后端安全与稳定性修复
...
- Agent per-server API Key认证 (agent.py)
- JWT updated_at校验与会话超时 (auth_jwt.py)
- 服务器凭据Fernet加密存储+密码脱敏 (servers.py)
- WebSSH服务器级授权检查 (webssh.py)
- Config同步去重+回滚机制 (sync_engine_v2.py)
- DB层分页offset/limit (server_repo.py)
- session.py logger修复 + @property死代码清理
- 心跳刷入rollback误用修复 (heartbeat_flush.py)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-22 22:28:57 +08:00
Your Name
8530f0e0d5
安全补强: 6项P0/P1漏洞修复
...
P0-1: PHP配置注入防护 — install.py添加_escape_php_string()转义单引号和反斜杠
P0-2: WebSocket JWT校验 — _verify_ws_token()要求exp+sub字段
P1-1: 删除SHA256密码fallback — auth_service.py和auth.py直接import bcrypt
P1-3: LIKE通配符转义 — search.py添加_escape_like()并对所有ilike()加escape参数
P1-2: 安全响应头中间件 — main.py添加SecurityHeadersMiddleware注入4个安全头
P0-3: Refresh Token重用检测 — Admin模型添加token_version字段,token格式改为token:admin_id:version
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-05-22 22:16:50 +08:00
Your Name
e9feaa6cdc
前后端一致性审计 + 批量操作 + 调度同步模式
...
- 服务器列表: 添加批量选择(checkbox)+批量推送/删除操作栏
- 推送页面: 支持从服务器列表页预选服务器跳转(sessionStorage)
- 调度页面: 添加同步模式选择(增量/全量/校验和)
- 后端: PushSchedule模型+Schema+API+ScheduleRunner添加sync_mode字段
- 仪表盘: 移除重复的函数定义和初始化调用
- 数据库迁移: 启动时自动执行schema migration(添加sync_mode列)
- 安装向导: 添加schema migration步骤
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-22 11:01:17 +08:00
Your Name
249a1aaed9
重试队列增强 + 审计分页
...
- 后端: 添加 POST /api/retries/{id}/retry (手动重试) + DELETE /api/retries/{id}
+ 审计日志分页(offset/limit/count) + PushRetryJobRepo新增get_all/get_by_id/delete
- 前端retries: 手动重试按钮、删除按钮、状态过滤、操作人显示、toast反馈
- 前端audit: 分页控件(上一页/下一页)、每页50条、新增retry_job/delete_retry过滤
- 修复index.html: 适配审计API新返回格式(data.items)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-22 09:41:33 +08:00
Your Name
c9a99f4fb3
fix: 全项目文档对齐 + 代码清理
...
代码修复:
- web/agent/agent.py: datetime.utcnow() → datetime.now(timezone.utc)
- requirements.txt: 移除 paramiko==3.5.0 (已无活跃引用)
- 删除 server/infrastructure/ssh/pool.py (DEPRECATED, 无引用)
连接池三层对齐 (config.py/.env.example/session.py):
- DB_POOL_SIZE 100→160, DB_MAX_OVERFLOW 100→120
- 基于 MySQL max_connections=400, install.php 公式
文档修复 (21项):
- P0: 硬编码域名/IP替换为配置变量占位符
- P1: 10个过时设计文档加归档标注 (引用旧文件结构)
- P2: step-3-webssh报告 paramiko引用修正
- 6份审查报告连接池参数勘误 100/100→160/120
- ECC安全报告 EC5 datetime.utcnow 标记已修复
- docs/README.md 文档索引重写
- docs/memory/mem_nexus_overview.md 移除硬编码凭证
- docs/project/tech-stack-inventory.md paramiko标记已移除
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-22 08:19:56 +08:00
Your Name
ead4b2580f
fix: 3 code bugs + test fixes (46/46 passing)
...
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
1. infrastructure/__init__.py: remove nonexistent get_ssh_pool import,
use lazy __getattr__ to avoid triggering MySQL engine at import time
2. auth_service.py + auth_jwt.py: JWT sub field must be string
(PyJWT 2.12+ enforces RFC 7519), decode with int() conversion
3. session.py: lazy engine init — engine created on first access
instead of module import time, allows testing without MySQL
4. Tests: fix Column default assertions (SQLAlchemy defaults only
apply on DB INSERT), fix Request.url mock for Starlette
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-21 22:30:34 +08:00
Your Name
539c33ef42
feat: Nexus 6.0 6-step implementation (Step 0-5)
...
Step 0: Infrastructure hardening — Redis BlockingConnectionPool,
WebSocket two-layer (memory+Redis Pub/Sub), JWT auth, DB session leak fix
Step 1: Data layer — 4 new tables (platforms/nodes/command_logs/ssh_sessions),
data migration (category→Node), repos + API routes
Step 2: Auth layer — JWT middleware on all routes, TOTP JWT integration
Step 3: Web SSH — asyncssh connection pool, /ws/terminal endpoint,
xterm.js frontend, Koko protocol
Step 4: Sync engine v2 — file/command/config/SFTP modes, parallel execution
Step 5: Frontend migration — 12 Tailwind CSS v4 + Alpine.js pages,
PHP-FPM removal from nginx config
21 Python backend + 12 HTML frontend + 2 deploy configs + 3 test files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-21 22:11:38 +08:00
Your Name
f9045a8404
refactor: 仓库结构扁平化 + PHP前端合并到Nexus仓库
...
- 将 Nexus/Nexus/* 移到仓库根目录(消除双层嵌套)
- 删除旧的多层空壳目录 (server/, web/, agent/, deploy/, docs/)
- 将PHP前端 (web/) 合并进Nexus仓库 — 统一管理
- 部署时 git clone Nexus 仓库即可,不再需要两个仓库
目录结构:
server/ ← Python FastAPI后端
web/ ← PHP前端 (install.php, config.php, etc)
deploy/ ← Supervisor + Shell健康检查
docs/ ← 部署文档
tests/ ← 测试
.env ← 不在git中 (install.php生成)
.gitignore ← 排除 .env, SECRETS.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-20 17:24:21 +08:00