小优化,产品愿景,视觉规范,交互和导航大版本

This commit is contained in:
Nostars Developer
2026-04-16 18:11:35 +08:00
parent 5878f7d9f4
commit 10f9c0061a
51 changed files with 5010 additions and 847 deletions

38
.cursor/hooks/README.md Normal file
View File

@@ -0,0 +1,38 @@
# Cursor Hooks 说明
## 结构
```
hooks/
├── run-hook.ps1 # Windows dispatcher读取 local-env.json 后分发)
├── session-init.ps1 # sessionStart hookPowerShell 版)
├── session-init.sh # sessionStart hookbash 版)
├── check-changelog.ps1 # stop hookPowerShell 版)
├── check-changelog.sh # stop hookbash 版)
└── README.md # 本文件
```
## 跨平台适配
`hooks.json` 中的 `command` 字段是**平台绑定的**——Windows 用 `powershell`macOS/Linux 用 `bash`
### Windows当前
hooks.json 使用 `powershell ... run-hook.ps1` 作为入口dispatcher 根据
`.cursor/local-env.json``shell` 字段决定执行 `.ps1` 还是 `.sh` 脚本。
### 迁移到 macOS / Linux
将 hooks.json 的 command 改为直接调用 `.sh` 脚本:
```json
{
"version": 1,
"hooks": {
"sessionStart": [{ "command": "bash .cursor/hooks/session-init.sh", "timeout": 5 }],
"stop": [{ "command": "bash .cursor/hooks/check-changelog.sh", "timeout": 10, "loop_limit": 1 }]
}
}
```
同时更新 `.cursor/local-env.json``shell` 字段为 `bash``zsh`

View File

@@ -0,0 +1,58 @@
#!/usr/bin/env bash
# Changelog sync guard — stop hook (bash 版)
input=$(cat)
# === 豁免检查 1环境变量跳过标志 ===
if [ -n "$CURSOR_SKIP_CHANGELOG" ]; then
echo '{}'; exit 0
fi
# === 豁免检查 2从 stdin 解析 composer_mode ===
mode=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('composer_mode',''))" 2>/dev/null || echo "")
if [ -n "$mode" ] && [ "$mode" != "agent" ]; then
echo '{}'; exit 0
fi
# === 豁免检查 3从 stdin 文本匹配 debug 上下文关键词 ===
if echo "$input" | grep -qiE '"mode"\s*:\s*"debug"|debug[\s_-]?mode|Debug Mode'; then
echo '{}'; exit 0
fi
changelog=".cursor/changelog/changelog-headlines.md"
srcDir="art-agent"
# === 豁免检查 4changelog 文件不存在 ===
if [ ! -f "$changelog" ]; then
echo '{}'; exit 0
fi
clMtime=$(stat -c %Y "$changelog" 2>/dev/null || stat -f %m "$changelog" 2>/dev/null)
# === 豁免检查 5ack 标记文件足够新 ===
ackFile=".cursor/changelog/.changelog-ack"
if [ -f "$ackFile" ]; then
ackMtime=$(stat -c %Y "$ackFile" 2>/dev/null || stat -f %m "$ackFile" 2>/dev/null)
if [ "$ackMtime" -ge "$clMtime" ] 2>/dev/null; then
echo '{}'; exit 0
fi
fi
# === 豁免检查 6stdin 中无文件编辑证据 ===
if ! echo "$input" | grep -qE 'StrReplace|Write\s*tool|edit_file|file_write|write_to_file|Created file|Modified file|Wrote contents|"tool"\s*:\s*"(str_replace|write|edit)"'; then
echo '{}'; exit 0
fi
# === 核心检查:是否有源文件比 changelog 更新 ===
newerFile=$(find "$srcDir" -type f \( -name "*.py" -o -name "*.tsx" -o -name "*.ts" -o -name "*.css" \) \
! -path "*/node_modules/*" ! -path "*/.next/*" ! -path "*/__pycache__/*" ! -path "*/venv/*" \
-newer "$changelog" -print -quit 2>/dev/null)
if [ -n "$newerFile" ]; then
fname=$(basename "$newerFile")
msg="[Hook] Source file updated (e.g. $fname) but changelog not synced. Run dev-changelog Skill operation A NOW to write all three changelog layers."
echo "{\"followup_message\":\"$msg\"}"
else
echo '{}'
fi
exit 0

View File

@@ -0,0 +1,35 @@
# run-hook.ps1 — 通用 hook dispatcher
# 从 .cursor/local-env.json 读取 shell 类型,决定执行 .ps1 还是 .sh 脚本
# 用法powershell -ExecutionPolicy Bypass -File .cursor/hooks/run-hook.ps1 <hook-name>
# 示例run-hook.ps1 session-init → 执行 session-init.ps1 或 session-init.sh
param([string]$HookName)
$localEnvPath = ".cursor\local-env.json"
$shell = "powershell"
if (Test-Path $localEnvPath) {
try {
$config = Get-Content $localEnvPath -Raw | ConvertFrom-Json
if ($config.shell) { $shell = $config.shell }
} catch {}
}
$hookDir = ".cursor\hooks"
$input = [Console]::In.ReadToEnd()
if ($shell -eq "powershell") {
$scriptPath = Join-Path $hookDir "$HookName.ps1"
if (Test-Path $scriptPath) {
$input | powershell -ExecutionPolicy Bypass -File $scriptPath
} else {
Write-Output '{}'
}
} else {
$scriptPath = Join-Path $hookDir "$HookName.sh"
if (Test-Path $scriptPath) {
$input | bash $scriptPath
} else {
Write-Output '{}'
}
}

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# session-init.sh — 会话启动时检测 composer_mode非 agent 模式设置跳过标志
input=$(cat)
mode=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('composer_mode',''))" 2>/dev/null || echo "")
rm -f ".cursor/changelog/.changelog-ack"
if [ -n "$mode" ] && [ "$mode" != "agent" ]; then
echo "{\"env\":{\"CURSOR_SKIP_CHANGELOG\":\"1\",\"CURSOR_COMPOSER_MODE\":\"$mode\"}}"
else
echo "{}"
fi
exit 0